/**
 * Pager Class
 */
Pager = new Class({
    /**
     * Constructor
     */
    initialize: function() {
        this.loading = new Loading();
        this.lightbox_manager = new LightboxManager();

        var thisObject = this;
        var a_arr = $$('a').filterByAttribute('rel', '=', 'lightbox');
        for (var i = 0; i < a_arr.length; i++) {
            a_arr[i].addEvent('click', function(e) {
                new Event(e).stop();

                thisObject.request(this.href);
            });
        }
    },

    ajaxify: function() {
    },

    /**
     * @param string
     * @return void
     */
    request: function(uri) {
        this.loading.show();

        var ajax = new Ajax(uri +'/?ajax', {
            method: 'post',
            evalScripts: true
        });

        ajax.request();
    },

    /**
     * @param string
     * @param string
     * @param integer
     * @param integer or '*'
     * @return void
     */
    pageResponse: function(data) {
        this.loading.hide();

    },

    /**
     * @param string
     * @param string
     * @param integer
     * @param integer or '*'
     * @return void
     */
    lightboxResponse: function(id, data, width, height) {
        this.loading.hide();

        this.lightbox_manager.open(id, data, width, height);
    }
});

/**
 * LightboxManager Class
 */
LightboxManager = new Class({
    initialize: function() {
        this.depth = 800;
        this.lightbox_arr = [];
        this.ghost_container = new GhostContainer();
    },

    /**
     * @param string
     * @param string
     * @param integer
     * @param integer or '*'
     * @return void
     */
    open: function(id, data, width, height) {
        var lightbox = this.find(id);

        if (! lightbox) {
            lightbox = this.create(id);
        }

        this.ghost_container.render(data, width, height, lightbox)
        //lightbox.show(data, width, height);
    },

    /**
     * @param string
     * @return Lightbox
     */
    create: function(id) {
        var lightbox = new Lightbox(this.depth++, id);

        this.lightbox_arr.push({id: id, lightbox: lightbox});

        return lightbox;
    },

    /**
     * @param string
     * @return Lightbox
     */
    find: function(id) {
        for (var i = 0; i < this.lightbox_arr.length; i++) {
            if (this.lightbox_arr[i].id == id) {
                return this.lightbox_arr[i].lightbox;
            }
        }

        return false;
    }
});

/**
 * GhostContainer Class
 */
GhostContainer = new Class({
    /**
     * Constructor
     */
    initialize: function() {
        this.container = new Element('div', {
            'class': 'lightbox-tmp'
        });

        this.container.injectInside(document.body);

        this.content = new Element('div', {
            'class': 'lightbox-tmp-content'
        });

        this.content.injectInside(this.container);
    },

    /**
     * @param string
     * @param integer
     * @param integer or '*'
     * @param Lightbox
     * @return void
     */
    render: function(data, width, height, lightbox) {
        this.data = data;
        this.width = width;
        this.height = height;
        this.lightbox = lightbox;

        if (this.height != '*') {
            this.lightbox.show(this.data, this.width, this.height);
        } else {
            this.content.setStyles({
                width: this.width,
                left: (-2 * this.width)
            })

            this.content.setHTML(this.data);

            var image_arr = $ES('img', this.content);
            var image_src_arr = [];
            for (var i = 0; i < image_arr.length; i++) {
                image_src_arr.push(image_arr[i].src);
            }

            if (image_src_arr.length > 0) {
                var thisObject = this;
                new Asset.images(image_src_arr, {
                    onComplete: function() {
                        thisObject.onImagesLoaded();
                    }
                });
            }
        }
    },

    /**
     * @return void
     */
    onImagesLoaded: function() {
        var coordinates = this.content.getCoordinates();

        this.height = coordinates.height;
        this.lightbox.show(this.data, this.width, this.height);
    }
});


/**
 * Lightbox Class
 */
