/* 
SlashC jQuery horizontal scrollbar plugin
hi@slashc.com, www.slashc.com
*/
(function($)
{	
	/* plugin methods */
	var methods =
	{
		/* intialization */
		init : function()
		{
			return this.each(function()
			{
				var $this = $(this), props = $this.data('props');				
				if(!props)
				{
					var scrollTrack = $('div.scroll-track', $this);
					var scrollButton = $('div.scroll-button', $this);
					var scrollEvent = $.Event('scroll');					
					$this.data('props', 
					{
						scrollEvent: scrollEvent,
						stage : $(document),
						scrollTrack : scrollTrack,
						scrollButton : scrollButton,
						percentage : 0, proportion : 0.5, dx : 0, maxX: 1
					});
					scrollTrack.bind('mousedown.slashcScrollBar', $.proxy(methods.onScrollTrackMouseDown, $this));
					scrollButton.bind('mousedown.slashcScrollBar', $.proxy(methods.onScrollButtonMouseDown, $this));
					methods.applyProportion.call($this);
				}
			});
		},
		/* dispose */
		dispose : function()
		{
			return this.each(function()
			{
				var $this = $(this), props = $this.data('props');
				if (props)
				{
					props.scrollTrack.unbind('.slashcScrollBar', methods.onTrackMouseDown);
					props.scrollButton.unbind('.slashcScrollBar', methods.onScrollButtonMouseDown);
					$this.removeData('props');	
				}
			});		
		},
		/* set scroll percentage */
		setPercentage : function(p)
		{
			p = p < 0 ? 0 : (p > 1 ? 1 : p);
			return this.each(function()
			{
				var $this = $(this), props = $this.data('props');
				if (props)
				{
					if (props.percentage != p)
					{
						props.percentage = props.scrollEvent.percentage = p;
						methods.applyPercentage.call($this);
						$this.trigger(props.scrollEvent);
					}
				}
			});
		},
		/* apply scroll percentage */
		applyPercentage : function()
		{
			return this.each(function()
			{
				var $this = $(this), props = $this.data('props');
				if (props)
				{
					props.scrollButton.css('left', props.maxX * props.percentage);
				}
			});
		},
		/* set scroll proportion */
		setProportion : function(p)
		{
			p = p < 0 ? 0 : (p > 1 ? 1 : p);
			return this.each(function()
			{
				var $this = $(this), props = $this.data('props');
				if (props)
				{
					if (props.proportion != p)
					{
						props.proportion = p;
						methods.applyProportion.call($this);
					}
				}
			});
		},
		/* apply scroll percentage */
		applyProportion : function()
		{
			return this.each(function()
			{
				var $this = $(this), props = $this.data('props');
				if (props)
				{
					props.scrollButton.css('width', Math.max(45, props.scrollTrack.width() * props.proportion));
					props.scrollButton.css('display', props.proportion < 1 ? 'block' : 'none');
					props.maxX = props.scrollTrack.width() - props.scrollButton.width();
					methods.applyPercentage.call($this);
				}
			});
		},
		/* scroll track mouse down handler */
		onScrollTrackMouseDown : function(e)
		{
			var props = this.data('props');
			if (props)
			{
				if (props.proportion < 1)
				{
					props.dx = props.scrollButton.width() * 0.5;
					props.stage.bind('mousemove.slashcScrollBar', $.proxy(methods.onStageMouseMove, this));
					props.stage.bind('mouseup.slashcScrollBar', $.proxy(methods.onStageMouseUp, this));
					var mme = $.Event('mousemove'); mme.pageX = e.pageX;
					props.stage.trigger(mme);
				}
			}
			e.preventDefault();
		},
		/* scroll button mouse down handler */
		onScrollButtonMouseDown : function(e)
		{
			var props = this.data('props');
			if (props)
			{
				props.dx = e.pageX - props.scrollButton.offset().left;
				props.stage.bind('mousemove.slashcScrollBar', $.proxy(methods.onStageMouseMove, this));
				props.stage.bind('mouseup.slashcScrollBar', $.proxy(methods.onStageMouseUp, this));
			}
			e.preventDefault();
		},
		/* mouse move handler */
		onStageMouseMove : function(e)
		{
			var props = this.data('props');
			if (props)
			{
				methods.setPercentage.call(this, (e.pageX - props.scrollTrack.offset().left - props.dx) / props.maxX);
			}
			e.preventDefault();
		},
		/* mouse up handler */
		onStageMouseUp : function(e)
		{
			var props = this.data('props');
			if (props) { props.stage.unbind('.slashcScrollBar', methods.onStageMouseMove); }
			e.preventDefault();
		}
	};
	/* Scrollbar plugin */
	$.fn.slashcScrollBar = function(method)
	{
		if(methods[method])
		{
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if(!method)
		{
			return methods.init.call(this);
		}		
	};
})(jQuery);
