/**
 * Javascript Scrollbar
 * @author 	Keith Foster
 * @date	June 2009
 */

if(!site) var site = {};
site.h = function(Elem) { var elem; if(typeof(Elem)=="object") elem = Elem; else if(document.getElementById) var elem = document.getElementById(Elem); else if (document.all) var elem = document.all[Elem]; xPos = elem.offsetHeight;	return xPos; }
site.w = function(Elem) { var elem; if(typeof(Elem)=="object") elem = Elem; else if(document.getElementById) var elem = document.getElementById(Elem); else if (document.all) var elem = document.all[Elem]; if(elem) xPos = elem.offsetWidth; return xPos; }
site.getMouseCoordinates = function(e) { var m = new Array(); m["x"] = 0; m["y"] = 0; if(!e) var e = window.event; if (e.pageX || e.pageY) { m.x = e.pageX; m.y = e.pageY; } else if (e.clientX || e.clientY) { m.x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; m.y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } return m; };
site.getByClassName = function(element, classname) { var children = element.childNodes; for(var i=0, child=null; n=children.length, child=children[i], i<n; i++) { if(child.className && (child.className.toString().indexOf(classname)!=-1)) { return child; } } return null; }

site.ScrollbarController = (function(){
	var SCROLLBARS = new Array();
	
	function build(scrollbars) {
		var config = { height:20, width:20 };
		for(var i=0, container=null; n=scrollbars.length, container=scrollbars[i], i<n; i++) {						
			SCROLLBARS[SCROLLBARS.length] = new site.ScrollBar(container);			
		}
	}
	return function(){
		var scrolling = jQuery('.to-scroll');
		build(scrolling);
		
		jQuery(window).resize(function(e){
			for(var i=0, sb=null; n=SCROLLBARS.length, sb=SCROLLBARS[i], i<n; i++) {
				sb.rebuild();
			}
		});
		
		this.rebuild = function() {
			for(var i=0, sb=null; n=SCROLLBARS.length, sb=SCROLLBARS[i], i<n; i++) {
				sb.rebuild();
				if(!sb.getIsBound()) {
					sb.bind();
				}
			}
		}
	}
})();

