/*
 * @name		albert-scroller.v2.js
 * @author		Albert Ahronian
 * @desc		Vertical Scroller, including multiple scrollers on same page
 * @since		June 16, 2010
 */

(function($) {
	$.vScroller = (function() {
		function vScroller(suffix) {
			var self = this,
				scrollerEventsBound = false,
				contentWrapperSelector = '#list-content' + suffix,
				scrollerWrapperSelector = '#scroller-wrapper' + suffix,
				$contentWrapper = $(contentWrapperSelector),
				$scrollerWrapper = $(scrollerWrapperSelector),
				$content = $contentWrapper.children('.scroller-container'),
				$scrollbarTrack = $scrollerWrapper.find('.scrollbar-track'),
				$scrollbarHandle = $scrollerWrapper.find('.scrollbar-handle'),
				$body = $('body');
				
			this.scrollerTimerID = 0;
			this.suffix = suffix;
			this.$contentWrapper = $contentWrapper;
			this.$content = $content;
			this.$scrollbarHandle = $scrollbarHandle;
			this.$scrollbarTrack = $scrollbarTrack;
			this.elevatorOffset = 0;
			
			
			if(typeof window.disableTextSelection == 'function') {
				window.disableTextSelection(contentWrapperSelector);
				window.disableTextSelection(scrollerWrapperSelector);
			}
			
			if($content.height() <= $contentWrapper.height()) {
				$scrollerWrapper.hide();
			} else {
				$scrollerWrapper.show();
			}
			
			if(!scrollerEventsBound) {
				scrollerEventsBound = true;
				$scrollerWrapper.find('.scrollbar-up').bind('mousedown', function() {
					window.clearInterval(self.scrollerTimerID);
					self.scrollerTimerID = window.setInterval(function() {
						self.scrollByArrow(-1);
					}, 50);
				}).bind('mouseup', function() {
					window.clearInterval(self.scrollerTimerID);
				});
				
				$scrollerWrapper.find('.scrollbar-down').bind('mousedown', function() {
					window.clearInterval(self.scrollerTimerID);
					self.scrollerTimerID = window.setInterval(function() {
						self.scrollByArrow(1);
					}, 50);
				}).bind('mouseup', function() {
					window.clearInterval(self.scrollerTimerID);
				});
				
				$scrollbarHandle.bind('mousedown', function(event) {
					self.elevatorOffset = $scrollbarHandle.offset().top - event.pageY;
					$body.bind('mousemove', function(event) {
						var dY = event.pageY - $scrollbarTrack.offset().top;
						self.scrollByElevator(dY);
					}).bind('mouseup', function() {
						$body.unbind('mousemove');
					});
				});
				
				$contentWrapper.bind('mousewheel', function(event, delta) {
					self.scrollByArrow(delta * -1);
					event.preventDefault();
				});
				
				$scrollerWrapper.bind('mousewheel', function(event, delta) {
					self.scrollByArrow(delta * -1);
					event.preventDefault();
				});
			}
		}
		
		vScroller.prototype.scrollByArrow = function(direction) {
			var scrollRange = {
					'from': 0,
					'to': this.$content.height() - this.$contentWrapper.height()
				},
				elevatorRange = {
					'from': 0,
					'to': this.$scrollbarTrack.height() - this.$scrollbarHandle.height()
				},
				scrollTo = this.$contentWrapper.scrollTop() + (10 * direction);
				
			if(scrollTo > scrollRange.to) {
				scrollTo = scrollRange.to;
				window.clearInterval(this.scrollerTimerID);
			} else if(scrollTo < 0) {
				scrollTo = 0;
				window.clearInterval(this.scrollerTimerID);
			}
			
			this.$scrollbarHandle.css('margin-top',
				Math.floor(elevatorRange.to * (scrollTo / scrollRange.to)) + 'px'
			);
			this.$contentWrapper.scrollTop(scrollTo);
		};
		
		vScroller.prototype.scrollByElevator = function(distance) {
			distance += this.elevatorOffset;
			var scrollRange = {
					'from': 0,
					'to': this.$content.height() - this.$contentWrapper.height()
				},
				elevatorRange = {
					'from': 0,
					'to': this.$scrollbarTrack.height() - this.$scrollbarHandle.height()
				},
				scrollTo;
			
			if(distance > elevatorRange.to) {
				distance = elevatorRange.to;
				window.clearInterval(this.scrollerTimerID);
			} else if(distance < 0) {
				distance = 0;
				window.clearInterval(this.scrollerTimerID);
			}
			
			scrollTo = Math.floor(scrollRange.to * (distance / elevatorRange.to));
			this.$scrollbarHandle.css('margin-top', distance);
			this.$contentWrapper.scrollTop(scrollTo);
		};
		
		return vScroller;
	}());
}(window.jQuery));
