(function($) { $.fn.scroller = function (options){ options = options || {}; if (typeof options == 'object') {return methods.init.call(this, $.extend({}, $.fn.scroller.defaults, options));	} else if (typeof methods[options] == 'function') { var args = $.makeArray(arguments); args.shift(); return methods[options].apply(this, args);} else { throw '$.fn.scroller - Unknown method '+options; }};$.noop = function() {}; methods = { init: function(options) {var options = $.extend({}, $.fn.scroller.defaults, options); return this.each (function (){ var scroller = $(this); scroller.addClass('scroller'); scroller.data('scroller', { options: options, state: { speed: 0, intervalObj: null }}); if (options.scrollOnHover) { scroller.bind('mouseenter.scroller', handleScrollMouseOver); scroller.bind('mouseleave.scroller', handleScrollMouseOut); } if (options.forwardLink && options.backwardLink) { $(options.forwardLink).click(function() { if (!$(this).hasClass('disabled')) {methods.scrollForward.call(scroller, options.scrollAmount); } }); $(options.backwardLink).click(function() { if (!$(this).hasClass('disabled')) { methods.scrollBackward.call(scroller, options.scrollAmount);}});} $(window)[$.fn.afterResize ? 'afterResize' : 'resize'](function() { onResize.call(scroller[0]); }); onResize.call(scroller[0]); });}, scrollForward: function(amount) {return this.each (function () {scrollRight.call(this, amount);})},scrollBackward: function(amount) {return this.each (function () {scrollLeft.call(this, amount);})},scrollTo: function(position) {return this.each (function () {scrollTo.call(this, position);})}}
function onResize(ev) { var scroller = $(this), options = scroller.data('scroller').options, scrollLeft = scroller.scrollLeft(), lastChild = scroller.children(':last'), max = 0;
if (lastChild.length) { max = parseInt(scroller.scrollLeft() + lastChild.position().left + lastChild.outerWidth() - scroller.innerWidth());}
if (scrollLeft >= max) {$(options.forwardLink).addClass('disabled');} else {$(options.forwardLink).removeClass('disabled');}if (scrollLeft == 0) {$(options.backwardLink).addClass('disabled');} else {$(options.backwardLink).removeClass('disabled');}if (options.hideLinks && scrollLeft >=max && scrollLeft == 0) {$(options.backwardLink).add($(options.forwardLink)).hide();}}
function scrollLeft(amount) {var scroller = $(this),options = scroller.data('scroller').options;amount = amount || 0;scrollTo.call(this, scroller.scrollLeft() - (amount ? amount : options.scrollAmount) * scroller.innerWidth());}function scrollRight(amount) {
		var scroller = $(this),
			options = scroller.data('scroller').options;
		amount = amount || 0;
		scrollTo.call(this, scroller.scrollLeft() + (amount ? amount : options.scrollAmount) * scroller.innerWidth());
	}
	function scrollTo(position) {
		var scroller = $(this), 
			options = scroller.data('scroller').options, 
			lastChild = scroller.children(':last'),
			scrollLeft = scroller.scrollLeft(), 
			max = scroller.scrollLeft() + lastChild.position().left + lastChild.outerWidth() - scroller.innerWidth();
	
		position = position > max ? max : position < 0 ? 0 : position;
		var duration = position == scrollLeft ? 0 : options.scrollTime;
		
		$(options.forwardLink).addClass('disabled');
		$(options.backwardLink).addClass('disabled');
		
		scroller.stop(true).animate({scrollLeft: position+'px'}, {duration:duration, complete: function() {
			if (position == max) {
				options.scrollMaxReached.call(scroller, options);
			} else {
				$(options.forwardLink).removeClass('disabled');
			}
			if (position == 0) {
				options.scrollMinReached.call(scroller, options);
			} else {
				$(options.backwardLink).removeClass('disabled');
			}
			scrollComplete(scroller, options, position > 0, position < max);
		}});		
	}
	function scrollComplete(scroller, options, showLess, showMore) {
		if (options.hideLinks) {
			if (!showLess && !showMore) {
				$(options.backwardLink).add($(options.forwardLink)).hide();
			} else {
				$(options.backwardLink).add($(options.forwardLink)).show();
			}
		}
		options.scrollComplete.call(scroller, options, showLess, showMore);
	}
				
	function handleScrollMouseOver(ev) {
		var scroller = $(this), 
			options = scroller.data('scroller').options,
			scrollState = scroller.data('scroller').state;
		
		handleScrollMouseMove(ev, scroller, options, scrollState);
		
		if (!scrollState.intervalObj ) {
			scrollState.intervalObj = setInterval(function() {updateScroller(scroller, scrollState);}, 10);
		}	
		scroller.bind('mousemove.scroller', function(ev) {handleScrollMouseMove(ev, scroller, options, scrollState); });
	}
	function handleScrollMouseMove(ev, scroller, options, scrollState) {
		var width = scroller.width(),
			x = ev.pageX - scroller.offset().left;
		scrollState.speed = -options.scrollOnHoverSpeed * (0.5-x/width);
	}
	function handleScrollMouseOut(ev) {
		var scroller = $(this), 
			scrollState = scroller.data('scroller').state;
		
		scroller.unbind('mousemove.scroller');
		scrollState.speed = 0;
		clearInterval(scrollState.intervalObj);
		scrollState.intervalObj = null;
	}
	function updateScroller(scroller, scrollState) {
		var left = scroller.scrollLeft();
		scroller.scrollLeft(left + scrollState.speed);
	}
	$.fn.scroller.defaults = {
		scrollOnHover: true, 
		scrollOnHoverSpeed: 10, 
		
		backwardLink: 'a.backward', 
		forwardLink: 'a.forward',
		hideLinks: false,
		
		scrollAmount: 0.5, 
		scrollDuration:800, 
		
		
		scrollMaxReached: $.noop, 
		scrollMinReached: $.noop, 
		scrollComplete: $.noop
	};
})(jQuery);
