/**
 * Continuous Carousel
 *
 * @author		Chris Willerton <chris@chriswillerton.com>
 * @copyright	Chris Willerton 2011
 * @version		1.0.1
 *
 * Requirements - expects the markup to be an unordered list <ul> complete with list items <li>, list items need to be same dimensions
 */
;(function($){
	
	var plugin = "continuousCarousel";
	
	$[plugin] = {};
	
	// Default options
	$[plugin].defaults = {
		defaultSpeed 	: 15000,
		hoverSpeed		: 10000,
		visibleItems 	: 4, 									// How many <li> elements that are visible at any one time
		direction 		: "rtl",								// Either rtl (right to left) or ltr (left to right)
		wrapperClass	: "carousel_wrapper",
		clickLeftClass	: "move_left",
		clickRightClass	: "move_right"
	};
	
	$.fn[plugin] = function(opts)
	{
		var options = $.extend(true, {}, $[plugin].defaults, opts);

		return this.each(function(){
			
			// "Cache" the carousel and get the contents for use later
			var $carousel = $(this),
				carouselContents = $carousel.html();
				
			// Set up some initial CSS defaults
			// Clone and append/prepend the contents for a seamless overlap
			// Wrap the carousel in a wrapper
			$carousel.css({
				'position'		: "absolute",
				'top'			: 0,
				'left'			: 0,
				'list-style'	: "none"
			}).append(carouselContents).prepend(carouselContents).wrap('<div class="' + options.wrapperClass + '"></div>');
			
			// Float all the items in the carousel left so that they line up
			$item = $carousel.find("li").css("float", "left");
			
			// Work out some dimensions and set up some default values
			var	$wrapper = $carousel.closest("div"),
				itemWidth = $item.width(),
				itemHeight = $item.height(),
				itemCount = $item.size(),
				carouselWidth = itemWidth * itemCount,
				defaultSpeed = (options.defaultSpeed || 20000),
				visibleItems = (options.visibleItems || 4),
				animVal = carouselWidth / 3,
				startPos = "-" + animVal,
				direction = (options.direction || "rtl");
			
			// Set the carousel width and start position
			$carousel.css({ width : carouselWidth, "left" : startPos + "px"});
			
			// Set the wrapper CSS defaults
			$wrapper.css({
				position	: "relative",
				overflow	: "hidden",
				width		: itemWidth * visibleItems,
				height		: itemHeight
			});
			
			
			/*
			 * Run - the main function which controls the carousel animation (recursive)
			 *
			 * @param	direction	The the direction for the carousel to move.
			 * @param	speed		The animation speed of the carousel
			 */	
			function run(direction, speed){
				
				var rtlVal = animVal * 2,
					endPos = (direction === "rtl") ? "-" + rtlVal : 0,
					leftPos = $carousel.css("left").replace("px", "").replace("-", ""),
					finish = endPos.toString().replace("-", ""),
					distance = (leftPos - finish).toString().replace("-", ""),
					speedPercentage = Math.floor((100 / animVal) * distance),
					speed = (speed / 100) * speedPercentage;

				$carousel
					.data({"direction" : direction, "speed" : speed})
					.animate({left : endPos}, speed, "linear", function(){
						$carousel.clearQueue().css("left", startPos + "px");
						run(direction, defaultSpeed);
				});
			};
			
			/*
			 * Hover Function
			 * 
			 * Works out which side of the carousel you are hovering on and changes the animation accordingly, calls run()
			 */
			$wrapper.hover(function(){
				var $this = $(this);
				
				$this.mousemove(function(e){
					var relativeX = e.pageX - this.offsetLeft,
						wrapperWidth = $this.width(),
						currentDirection = $carousel.data("direction"),
						currentSpeed = $carousel.data("speed"),
						newDirection = (relativeX > (wrapperWidth / 2)) ? "rtl" : "ltr",
						newSpeed = (options.hoverSpeed || 10000);
					
					console.log(wrapperWidth);
					
					// Decide if anything has changed and call run() again
					if (newDirection !== currentDirection || newSpeed !== currentSpeed)
					{
						$carousel.stop(true, false);
						run(newDirection, newSpeed);
					}
				});
		
			}, function(){
				$(this).unbind("mousemove");
				$carousel.stop(true, false);
				run(direction, defaultSpeed);	
			});
			
			
			/*
			 * Direction Change Click Events
			 *
			 * Calls run(), changes the direction of the animation
			 */
			$("." + options.clickLeftClass).click(function(){
				$carousel.stop(true, false);
				run("rtl", defaultSpeed);
				return false;
			});
			
			$("." + options.clickRightClass).click(function(){
				$carousel.stop(true, false);
				run("ltr", defaultSpeed);
				return false;
			});
			
			
			// Start the carousel - pass in the default options
			run(direction, defaultSpeed);
			
		});
		
	}

})(jQuery);
