var Lightbox = new Class({

	Implements: Options,

	options: {
		layerFxDuration: 500,
		imageFxDuration: 300,
		resizeFxDuration: 300,
		captionFxDuration: 300,
		controlPanelHeight: 50,
		captionPanelHeight: 50,
		margin: 10
	},

	Effects: {

	},

	Elements: {

		layer: null,
		frame: null,
		image: null
	},

	Controls: {
		previous: null,
		next: null,
		play: null,
		close: null
	},

	Galleries: [],

	opened: false,
	controlsBuilt: false,
	currentGallery: null,
	currentImage: null,
	currentOptions: null,

	initialize: function(options) {

		this.setOptions(options);
		this.initElements();
		this.initFx();
		this.initGalleries();
	},

	initElements: function() {

		this.Elements.layer = $('tx-perfectlightbox-layer');
		this.Elements.layer.setStyles({display: 'none', left: 0, top: 0});
		this.Elements.layer.addEvent('click', function() {
			this.close();
		}.bindWithEvent(this));

		this.Elements.frame = $('tx-perfectlightbox-frame');
		this.Elements.frame.setStyles({display: 'none'});
		
		this.Elements.image = $('tx-perfectlightbox-image');

		this.Elements.caption = $('tx-perfectlightbox-caption');

		this.Controls.previous = $('tx-perfectlightbox-control-previous');
		this.Controls.next = $('tx-perfectlightbox-control-next');
		this.Controls.play = $('tx-perfectlightbox-control-play');
		this.Controls.close = $('tx-perfectlightbox-control-close');
	},

	initFx: function() {

		this.Effects.layer = new Fx.Tween(this.Elements.layer, {duration: this.options.layerFxDuration, property: 'opacity'});
		this.Effects.frame = new Fx.Tween(this.Elements.frame, {duration: this.options.layerFxDuration, property: 'opacity'});
		this.Effects.image = new Fx.Tween(this.Elements.image, {duration: this.options.imageFxDuration, property: 'opacity'});
		this.Effects.resizeFrame = new Fx.Morph(this.Elements.frame, {duration: this.options.resizeFxDuration});
		this.Effects.resizeImage = new Fx.Morph(this.Elements.image, {duration: this.options.resizeFxDuration});
		this.Effects.caption = new Fx.Morph(this.Elements.caption, {duration: this.options.captionFxDuration});
		this.Effects.control = new Fx.Morph($('tx-perfectlightbox-controls'), {duration: this.options.captionFxDuration});
		
	},

	initGalleries: function() {

		$$('a').filter(function(el) {
			return el.rel && el.rel.test(/^lightbox/);
		}).each(function(el) {

			var pattern = /^lightbox\[(\D*)(\d*)(\D*)\]/;
			var parts = pattern.exec(el.rel);

			var pres = parts[1]
			var uid = parts[2];
			var slide = parts[3];

			if(!this.Galleries[uid]) {

				this.Galleries[uid] = {}
				this.Galleries[uid].images = [];
				this.Galleries[uid].captions = [];
			}

			this.Galleries[uid].images.extend([el.href]);
			this.Galleries[uid].captions.extend([el.title]);

			var options = {};

			if(pres == 'presentlb') {

				options.presentation = true;
			}

			if(slide == 'slideshow') {

				options.slideshow = true;
			}

			el.addEvent('click', function(ev) {

				ev.preventDefault();
				this.show(arguments[1], arguments[2], arguments[3]);
			
			}.bindWithEvent(this, [uid, this.Galleries[uid].images.length - 1, options]))
		}.bind(this));
	},

	show: function(gallery, image, options) {

		this.currentGallery = gallery;
		this.currentImage = image;
		this.currentOptions = options;

		if(image == 0) {
			this.Controls.previous.addClass('disabled');
		} else {
			this.Controls.previous.removeClass('disabled');
		}

		if(image == this.Galleries[gallery].images.length - 1) {
			this.Controls.next.addClass('disabled');
		} else {
			this.Controls.next.removeClass('disabled');
		}

		this.Elements.image.addClass('loading');

		//console.debug(document.getScrollHeight());
		this.Elements.layer.setStyle('height', document.getScrollHeight());

		var winMiddle = {x: window.getWidth().toInt()/2, y: window.getHeight().toInt()/2};
		this.Elements.image.setStyle('background-image','');
		this.Elements.image.setStyle('opacity', 0);
		this.Effects.caption.start({height: 0}).chain(function() {
			var preloadImage = new Image();
			preloadImage.src = this.Galleries[gallery].images[image];
			preloadImage.onload = function() {

				var frameDimensions = {
					height: preloadImage.height + this.options.margin*2,
					left: winMiddle.x - preloadImage.width/2,
					top: winMiddle.y - preloadImage.height/2,
					width: preloadImage.width + this.options.margin*2
				}

				this.Controls.previous.setStyles({
					height: preloadImage.height,
					left: this.options.margin,
					top: this.options.margin
				});

				this.Controls.next.setStyles({
					height: preloadImage.height,
					right: this.options.margin,
					top: this.options.margin
				});

				this.Effects.resizeFrame.start({
					height: [this.Elements.frame.getStyle('height'), frameDimensions.height + this.options.controlPanelHeight],
					left: [this.Elements.frame.getStyle('left'), frameDimensions.left],
					top: [this.Elements.frame.getStyle('top'), frameDimensions.top],
					width: [this.Elements.frame.getStyle('width'), frameDimensions.width]
				});
				//alert('foo: line 181');
				//console.debug(preloadImage.height, preloadImage.width, frameDimensions + this.options.margin);
				this.Effects.resizeImage.start({
					height: [this.Elements.image.getStyle('height'), preloadImage.height],
					width: [this.Elements.image.getStyle('width'), preloadImage.width],
					margin: [this.Elements.image.getStyle('margin'), this.options.margin]
				}).chain(function() {
					//alert('foo: line 186');
					//alert(preloadImage.src);
					this.Elements.image.removeClass('loading');
					//console.debug(preloadImage.src);
					var bgImage = 'url(\'' + preloadImage.src + '\')';
					//console.debug(bgImage);
					this.Elements.image.setStyles({
						backgroundImage: bgImage,
						margin: this.options.margin
					});
					this.Effects.image.start(0,1);
					if(this.Galleries[gallery].captions[image].length > 0) {
						/*this.Elements.caption.setStyles({
							left: frameDimensions.left,
							position: 'absolute',
							top: frameDimensions.top + frameDimensions.height + this.options.controlPanelHeight,
							width: frameDimensions.width
						});*/
						this.Elements.caption.set('text',this.Galleries[gallery].captions[image]);
						this.Effects.caption.start({height: this.options.captionPanelHeight});
					}
					if(this.Galleries[gallery].images.length > 1) {


					}
				}.bind(this));
				//alert('foo: line 213');
				this.Effects.control.start({
					height: this.options.controlPanelHeight,
					left: frameDimensions.left,
					top: frameDimensions.top + frameDimensions.height,
					width: frameDimensions.width
				});
			}.bind(this);
		}.bind(this));

		if(!this.opened) {

			this.opened = true;

			// open up the layer
			this.Elements.layer.setStyle('display', '');
			this.Effects.layer.start(0,0.8);

			//open up the frame
			this.Elements.frame.setStyles({
				display: '',
				left: winMiddle.x - this.Elements.frame.getStyle('width').toInt()/2,
				top: winMiddle.y - this.Elements.frame.getStyle('height').toInt()/2
			});
			this.Effects.frame.start(0,1);
			this.buildControls(gallery, options);
		}
	},

	nextImage: function() {
		if(this.currentImage < this.Galleries[this.currentGallery].images.length - 1) {
			this.show(this.currentGallery, this.currentImage+1, this.currentOptions);
		}
	},

	prevImage: function() {
		if(this.currentImage > 0) {
			this.show(this.currentGallery, this.currentImage-1, this.currentOptions);
		}
	},

	gotoImage: function(image) {
		if(image >= 0 && image <= this.Galleries[this.currentGallery].images.length - 1) {
			this.show(this.currentGallery, image, this.currentOptions);
		}
	},

	buildControls: function(gallery, options) {
		$('tx-perfectlightbox-controls').empty();
		if(options.presentation) {
			var link;
			for(i = 0; i< this.Galleries[gallery].images.length; i++) {
				link = new Element('a', {'class': 'tx-perfectlightbox-control-direct', href: '#'});
				link.addEvent('click', function(ev, image) {
					ev.preventDefault();
					this.gotoImage(image);
				}.bindWithEvent(this, i));
				link.set('text',(i+1));
				link.inject($('tx-perfectlightbox-controls'));
			}
		} else if(this.Galleries[gallery].images.length > 1) {

			this.Controls.previous.addEvent('click', function(ev) {
				ev.preventDefault();
				this.prevImage();
			}.bindWithEvent(this));
			this.Controls.previous.inject($('tx-perfectlightbox-controls'));

			this.Controls.next.addEvent('click', function(ev) {
				ev.preventDefault();
				this.nextImage();
			}.bindWithEvent(this));
			this.Controls.next.inject($('tx-perfectlightbox-controls'));
		}

		this.Controls.close.addEvent('click', function(ev) {
				ev.preventDefault();
				this.close();
			}.bindWithEvent(this));
		this.Controls.close.inject($('tx-perfectlightbox-controls'));
	},

	close: function() {
		// fade out the caption
		this.Effects.caption.start({height: 0}).chain(function() {
			this.Elements.caption.set('text','');
			// fade out the control panel after the caption has gone
			this.Effects.control.start({height: 0}).chain(function() {
				$('tx-perfectlightbox-controls').empty();
				// fade out the frame after the control panel has gone
				// after fading out the frame, clean up and fade out the layer
				this.Effects.frame.start(0).chain(function() {
					this.Elements.frame.setStyle('display', 'none');
					this.Elements.image.setStyles({
						backgroundImage: 'none',
						//display: 'none',
						opacity: 0
					});

					this.Effects.layer.start(0).chain(function() {
						this.Elements.frame.setStyle('display', 'none');
					}.bind(this))
				}.bind(this))
			}.bind(this))
		}.bind(this));

		this.Controls.previous.removeEvents();
		this.Controls.next.removeEvents();
		this.Controls.close.removeEvents();
		
		this.opened = false; // the lightbox is set to closed
	}
});

window.addEvent('domready', function() {
	document.lightbox = new Lightbox();
})