site.ScrollBar = (function(){
	var _currentSlider = new Array(), _currentContentArea = null, _mouseDown = false, _mouseDownPosition = null;

	function getBoundaries(orientation) { var bounds = new Array(); bounds.x = 0; bounds.y = (_currentSlider.parent().get(0))?((orientation)?_currentSlider.parent().width():_currentSlider.parent().height()):false;	return bounds; };

	function getSliderWidth(container, content) {
		var contentWidth = site.w(content);
		var containerWidth = site.w(container);		
		return Math.round((containerWidth/contentWidth) * containerWidth);
	}
	function getSliderHeight(container, content) {
		var contentHeight = site.h(content);
		var containerHeight = site.h(container);		
		return Math.round((containerHeight/contentHeight) * containerHeight);
	}
	
	function withinBoundaries(slider, orientation) {
		var bounds = getBoundaries(orientation);
		var st = (orientation===0) ? parseInt(slider.css('top')) : parseInt(slider.css('left'));
		var sb = (orientation===0) ? (slider.height()+st) : (slider.width()+st);		
		if(!bounds.y) alert("No");
		
		return (st>=bounds.x && sb<=bounds.y)?true:false;	
	};
	
	function mouseDownEvent(element, event, orientation) {
		_mouseDown = true, _currentSlider = jQuery(element);
		var container = element.parentNode.parentNode, content = jQuery('div.content', container).get(0);
		var contentHeight = site.h(content), contentWidth = site.w(content), containerHeight = site.h(container), containerWidth = site.w(container);
		
		if(orientation===0) {
			_currentSlider.ratio = (contentHeight-containerHeight)/(_currentSlider.parent().height()-_currentSlider.height());			
		} else {
			_currentSlider.ratio = ((contentWidth)-containerWidth)/(_currentSlider.parent().width()-_currentSlider.width());
		}
		_mouseDownPosition = site.getMouseCoordinates(event);
		_currentSlider["top"] = parseInt(jQuery(element).css('top'));
		_currentSlider["left"] = parseInt(jQuery(element).css('left'));			
		_currentContent = jQuery(content);
	}
	
	function mouseMoveEvent(element, event, orientation, delta) {
		var sliderPosition = null;
		delta = delta || null;
		var positionSlider = function(property) {
			diff  = property == 'top' ? _mouse.y-_mouseDownPosition.y : _mouse.x-_mouseDownPosition.x;
			st = parseInt(_currentSlider[property]);
			sliderPosition = st + diff;
			if (sliderPosition < 0) {
				sliderPosition = 0;
			} else {
				var sliderLength = (property == 'top' ? parseInt(_currentSlider.height()) : parseInt(_currentSlider.width()));
				if (sliderPosition > (bounds.y - sliderLength)) {
					sliderPosition = (bounds.y - sliderLength);
				}
			}
			_currentSlider.css(property, sliderPosition+'px');
			_currentContent.css(property, -(sliderPosition*_currentSlider.ratio)+'px');
		}
		if(delta != null) {
			var st = null, bounds = getBoundaries(orientation);
			delta *= -15;
			if (withinBoundaries(_currentSlider, orientation)) {
				if (orientation === 0) {
					st = parseInt(_currentSlider.css('top'));
					sliderPosition = (delta + st);
					if (sliderPosition < 0) 
						sliderPosition = 0;
					else if (sliderPosition > (bounds.y - parseInt(_currentSlider.css('height')))) 
						sliderPosition = (bounds.y - parseInt(_currentSlider.css('height')));
					
					_currentSlider.css('top', sliderPosition + 'px');
					_currentContent.css('top', -(Math.round(sliderPosition * _currentSlider.ratio)) + 'px');
				} else {
					st = parseInt(_currentSlider.css('left'));
					sliderPosition = (delta + st);
					if (sliderPosition < 0) 
						sliderPosition = 0;
					else if (sliderPosition > (bounds.y - parseInt(_currentSlider.css('width')))) 
						sliderPosition = (bounds.y - parseInt(_currentSlider.css('width')));
					
					_currentSlider.css('left', sliderPosition + 'px');
					_currentContent.css('left', -(Math.round(sliderPosition * _currentSlider.ratio)) + 'px');
				}
			} else if (!withinBoundaries(_currentSlider, orientation)) {
				st = parseInt(_currentSlider.css('top'));
				if (st > 0) 
					_currentSlider.css('top', (bounds.y - _currentSlider.height) + 'px');
				else 
					_currentSlider.css('top', '0px');
			}
			
		} else if(_mouseDown) {
			var st = null, bounds = getBoundaries(orientation);
			_mouse = site.getMouseCoordinates(event);
			if(_mouseDown && withinBoundaries(_currentSlider, orientation)) {
				if(orientation===0) {
					positionSlider('top');
				} else {
					positionSlider('left');
				}
				
			} else if(!withinBoundaries(_currentSlider, orientation)) {
				st = parseInt(_currentSlider.css('top'));
				if(st>0) _currentSlider.css('top', (bounds.y-_currentSlider.height)+'px');
				else _currentSlider.css('top', '0px');
			}
		}
	}

	function mouseUpEvent(){
		_mouseDown = false;
		_currentContent = null;
		_currentSlider.ratio = null;
	}
	function mouseWheelEvent(element, slider, event, orientation) {
		var delta = null;
		_currentContent = jQuery(element), _currentSlider = jQuery(slider);
		
		var contentHeight = parseInt(site.h(_currentContent.get(0))), containerHeight = parseInt(site.h(_currentContent.parent().get(0)));
		var contentWidth = parseInt(site.w(_currentContent.get(0))), containerWidth = parseInt(site.w(_currentContent.parent().get(0)))
		
		if(orientation===0) {
			_currentSlider.ratio = (contentHeight-containerHeight)/(_currentSlider.parent().height()-_currentSlider.height());			
		} else {
			_currentSlider.ratio = ((contentWidth)-containerWidth)/(_currentSlider.parent().width()-_currentSlider.width());
		}
		
		if (!event) { event = window.event; }
		if (event.wheelDelta) {
        	delta = event.wheelDelta/120;
        } else if (event.detail) { 
			delta = -event.detail/3;
		}
		
		if (delta!==null) {
			mouseMoveEvent(element, event, orientation, delta);
		}
		
		if (event.preventDefault) {
			event.preventDefault();
		}
		event.returnValue = false;		
	}
	function scrollbarBuilt(container){
		var divs = container.getElementsByTagName('div');
		for(var i=0; n=divs.length, i<n; i++) {
			if(divs[i].className.toString().indexOf('scrollbar-path') != -1) {
				return true;
			}
		}
		return false;
	}

	function resizeScrollbar(container, content, config, orientation) {
		var resize = function() {
			slider.style.height = ((orientation === 1) ? config.height : getSliderHeight(container, content)) + 'px';
			slider.style.width = ((orientation === 1) ? getSliderWidth(container, content) : config.width) + 'px';
			path.style.width = ((orientation === 1) ? site.w(container) : config.width) + 'px';
			path.style.height = ((orientation === 1) ? config.height : site.h(container)) + 'px';
		}
		
		var path = container.getElementsByClassName('scrollbar-path')[0], slider = container.getElementsByClassName('scrollbar-slider')[0];		
		
		var needed = site.h(content) > site.h(container) || site.w(content) > site.w(container);		
		if(!needed) {
			path.style.display = 'none';
			content.style.width = (site.w(content)+25) +'px'
		} else {
			if(path.style.display == 'none') {
				path.style.display = 'block';
			}
			resize();
		}
		
	}
		
	function getDimensions(container, content) {
		var containerHeight = site.h(container);
		var containerWidth = site.w(container);
		var contentHeight = site.h(content);
		var contentWidth = site.w(content);				
		return {
			content: {
				width: contentWidth,
				height: contentHeight
			},
			container: {
				width: containerWidth,
				height: containerHeight
			}
		}
	}
	
	function getHTML(container, content, config, orientation) {
		var path = document.createElement('div'); path.className = 'scrollbar-path'; 
		var slider = document.createElement('div'); slider.className = 'scrollbar-slider'; 
		if(orientation===1) {
			path.style.width = site.w(container)+'px'; path.style.height = config.height +'px';
			slider.style.height = config.height+'px'; slider.style.width = getSliderWidth(container, content)+'px'; path.appendChild(slider);
		} else {
			path.style.width = config.width+'px'; path.style.height = site.h(container) +'px';
			slider.style.width = config.width+'px'; slider.style.height = getSliderHeight(container, content)+'px'; path.appendChild(slider);
		}
		return path;
	}
	
	return function(element) {
		var container = element, content = null, config = { height:15, width:15 }, orientation = null, scrollbar = null, bound=false;
		this.getContainer = function() { return container; };
		this.setContainer = function(value) { container = value; };
		this.getContent = function() {
			if(content === null) {
				content = site.getByClassName(container, 'content');
			}
			return content;
		}
		this.getConfig = function() { return config; };
		this.setOrientation = function(value) { orientation = value; };		
		this.getOrientation = function() { 
			if(orientation === null) {
				var containerHeight = site.h(this.getContainer());
				var containerWidth = site.w(this.getContainer());
				var contentHeight = site.h(this.getContent());
				var contentWidth = site.w(this.getContent());
				if(contentHeight > containerHeight) {
					if(contentWidth > containerWidth) {
						orientation = 2;
					} else {
						orientation = 0;
					}
				} else if(contentWidth > containerWidth) {
					if(contentHeight > containerHeight) {
						orientation = 2;
					} else {
						orientation = 1;
					}
				}
			}
			return orientation; 
		}
		this.setScrollbar = function(value) { scrollbar = value; };
		this.getScrollbar = function() { return scrollbar; };
		this.setIsBound = function(value) { isBound = value; };
		this.getIsBound = function() { return bound; };
		
		this.build = function() {
			var build = function(property) {
				var sb = null;
				if(!scrollbarBuilt(container)) {
					sb = getHTML(container, content, config, this.getOrientation());
					container.appendChild(sb);
				} else {
					sb = site.getByClassName(container, 'scrollbar-path');
					resizeScrollbar(container, content, config, this.getOrientation());
				}
				return sb;
			};	
				
			var container = this.getContainer(), content = this.getContent(), config = this.getConfig(), dimensions = getDimensions(container, content);
			
			if(this.getOrientation()==null) {
				return false;
			}
			if(this.getOrientation()===0) {
				this.setScrollbar(build.call(this, 'width'));
			} else if(this.getOrientation()===1) {
				this.setScrollbar(build.call(this, 'height'));
			} else {
				if(this.getScrollbar()!=null) {
					if(container.style.height) {
						container.style.height = dimensions.content.height+'px';
					} else if(container.style.width) {
						container.style.width = dimensions.content.width+'px';
					}
					this.getScrollbar().style.display = 'none';
				}
			}
			return true;
		}
		
		this.bind = function(){
			var orientation = this.getOrientation();
			var slider = site.getByClassName(this.getScrollbar(), 'scrollbar-slider');
			var content = site.getByClassName(this.getContainer(), 'content');
			
			jQuery(slider).mousedown(function(e){
				mouseDownEvent(this, e, orientation);
				return false;
			});
			jQuery(slider).mouseup(function(e){
				mouseUpEvent(this, e, orientation);
				return false;
			});
			jQuery(slider).mousemove(function(e){
				mouseMoveEvent(this, e, orientation);
				return false;
			});
			jQuery(slider).mouseout(function(e){
				if(!_mouseDown) {
					this.className = this.className.toString().replace('active', '');
				}
			});	
			if (window.addEventListener) {
				content.addEventListener('DOMMouseScroll', function(e){
					mouseWheelEvent(this, slider, e, orientation)
				}, false);
			} else {
				content.onmousewheel = function(e) {
					mouseWheelEvent(this, slider, e, orientation);
				}
			}
			jQuery(document).mousemove(function(e){
				if(_mouseDown) {
					mouseMoveEvent(this, e, orientation);
				}
				return false;
			});
			jQuery(document).mouseup(function(e){
				mouseUpEvent(this, e, orientation);
				return false;
			});
			
			this.setIsBound(true);
		}		
		
		this.rebuild = function() { this.build(); }		
		if(this.build()) {
			this.bind();
		}
		
	};
	
})();

