﻿Popup.Lightbox = new Class({
	
	Extends: Popup,
	
	options: {
		elementFx: { duration: 300 },
		contentFx: { duration: 500 }
	},
	/*
	content: $empty,
	image: $empty,
	title: $empty,
	*/
	images: [],
	titles: $empty,
	current: $empty,
	
	initialize: function(element, options){
		if($type(element) == 'object' || $type(element) == 'undefined') {
			options = element;
			element = new Element('div', { 'class': 'Lightbox', html: '<div class="Content"><div class="Image"><a class="Next" href="javascript:void(0);"></a><a class="Previous" href="javascript:void(0);"></a></div><div class="Bottom"><a class="Close" href="javascript:void(0);"></a><div class="Title"></div></div></div>' });
		}
		if(options){
			if (options.elementFx) this.options.elementFx = options.elementFx;
			if (options.contentFx) this.options.contentFx = options.contentFx;
			this.setOptions(options);
		}
		var e = this.element = $(element);
		e.set('tabindex', -1);
		this.elementFx = new Fx.Morph(e, $merge(this.options.elementFx, {link: 'cancel'}));
		this.elementFx.set({'opacity': 0});
		var s = e.setStyle;
		e.setStyle = function() { s.apply(this, arguments); var z = this.getSize(); s.apply(s.apply(this, ['marginTop', -(z.y/2)]), ['marginLeft', -(z.x/2)]); };
		
		this.content = e.getElement('.Content');
		this.contentFx = new Fx.Morph(this.content, $merge(this.options.contentFx, {link: 'cancel'}));
		this.contentFx.set({'opacity': 0});
		
		this.image = e.getElement('.Image');
		var actions = new Hash({'.Next': this.next, '.Previous': this.previous, '.Close': this.hide});
		var t = this;
		actions.each(function(fn, k){
			var a = e.getElement(k);
			if(a) a.addEvent('click', function(e) { e.preventDefault(); fn.apply(t, arguments); });
		});
		this.titles = new Hash();
		this.title = e.getElement('.Title');
		
		this.element.addEvent('keyup', this.keyboardListener.bindWithEvent(this));
		
		this.parent(this.element, options);
	},
	
	onShow: function(uri, title){
		if(this.holder)
			this.holder.element.adopt(this.element);
		else
			this.element.inject(document.body);
			
		this.element.addClass('LightboxLoading');

		this.current = uri;
		if($defined(title)) this.titles.set(uri, title);
		
		var loaded = false;
		var img = new Asset.image(uri, {onload: function(){ this.element.removeClass('LightboxLoading'); if(this.elementFx.timer || this.contentFx.timer) loaded = true; else this.animation(img); }.bind(this)});
		
		this.elementFx.start({'opacity': 1}).chain(function(){
			if(loaded)
				this.animation(img);
		}.bind(this));
	},
	
	onHide: function(){
		this.elementFx.start({'opacity': 0}).chain(function(){
			this.contentFx.set({'opacity': 0});
			this.element.dispose();
			this.complete();
		}.bind(this));
	},
	
	onTransition: function(uri){
		this.contentFx.start({'opacity': 0}).chain(
			this.onShow.bind(this, arguments)
		);
	},
	
	onCancel: function(){
		this.elementFx.cancel();
		this.contentFx.cancel();
	},
	
	animation: function(img){
		this.image.setStyles({'backgroundImage': 'url(' + img.src + ')', width: img.width, height: img.height});
		if (this.title) this.title.set('html', this.titles.get(img.src));
		var w = img.width;
		this.elementFx.start({'width': w}).chain(function(){
			var h = this.content.getScrollHeight();
			this.elementFx.start({'height': h}).chain(function(){
				this.contentFx.start({'opacity': 1}).chain(function(){
					this.element.focus();
					this.complete();
				}.bind(this));
			}.bind(this));
		}.bind(this));
	},
	
	add: function(uri, title){
		this.images.include(uri);
		this.titles.set(uri, title);
		return this;
	},
	
	next: function(){
		var i = this.images.indexOf(this.current);
		i = (i >= this.images.length-1) ? 0 : i+1;
		return this.show(this.current = this.images[i]);
	}, 
	
	previous: function(){
		var i = this.images.indexOf(this.current);
		i = (i <= 0) ? this.images.length-1 : i-1;
		return this.show(this.current = this.images[i]);
	},
		
	keyboardListener: function(e){
		switch (e.key){
			case 'esc': case 'backspace': case 'delete': this.hide(); break;
			case 'left': case 'down': this.previous(); break;	
			case 'right': case 'up': this.next();
		}
	}
});