import is from '@pilotlab/is';
import { ISpeed, IAnimationEaseFunction } from '@pilotlab/animation';
import { NodeChangeOptions, NodeChangeInitiationType } from '@pilotlab/nodes';
import { IPromise, Result } from '@pilotlab/result';
import IAttributeChangeOptions from './interfaces/iAttributeChangeOptions';
import { AttributeChangeActions } from './attributeEnums';


export class AttributeChangeOptions extends NodeChangeOptions {
    constructor(
        action:AttributeChangeActions = AttributeChangeActions.SIGNAL_CHANGE,
        durationSpeed?:(number | ISpeed),
        ease?:IAnimationEaseFunction,
        changeInitiationType?:NodeChangeInitiationType,
        configuration?:Object,
        isInitialize:boolean = true
    ) {
        super(null, null, null, null, null, false);
        if (isInitialize) this.initialize(action, durationSpeed, ease, changeInitiationType, configuration);
    }


    protected p_onInitializeStarted(result:Result<any>, args:any[]):IPromise<any> {
        const action:AttributeChangeActions = args[0];
        const durationSpeed:(number | ISpeed) = args[1];
        const ease:IAnimationEaseFunction = args[2];
        const changeInitiationType:NodeChangeInitiationType = args[3];
        const configuration:Object = args[4];

        this._action = action;

        this.changeInitiationType = is.notEmpty(changeInitiationType) ? changeInitiationType : NodeChangeInitiationType.NONE;

        if (is.notEmpty(durationSpeed)) this.durationSpeed = durationSpeed;
        if (is.notEmpty(ease)) this.ease = ease;
        if (is.notEmpty(configuration)) this.configuration = configuration;

        return result.resolve();
    }


    static get default():IAttributeChangeOptions { return new AttributeChangeOptions(); }
    static get noSaveOrSignal():IAttributeChangeOptions { return new AttributeChangeOptions(AttributeChangeActions.NONE); }
    static get signal():IAttributeChangeOptions { return new AttributeChangeOptions(AttributeChangeActions.SIGNAL_CHANGE); }
    static get save():IAttributeChangeOptions { return new AttributeChangeOptions(AttributeChangeActions.SAVE); }
    static get zero():IAttributeChangeOptions { return new AttributeChangeOptions(AttributeChangeActions.NONE).durationZero; }


    get action():AttributeChangeActions { return this._action; }
    setAction(value:AttributeChangeActions):IAttributeChangeOptions {
        this._action = value;
        return this;
    }
    private _action:AttributeChangeActions = AttributeChangeActions.SIGNAL_CHANGE;


    setDuration(value:(number | ISpeed)):IAttributeChangeOptions {
        this.p_durationSpeed = value;
        return this;
    }
    get durationZero():IAttributeChangeOptions { return this.copy.setDuration(0); }
    get durationDefault():IAttributeChangeOptions { return this.copy.setDuration(null); }


    get noSaveOrSignal():IAttributeChangeOptions { return this.copy.setAction(AttributeChangeActions.NONE); }
    get signal():IAttributeChangeOptions { return this.copy.setAction(AttributeChangeActions.SIGNAL_CHANGE); }
    get save():IAttributeChangeOptions { return this.copy.setAction(AttributeChangeActions.SAVE); }
    get isSignalChange():boolean { return this.action === AttributeChangeActions.SIGNAL_CHANGE || this.action === AttributeChangeActions.SAVE; }
    get isSave():boolean { return this.action === AttributeChangeActions.SAVE; }



    setChangeInitiationType(value:NodeChangeInitiationType):IAttributeChangeOptions {
        this.changeInitiationType = value;
        return this;
    }


    get copy():IAttributeChangeOptions {
        let changeOptionsCopy:IAttributeChangeOptions = new AttributeChangeOptions(this.action, this.durationSpeed, this.ease, this.changeInitiationType, this.configuration);
        changeOptionsCopy.repeatCount = this.repeatCount;
        return changeOptionsCopy;
    }
} // End class


export default AttributeChangeOptions;
