//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2009 Aaron Newton <http://clientcide.com/>, Valerio Proietti <http://mad4milk.net> & the MooTools team <http://mootools.net/developers>, MIT Style License.

MooTools.More={version:"1.2.4.4",build:"6f6057dc645fdb7547689183b2311063bd653ddf"};(function(d,e){var c=/(.*?):relay\(([^)]+)\)$/,b=/[+>~\s]/,f=function(g){var h=g.match(c);
return !h?{event:g}:{event:h[1],selector:h[2]};},a=function(m,g){var k=m.target;if(b.test(g=g.trim())){var j=this.getElements(g);for(var h=j.length;h--;
){var l=j[h];if(k==l||l.hasChild(k)){return l;}}}else{for(;k&&k!=this;k=k.parentNode){if(Element.match(k,g)){return document.id(k);}}}return null;};Element.implement({addEvent:function(j,i){var k=f(j);
if(k.selector){var h=this.retrieve("$moo:delegateMonitors",{});if(!h[j]){var g=function(m){var l=a.call(this,m,k.selector);if(l){this.fireEvent(j,[m,l],0,l);
}}.bind(this);h[j]=g;d.call(this,k.event,g);}}return d.apply(this,arguments);},removeEvent:function(j,i){var k=f(j);if(k.selector){var h=this.retrieve("events");
if(!h||!h[j]||(i&&!h[j].keys.contains(i))){return this;}if(i){e.apply(this,[j,i]);}else{e.apply(this,j);}h=this.retrieve("events");if(h&&h[j]&&h[j].keys.length==0){var g=this.retrieve("$moo:delegateMonitors",{});
e.apply(this,[k.event,g[j]]);delete g[j];}return this;}return e.apply(this,arguments);},fireEvent:function(j,h,g,k){var i=this.retrieve("events");if(!i||!i[j]){return this;
}i[j].keys.each(function(l){l.create({bind:k||this,delay:g,arguments:h})();},this);return this;}});})(Element.prototype.addEvent,Element.prototype.removeEvent);
Element.implement({isDisplayed:function(){return this.getStyle("display")!="none";},isVisible:function(){var a=this.offsetWidth,b=this.offsetHeight;return(a==0&&b==0)?false:(a>0&&b>0)?true:this.isDisplayed();
},toggle:function(){return this[this.isDisplayed()?"hide":"show"]();},hide:function(){var b;try{b=this.getStyle("display");}catch(a){}return this.store("originalDisplay",b||"").setStyle("display","none");
},show:function(a){a=a||this.retrieve("originalDisplay")||"block";return this.setStyle("display",(a=="none")?"block":a);},swapClass:function(a,b){return this.removeClass(a).addClass(b);
}});var Asset={javascript:function(f,d){d=$extend({onload:$empty,document:document,check:$lambda(true)},d);if(d.onLoad){d.onload=d.onLoad;}var b=new Element("script",{src:f,type:"text/javascript"});
var e=d.onload.bind(b),a=d.check,g=d.document;delete d.onload;delete d.check;delete d.document;b.addEvents({load:e,readystatechange:function(){if(["loaded","complete"].contains(this.readyState)){e();
}}}).set(d);if(Browser.Engine.webkit419){var c=(function(){if(!$try(a)){return;}$clear(c);e();}).periodical(50);}return b.inject(g.head);},css:function(b,a){return new Element("link",$merge({rel:"stylesheet",media:"screen",type:"text/css",href:b},a)).inject(document.head);
},image:function(c,b){b=$merge({onload:$empty,onabort:$empty,onerror:$empty},b);var d=new Image();var a=document.id(d)||new Element("img");["load","abort","error"].each(function(e){var g="on"+e;
var f=e.capitalize();if(b["on"+f]){b[g]=b["on"+f];}var h=b[g];delete b[g];d[g]=function(){if(!d){return;}if(!a.parentNode){a.width=d.width;a.height=d.height;
}d=d.onload=d.onabort=d.onerror=null;h.delay(1,a,a);a.fireEvent(e,a,1);};});d.src=a.src=c;if(d&&d.complete){d.onload.delay(1);}return a.set(b);},images:function(d,c){c=$merge({onComplete:$empty,onProgress:$empty,onError:$empty,properties:{}},c);
d=$splat(d);var a=[];var b=0;return new Elements(d.map(function(e){return Asset.image(e,$extend(c.properties,{onload:function(){c.onProgress.call(this,b,d.indexOf(e));
b++;if(b==d.length){c.onComplete();}},onerror:function(){c.onError.call(this,b,d.indexOf(e));b++;if(b==d.length){c.onComplete();}}}));}));}};

