(function($){
	$.fn.scrollArea = function(options){
		var fn = {
			scrollAxis: null,
			scrollAmount: null,
			scrollInterval: null,
			scrollVertical: function(addition){
				fn.scrollAmount = addition;
				
				var top = parseInt($content.css('top'));
				if (isNaN(top)) top = 0;
				
				top += addition;
				
				if (top > 0) top = 0;
				else if  (top < maxVScroll) top = maxVScroll;
				
				$content.css('top', top + 'px');
				
				if (typeof(options.onScroll) == 'function')
				{
					var pct = top / maxVScroll;
					options.onScroll.call($this, pct, 'vertical');
				}
			},
			scrollHorizontal: function(addition){
				fn.scrollAmount = addition;

				var left = parseInt($content.css('left'));
				if (isNaN(left)) left = 0;
				
				left += addition;
				
				if (left > 0) left = 0;
				else if  (left < maxHScroll) left = maxHScroll;
				
				$content.css('left', left + 'px');
				
				if (typeof(options.onScroll) == 'function')
				{
					var pct = left / maxHScroll;
					options.onScroll.call($this, pct, 'horizontal');
				}
			},
			scrollUp: function(){
				fn.scrollAxis = 'y';
				fn.scrollInterval = setInterval(function(){
					fn.scrollVertical(options.scrollAmount);
				}, options.speed);
			},
			scrollDown: function(){
				fn.scrollAxis = 'y';
				fn.scrollInterval = setInterval(function(){
					fn.scrollVertical(options.scrollAmount*-1);
				}, options.speed);
			},
			scrollLeft: function(){
				fn.scrollAxis = 'x';
				fn.scrollInterval = setInterval(function(){
					fn.scrollHorizontal(options.scrollAmount);
				}, options.speed);
			},
			scrollRight: function(){
				fn.scrollAxis = 'x';
				fn.scrollInterval = setInterval(function(){
					fn.scrollHorizontal(options.scrollAmount*-1);
				}, options.speed);
			},
			scrollStop: function(){
				clearInterval(fn.scrollInterval);

				if (options.fluid)
				{
					var prop, maxScroll;
					switch (fn.scrollAxis)
					{
						case 'x':
							prop = 'left';
							maxScroll = maxHScroll;
							break;
						case 'y':
							prop = 'top';
							maxScroll = maxVScroll;
							break;
					}

					var curVal = $content.css(prop);
					var animateObject = {};
					animateObject[prop] = Math.max(maxScroll, Math.min(0, (parseInt(curVal) + (fn.scrollAmount * 2)))) + 'px';
	
					$content.animate(animateObject, {duration: (options.fluidSpeed || options.speed * 10)})
				}
			},
			scrollInit: function(){
				var $active = $content.find('.active');
				if ($active.length > 0)
				{
					var left = $active.get(0).offsetLeft * -1;
					left += ($this.width() - $active.width()) / 2;
					$content.css('left', left + 'px');
				}
			}
		}
		
		var defaults = {
			// Settings:
			arrowUp: 		'.arrow-up',
			arrowDown: 		'.arrow-down',
			arrowLeft: 		'.arrow-left',
			arrowRight: 	'.arrow-right',
			content: 		'.content',
			fluid: 			false,
			padding: 		20,
			paddingHorizontal: 20,
			speed: 			20,
			scrollAmount: 	3,
			// Events:
			onInit: 		function(overflowVertical, overflowHorizontal){},
			onScroll: 		function(positionPercent, scrollDirection){}
		}
		
		options = $.extend(defaults, options);
		
		var $this 		= $(this);
		var $content 	= $this.find(options.content);
		
		var $arrowUp 	= typeof(options.arrowUp) == 'string' ? $this.find(options.arrowUp) : $(options.arrowUp);
		var $arrowDown 	= typeof(options.arrowDown) == 'string' ? $this.find(options.arrowDown) : $(options.arrowDown);
		
		var $arrowLeft 	= typeof(options.arrowLeft) == 'string' ? $this.find(options.arrowLeft) : $(options.arrowLeft);
		var $arrowRight = typeof(options.arrowRight) == 'string' ? $this.find(options.arrowRight) : $(options.arrowRight);
		
		var calcMaxScroll = function(contentSize, scrollAreaSize, padding)
		{
			return Math.min(0, ((contentSize - scrollAreaSize) + padding) * -1);
		}
		
		var maxVScroll 	= calcMaxScroll($content.height(), $this.height(), options.padding);
		var maxHScroll 	= calcMaxScroll($content.width(), $this.width(), options.paddingHorizontal);
		
		if (typeof(options.onInit) == 'function')
		{
			options.onInit.call($this, (maxVScroll < 0), (maxHScroll < 0));
		}
		
		if (maxVScroll > 0 && maxHScroll > 0) return;
		
		$arrowUp.mouseover(fn.scrollUp);
		$arrowUp.mouseout(fn.scrollStop);
		$arrowDown.mouseover(fn.scrollDown);
		$arrowDown.mouseout(fn.scrollStop);
		
		$arrowLeft.mouseover(fn.scrollLeft);
		$arrowLeft.mouseout(fn.scrollStop);
		$arrowRight.mouseover(fn.scrollRight);
		$arrowRight.mouseout(fn.scrollStop);
		
		fn.scrollInit();
		
		return $this;
	}
})(jQuery);
