/*
 * tinyLightbox 2.2 - 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 ) {

			return this.each(function(){
                !$.data(this, 'tinyLightbox') && $.data( this, 'tinyLightbox', new $.tinyLightbox(this, options)).init();
			});
			
		}
	});

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

		$.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,
			$doc = $(document)
		;
		
		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.barHeight = 0;
		this.top;
		this.$clickedElem;
		*/

		this.doc = {};
		
		this.init = function ()
		{
			
			$.tinyLightbox.animations[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);

				//init document
				$.extend(self.doc, {}, {
					scrollTop: $doc.scrollTop(),
					height: $doc.height(),
					width: $doc.width()
				});

				//create overlay
				self.$overlay = $('<div class="tiny-lightbox-overlay" />').
				css('opacity', d.opacity).click(self.destroy).appendTo('body');
				
				//fix flash and selectboxes in IE6
				d.bgiframe && $.fn.bgiframe && self.$overlay.bgiframe();
				
				//create container
				self.$tinyLightbox = $('<div class="tiny-lightbox tiny-lightbox-loading tiny-lightbox-changing" />').
				appendTo('body').
				click(function(e){
					var method = $(e.target).attr('rel');
					self[method] && self[method]();
					return false;
				});		

		
				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.paddingBottom = ( self.$tinyLightbox.innerHeight() - self.$tinyLightbox.height() )/2;
				
				resizeOverlay();

				self.$image = $('<img src="" class="tiny-lightbox-image" rel="showNext"/>').appendTo(self.$tinyLightbox);
				
				self.$bar = $('<div class="tiny-lightbox-bar"><a href="#" class="tiny-lightbox-label-close" rel="destroy" alt="Close" title="Close"/></div>').appendTo(self.$tinyLightbox);


				if (images.length>1)
				{
					self.$labelPrev = $('<a href="#" hidefocus="hidefocus" class="tiny-lightbox-label-prev" rel="showPrev"><span  rel="showPrev"/></a>').appendTo(self.$tinyLightbox);
					self.$labelNext = $('<a href="#" hidefocus="hidefocus" class="tiny-lightbox-label-next" rel="showNext"><span rel="showNext"/></a>').appendTo(self.$tinyLightbox);
					self.$labelPrev.add(self.$labelNext).hover(function(){
						$(this).children('span').addClass('tiny-lightbox-hover');
					}, function(){
						$(this).children('span').removeClass('tiny-lightbox-hover');
					});
					if (d.slideshow)
						self.$slideshow = $('<a href="#" class="tiny-lightbox-label-slideshow" rel="slideshow" alt="Slideshow" title="Slideshow"/>').appendTo(self.$bar);
				};

				

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

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


				
				d.keyNavigation && keyNavigation();
				

				return false;
			});
		};
		
		this.showNext = function ()
		{
			activeImageId+1 < images.length ? change(activeImageId+1) : cycle ? change(0)  : self.limit();	
			running && runSlideshow(true);
			
		};
		
		this.showPrev = function ()
		{
			activeImageId-1 >= 0 ? change(activeImageId-1) : cycle ? change(images.length-1)  : self.limit();	
			running && runSlideshow(true);
		};
		
			
		this.slideshow = function ()
		{
			self.$slideshow.toggleClass('running');
			self.$slideshow.hasClass('running') ? runSlideshow() : stopSlideshow();
			function stopSlideshow ()
			{
				cycle = d.cycle;
				running = false;
				clearTimeout(timeout);
			};
		};	
		
		this.destroy = function () 
		{
			inProgress = false;
			$doc.unbind('keydown');
			running = false;
			self.close();	
		};
		
				

		/********************************************************************************************************/
		//Private methods 

		function change (id)
		{
			self.$tinyLightbox.addClass('tiny-lightbox-changing');

			activeImageId = id;
			
			self.prepare( function(){
				preload(images[activeImageId], function(image){
					self.$stats.text(getStats());
					self.$descr.text(getDescr());
					self.change(function(){
						self.$tinyLightbox.removeClass('tiny-lightbox-changing');
					});	
				});
			});
		};
		
		function getStats ()
		{
			return images.length>1 ? d.labelImage+' '+(activeImageId+1)+' '+d.labelFrom+' '+images.length : '';
		};
		
		function getDescr ()
		{
			return descr[activeImageId] ? descr[activeImageId] : '';
		};
		
		function preload (src, callback)
		{
			self.$tinyLightbox.addClass('tiny-lightbox-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('tiny-lightbox-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 keyNavigation ()
		{
			$doc.keydown(function(e){
				//39 -> 37 <- 27 esc
				e.keyCode == 39 ? self.showNext() : e.keyCode==37 ? self.showPrev() : e.keyCode==27 && self.destroy();	
			 });		
		};

		
		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);
		};



	};//end of $.tinyLightbox

	$.tinyLightbox.animations = {};
	
	

})( jQuery );