var Popup = new Class({

	Implements: [Options, Events],

	options: {
		/*
		onBeforeLoad: $empty,
		onLoad: $empty,
		onShow: $empty,
		onHide: $empty,
		onTransition: $empty,
		onCancel: $empty,
		multipleChildren: false,
		hideWhenEmpty: false
		*/
	},

	/*
	visible: false,
	enableBeforeLoad: false,
	enableLoad: false,
	*/
	children: [],

	initialize: function(element, options){
		this.element = document.id(element);
		if(options){
			if(options.holder){
				options.holder.addChild(this);
				delete options.holder;
			}
			if(options.onBeforeLoad)
				this.enableBeforeLoad = true;

			if(options.onLoad)
				this.enableLoad = true;
		}

		this.setOptions(options);
	},

	addChild: function(child){
		child.holder = this;
		this.children.include(child);
	},

	show: function(){
		if(this.holder)
			if(!this.holder.shown)
				this.holder.show();
			else if(!this.holder.options.multipleChildren){
				var th = this;
				this.holder.children.each(function(c){if(c != th) c._hide();});
			}

		if(this.enableBeforeLoad)
			this.call(this.onBeforeLoad.bind(this, arguments));

		if(this.enableLoad)
			this.call(this.onLoad.bind(this, arguments));
		else
			this.loadComplete.apply(this, arguments);
	},

	hide: function(){
		if(this.holder && this.holder.visible && this.holder.options.hideWhenEmpty){
			var c = this.holder.children;
			for(var i=0;i<c.length;i++)
				if(c[i].visible && c[i] != this){
					this._hide();
					return;
				}
			this.holder.hide();
			return;
		}
		this._hide();
	},

	_hide: function(){
		if(this.visible){
			this.children.each(function(c){ c._hide(); });
			this.visible = false;
			this.call(this.onHide);
		}
	},

	$next: $empty,

	requestQueue: function(popup){
		if(this.holder)
			this.holder.requestQueue(popup);
		else if(this.running){
			(this.$queue = (this.$queue || []).erase(popup)).push(popup);
		} else {
			this.running = true;
			popup.callNext();
		}
	},

	nextInQueue: function(){
		if(this.holder)
			this.holder.nextInQueue();
		else if(this.$queue && this.$queue.length > 0)
			this.$queue.shift().callNext();
		else
			this.running = false;
	},

	call: function(fn){
		// TODO: Check to see if event exists, so we can remove checks in initialize
		this.$next = fn;
		this.requestQueue(this);
	},

	callNext: function(){
		this.running = true;
		this.$next.apply(this);
		this.$next = $empty;
	},

	cancel: function(){
		if(this.running){
			this.running = false;
			this.$next = false;
			if(this.$queue) this.$queue.empty();
			this.children.each(function(c){c.cancel();});
		}
	},

	complete: function(){
		this.running = false;
		this.nextInQueue();
	},

	loadComplete: function(){
		this.complete.apply(this);

		if(this.visible)
			this.call(this.onTransition.bind(this, arguments));
		else {
			this.visible = true;
			this.call(this.onShow.bind(this, arguments));
		}
	},

	onBeforeLoad: function(){ return this.fireEvent('onBeforeLoad', arguments); },

	onLoad: function(){ return this.fireEvent('onLoad', arguments); },

	onShow: function(){ return this.fireEvent('onShow', arguments); },

	onHide: function(){ return this.fireEvent('onHide', arguments); },

	onTransition: function(){ return this.fireEvent('onTransition', arguments); },

	onCancel: function(){ return this.fireEvent('onCancel', arguments); }
});

Popup.Overlay = new Class({

	Extends: Popup,

	options: {
		/*
		parentElement: false,
		className: null,
		*/
		fx: {
			duration: 100
		},
		styles: {
			position: 'absolute',
			width: '100%',
			height: '100%',
			top: '0',
			left: '0',
			backgroundColor: '#000000'
		},
		showStyle: {opacity: .8},
		hideStyle: {opacity: 0},
		hideWhenEmpty: true
	},

	initialize: function(options){
		if (options){
			if (options.showStyle) this.options.showStyle = options.showStyle;
			if (options.hideStyle) this.options.hideStyle = options.hideStyle;
			this.setOptions(options);
		}
		var fix = Browser.Engine.trident5 || Browser.Engine.gecko || Browser.Engine.webkit || Browser.Engine.presto;

		var pe = document.id(this.options.parentElement) || document.id(document.body);
		var element = new Element('div', {
			'styles': {
				position: fix ? 'fixed' : 'absolute',
				display: 'none',
				visibility: 'visible',
				width: '100%',
				height: '100%',
				overflow: 'hidden',
				top: 0,
				left: 0,
				margin: 0,
				padding: 0,
				border: 0,
				zIndex: 1000
			}
		}).inject(pe);

		this.bg = new Element('div', {
			'class': this.options.className,
			'styles': this.options.styles,
			'events': { click: this.hide.bind(this) }
		}).inject(element);
		this.morph = new Fx.Morph(this.bg, $merge(this.options.fx, { link: 'cancel', onComplete: this.complete.bind(this) }));
		this.morph.set(this.options.hideStyle);

		this.parent(element, options);

		if (!fix){
			(pe.get('tag') == 'body' ? window : pe).addEvent('scroll', this.posFix.bind(this, pe)).addEvent('resize', this.posFix.bind(this, pe));
			this.posFix(pe);
		}
	},

	posFix: function(pe){
		var p = pe.getScroll(), s = pe.getSize();
		this.element.set('styles', {top: p.y, left: p.x, height: s.y + 'px', width: s.x + 'px'});
	},

	onShow: function(){
		this.element.setStyle('display', 'block');
		this.morph.start(this.options.showStyle);
		this.parent.apply(this, arguments);
	},

	onHide: function(){
		this.morph.start(this.options.hideStyle).chain(function(){
			this.element.setStyle('display', 'none');
		}.bind(this));
		this.parent.apply(this, arguments);
	},

	onTransition: function(){
		this.complete();
		this.parent.apply(this, arguments);
	},

	onCancel: function(){
		this.morph.cancel();
		this.parent.apply(this, arguments);
	}

});

Popup.Lightbox = new Class({

	Extends: Popup,

	options: {
		elementFx: { duration: 100 },
		contentFx: { duration: 100 }
	},
	/*
	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 = document.id(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('lightbox-loading');

		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('lightbox-loading'); 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();
		}
	}
});