
/**
 * Silhouette (http://wilsonwebconsulting.com/)
 *
 * Version 1.1
 * March 07, 2010
 *
 * Copyright (c) 2010 Ross Wilson (http://wilsonwebconsulting.com/)
 * Licensed under the GPL licenses.
 * http://www.gnu.org/licenses/gpl.txt
 **/

/**
 * 
 * @desc Convert images from a simple html <ul> into a horizontal panoramic
 * @author Ross Wilson
 * @version 1.0
 *
 * @name Silhouette
 * @type jQuery
 *
 * @cat plugins/Media
 * 
 * @example $('#silhouette_container').silhouette({options});
 * @desc Create a circular scrolling gallery from an unordered list of images with thumbnails
 * @options
 * //todo
**/

(function($) {

	var $$;
	
	$$ = $.fn.silhouette = function(options){

		// default configuration properties
		var defaults = {
			current: 			2,
			range:				4,
			container_height:	495,
			container_width:	960,
			container_edge:		25,
			scroll_speed: 		700,
			scroll_easing: 		'swing',
			fade_speed: 		500,
			img_padding_right: 	0,
			img_opacity: 		0.4,
			auto_advance:		0,
			first:				true
		}; 
		
		//set variables
		var _container = $(this);
		var _float = $('#sil-float');
		$("ul",_container).wrap('<div id="silhouette_gallery"/>');
		var _gallery = $("div", _container);
		var _thumbs = $("ul", _gallery);
		var thumbArray = $("a img",_thumbs).toArray();
		var options = $.extend(defaults, options);
		
		swapPrev = function(){
			var curGalleryLeft = parseInt(_gallery.css("left").replace(/px,*\)*/g,""));
			$('ul li:first', _container).before($('ul li:last', _container));
			//var galLeft = curGalleryLeft - $('ul li:first', _container).width();
			//_gallery.css("left", galLeft + "px");
			options.current = 2;
			_gallery.css("left",(Math.round(((_container.parent().width()-options.container_width)/2))-(options.container_width +options.img_padding_right)*options.current)+"px");
			setLinks();
		};
		
		swapNext = function(){
			var curGalleryLeft = parseInt(_gallery.css("left").replace(/px,*\)*/g,""));
			$('ul li:last', _container).after($('ul li:first', _container));
			//var galLeft = curGalleryLeft + $('ul li:first', _container).width();
			//_gallery.css("left", galLeft + "px");
			options.current = 2;
			_gallery.css("left",(Math.round(((_container.parent().width()-options.container_width)/2))-(options.container_width +options.img_padding_right)*options.current)+"px");
			setLinks();
		}
		
		changeImageMove = function(moveTo, keepCurrent){
			var callback = null;
			if(moveTo > 2){
				callback = swapNext;
				moveTo = 3;
			}
			if(moveTo < 2){
				callback = swapPrev; 
				moveTo = 1;
			}
			thumbArray = $("a img",_thumbs).toArray();
	
			//grab images
			var curImageLi = $(thumbArray[options.current]);
			var toImageLi = $(thumbArray[moveTo]);

			var toImgTop = toImageLi.offset().top - _container.offset().top;
			if( toImgTop >= options.container_height ){
				_gallery.width( _gallery.width() * Math.ceil(toImgTop/options.container_height) );
			}

			//calculate its left since .position doesn't work with block/float
			var curGalleryLeft = _gallery.css("left").replace(/px,*\)*/g,"");
			var toImgLeft = toImageLi.offset().left - _container.offset().left;

			//fade out current image, fade in new image and change links
			if( options.current != moveTo ){
				curImageLi.stop().animate({ 'opacity' : options.img_opacity }, options.fade_speed);
			} 
			toImageLi.stop().animate({ 'opacity' : "1.0"}, options.fade_speed);
			

			//check to see if everything is good, loaded and it the right position -- if not, we will re-call this function until it is
			var allSet = false;
			var toGalleryLeft = _container.width()/2 - (toImgLeft-curGalleryLeft) - toImageLi.width()/2;
			if( Math.abs(toGalleryLeft-curGalleryLeft)>0.5 ){
				//move middle of image to middle of container
				_gallery.stop().animate({
					'left' : Math.round(toGalleryLeft)+"px"},
					options.scroll_speed,
					options.scroll_easing,
					callback
				);
				_container.data("silhouette_animating", true );
			}
			options.current = moveTo;
			window.currentImage = moveTo;
		};
		
		positionFloat = function(){
			_float.css("left",Math.round(((_container.parent().width()-_float.width())/2))+"px");
		}

		changeImage = function(moveTo){
			changeImageMove( moveTo, false );
		}
		
		setLinks = function(){
			$('li a:lt(2)', _container).attr({href: "javascript:changeImage(1)"});
			$('li a:eq(2)', _container).attr({href: ""});
			$('li a:gt(2)', _container).attr({href: "javascript:changeImage(3)"});
		}
		
		var init = function() {
			var singleImg = false;
			if($("li", _thumbs).length <=1){
				singleImg = true;
				//hide the arrows
				$('.sil-next-over, .sil-previous-over').css('display', 'none');
			}
			
			if(!singleImg){
				//we need at least 5 elements for a good slider, clone them if they aren't there
				while($("li", _thumbs).length < 5){
					$("li",_thumbs).clone().appendTo(_thumbs);	
				}
				
				//move the last two images in front of the first
				$('ul li:first', _container).before($('ul li:last', _container));
				$('ul li:first', _container).before($('ul li:last', _container)); 
			}
			thumbArray = $("a img",_thumbs).toArray();
			
			//set the container div height and properties
			_container.height(options.container_height+"px");
			_container.width(_container.parent().width()-options.container_edge+"px"); //todo:  IE6 (and sometimes FF) is too wide, adds horizontal scroll
			_container.css("overflow","hidden");
			_container.css("position","relative"); //IE6 sucks
	
			_gallery.css("position","relative");
			_gallery.height(options.container_height+"px");
			_gallery.width( _container.width() );
	
			_thumbs.css("padding","0");
			_thumbs.css("margin","0");
			_thumbs.css("top","0");
			_thumbs.css("list-style","none");
	
			//restyle and add images from thumbs
			var _counter = 0;
			_thumbs.children().each(function() {
				var thumb_image = $("a img", this);
	
				$(this).css("position","relative");
				$(this).css("zoom","1"); //IE is stoopid
				$(this).css("display","inline");
	
				thumb_image.height(options.container_height+"px");
	
				// expand the gallery width as images are loaded (chrome has image width at 0 until it loads)
				$(thumb_image).load(function() {
					_gallery.width( _gallery.width() + $(this).width() + options.img_padding_right );
				});
				
				thumb_image.css("opacity",options.img_opacity);
				_counter++;
				
			});
			
			if(singleImg){
				options.current = 0;
			}
			//start with the current image centered
			_gallery.css("left",(Math.round(((_container.parent().width()-options.container_width)/2))-(options.container_width +options.img_padding_right)*options.current)+"px");
			//set the float and current image properties
			positionFloat();
			$(thumbArray[options.current]).css({ 'opacity' : 1 });
			window.currentImage = options.current;
			
			if(!singleImg){
				setLinks();
				
				//register the key listeners
				$(document).keydown(function(e) {
					if(e.keyCode==37){ //left arrow
						changeImage(options.current-1);
					}
					else if(e.keyCode==39){ //right arrow
						changeImage(options.current+1);
					}
		
		
				});
				
				//register the resize event handler
				$(window).resize(function() {
					_container.width(_container.parent().width()-options.container_edge+"px");
					changeImageMove(options.current,true);
					positionFloat();
				});
				
				var timer;
				//if option is set we will turn on auto scrolling
				if(options.auto_advance > 0){
					timer = setInterval(function(){
						changeImage(currentImage+1);
					},options.auto_advance);	
				}
			} else{
				$(window).resize(function() {
					init();
				});
			}
		}
		
		init();
		
	};
})(jQuery);