Lightbox = new Class({
    /**
     * @param integer
     * @param string
     */
    initialize: function(depth, id) {
        this.id = id;

        this.data = '';
        this.width = 0;
        this.height = 0;

        this.lightbox_min_width = 40;
        this.lightbox_min_height = 40;

        var thisObject = this;
        this.container = new Element('div', {
            'styles': {
                'z-index': depth
            },
            'class': 'lightbox'
        });

        this.overlay = new Element('div', {
            'styles': {
                'opacity': 0,
                'width': Window.getScrollWidth().toInt(),
                'height': Window.getScrollHeight().toInt(),
                'z-index': 10
            },
            'events': {
                'click': function() {
                    // do totally nothing
                }
            },
            'class': 'lightbox-overlay'
        });

        this.canvas = new Element('div', {
            'styles': {
                'z-index': 20,
                'width': this.lightbox_min_width,
                'height': this.lightbox_min_height
            },
            'class': 'lightbox-canvas'
        });

        this.content = new Element('div', {
            'class': 'lightbox-content'
        });

        this.container.injectInside(document.body);
        this.overlay.injectInside(this.container);
        this.canvas.injectInside(this.container);
        this.content.injectInside(this.canvas);

        var thisObject = this;
        this.fx = {
            overlay: new Fx.Style(this.overlay, 'opacity', {
                duration: 400, 
                transition: Fx.Transitions.Quart.easeIn,
                onComplete: function() {
                    thisObject.animate('canvas_height');
                }
            }),
            canvas_height: new Fx.Styles(this.canvas, {
                duration: 400, 
                transition: Fx.Transitions.Quart.easeIn,
                onComplete: function() {
                    thisObject.animate('canvas_width');
                }
            }),
            canvas_width: new Fx.Styles(this.canvas, {
                duration: 400, 
                transition: Fx.Transitions.Quart.easeIn,
                onComplete: function() {
                    thisObject.animate('finished');
                }
            })
        }
    },

    /**
     * @param string
     * @param integer
     * @param integer
     * @return void
     */
    show: function(data, width, height) {
        this.data = data;
        this.width = width;
        this.height = height;

        if (this.overlay.getStyle('opacity') == 0) {
            this.animate('init');
        } else if (this.width == this.canvas.getStyle('width').toInt() && this.height == this.canvas.getStyle('height').toInt()) {
            // no animation
            this.setContent();
        } else {
            this.content.setStyle('display', 'none');
            this.animate('canvas_height');
        }
    },

    /**
     * @return void
     */
    setContent: function() {
        this.content.setHTML(this.data);
        this.content.setStyle('display', 'block');
        this.container.setStyle('display', 'block');

        var thisObject = this;
        var anchor_arr = $ES('a', this.content);
        for (var i = 0; i < anchor_arr.length; i++) {
            anchor_arr[i].addEvent('click', function(e) {
                new Event(e).stop();

                if (this.rel == 'close') {
                    thisObject.hide();
                } else {
                    window.pager.request(this.href);
                }
            });
        }
    },

    /**
     * @return void
     */
    hide: function() {
        this.content.setStyle('display', 'none');
        this.content.empty();
        this.container.setStyle('display', 'none');
        this.overlay.setStyle('opacity', 0);
        this.canvas.setStyles({
            width: this.lightbox_min_width, 
            left: ((Window.getWidth().toInt() - this.lightbox_min_width) / 2) + Window.getScrollLeft(),
            height: this.lightbox_min_height,
            top: ((Window.getHeight().toInt() - this.lightbox_min_height) / 2) + Window.getScrollTop()
        });
    },

    /**
     * @param string
     * @return void
     */
    animate: function(fx) {
        switch (fx) {
            case 'init':
                this.content.setStyle('display', 'none');
                this.container.setStyle('display', 'block');
                this.canvas.setStyles({
                    width: this.lightbox_min_width, 
                    left: ((Window.getWidth().toInt() - this.lightbox_min_width) / 2) + Window.getScrollLeft(),
                    height: this.lightbox_min_height,
                    top: ((Window.getHeight().toInt() - this.lightbox_min_height) / 2) + Window.getScrollTop()
                });

                this.animate('overlay');
                break;
            case 'overlay':
                this.fx.overlay.start(0, 0.8);
                break;
            case 'canvas_height':
                if (this.canvas.getStyle('height').toInt() == this.height) { 
                    this.animate('canvas_width');
                } else{
                    this.fx.canvas_height.start({
                        'top': ((Window.getHeight().toInt() - this.height) / 2) + Window.getScrollTop(),
                        'height': this.height
                    });
                }
                break;
            case 'canvas_width':
                if (this.canvas.getStyle('width').toInt() == this.width) {
                    this.animate('finished');
                } else {
                    this.fx.canvas_width.start({
                        'width': this.width,
                        'left': ((Window.getWidth().toInt() - this.width) / 2) + Window.getScrollLeft()
                    });
                }
                break;
            case 'finished':
                this.setContent();
                break;
        }
    }
});

/**
 * Loading Class
 * This class is only used to prevent that users can click on an anchor or a button
 */
Loading = new Class({
    /**
     * Constructor
     */
    initialize: function() {
        this.container = new Element('div', {
            'styles': {
                'width': Window.getScrollWidth().toInt(),
                'height': Window.getScrollHeight().toInt()
            },
            'events': {
                'click': function() {
                    // do totally nothing
                }
            },
            'class': 'loading'
        });

        this.container.injectInside(document.body);
    },

    /**
     * @return void
     */
    show: function() {
        this.container.setStyle('display', 'block');
    },

    /**
     * @return void
     */
    hide: function() {
        this.container.setStyle('display', 'none');
    }
});

/**
 * Start pager
 */
window.addEvent('load', function() {
    window.pager = new Pager();
});

