/**
 * @author Bartek
 */
var ZoomBox = new Class({
    Implements: Options,
    options: {
        selector: 'zoombox',
        next: 'next',
        prev: 'previous',
        close: 'close',
        back: false,
        slideshow: null,
        thumbnails: null,
        fullscreen: null,
        scrolling: null,
        caption: 1,
        elements: null,
        keys: 1
    },
    loader: null,
    backdrop: null,
    fx: null,
    caption: null,
    zbHash: null,
    keys: null,
    next: null,
    prev: null,
    current: null,
    timer: null,
    period: null,
    initialize: function(options) {
        var zb = this;
        this.setOptions(options);
        if (this.options.back) {
            this.backdrop = new Element('div', {
                'class': 'zbBackground'
            }).fade('hide').inject(document.body).addEvent('click',function(){
                zb.close($('zbImage'));
            });
            window.addEvent('resize',function(){
                zb.backdrop.setStyles({
                    'width': window.getSize().x + 'px',
                    'height': window.getSize().y + 'px'
                });
                if(zb.options.fullscreen) {
                    zb.caption.unpin().setStyles({
                        'width': window.getSize().x + 'px',
                        'top': window.getSize().y + window.getScroll().y - zb.caption.getSize().y + 'px'
                    }).pin();
                }
            });
        }
        this.loader = new Element('div',{
            'class':'zbLoader',
            'id':'zbLoader'
        }).fade('hide').inject(document.body);
        this.caption = new Element('div',{
            'class':'zbCaption',
            'id':'zbCaption',
            'html': '<span></span>'
        }).fade('hide').inject(this.loader,'after');
        this.closer = new Element('a',{
            'class':'zbClose',
            'html':this.options.close,
            'href':'#'
        }).fade('hide').inject(this.caption,'after').addEvent('click',function(e){
            var e = new Event(e);
            e.preventDefault();
            zb.close($('zbImage'));
        });
        this.fx = new Fx.Morph(this.loader,{duration:400,wait:false});
        if(this.options.keys) {
            this.keys = new Keyboard({
                eventType: 'keyup', 
                events: { 
                    'esc': function(){
                        zb.close($('zbImage'));
                    },
                    'right': function() {
                        if(zb.next) zb.slideTo($('zbImage'),zb.next);
                    },
                    'left': function() {
                        if(zb.prev) zb.slideTo($('zbImage'),zb.prev);
                    }/*,
                    'p': function() {
                        if (zb.period) {
                            alert(typeof zb.period + ' pauza slideshowa');
                            $clear(zb.period);
                            zb.period = -1;
                        }
                    },
                    'r': function() {
                        if (zb.period) {
                            alert(typeof zb.period + ' resume slideshowa');
                            zb.period = 1;
                            zb.slideTo($('zbImage'),zb.next);
                        }
                    }*/
                }
            });
            this.keys.deactivate();
        }
        if (this.options.elements) this.wrap(this.options.elements);
        else this.wrap(this.options.selector);
		if (!Browser.Engine.trident) {
            $$('embed').each(function(el){
				var x = el.getParent();
				el.dispose().set('wmode','opaque').inject(x);
			});
        }
    },
    wrap: function(selector) {
        var zb = this;
        if(this.options.elements) {
            this.options.elements.each(function(el,index){
                var trigger = new Element('a',{
                    'class':'zbElements',
                    'href':el[0],
                    'title':el[1]
                }).inject(document.body).pin();
                trigger.store('index',index + 1).store('length',zb.options.elements.length);
            });
            var a = $$('.zbElements');
            a.each(function(el,i){
                if(i>0) el.store('prev',a[i-1]);
                if(i<a.length) el.store('next',a[i+1]);
                if(i==0) zb.click(el);
            });
        }
        else {
            $$('a[rel="' + selector + '"]').each(function(el){
                el.addEvent('click',function(e){
                    var e = new Event(e);
                    e.preventDefault();
                    if($('zbImage') && zb.loader.retrieve('el') == el) zb.close($('zbImage'));
                    else if($('zbImage')) zb.slideTo($('zbImage'),el);
                    else zb.click(el);
                });
            });
            this.zbHash = new Hash();
            $$('a[rel^="' + selector + '["]').each(function(el){
                if (!zb.zbHash.has(el.get('rel'))) {
                    var zbArray = $$('a[rel="' + el.get('rel') + '"]');
                    if (zbArray.length > 0) zb.zbHash.set(el.get('rel'), zbArray);
                }
            });
            zb.zbHash.each(function(val,key){
                val.each(function(el,i){
                    el.store('index',i + 1).store('length',val.length);
                    if(i>0) el.store('prev',val[i-1]);
                    if(i<val.length) el.store('next',val[i+1]);
                    el.addEvent('click',function(e){
                        var e = new Event(e);
                        e.preventDefault();
                        if($('zbImage') && zb.loader.retrieve('el') == el) zb.close($('zbImage'));
                        else if($('zbImage')) zb.slideTo($('zbImage'),el);
                        else zb.click(el);
                    });
                });
            }); 
        }
    },
    click: function(el) {
        this.current = el;
        this.loading(el);
        var zb = this;
        var image = new Asset.image(el.get('href'), {
            onload: function(){
                if(el == zb.current) zb.zoom(image,el);
            }
        });
        var number = '';
        if(el.retrieve('index') && el.retrieve('length')) var number = el.retrieve('index') + '/' + el.retrieve('length');
        var title = el.get('title');
        if (title == null && el.getElement('img') && el.getElement('img').get('alt')) title = el.getElement('img').get('alt');
        if (title == null) title = '';
        else number = number + ':'
        this.caption.getElement('span').set('html', number + ' <strong>' + title + '</strong>').setStyle('display','none');
        this.closer.fade('hide');
        if (this.options.fullscreen && this.options.caption > 0) {
            this.caption.getElement('span').setStyle('display', 'block');
            this.closer.pin().setStyle('display', 'block');
        }
        if(el.retrieve('next')) {
            zb.next = el.retrieve('next');
            var next = new Element('a',{
                'href':zb.next.get('href'),
                'html':this.options.next,
                'class':'zbNext'
            }).inject(this.caption.getElement('span')).addEvent('click',function(e){
                var e = new Event(e);
                e.preventDefault();
                zb.slideTo(image,zb.next);
            });
        }
        else zb.next = null;
        if(el.retrieve('prev')) {
            zb.prev = el.retrieve('prev');
            var prev = new Element('a',{
                'href':zb.prev.get('href'),
                'html':this.options.previous,
                'class':'zbPrev'
            }).inject(this.caption.getElement('span'),'top').addEvent('click',function(e){
                var e = new Event(e);
                e.preventDefault();
                zb.slideTo(image,zb.prev);
            });
        }
        else zb.prev = null;
        if (this.options.back) {
            //alert(this.options.back);
            if (Browser.Engine.trident4 || !zb.backdrop.hasClass('isPinned')) {
                var scroll = window.getScroll();
            }
            else 
                var scroll = new Hash({
                    x: 0,
                    y: 0
                });
            this.backdrop.setStyles({
                'display': 'block',
                'width': window.getSize().x + 'px',
                'height': window.getSize().y + 'px',
                'top': scroll.y + 'px',
                'left': scroll.x + 'px'
            }).fade(0.7).pin().addClass('isPinned');
			if (Browser.Engine.trident) {
				this.iframe = new Element('iframe').inject(this.backdrop).set('width', window.getSize().x).set('height', window.getSize().y).setOpacity('0.01');
			}
        }
    },
    loading: function(el) {
        if(el.getElement('img')) var img = el.getElement('img');
        else var img = el;
        this.loader.setStyles({
            'top':img.getPosition().y + 'px',
            'left':img.getPosition().x + 'px',
            'width':img.getSize().x - parseInt(this.loader.getStyle('border-left-width')) - parseInt(this.loader.getStyle('border-right-width')) + 'px',
            'height':img.getSize().y  - parseInt(this.loader.getStyle('border-top-width')) - parseInt(this.loader.getStyle('border-right-width')) + 'px',
            'background-image':''
        }).store('el',el).store('caption',el.get('title')).fade(0.5);
    },
    zoom: function(img) {
        var zb = this;
        if(this.options.keys) this.keys.activate();
        img.inject(this.loader,'after').fade('hide').set('id','zbImage');
        var x = img.get('width');
        var y = img.get('height');
        var m = 0;
        if(this.options.fullscreen) m = zb.caption.getSize().y;
        var w = window.getSize();
        var s = window.getScroll();
        if (x > w.x) {
            img.set('width',w.x - 60);
            img.set('height',y * ((w.x - 60) / x));
        }
        if (img.get('height') > w.y) {
            img.set('height',w.y - m - 20);
            img.set('width',x * ((w.y - m - 60) / y));
        }
        img.setStyles({
            'position':'absolute',
            'top':s.y + (w.y / 2) - (img.get('height') / 2) + 'px',
            'left':s.x + (w.x / 2) - (img.get('width') / 2) + 'px'
        }).pin();
        if(zb.options.fullscreen) {
            zb.caption.getElement('span').setStyle('display','block');
            zb.caption.unpin().setStyles({
                'width':w.x + 'px',
                'top':s.y + w.y - zb.caption.getSize().y + 'px',
                'left':0,
                'display':'block'
            }).pin();
            zb.closer.setStyle('display','block');
        }
        else {
            (function(){
                zb.caption.getElement('span').setStyle('display','block');
                zb.caption.unpin().setStyles({
                    'width':img.get('width') + 'px',
                    'top':window.getScroll().y + (window.getSize().y / 2) + (img.getSize().y / 2) - zb.caption.getSize().y + 'px',
                    'left':img.getPosition().x + 'px',
                    'display':'block'
                }).fade('hide').pin();
                zb.closer.pin();
                zb.closer.setStyles({
                    'top': parseInt(img.getStyle('top')) + 8 + 'px',
                    'left':img.getPosition().x + (img.getSize().x) - 24 + 'px',
                    'display':'block'
                }).fade('hide');
                if(Browser.Engine.trident4) {
                    zb.closer.unpin();
                    window.addEvent('scroll',function(){zb.closer.setStyle('top',parseInt(img.getStyle('top')) + 8 + 'px');});
                }
            }).delay(200);
        }
        if(!Browser.Engine.trident4) this.loader.pin();
        this.loader.fade(0.8);
        this.fx.start({
            'top':img.getPosition().y - parseInt(this.loader.getStyle('border-top-width')) + 'px',
            'left':img.getPosition().x - parseInt(this.loader.getStyle('border-left-width')) + 'px',
            'width':img.getSize().x + 'px',
            'height':img.getSize().y + 'px'
        });
        (function(){
            if (Browser.Engine.trident4) {
                zb.loader.setStyles({
                    'top':img.getPosition().y - parseInt(zb.loader.getStyle('border-top-width')) + 'px',
                    'left':img.getPosition().x - parseInt(zb.loader.getStyle('border-left-width')) + 'px'
                });
            }
            zb.loader.pin();
            img.fade(1);
            img.addEvent('click', function(){
                //zb.close(img);
            });
            if(zb.options.caption==1) 
                img.addEvent('mouseover',function(){
                    zb.showcaption(img);
                });
            else if (zb.options.caption==2)
                zb.showcaption(img);
        }).delay(500);
        if(zb.options.slideshow && zb.next) {
            zb.timer = zb.options.slideshow;
            var checkPeriod = function() {
                zb.timer = zb.timer - 500;
                if (parseInt(zb.timer) < 0) {
                    $clear(zb.period);
                    zb.slideTo($('zbImage'),zb.next);
                }
            };
            if(zb.period > -1) zb.period = (function(){
                checkPeriod();
            }).periodical(500);
        }
    },
    close: function(img) {
        if (this.options.back) {
			this.backdrop.setStyle('display', 'none').fade('hide').unpin();
			if(Browser.Engine.trident) this.iframe.destroy();
		}
        if(this.options.keys) this.keys.deactivate();
        var zb = this;
        if(zb.period) $clear(zb.period);
        if(img) img.unpin().dispose();
        this.loader.setStyle('background-image','none');
        if(this.loader.retrieve('el').getElement('img'))
        var el = this.loader.retrieve('el').getElement('img');
        else var el = this.loader.retrieve('el');
        this.loader.unpin().fade(0.5);
        this.fx.start({
            'top':el.getPosition().y - parseInt(el.getStyle('border-top-width')) + 'px',
            'left':el.getPosition().x - parseInt(el.getStyle('border-left-width')) + 'px',
            'width':el.getSize().x + 'px',
            'height':el.getSize().y + 'px'
        });
        (function(){
            zb.loader.fade(0);
        }).delay(500);
        this.caption.getElement('span').empty().setStyle('display','none');
        this.closer.fade('hide').setStyle('display','none');
        zb.next = null;
        zb.prev = null;
        zb.current = null;
    },
    showcaption:function(img) {
        var zb = this;
        if (!this.options.fullscreen || this.options.caption == 1) {
            this.caption.fade(0.7);
            this.closer.fade(0.7);
        }
        else {
            this.caption.fade('show').setOpacity(0.7);
            this.closer.fade('show').setOpacity(0.7);
        }
        if(zb.options.caption == 1) {
            img.addEvent('mouseleave',function(){
                zb.caption.fade(0);
                zb.closer.fade(0);
            });
            zb.caption.addEvents({
                'mouseenter':function(){
                    this.fade(0.7);
                    zb.closer.fade(0.7);
                },
                'mouseleave':function(){
                    this.fade(0);
                    zb.closer.fade(0);
                }
            });
            zb.closer.addEvents({
                'mouseenter':function(){
                    this.fade(0.7);
                    zb.caption.fade(0.7);
                },
                'mouseleave':function(){
                    this.fade(0);
                    zb.caption.fade(0);
                }
            });
        }       
    },
    slideTo:function(img,el) {
        var zb = this;
        if (this.options.scroll) {
            var scrollFx = new Fx.Scroll(window);
            scrollFx.start(0,el.getPosition().y - (window.getSize().y /2 - el.getSize().y/2));
        }
        if(this.period) $clear(zb.period);
        if (!this.options.fullscreen) {
            this.caption.fade('hide').getElement('span').setStyle('display', 'none').empty();
            this.closer.fade('hide').setStyle('display','none');
        }
        if (this.loader.retrieve('el').getElement('img')) var prevEl = this.loader.retrieve('el').getElement('img');
        else var prevEl = this.loader.retrieve('el');
        if(el.getElement('img')) var t = el.getElement('img');
        else var t = el;
        this.loader.unpin().setStyles({
            'top':window.getScroll().y + t.getPosition().y - parseInt(el.getStyle('border-top-width')) + 'px',
            'left':t.getPosition().x - parseInt(el.getStyle('border-left-width')) + 'px',
            'width':t.getSize().x - parseInt(el.getStyle('border-left-width')) - parseInt(el.getStyle('border-right-width')) + 'px',
            'height':t.getSize().y - parseInt(el.getStyle('border-top-width')) - parseInt(el.getStyle('border-bottom-width')) + 'px'
        }).fade('hide').fade(0.5);
        if(img) var altLoader = new Element('div',{
            'class':'zbLoader'
        }).inject(zb.loader,'after').pin().setStyles({
            'background-image':'none',
            'top':img.getPosition().y - parseInt(zb.loader.getStyle('border-top-width')) + 'px',
            'left':img.getPosition().x - parseInt(zb.loader.getStyle('border-left-width')) + 'px',
            'width':img.getSize().x + 'px',
            'height':img.getSize().y + 'px'
        }).fade(0.5).unpin();
        var fx = new Fx.Morph(altLoader);
        fx.start({
            'top':prevEl.getPosition().y - parseInt(prevEl.getStyle('border-top-width')) + 'px',
            'left':prevEl.getPosition().x - parseInt(prevEl.getStyle('border-left-width')) + 'px',
            'width':prevEl.getSize().x + 'px',
            'height':prevEl.getSize().y + 'px'
        });
        img.unpin().dispose();
        (function(){
            altLoader.fade(0);
        }).delay(500);
        (function(){
            altLoader.destroy();
        }).delay(900);
        zb.click(el);
    }
});
