/**
 * Add autoScroll to a fixed sized div on mouse over.
 *
 * @example jQuery(".scroll-div").jAutoScroll({ options });
 *
 * @name jAutoScroll
 * @version 2.0 - 2011/02/05
 * @type jQuery
 * @param Object	opt	hash with options, described below.
 *								scrollDirection: 	'both', // either 'vertical' or 'horizontal'
 * @return jQuery
 * @cat Plugins/jAutoScroll
 * @author Pitoo (mail AT pitoo DOT com || http://www.pitoo.com)
 * @inspired by jScrollPane by Kelvin Luck (kelvin AT kelvinluck DOT com || http://www.kelvinluck.com)
 */

(function($) 
{

	$.fn.jAutoScroll = function(opt)
	{
		settings = $.extend({
			scrollDirection: 'both', // either 'vertical' or 'horizontal'
			scrollMethod: 'smooth', // either 'smooth' or 'fast'
			extraScroll: 25, // pixels of extra scroll
			animDuration: 400, // duration of anim
			autoSwing: 1, // swing pixels when mouseout
		}, opt);
	
		return this.each(function()
		{
			var $this = $(this);
			$this.addClass('jAutoScrollPane');
			// Switch the element's overflow to hidden to ensure we get the size of the element without the scrollbars [http://plugins.jquery.com/node/1208]
			$this.css('overflow', 'hidden');
			$this.css('position', 'relative');
			
			// create inner Div if not exists
			if (!$this.children().is('div.jAutoScrollContent'))
			{
				$this.wrapInner($('<div></div>').addClass('jAutoScrollContent'));
			}

			contDiv = $this.find('.jAutoScrollContent:first');
			// add extra margin
			if(settings.scrollDirection == 'horizontal') 	contDiv.css("padding-left",settings.extraScroll+"px"); //add margin
			else 											contDiv.css("padding-top",settings.extraScroll+"px"); //add margin
			// position it absolute and auto sized
			contDiv.css({
				'position':'absolute', 
				'top':'0px', 
				'left':'0px'
			});
			// get frame dimensions
			var panePos = $.fn.jAutoScroll.getElementPosition(this);
			paneX = panePos.x;
			paneY = panePos.y;
			paneWidth = $this.width();
			paneHeight = $this.height();
			// get inner Div dimensions
			contWidth = contDiv.width();
			contHeight = contDiv.height();
			hPixToScroll = 0;
			vPixToScroll = 0;
			if((settings.scrollDirection != 'vertical') && contWidth) 		hPixToScroll = (paneWidth - (contWidth + (2 * settings.extraScroll)));
			if((settings.scrollDirection != 'horizontal') && contHeight) 	vPixToScroll = (paneHeight - (contHeight + (2 * settings.extraScroll)));
			autoSwing = settings.autoSwing;
			th=null;
			
			if ((hPixToScroll<0) || (vPixToScroll<0)) {
				
				$this.mousemove(function(ev) 
				{
					var $target = $(ev.currentTarget).find('.jAutoScrollContent:first');
					
					// get inner Div dimensions if not set
					if((settings.scrollDirection != 'vertical') && (contWidth == 0)) 
					{ 
						contWidth = contDiv.width();
						hPixToScroll = (paneWidth - contWidth);
					}
					var mX = Math.floor(((ev.pageX - paneX) / paneWidth) * (hPixToScroll));
					if(settings.scrollMethod != 'smooth') $target.css({'left':''+mX+'px'});
					else $target.animate(
							{ 'left': mX }, 
							{ queue:false, easing:'easeOutExpo', duration:settings.animDuration }
						);
					if((settings.scrollDirection != 'horizontal') && (contHeight == 0)) 
					{ 
						contHeight = contDiv.height();
						vPixToScroll = (paneHeight - contHeight);
					}
					var mY = Math.floor(((ev.pageY - paneY) / paneHeight) * (vPixToScroll));
					if(settings.scrollMethod != 'smooth') $target.css({'top':''+mY+'px'});
					else $target.animate(
							{ 'top': mY }, 
							{ queue:false, easing:'easeOutExpo', duration:settings.animDuration }
						);
				});
				
				$this.hover(
					function (ev) {
						clearInterval(th);
						autoSwing = 0;
					}, 
					function (ev) {
						var $target = $(ev.currentTarget).find('.jAutoScrollContent:first');
						$.fn.jAutoScroll.swing($target);
					}
				);
	
				// deal with text size changes (if the jquery.em plugin is included)
				// and re-initialise the scrollPane so the track maintains the
				// correct size
				$(document).bind(
					'emchange', 
					function(e, cur, prev) { $this.jAutoScroll(settings); }
				);
				
				$.fn.jAutoScroll.swing($this.find('.jAutoScrollContent:first'));
				
			}
		})
	};
	
	$.fn.jAutoScroll.getElementPosition = function(elem)
	{
		var posX = 0;
		var posY = 0;
				  
		while(elem != null) {  //Loop through all of the parents until we get to the top
			posX += elem.offsetLeft;  //Grab the offset distance from the current element to its parent element
			posY += elem.offsetTop;
			elem = elem.offsetParent; //switch to the parent element and repeat
		}
										  
		return { x : posX, y : posY };  //return our object
	};
	
	$.fn.jAutoScroll.swing = function(target)
	{
		autoSwing = settings.autoSwing;
		if (autoSwing != 0) {
			th=window.setInterval(function() {
				target.stop();
				if(settings.scrollDirection == 'horizontal') {
					var tmp = parseInt(target.css('left')) + autoSwing;
					if (tmp>0 && autoSwing>0) autoSwing = settings.autoSwing = (0 - settings.autoSwing);
					else if (tmp<hPixToScroll && autoSwing<0) autoSwing = settings.autoSwing = (0 - settings.autoSwing);
					target.css({'left':''+tmp+'px'});
				}
				else if(settings.scrollDirection == 'vertical')  {
					var tmp = parseInt(target.css('top')) + autoSwing;
					if (tmp>0 && autoSwing>0) autoSwing = settings.autoSwing = (0 - settings.autoSwing);
					else if (tmp<vPixToScroll && autoSwing<0) autoSwing = settings.autoSwing = (0 - settings.autoSwing);
					target.css({'top':''+tmp+'px'});
				}
			}, 40);
		}
	};

})(jQuery);
