/**
 * LightboxAnimation Class
 */
LightboxAnimation = new Class({
    /**
     * @var lightbox
     */
    lightbox: null,

    /**
     * @var Object
     */
    data: null,

    /**
     * @var Object
     */
    options: null,

    /**
     * @var Number
     */
    overlay_opacity: null,

    /**
     * @var Number
     */
    canvas_width: null,

    /**
     * @var Number
     */
    canvas_height: null,

    /**
     * Indicates if the animation is in progress
     * @var boolean
     */
    animating: false,

    /**
     * The anchors that control the lightbox, i.e. close lightbox or next image
     * @var array
     */
    control_anchor_arr: [],

    /**
     * @var (Fx)Chain
     */
    fx_chain: null,

    /**
     * Constructor
     *
     * @param Lightbox
     * @param Object, options
     */
    initialize: function(lightbox, options) {
        this.lightbox           = lightbox;
        this.options            = options;
        this.control_anchor_arr = this.getControlAnchorArr();

        if (this.options.overlay_color) {
            this.lightbox.overlay.setStyle('background-color', this.options.overlay_color);
        }
    },

    /**
     * @return array
     */
    getControlAnchorArr: function() {
        var anchor_arr = [];

        var close_anchor = this.lightbox.container.getElement('.js-lightbox-close');
        if (close_anchor) {
            anchor_arr.push(close_anchor);
        }

        var next_anchor = this.lightbox.container.getElement('.js-lightbox-next');
        if (next_anchor) {
            anchor_arr.push(next_anchor);
        }

        var previous_anchor = this.lightbox.container.getElement('.js-lightbox-previous');
        if (previous_anchor) {
            anchor_arr.push(previous_anchor);
        }

        return anchor_arr;
    },

    /**
     * @param string "visibility" or "hidden"
     * @return void
     */
    setControlAnchorsVisibility: function(visibility) {
        for (var i = 0; i < this.control_anchor_arr.length; i++) {
            this.control_anchor_arr[i].setStyle('visibility', visibility);
        }
    },

    /**
     * @param Object, width, height, content, trigger, class
     * @return void
     */
    show: function(data) {
        this.data = data;

        this.setControlAnchorsVisibility('hidden');

        this.lightbox.setContent(this.data.content);

        var thisObject = this;

        // if there was a fx chain stop it
        if (this.fx_chain) {
            this.fx_chain.stop();
        }

        // create an fx chain
        this.fx_chain = new nl.code.fx.Chain({
            onChainFinished: function() {
                thisObject.onLightboxVisible();
            }
        });


        // if the lightbox is already visible just resize it
        if (this.lightbox.visible) {
            this.storeAttributes();
            this.lightbox.content.setStyle('display', 'none');

            this.fx_chain.addStep(new nl.code.fx.Fx({
                duration: 200,
                transition: Fx.Transitions.Quart.easeIn,
                onSet: function(value) {
                    thisObject.canvasSize(value);
                }
            }), 0, 100);
        } else {
            // position the lightbox in the center of the browser
            if (!this.animating) {
                this.setBaseDimensions();
            }

            this.storeAttributes();

            this.fx_chain.addStep(new nl.code.fx.Fx({
                duration: 100,
                transition: Fx.Transitions.Linear,
                onSet: function(value) {
                    thisObject.overlayOpacity(value);
                }
            }), 0, 100);

            this.fx_chain.addStep(new nl.code.fx.Fx({
                duration: 200,
                transition: Fx.Transitions.Quart.easeOut,
                onSet: function(value) {
                    thisObject.canvasSize(value);
                }
            }), 0, 100);
        }

        this.animating = true;
        this.fx_chain.start();
    },

    storeAttributes: function() {
        // store the current width, height and opacity to determine the delta width, height and opacity
        this.canvas_width    = this.lightbox.canvas.getSize().x;
        this.canvas_height   = this.lightbox.canvas.getSize().y;
        this.overlay_opacity = this.lightbox.overlay.getStyle('opacity');
    },

    /**
     * @return void
     */
    onLightboxVisible: function() {
        this.animating = false;
        this.setControlAnchorsVisibility('visible');
        this.lightbox.showContent();
    },

    /**
     * @return void
     */
    onLightboxHidden: function() {
        this.animating = false;
        this.lightbox.hideContent();
    },

    /**
     * @return void
     */
    hide: function() {
        this.animating = true;
        this.setControlAnchorsVisibility('hidden');
        this.data = {
            width: 0,
            height: 0,
            content: ''
        };
        this.canvas_width    = this.lightbox.canvas.getSize().x;
        this.canvas_height   = this.lightbox.canvas.getSize().y;
        this.overlay_opacity = this.lightbox.overlay.getStyle('opacity');

        // if there was a fx chain stop it
        if (this.fx_chain) {
            this.fx_chain.stop();
        }

        var thisObject = this;
        this.fx_chain = new nl.code.fx.Chain({
            onChainFinished: function() {
                thisObject.onLightboxHidden();
            }
        });
        this.fx_chain.addStep(new nl.code.fx.Fx({
            duration: 200,
            transition: Fx.Transitions.Quart.easeIn,
            onSet: function(value) {
                thisObject.canvasSize(value);
            }
        }), 0, 100);

        this.fx_chain.addStep(new nl.code.fx.Fx({
            duration: 100,
            transition: Fx.Transitions.Linear,
            onSet: function(value) {
                thisObject.overlayOpacity(value);
            }
        }), 0, -100);

        this.lightbox.content.setStyle('display', 'none');

        this.fx_chain.start();
    },

    /**
     * @return void
     */
    setBaseDimensions: function() {
        this.lightbox.content.setStyle('display', 'none');
        this.lightbox.container.setStyle('display', 'block');
        this.lightbox.canvas.setStyles({
            width: 20, 
            left: nl.code.lightbox.Lightboxer.calculateCanvasXPosition(20),
            height: 20,
            top: nl.code.lightbox.Lightboxer.calculateCanvasYPosition(20)
        });
        this.lightbox.overlay.setStyles({
            width: nl.code.lightbox.Lightboxer.calculateWindowWidth(this.data.width),
            height: nl.code.lightbox.Lightboxer.calculateWindowHeight(this.data.height),
            opacity: 0
        });
    },

    /**
     * @var float
     * @return void
     */
    canvasSize: function(value) {
        var percent = value / 100;

        var width  = this.canvas_width + Math.round((this.data.width - this.canvas_width) * percent);
        var height = this.canvas_height + Math.round((this.data.height - this.canvas_height) * percent);

        this.lightbox.canvas.setStyles({
            top: nl.code.lightbox.Lightboxer.calculateCanvasYPosition(height),
            left: nl.code.lightbox.Lightboxer.calculateCanvasXPosition(width),
            width: width,
            height: height
        });
    },

    /**
     * @var float
     * @return void
     */
    overlayOpacity: function(value) {
        // percent: 0.00 to 1.00
        var percent = value / 100;

        // opacity: 0 to 0.4
        var opacity = this.overlay_opacity + ((this.options.overlay_opacity - this.overlay_opacity) * percent);

        this.lightbox.overlay.setStyle('opacity', opacity);
    }
});