//
// Scroll Bar
//
(function ($) {
	//
	// plugin definition
	//
	$.fn.sb = function (options) {
		// build main options before element iteration
		var el_count = 0;
		var opts = $.extend({}, $.fn.sb.defaults, options);
		// iterate and reformat each matched element
		return this.each(function () {
			var $this = $(this);
			// build element specific options
			var data = $this.metadata();
			//debug(inspect(data));
			var o = data ? $.extend({}, opts, data) : opts;
			// call our markup function
			var co = $this.html();
			//var width = $this.width();
			//var height = $this.height();
			var m = $.fn.sb.markup(o);
			$this.html(m);
			$this.find('.overview').append(co);
			//$('.viewport', $this).width(width);
			//$('.viewport', $this).height(height);

			var oViewport = { obj: $('.viewport', $this) };
			var oContent = { obj: $('.overview', $this) };
			var oScrollbar = { obj: $('.scrollbar', $this) };
			var oTrack = { obj: $('.track', oScrollbar.obj) };
			var oThumb = { obj: $('.thumb', oScrollbar.obj) };
			var sAxis = o.axis == 'x', sDirection = sAxis ? 'left' : 'top', sSize = sAxis ? 'Width' : 'Height';
			var iScroll, iPosition = { start: 0, now: 0 }, iMouse = {};
			var $d = $(document);

			// handle wheel events
			$this.wheel(function (oEvent) {
				if (!(oContent.ratio >= 1)) {
					oEvent = $.event.fix(oEvent || window.event);
					var iDelta = oEvent.wheelDelta ? oEvent.wheelDelta / 120 : -oEvent.detail / 3;
					iScroll -= iDelta * o.wheel;
					iScroll = Math.min((oContent[o.axis] - oViewport[o.axis]), Math.max(0, iScroll));
					oThumb.obj.css(sDirection, iScroll / oScrollbar.ratio);
					oContent.obj.css(sDirection, -iScroll);
					oEvent.preventDefault();
				}
			});

			$this.update = function () {
				iScroll = 0;
				oViewport[o.axis] = oViewport.obj[0]['offset' + sSize];
				oContent[o.axis] = oContent.obj[0]['scroll' + sSize];
				oContent.ratio = oViewport[o.axis] / oContent[o.axis];
				oScrollbar.obj.toggleClass('disable', oContent.ratio >= 1);
				oTrack[o.axis] = o.size == 'auto' ? oViewport[o.axis] : o.size;
				oThumb[o.axis] = Math.min(oTrack[o.axis], Math.max(0, (o.sizethumb == 'auto' ? (oTrack[o.axis] * oContent.ratio) : o.sizethumb)));
				oScrollbar.ratio = o.sizethumb == 'auto' ? (oContent[o.axis] / oTrack[o.axis]) : (oContent[o.axis] - oViewport[o.axis]) / (oTrack[o.axis] - oThumb[o.axis]);
				$this.setSize();
			};
			$this.setSize = function () {
				oContent.obj.removeAttr('style');
				oThumb.obj.removeAttr('style');
				iMouse['start'] = oThumb.obj.offset()[sDirection];
				var sCssSize = sSize.toLowerCase();
				oScrollbar.obj.css(sCssSize, oTrack[o.axis]);
				oTrack.obj.css(sCssSize, oTrack[o.axis]);
				oThumb.obj.css(sCssSize, oThumb[o.axis]);
			};

			$this.setEvents = function () {
				oThumb.obj.bind('mousedown', $this.start);
				oTrack.obj.bind('mouseup', $this.drag);
				oContent.obj.bind('update', function () { $this.update(); });
			};
			$this.start = function (oEvent) {
				iMouse.start = sAxis ? oEvent.pageX : oEvent.pageY;
				iPosition.start = parseInt(oThumb.obj.css(sDirection));
				$d.bind('mousemove', $this.drag);
				$d.bind('mouseup', $this.end);
				oThumb.obj.bind('mouseup', $this.end);
				return false;
			};
			$this.end = function (oEvent) {
				$d.unbind('mousemove', $this.drag);
				$d.unbind('mouseup', $this.end);
				oThumb.obj.unbind('mouseup', $this.end);
				return false;
			};
			$this.drag = function (oEvent) {
				if (!(oContent.ratio >= 1)) {
					iPosition.now = Math.min((oTrack[o.axis] - oThumb[o.axis]), Math.max(0, (iPosition.start + ((sAxis ? oEvent.pageX : oEvent.pageY) - iMouse.start))));
					iScroll = iPosition.now * oScrollbar.ratio;
					oContent.obj.css(sDirection, -iScroll);
					oThumb.obj.css(sDirection, iPosition.now); ;
				}
				return false;
			};

			$this.update();
			$this.setEvents();

		});
	};

	//
	// define and expose our format function
	//
	$.fn.sb.markup = function (o) {
		var s = '<div class="scrollbar"><div class="track"><div class="thumb"><div class="end"></div></div></div></div><div class="viewport"><div class="overview"></div></div>';
		return s;
	}; //
	// plugin defaults
	//
	$.fn.sb.defaults = {
		axis: 'y', // vertical or horizontal scrollbar? ( x || y ).
		wheel: 40,  //how many pixels must the mouswheel scroll at a time.
		scroll: true, //enable or disable the mousewheel scrollbar
		size: 'auto', //set the size of the scrollbar to auto or a fixed number.
		sizethumb: 'auto' //set the size of the thumb to auto or a fixed number.
	};

})(jQuery);

