// create namespace
Core.createNamespace('nl.code.fx');

/**
 * Custum Chain Fx Class
 *
 * Events 'chainFinished'
 */
nl.code.fx.Chain = new Class({
    /**
     * @implements Options, Events
     */
    Implements: [Options, Events],

    /**
     * @var Object
     */
    options: {
    },

    /**
     * @var Array
     */
    step_arr: [],

    /**
     * @var int
     */
    current_step: null,

    /**
     * Constructor
     *
     * @param Object
     */
    initialize: function(options) {
        this.setOptions(options);
    },

    /**
     * @param Fx
     * @param Number
     * @param Number
     * @return void
     */
    addStep: function(fx, start_value, end_value) {
        if ($type(fx) == 'function') {
            this.step_arr.push(fx);
        } else {
            var thisObject = this;
            fx.addEvent('complete', function() {
                thisObject.onComplete();
            });

            this.step_arr.push({fx: fx, start_value: start_value, end_value: end_value});
        }
    },

    /**
     * @return void
     */
    reset: function() {
        this.current_step = null;
        this.step_arr     = [];
    },

    /**
     * @return void
     */
    start: function() {
        var step = this.getCurrentStep();

        if ($type(step) == 'function') {
            step();
            this.onComplete();
        } else {
            step.fx.start(step.start_value, step.end_value);
        }
    },

    /**
     * Stop the chain by stopping the current step
     *
     * @return void
     */
    stop: function() {
        var step = this.getCurrentStep();

        if ($type(step) != 'function') {
            step.fx.cancel();
        }

        this.reset();
    },

    /**
     * Get the current step
     *
     * @return Fx or function
     */
    getCurrentStep: function() {
        if (this.current_step == null) {
            this.current_step = 0;
        }

        return this.step_arr[this.current_step];
    },

    /**
     * @return void
     */
    onComplete: function() {
        this.current_step++;

        if (this.current_step < this.step_arr.length) {
            this.start();
        } else {
            this.current_step = null;

            this.fireEvent('chainFinished');
        }
    }
});