/*
 * tinyLightbox 2.1 - Plugin for jQuery
 * 
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Depends:
 *   jquery.js
 * 
 *
 *  Copyright (c) 2008 Oleg Slobodskoi (ajaxsoft.de)
 */
;(function($) {

 	
	$.fn.extend({
		tinyLightbox: function ( options ) {
			this.each(function(){
				new $.tinyLightbox(this, options).init();
				return this;
			});
			
		}
	});

 	$.tinyLightbox = function ( container, opt )
	{
		//defaults
		var d = {
			item: 'a',
			slideshow: 5000,
			slideshowAutostart: false,
			pathAttr: 'href',
			descrAttr: 'title',				
			speed: 300,
			labelImage: 'Bild', 
			labelFrom: 'von',
			animation: 'original',
			keyNavigation: true,
			opacity: 0.7,
			cycle: false,
			minWidth: 350
		};

		$.extend( d, opt);
		
		var 
			self = this,
			$elems = $(container).find(d.item).filter('['+d.pathAttr+'!=""]'), //filter elements without path attr
			images = [],
			descr = [],
			activeImageId,
			running,
			animation,
			timeout,
			cycle = d.cycle
		;
		
		this.d = d;

		// public not initialized variables
		/*
		this.$overlay;
		this.$tinyLIghtbox;
		this.$labelClose;
		this.$labelPrev;
		this.$labelNext;
		this.$image;
		this.$bar;
		this.$descr;
		this.$stats;
		this.$slideshow;
		this.imageWidth = 0;
		this.imageHeight = 0;
		this.paddingTop = 0;
		this.barHeight = 0;
		this.top;
		this.$clickedElem;
		*/

		this.doc = {};
		
		this.init = function ()
		{
			
			$.tinyLightbox.animation[d.animation].apply(self);
			
			//serialize the gallery
			$elems.each(function(i, elem){
				images[i] = $(elem).attr(d.pathAttr);				
				descr[i] = $(elem).attr(d.descrAttr) || '';				
			}).		
			
			click(function() {

				var path = $(this).attr(d.pathAttr);
				activeImageId = $.inArray(path, images);

				initDocument();
				//create overlay
				self.$overlay = $('<div class="tinyLightbox-overlay" />').
				css('opacity', d.opacity).click(close).appendTo('body');
				
				//create container
				self.$tinyLightbox = $('<div class="tinyLightbox loading" />').
				click(clickHandler).
				appendTo('body');
		
				self.$tinyLightbox.css({left: ( self.doc.width-self.$tinyLightbox.innerWidth() )/2}).show();
				self.top = self.$tinyLightbox.position().top;
				self.$tinyLightbox.css({top: self.top+self.doc.scrollTop});
				
				self.paddingTop = ( self.$tinyLightbox.innerHeight() - self.$tinyLightbox.height() )/2;
				
				resizeOverlay();

				self.$labelClose = $('<div class="label-close" rel="close"/>').
				appendTo(self.$tinyLightbox);
				
				self.$image = $('<img src="" alt="'+descr[activeImageId]+'" title="'+descr[activeImageId]+'" class="image" rel="showNext"/>').
				appendTo(self.$tinyLightbox);
				
				self.$bar = $('<div class="bar"/>').
				appendTo(self.$tinyLightbox);
				
				if (images.length>1)
				{
					self.$labelPrev = $('<a class="button prev" rel="showPrev"/>').appendTo(self.$bar);
					self.$labelNext = $('<a class="button next" rel="showNext"/>').appendTo(self.$bar);
					if (d.slideshow)
					self.$slideshow = $('<a class="button slideshow" rel="slideshow"/>').appendTo(self.$bar);
				};

				
				//d.slideshowAutostart && self.$slideshow.addClass('stop');

				self.$descr = $('<p class="descr"/>').text(getDescr()).
				appendTo(self.$bar);

				self.$stats = $('<p class="stats"/>').text(getStats()).
				appendTo(self.$bar);
				
				preload(path, function(image){
					self.show(function(){
						resizeOverlay();
						d.slideshow && d.slideshowAutostart && setTimeout(slideshow, d.slideshow);
					});	
				});


				
				d.keyNavigation && keyNavigation();

				return false;
			});
		};
		
		
		
		
		/********************************************************************************************************/
		//Private methods 
		function showNext ($elem)
		{
			activeImageId+1 < images.length ? change(activeImageId+1) : cycle ? change(0)  : self.limit();	
			running && runSlideshow(true);
			
		};
		
		function showPrev ($elem)
		{
			activeImageId-1 >= 0 ? change(activeImageId-1) : cycle ? change(images.length-1)  : self.limit();	
			running && runSlideshow(true);
		};
		
		function change (id, callback)
		{

			activeImageId = id;

			self.prepare( function(){
				preload(images[activeImageId], function(image){
					self.$stats.text(getStats());
					self.$descr.text(getDescr());
					
					self.change(function(){
						callback && callback();
					});	
				});
			});
		};
		
		function clickHandler (e)
		{
			var $elem = $(e.target);
			createCallback( $elem.attr('rel'), [$elem]);
		};
		
		function getStats ()
		{
			return images.length>1 ? d.labelImage+' '+(activeImageId+1)+' '+d.labelFrom+' '+images.length : '';
		};
		function getDescr ()
		{
			return descr[activeImageId] ? descr[activeImageId] : '';
		};
		
		function close ()
		{
			inProgress = false;
			$(document).unbind('keydown');
			self.close();	
			running = false;
		};
	
		
		function preload (src, callback)
		{
			self.$tinyLightbox.addClass('loading');
			
			if (images.length>1)
			{
				activeImageId-1 < 0 && !cycle ? self.$labelPrev.addClass('disabled') : self.$labelPrev.removeClass('disabled');
				activeImageId+2 > images.length && !cycle ? self.$labelNext.addClass('disabled') : self.$labelNext.removeClass('disabled');
			};
			
			var image = new Image();
			image.onload=function()
			{	
				self.$tinyLightbox.removeClass('loading');
				self.$image.attr('src',image.src);
				self.imageWidth = image.width;
				self.imageHeight = image.height;
				callback(image);
			}
			image.src= src;
		};		
		
		function resizeOverlay ()
		{
			var tinyLightboxHeight = self.$tinyLightbox.innerHeight() + self.barHeight||0,
				overlayHeight = self.doc.height > tinyLightboxHeight ? self.doc.height : tinyLightboxHeight
			;
			self.$overlay.height(overlayHeight+self.top + self.doc.scrollTop);
			
		};
		
		function initDocument ()
		{
			$.extend(self.doc, {}, {
				scrollTop: $(document).scrollTop(),
				height: $(document).height(),
				width: $(document).width()
			});
		};		

		function keyNavigation ()
		{
			$(document).keydown(function(e){
				//39 -> 37 <- 27 esc
				e.keyCode == 39 ? showNext() : e.keyCode==37 ? showPrev() : e.keyCode==27 && close();	
			 });		
		};
		
		function slideshow ()
		{
			self.$slideshow.toggleClass('stop');
			self.$slideshow.hasClass('stop') ? runSlideshow() : stopSlideshow();
			function stopSlideshow ()
			{
				cycle = d.cycle;
				running = false;
				clearTimeout(timeout);
			};
		};
		
		function runSlideshow (reset)
		{	
			if (reset)
			{
				clearTimeout(timeout);
				timeout = setTimeout(runSlideshow, d.slideshow);
				return;
			};		
			
			running = true;
			cycle = true;
			change(activeImageId+2 > images.length ? 0 : activeImageId+1);
			timeout = setTimeout(runSlideshow, d.slideshow);
		};



		
		function createCallback (f,params)
		{		
			typeof f == 'string' && eval('f='+f);
			typeof f == 'function' && f.apply(self,params);
		};	



	};//end of $.tinyLightbox
	
	//Super method for animations
	$.extend($.tinyLightbox, {animation:{}});

	
	

})( jQuery );