/*
    Copyright 2008 Thierry Dulieu (http://www.linuance.com/)
	
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
(function($) {
	//---------------------------------------------------------------------------
	// $.transition plugin class
	//---------------------------------------------------------------------------
	$.transition = function($el, settings)
	{
		this.settings = settings;
		this.current = 0;
		this.slideshowRunning = false;
		this.thumbstripOffset = 0;
		
		var self = this;
		
		if ($el.is('ul') || $el.is('ol')) {
			// create gallery from HTML code
			this.$thumbnails = $el;
			this.count = $('li', $el).size();
		} else if (this.settings.images && this.settings.images.length > 0) {
			// create gallery from plugin settings
			this.$thumbnails = $('<ul></ul>');
			$.each(this.settings.images, function(i, data) {
				var title = data.title ? ' title="' + data.title + '"' : '';
				self.$thumbnails.append('<li><a href="' + data.image + '"' + title + '><img src="' + data.thumb + '" alt="" /></a></li>');
			});
			$el.append(this.$thumbnails);
			this.count = this.settings.images.length;
		} else {
			// nothing to display ?
			return;
		}
		
		// clicking on a thumbnail display the corresponding image
		$('a', this.$thumbnails).each(function(i) {
			$(this).attr('rel', i).click(function(evt) {
				evt.preventDefault();
				evt.stopPropagation();
				self.stopSlideshow();
				self.displayImage(parseInt($(this).attr('rel')), true);
				return false;
			});
		});
		
		if (typeof(this.settings.thumbSize) == 'number') {
			this.thumbWidth = this.settings.thumbSize;
			this.thumbHeight = this.settings.thumbSize;
		} else {
			this.thumbWidth = this.settings.thumbSize.width;
			this.thumbHeight = this.settings.thumbSize.height;
		}
		
		// build the gallery structure around the thumbnails list
		var $wrapper = $(HTML).width(this.settings.width);
		this.$thumbnails.before($wrapper);
		this.$thumbstrip = $('.transition-thumbstrip', $wrapper)
			.prepend(this.$thumbnails)
			.width(this.settings.width)
			.height(this.thumbHeight);
		
		// get references on some gallery elements
		this.$image = $('img:eq(0)', $wrapper);
		this.$caption = $('.transition-caption', $wrapper);
		this.$previousButton = $('.transition-prev', $wrapper).hide();
		this.$slideshowButton = $('.transition-slideshow', $wrapper).hide();
		this.$nextButton = $('.transition-next', $wrapper).hide();
		this.$backwardButton = $('.transition-backward', $wrapper).hide();
		this.$forwardButton = $('.transition-forward', $wrapper).hide();
		
		// set attributes and css properties
		$('.transition-view', $wrapper).width(this.settings.width).height(this.settings.height);
		var $title = $('.transition-title', $wrapper).text(this.$thumbnails.attr('title') || this.settings.title || 'jQuery Transition');
		
		if ($.browser.msie) {
			// IE7 is unable to handle correctly alpha transparency and css opacity
			$('.transition-view a', $wrapper).css({opacity: '.67'});
			self.$backwardButton.css({opacity: '.67'});
			self.$forwardButton.css({opacity: '.67'});
		}
		
		// bind main view controls with their respective action
		this.$previousButton.click(function() {
			self.stopSlideshow();
			self.displayPreviousImage();
		});
		this.$nextButton.click(function() {
			self.stopSlideshow();
			self.displayNextImage();
		});
		this.$slideshowButton.click(function() {
			if (self.slideshowRunning) {
				self.stopSlideshow();
			} else {
				self.displayNextImage(true);
			}
		});
		
		// buind thumbstrip controls with their respective action
		this.$backwardButton.click(function() {
			self.stopSlideshow();
			self.moveThumbstrip(-self.settings.thumbs);
		});
		this.$forwardButton.click(function() {
			self.stopSlideshow();
			self.moveThumbstrip(self.settings.thumbs);
		});
	
		// show or hide controls depending on mouse position
		$wrapper.hover(
			function() {
				if (self.settings.displayCaption) {
					self.$caption.animate({marginBottom: 0}, 'fast');
				}
				if (self.settings.displayTitle) {
					$title.animate({marginTop: 0}, 'fast');
				}
				$('.transition-view a', $wrapper).fadeIn('fast');
				self.$backwardButton.fadeIn('fast');
				self.$forwardButton.fadeIn('fast');
			},
			function() {
				if (self.settings.displayCaption) {
					self.$caption.animate({marginBottom: '-3em'}, 'slow');
				}
				if (self.settings.displayTitle) {
					$title.animate({marginTop: '-3em'}, 'slow');
				}
				$('.transition-view a', $wrapper).fadeOut('slow');
				self.$backwardButton.fadeOut('slow');
				self.$forwardButton.fadeOut('slow');
			}
		);
		
		if (this.settings.autoRun) {
			this.current = -1;
			this.displayNextImage(true);
		} else {
			this.displayImage(0, false);
		}
	};
	
	//---------------------------------------------------------------------------
	// loads an image with the given src attribute
	//---------------------------------------------------------------------------
	$.transition.prototype.loadImage = function(img, src, callback)
	{
		$(img).load(function() {
			$(this).css({
				marginLeft : -$(this).width()  / 2,
				marginTop  : -$(this).height() / 2
			}).show();
			if (callback) callback();
		}).hide().attr('src', src);
	};
	
	//---------------------------------------------------------------------------
	// displays the image with the given index with or without fading effect
	//---------------------------------------------------------------------------
	$.transition.prototype.displayImage = function(index, effect)
	{
		var $link = $('a:eq(' + index + ')', this.$thumbnails);
		
		if (effect) {
			var self = this;
			var $shadow = $('<img src=""/>').css({zIndex: 0});
			this.$image.css({zIndex: 1}).after($shadow);
			
			this.loadImage($shadow, $link.attr('href'), function() {
				self.$image.animate({opacity: 0}, self.settings.transitionTime, function() {
					self.$image.remove();
					self.$image = $shadow;
				});
			});
		} else {
			this.loadImage(this.$image, $link.attr('href'));
		}
		var title = (index + 1) + '/' + this.count;
		if ($link.attr('title')) {
			title += ' - ' + $link.attr('title');
		}
		this.$caption.text(title);
		
		this.current = index;
		var offset = index - Math.floor(this.settings.thumbs / 2);
		//this.displayThumbstrip(offset);
		this.maintainControls();
	};
	
	//---------------------------------------------------------------------------
	// displays the previous image
	//---------------------------------------------------------------------------
	$.transition.prototype.displayPreviousImage = function()
	{
		var index = this.current - 1;
		if (index <= 0) {
			index = 0;
		}
		this.displayImage(index, true);
	};
	
	//---------------------------------------------------------------------------
	// displays the next image
	//---------------------------------------------------------------------------
	$.transition.prototype.displayNextImage = function(slideshowMode)
	{
		var index= this.current + 1;
		if (index > this.count - 1) {
			if (slideshowMode) {
				index = 0;
			} else {
				index = this.count - 1
			}
		}
		if (slideshowMode) {
			var self = this;
			this.slideshowRunning = setTimeout(function() {
				self.displayNextImage(true);
			}, self.settings.displayTime);
		}
		this.displayImage(index, true);
	};
	
	//------------------------------------------------------------------------------
	// stops the slideshow animation
	//------------------------------------------------------------------------------
	$.transition.prototype.stopSlideshow = function()
	{
		if (this.slideshowRunning) {
			clearTimeout(this.slideshowRunning);
			this.slideshowRunning = false;
		}
		this.$slideshowButton.removeClass('transition-stop');
	};
	
	//---------------------------------------------------------------------------
	// moves the thumbstrip by the given offset
	//---------------------------------------------------------------------------
	$.transition.prototype.displayThumbstrip = function(offset) {
				
		if (offset < 0) {
			offset = 0;
		} else if (offset > this.count - this.settings.thumbs) {
			offset = this.count - this.settings.thumbs;
		}
		
		var width = 1 + this.settings.width / this.settings.thumbs;
		
		// outlines the current thumb
		$('.transition-current', this.$thumbnails).remove();
		var $outerFrame = $('<span class="transition-current"></span>');
		var $innerFrame = $('<span></span>');
		
		$outerFrame.width(this.thumbWidth - 4).height(this.thumbHeight - 4);
		$innerFrame.width(this.thumbWidth - 8).height(this.thumbHeight - 8);
		$('li:eq(' + this.current + ')', this.$thumbnails).append($outerFrame.append($innerFrame));
		
		// set the thumbstrip position
		if (offset != this.thumbstripOffset) {
			this.$thumbnails.animate({marginLeft: (-width * offset) + 'px'}, 'fast');
			this.thumbstripOffset = offset;
			this.maintainControls();
		}
	};
	
	//---------------------------------------------------------------------------
	// moves the thumbstrip by the given offset
	//---------------------------------------------------------------------------
	$.transition.prototype.moveThumbstrip = function(offset) {
		var newOffset = this.thumbstripOffset + offset;
		this.displayThumbstrip(newOffset);
	};

	//---------------------------------------------------------------------------
	// maintain main view control buttons
	//---------------------------------------------------------------------------
	$.transition.prototype.maintainControls = function()
	{
		if (this.current == 0) {
			this.$previousButton.addClass('transition-disabled');
		} else {
			this.$previousButton.removeClass('transition-disabled');
		}
		if (this.current == this.count - 1) {
			this.$nextButton.addClass('transition-disabled');
		} else {
			this.$nextButton.removeClass('transition-disabled');
		}
		if (this.slideshowRunning) {
			this.$slideshowButton.addClass('transition-stop');
		} else {
			this.$slideshowButton.removeClass('transition-stop');
		}
		
		if (this.thumbstripOffset == 0) {
			this.$backwardButton.addClass('transition-disabled');
		} else {
			this.$backwardButton.removeClass('transition-disabled');
		}
		if (this.thumbstripOffset >= this.count - this.settings.thumbs) {
			this.$forwardButton.addClass('transition-disabled');
		} else {
			this.$forwardButton.removeClass('transition-disabled');
		}
	};
	
   //---------------------------------------------------------------------------
	// instanciates $.transition class for each matched element
	//---------------------------------------------------------------------------
	$.fn.transition = function(settings)
	{
		var opts = $.extend({}, $.fn.transition.defaults, settings);
		
		return this.each(function() {
			var $this = $(this);
			var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
			new $.transition($this, o);
		});
	};
	
	//---------------------------------------------------------------------------
	// plugin default settings
	//---------------------------------------------------------------------------
	$.fn.transition.defaults = {
		title: '',             // Gallery title
		images: null,          // A list of images to display
		autoRun: false,        // Autorun slideshow ?
		displayTime: 5000,     // How long an image is displayed
		transitionTime: 1000,  // Duration of the fade in/fade out effect
		width: 323,            // Maximum width of the gallery images
		height: 280,           // Maximum height of the gallery images
		thumbs: 5,    		     // Number of thumbnails to display
		thumbSize: 60,         // Size of each thumbnail
		displayTitle: true,    // Display the gallery title
		displayCaption: true   // Display the images caption
	};

	var HTML = '<div class="transition"><div class="transition-view"><img src="" /><p class="transition-title"></p><p class="transition-caption"></p><a class="transition-prev" href="javascript:;"><span>Previous</span></a><a class="transition-slideshow" href="javascript:;"><span>Start/stop slideshow</span></a><a class="transition-next" href="javascript:;"><span>Next</span></a></div><div class="transition-thumbstrip"><a class="transition-backward" href="javascript:;"><span>Backward</span></a><a class="transition-forward" href="javascript:;"><span>Forward</span></a></div></div>';
})(jQuery);