/*
 * tinyLightbox 2.4 - 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
 *   - jquery.tinyLightbox.original.js or other animation extensions
 *   - optional jquery.bgiframe.js
 *
 *  Copyright (c) 2008 Oleg Slobodskoi (ajaxsoft.de)
 */
;(function($) {

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

/* defaults */
$.fn.tinyLightbox.defaults = {
	item: 'a',
	slideshowSpeed: 5000,
	slideshowAutostart: false,
	pathAttr: 'href',
	descrAttr: 'title',				
	speed: 300,
	labelImage: 'Image', 
	labelOf: 'of',
	animation: 'original',
	keyNavigation: true,
	cycle: false,
	minWidth: 250,
	minHeight: 190,
	overlayOpacity: 0.7,
	bgiframe: true	
};


function tinyLightbox ( container, options ) {
	
	
	var template = '\
		<div id="tiny-lightbox" class="tiny-lightbox-animating tiny-lightbox-loading">\
			<div id="tiny-lightbox-overlay" data-action="close"></div>\
			<div id="tiny-lightbox-box" >\
				<div id="tiny-lightbox-image"></div>\
				<a id="tiny-lightbox-prev" data-action="showPrev" hidefocus="hidefocus" href="#">\
					<span data-action="showPrev"></span>\
				</a>\
				<a id="tiny-lightbox-next" data-action="showNext" hidefocus="hidefocus" href="#">\
					<span data-action="showNext"></span>\
				</a>\
			</div>\
			<div id="tiny-lightbox-bar">\
				<div id="tiny-lightbox-description"></div>\
				<span id="tiny-lightbox-stats"></span>\
				<a id="tiny-lightbox-close" title="Close" alt="Close" data-action="close" href="#"></a>\
				<a id="tiny-lightbox-slideshow" title="Slideshow" alt="Slideshow" data-action="slideshow" href="#"/>\
			</div>\
		</div>\
	';
	
	var self = this,
		$container = $(container),
        $tl,
		$elems,
		$stats,
		$descr,
		$prevNext,
		Animations,
		activeIndex,
		running,
		cycle
	;
	
	var s = this.s = $.extend({}, $.fn.tinyLightbox.defaults, options);
	
	
	this.init  = function()
	{
        cycle = s.cycle;
        Animations = $.fn.tinyLightbox[s.animation](self);
		$elems = $(s.item+'['+s.pathAttr+']', $container);

        $container.bind('click', function( e ) {
            var $elem = $(e.target).closest(s.item);
            
			activeIndex = $elems.index($elem[0]);
            
            // it is not a preview
            if ( activeIndex == -1 ) return;

            // prevent double lightbox if user clicks via keyboard
            if ( self.$tl ) return false;
		
			self.$tl = $(template).appendTo(document.body);
			
			// overlay
			self.$overlay = $('#tiny-lightbox-overlay').css('opacity', s.overlayOpacity);
			resizeOverlay();
		
			// image container
			self.$box = $('#tiny-lightbox-box');
			self.$image = $('#tiny-lightbox-image');
			self.path = $elem.attr(s.pathAttr);
			
			self.boxData = {
				width: self.$box.width(),
				height: self.$box.height(),
				top: parseInt(self.$box.css('top')) + self.docData.scrollTop,
				borderWidth: (self.$box.outerWidth()-self.$box.innerWidth())/2 || 0
			};
			setLeft();
			
			

			// toolbar
			self.$bar = $('#tiny-lightbox-bar');
			$descr = $('#tiny-lightbox-description');
			$stats = $('#tiny-lightbox-stats');
			updateBar();
			
			// bind click handler
			self.$tl.bind('click',function(e) {
				var act = $(e.target).attr('data-action');
				if ( !act ) return;
				self[ act ]();
				return false;
			});

			// bind hover event
			$prevNext = $('#tiny-lightbox-next, #tiny-lightbox-prev').bind('mouseover',function(){
				$('span', this).addClass('tiny-lightbox-hover');
			}).bind('mouseout', function(){
				$('span', this).removeClass('tiny-lightbox-hover');
			});

			// bind window resize event for overlay
			$(window).bind('resize',resizeOverlay);

			s.keyNavigation && $(document).bind('keydown',keyNavigation);		
			s.bgiframe && $.fn.bgiframe && self.$tl.bgiframe();

			// start animations
			Animations.start( function(){
				preload(self.path, function(){
					Animations.animate(function(){
						resizeOverlay();
						self.$tl.removeClass('tiny-lightbox-animating');
        				if ( s.slideshowAutostart ) {
        					running = setTimeout(slideshow, s.slideshowSpeed);
        					self.$bar.addClass('tiny-lightbox-slideshow-running');
        				};
					});	
				});
			});
                            
			return false;			
		
		});
	};
	
	this.showNext = function() {
		change(activeIndex+1);	
	};
	
	this.showPrev = function() {
		change(activeIndex-1);	
	};
	
	this.slideshow = function( sw )	{
		if ( running && !sw ) {
			clearTimeout(running);
			cycle = s.cycle;
			self.$bar.removeClass('tiny-lightbox-slideshow-running');
			running = false;
		} else {
			cycle = true;
			self.$bar.addClass('tiny-lightbox-slideshow-running');
			change(activeIndex+1, function(){
				running = setTimeout(function(){
					self.slideshow( true );
				}, s.slideshowSpeed);
			});	
		};
	};
	
	this.close = function()	{
		clearTimeout(running);
		$prevNext.unbind('mouseover mouseout');
		$(window).unbind('resize', resizeOverlay);
		s.keyNavigation && $(document).unbind('keydown', keyNavigation);
		Animations.close(function(){
			self.$tl.unbind('click').remove();
            delete self.$tl;
		});
	};

	
	function resizeOverlay() {
		self.docData = {
			width: $(window).width(),
			height: $(document).height(),
			scrollTop: $(window).scrollTop(),
            scrollLeft: $(window).scrollLeft()
		};
		self.$tl.add(self.$overlay).css({height: self.docData.height, width: self.docData.width});
	};
	
	function keyNavigation( e )	{
		/* 39 -> 37 <- 27 esc */
		e.keyCode == 39 ? self.showNext() : e.keyCode==37 ? self.showPrev() : e.keyCode==27 && self.close();	
	};
	
	function preload( url, callback ) {
		self.$tl.addClass('tiny-lightbox-loading');
		var img = new Image();
		img.onload = function () { 
			self.$tl.removeClass('tiny-lightbox-loading');
			$.extend(self.boxData, {
				width: img.width>s.minWidth ? img.width : s.minWidth,
				height: img.height>s.minHeight ? img.height : s.minHeight
			});
			setLeft();
			callback();
		};
		img.src = self.path = url;
	};

	function setLeft() {
		self.boxData.left = (self.docData.width - (self.boxData.width + self.boxData.borderWidth*2) )/2;	
	};
	
	function updateBar() {
        $stats.text(s.labelImage+' '+(activeIndex+1)+' '+s.labelOf+' '+$elems.length);
        var descr = $elems.eq(activeIndex).attr(s.descrAttr);
        $descr.html(descr)[ descr ? 'show' : 'hide' ]();
	};
	
	function change( id, callback )	{
		if ( self.$tl.hasClass('tiny-lightbox-animating') ) return;
        
		if ( id > $elems.length-1 || id < 0 ) {
			if ( cycle )
				change(id < 0 ? $elems.length-1 : 0, callback);
			else {
				self.$tl.addClass('tiny-lightbox-animating');
				Animations.limit(function(){
					self.$tl.removeClass('tiny-lightbox-animating');
				});
			};
			return;
		};
		activeIndex = id;

		self.$tl.addClass('tiny-lightbox-animating');
		Animations.prepare(function(){
			preload($elems.eq(activeIndex).attr(s.pathAttr), function(){
				updateBar();
				Animations.animate(function(){
					self.$tl.removeClass('tiny-lightbox-animating');
					resizeOverlay();
					$(callback);
				});
			});
		});
	};		


};

})( jQuery );
