/**
 * Lightboxer Class
 *
 * @static
 */
Core.createNamespace('nl.code.lightbox');
nl.code.lightbox.Lightboxer = {
    /**
     * @var Pager, a refrence to this site's pager
     */
    pager: null,

    /**
     * @var boolean, if the lightbox becomes bigger then the visible screen, then make it fit the screen
     */
    fit_screen: false,

    /**
     * @var integer, the depth (z-index) at which the lightboxes are displayed
     */
    zIndex: 800,

    /**
     * @var array
     */
    lightbox_arr: [],

    /**
     * @var array
     */
    visible_lightbox_arr: [],

    /**
     * The Lightboxer has it's own parseLinks method
     * The PageData class does not contain this method because there would be a from of "tight coupling" between Lightboxer and PageData
     * This is a piece of functionality that stands on it's own
     *
     * @param Pager, refrence to this site's pager
     * @param Element, the html element to scan for anchors that refer to a lightbox, defaults to body
     * @return void
     */
    parseLightboxLinks: function(pager, root) {
        // store the reference to the pager in the static attribute
        nl.code.lightbox.Lightboxer.pager = pager;

        // if no Element is provided default to the body element
        if (! $type(root)) {
            root = $(document.body);
        }

        // get all anchors and loop through them
        var anchor_arr = root.getElements('a');
        for (var i = 0; i < anchor_arr.length; i++) {
            // we only need enchors with an rel attribute with a value "lightbox"
            if (anchor_arr[i].get('rel') != 'lightbox') {
                continue;
            }

            // remove all already attached onclick events
            anchor_arr[i].removeEvents('click');

            anchor_arr[i].addEvent('click', function(event) {
                event.stop();

                nl.code.pager.PageData.request(this.get('href'), nl.code.lightbox.Lightboxer);
            });
        }

        // if the user presses "ESC" hide the active lightbox
        document.removeEvents();
        document.addEvent('keydown', function(e) {
            var event = new Event(e);

            if (event.key == 'esc') {
                nl.code.lightbox.Lightboxer.hideLightbox();
            }
        });
    },

    /**
     * JSON request completed
     *
     * @param Object, the response JSON object {'content': content, 'width': width, 'height': height, 'scripts': scripts}
     * @paran string, the response JSON as text
     * @return void
     */
    setContent: function(JSON, text) {
        nl.code.lightbox.Lightboxer.openLightbox(JSON, text);
    },

    /**
     * @param JSON
     * @2retrun void
     */
    openLightbox: function(JSON) {
        // check if the lightbox is already generated and in the cache
        var lightbox = nl.code.lightbox.Lightboxer.findLightbox(JSON.id);

        // create the lightbox if it is not found in the cache
        if (! lightbox) {
            lightbox = nl.code.lightbox.Lightboxer.createLightbox(JSON.id);
        } else {
            // if the lightbox was already in the visible array then remove it
            if (nl.code.lightbox.Lightboxer.visible_lightbox_arr.contains(lightbox) && nl.code.lightbox.Lightboxer.visible_lightbox_arr[nl.code.lightbox.Lightboxer.visible_lightbox_arr.length - 1] != lightbox) {
                nl.code.lightbox.Lightboxer.visible_lightbox_arr.erase(lightbox);
            }
        }

        // set the z-index for the lightbox
        lightbox.setZIndex(nl.code.lightbox.Lightboxer.zIndex++);

        // add the lightbox to the stack array
        nl.code.lightbox.Lightboxer.visible_lightbox_arr.push(lightbox);

        $(document.body).addClass('lightbox');
        lightbox.show(JSON);
    },

    /**
     * Try to find a lightbox in the cache
     *
     * @param string, the id of the lightbox
     * @return Lightbox or false
     */
    findLightbox: function(id) {
        for (var i = 0; i < nl.code.lightbox.Lightboxer.lightbox_arr.length; i++) {
            if (nl.code.lightbox.Lightboxer.lightbox_arr[i].id == id) {
                return nl.code.lightbox.Lightboxer.lightbox_arr[i];
            }
        }

        return false;
    },

    /**
     * Create a lightbox
     *
     * @param integer
     * @return void
     */
    createLightbox: function(id) {
        var lightbox = new nl.code.lightbox.Lightbox(id);

        nl.code.lightbox.Lightboxer.lightbox_arr.push(lightbox);

        return lightbox;
    },

    /**
     * @param int
     * @return int
     */
    calculateCanvasXPosition: function(width) {
        var x = (Window.getSize().x - width) / 2;

        if (x < 10) {
            x = 10;
        }

        x += Window.getScroll().x;

        return x;
    },

    /**
     * @param int
     * @return int
     */
    calculateCanvasYPosition: function(height) {
        var y = (Window.getSize().y - height) / 2;

        if (y < 10)  {
            y = 10;
        }

        y += Window.getScroll().y;

        return y;
    },

    /**
     * @param int
     * @return int
     */
    calculateWindowWidth: function(canvas_width) {
        var x = nl.code.lightbox.Lightboxer.calculateCanvasXPosition(canvas_width);
        var min_width = x + canvas_width;
        var win_width = Window.getScrollSize().x;

        if (min_width > win_width) {
            return min_width;
        }

        return win_width;
    },

    /**
     * @param int
     * @return int
     */
    calculateWindowHeight: function(canvas_height) {
        var y = nl.code.lightbox.Lightboxer.calculateCanvasYPosition(canvas_height);
        var min_height = y + canvas_height;
        var win_height = Window.getScrollSize().y;

        if (min_height > win_height) {
            return min_height;
        }

        return win_height;
    },

    /**
     * Removes the focus of the currently active lightbox
     *
     * @return void
     */
    hideLightbox: function() {
        if (! nl.code.lightbox.Lightboxer.visible_lightbox_arr.length) {
            return;
        }

        var index = nl.code.lightbox.Lightboxer.visible_lightbox_arr.length - 1;

        nl.code.lightbox.Lightboxer.visible_lightbox_arr[index].hide();
        nl.code.lightbox.Lightboxer.visible_lightbox_arr.erase(nl.code.lightbox.Lightboxer.visible_lightbox_arr[index]);

        if (! nl.code.lightbox.Lightboxer.visible_lightbox_arr.length) {
            $(document.body).removeClass('lightbox');
        }
    },

    /**
     * Remove the focus of all lightboxes
     *
     * @return void
     */
    hideAllLightboxes: function() {
        for (var i = 0; i < nl.code.lightbox.Lightboxer.visible_lightbox_arr.length; i++) {
            nl.code.lightbox.Lightboxer.visible_lightbox_arr[i].hide();
        }

        nl.code.lightbox.Lightboxer.visible_lightbox_arr = [];
        $(document.body).removeClass('lightbox');
    }
};
