(function($) {
	$.fn.scroller = function (options){
		var opts = $.extend({}, $.fn.scroller.defaults, options);
		
		return this.each (function ()
		{
			var scroller = $(this);
			scroller.addClass('scroller')
			
			var busy=false, 
				speed=0, 
				intervalObj=null;
				
			function init() {
				scroller.unbind('.scoller');
				if (opts.enableMouseOverScroll) {
					scroller.bind('mouseenter.scroller', handleScrollMouseOver);
					scroller.bind('mouseleave.scroller', handleScrollMouseOut);
				}
				scroller.bind('scroller:left', scrollLeft);
				scroller.bind('scroller:right',scrollRight);
				scroller.bind('scroller:scrollto', scrollTo);
				
				if ($.fn.afterResize) 
					$(window).afterResize(onResize);
				else
					$(window).resize(onResize);
				
				//	scroller.scrollLeft(0);
			}
			function onResize(ev) {
				var scrollLeft = scroller.scrollLeft();
				var lastChild = scroller.children(':last');
				var max = 0;
				if (lastChild.length) {
					max = scroller.scrollLeft() + lastChild.position().left + lastChild.width() - scroller.innerWidth();
				}
				if (opts.change) 
					opts.change(scrollLeft > 0, scrollLeft < max );
			}
			function scrollLeft(ev) {
				var scrollLeft = scroller.scrollLeft();
				
				var duration = scrollLeft == 0 ? 0 : opts.scrollTime;				
				scrollLeft -= opts.scrollAmount * scroller.innerWidth();
				scrollLeft = scrollLeft < 0 ? 0 : scrollLeft;
				
				scroller.stop(true).animate({scrollLeft: scrollLeft+'px'}, {duration: duration, complete: function() {
					if (scrollLeft == 0) {
						scroller.trigger('scroller:min');
					}
					if (opts.change)  {
						var lastChild = scroller.children(':last');
						var max = scroller.scrollLeft() + lastChild.position().left + lastChild.width() - scroller.innerWidth();
						opts.change(scrollLeft > 0, scrollLeft < max );
					}
				}});
			}
			function scrollRight(ev) {
				var scrollLeft = scroller.scrollLeft();
				var lastChild = scroller.children(':last');
				var max = 0;
				if (lastChild.length) 
					max = scroller.scrollLeft() + lastChild.position().left + lastChild.width() - scroller.innerWidth();
				
				var duration = scrollLeft == 0 ? 0 : opts.scrollTime;
				scrollLeft += opts.scrollAmount * scroller.innerWidth();				
				scrollLeft = scrollLeft > max ? max : scrollLeft;
				
				scroller.stop(true).animate({scrollLeft: scrollLeft+'px'}, {duration:opts.scrollTime, complete: function() {
					if (scrollLeft == max) {
						scroller.trigger('scroller:max');
					}
					if (opts.change) 
						opts.change(scrollLeft > 0, scrollLeft < max );
				}});
			}
			function scrollTo(ev, to) {
				var scrollLeft = scroller.scrollLeft();
				var lastChild = scroller.children(':last');
				var max = scroller.scrollLeft() + lastChild.position().left + lastChild.width() - scroller.innerWidth();
				scrollLeft = to > max ? max : to < 0 ? 0 : to;
				scroller.stop(true).animate({scrollLeft: scrollLeft+'px'}, {duration:opts.scrollTime, complete: function() {
					if (scrollLeft == max) {
						scroller.trigger('scroller:max');
					}
					if (scrollLeft == 0) {
						scroller.trigger('scroller:min');
					}
					if (opts.change) 
						opts.change(scrollLeft > 0, scrollLeft < max );
				}});
				
			}
			function handleScrollMouseOver(ev) {
				handleScrollMouseMove(ev);
				if (!intervalObj ) {
					intervalObj = setInterval(updateScroller, 13);
				}	
				scroller.bind('mousemove.scroller.move', handleScrollMouseMove);
			}
			function handleScrollMouseMove(ev) {
				var width = scroller.width();
				var x = ev.pageX - scroller.offset().left;
				speed = -opts.scrollSpeed * (0.5-x/width);
			}
			function handleScrollMouseOut(ev) {
				var x = ev.pageX - scroller.offset().left;
				speed = 0;
				clearInterval(intervalObj);
				intervalObj = null;
			}
			function updateScroller() {
				var left = scroller.scrollLeft();
				scroller.scrollLeft(left + speed);
			}				
			init();		
		});
	}
		
	$.fn.scroller.defaults = {
		enableMouseOverScroll: false, 
		scrollSpeed: 10,
		
		scrollAmount: 0.5, // half
		scrollTime:800,
		
		change: null
		
	};
})(jQuery);
