(function($) {                                          // Compliant with jquery.noConflict()
	$.fn.hoverScroll = function(o) {   
		o = $.extend({
			easing: null,
			visible: 1,
			start: 0
			//speed:100
		}, o || {});
				
		// Returns the element collection. Chainable.
		return this.each(function() {  
			var div			= $(this); 
			var ul 			= $("ul", div); 
			var li 			= $("li", ul); 
			var img			= $("img", li);
			var itemLength 	= li.size(); 
			
			if (itemLength >=3){
			
				var curr = o.start;
				var v = o.visible;	
				var running = false;
				
				li.css("overflow", "hidden")	// If the list item size is bigger than required
				  .css("float", "left")     	// Horizontal list
				  .children()
				  .css("overflow", "hidden");	// If the item within li overflows its size, hide'em
		
				ul.css("margin", "0")				// Browsers apply default margin 
				  .css("padding", "0")          	// and padding. It is reset here.
				  .css("position", "relative") 		// IE BUG - width as min-width
				  .css("overflow", "hidden")
				  .css("list-style-type", "none")	// We dont need any icons representing each list item.
				  .css("z-index", "1");          	// IE doesnt respect width. So z-index smaller than div
		
				div.css("overflow", "hidden")		// Overflows - works in FF
				   .css("position", "relative")  	// position relative and z-index for IE
				   .css("z-index", "2")          	// more than ul so that div displays on top of ul
				   .css("left", "0px");         	// after creating carousel show it on screen
						
				var liSize	= width(li);   			// Full li size(incl margin)-Used for animation
				var ulSize	= liSize * itemLength; 	// size of full ul(total length, not just for the visible items)
				var divSize	= liSize * v;
				var imgSize	= width(img);
				
				ul.prepend(li.clone())
				  .append(li.clone());		
				
				ul.css("width", ulSize*3+"px")				// Width of the UL is the full length for all the images
				  .css("left", -(o.start*liSize + ulSize));	// Set the starting item
	
				div.css("width", "672px");  
				
				// Attach hoverscroll mouseover event to containing div
				$(div).mouseover(
					function (e) {
						scrollOnOver(e, this);
					}
				);
				
				$(div).mouseout(
					function () {
						stopLoop();
						return false;
					}
				);
				
				var direction;							// Indicates which side (left/right) of the carousel the cursor is on
				var increment = 5;						// Indicates how many pixels to animate by per iteration of the go() function
				
				//delineates mouse "-insensitive" and "-sensitive" areas of the carousel
				var zoneStart	= imgSize/2 - 5;				
				var zoneEnd 	= this.offsetWidth/2;
				
				var scrX			= findLeft(this) + zoneEnd;  	// Find the x-position of the center of the carousel
				var zoneSize 		= zoneEnd - zoneStart;
				
				// Divides the sensitive zone into five parts based on distance from the carousel's y-axis
				var zoneDivision 	= zoneSize/5;					
				var zoneOne			= zoneStart+zoneDivision;
				var zoneTwo			= zoneStart+(zoneDivision*2);
				var zoneThree		= zoneStart+(zoneDivision*3);
				var zoneFour		= zoneStart+(zoneDivision*4);
				
				// Tracks whether animation loop is turned on or off
				var loopOn = false;					
				var loopRunning;
			}
			
			else{
				li.css("overflow", "hidden")	// If the list item size is bigger than required
				  .css("display", "inline")     	// Horizontal list
	
				div.css("width", 672+"px").css("padding", "0").css("text-align", "center"); 
			}
		
			// On mouseover, determines direction and speed for the animation based on cursor position
			function scrollOnOver(e, el){//mouseEventHandler e, element holding the carousel el// 			
				// Find the current x-position of the cursor
				var mouseX		= e.clientX;			
				var distance	= mouseX - scrX;
							
				// Set variables to indicate the cursor's direction and absolute distance from the y-axis of the carousel
				if (distance<0){
					if (direction == "right"){
						directionSwitched = true;
					} 
					else {
						directionSwitched = false;
					}
					direction = "left";
				}
				else{
					if (direction == "left"){
						directionSwitched = true;
					} else {
						directionSwitched = false;
					}
					direction = "right";
				}
				distance = Math.abs(distance);
				
				// If the cursor is on a sensitive zone, set the animation speed according to its distance from the y-axis
				if (distance>zoneStart && distance<zoneEnd){
					/*if(distance<zoneOne){
						o.speed = 150;
					}
					else if(distance>=zoneOne && distance<zoneTwo){
						o.speed = 75;
					}
					else if(distance>=zoneTwo && distance<zoneThree){
						o.speed = 30;
					}
					else if(distance>=zoneThree && distance<zoneFour){
						o.speed = 10;
					}
					else if(distance>=zoneFour){
						o.speed = 5;
					}*/
					
					// If the animation loop is turned off, start it
					if(!loopOn && !loopRunning){
						loopOn = true;
						loop();
					}
				}
				else{
					stopLoop();
				}
				
			}
			
			// Invokes the animation function and calls itself recursively, until the animation loop is turned off 
			function loop(){
				if (loopOn){
					go();
					loopRunning = true;
					setTimeout(loop, 1)
				}
			}
			
			function stopLoop(){
				loopOn = false;
				loopRunning = false;
			}
			
			// Animates x pixels to the left or right, where x is the static variable "increment", and "to" is the direction
			function go() {
            	if(!running) {
					running = true;
					
					var currPos = parseInt(ul.css("left"));	//current position of the animating list
					var vector;									//how far to animate, in what direction (left / right -> negative / positive)
				
					// If the direction is "right", set the animation to move in the correct direction				
					if (direction == "right"){	
						vector = "-=" + increment + "px";
						
						//If we are at the first image, animating in a negative direction...
						if(currPos <= (ulSize*(-2)+increment) ){	
							
							// ... slice images off the end of the list and place them at the beginning, and reposition the list
							ul.append($("li", ul)
							  .slice(0, itemLength*2)
							  .remove()
							  .clone()
							);						
							ul.css("left",  (-ulSize));
						}
					}
					
					//If the direction is "left", set the animation to move in the correct direction
					else if (direction == "left"){
						vector = "+="+increment+"px";	
						
						// If we are at the last image, animating in a positive direction...
						if(currPos >= (ulSize*(-1)-increment) ){	
							
							// ... slice images off the beginning of the list and place them at the end, and reposition the list
							ul.prepend($("li", ul)
							  .slice(itemLength)
							  .remove()
							  .clone());
							ul.css("left",  (ulSize*(-2)) );
						} 
					}

					ul.animate(
						{ left: vector }, 
						5, 
						function() {
							// Indicate the animation has finished
							running = false;
						}
					);
				}
				return false;
			};
		});
	};
		
	function css(el, prop) {
		return parseInt($.css(el[0], prop)) || 0;
	};
	
	function width(el) {
		return  el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
	};
	
	function findLeft(obj) {
		var curleft = 0;
		if (obj.offsetParent) {
			curleft = obj.offsetLeft
			while (obj = obj.offsetParent) {
				curleft += obj.offsetLeft
			}
		}
		return curleft;
	}
})
(jQuery);