


var ABCScroll = (function () {
	
	var DEFAULT_ARGS = {
		style: "default",
		imgurl: "", 
		nub_height: 17,
		bg_margin: "0px 0px 0px 0px",
		nub_margin: "0px 0px 0px 1px",
		content_height: 120,
		on_bottom: function() { }
	};
	
	var SCROLL_TIME = 30;
	var SCROLL_DELTA = 10;
	
	var scollArea = null;
	var scrollBar = null;
	var scrollBarBG = null;
	var scrollBarTop = null;
	var scrollBarMiddle = null;
	var scrollBarBottom = null;
	var isScrollBarMouseDown = false;
	var prevScrollOffset = 0;
	var nubHeight = 0;
	var fullHeight = 0;
	var contentHeight = 0;
	var intervalId = 0;
	var scroll = 0;
	var scrollDir = 0;
	var content_area = null;
	var on_bottom = null;
	var isIE = false;
	
	window.onresize = _onWindowResize;
	
	function setup(id, args) {
		isIE  = navigator.userAgent.search("MSIE") != -1;
		args = args || { };
		scrollBarBG = document.getElementById(id);
		if(!scrollBarBG) return;
		_initArgs(args);
		on_bottom = args.on_bottom;
		contentHeight = args.content_height;
		nubHeight = args.nub_height;
		_buildABCScroll(scrollBarBG, args, _onBarReady);
		_setScrollArea(scrollBarBG, args);
		_onBarReady();
		window.document.onmouseup = _onMouseUp;
		window.document.onmousemove = _onMouseMove;
		if(parent){
			parent.document.onmouseup = _onMouseUp;
			parent.document.onmousemove = _onMouseMove;
		}
	}
	
	function resetWindowListeners() {
		window.document.onmouseup = _onMouseUp;
		window.document.onmousemove = _onMouseMove;
		if(parent){
			parent.document.onmouseup = _onMouseUp;
			parent.document.onmousemove = _onMouseMove;
		}
	}
	
	function _onTopNubDown() {
		scrollDir = 1;
		intervalId = setInterval(_onScroll, SCROLL_TIME);
	}
	
	function _onBottomNubDown() {
		scrollDir = -1;
		intervalId = setInterval(_onScroll, SCROLL_TIME);
	}
	
	function _onScrollBarMouseDown(e) {
		e = e || window.event;
		if(!e) return;
		isScrollBarMouseDown = true;
		prevScrollOffset = e.clientY;
	}
	
	function _onMouseUp() {
		isScrollBarMouseDown = false;
		clearInterval(intervalId);
	}
	
	function _onMouseMove(e) {
		if(!isScrollBarMouseDown) return;
		if(!scrollBarBG) return;
		if(scrollBarBG.offsetHeight == 0) return;
		e = e || window.event;
		if(!e) return;
		var newScroll = scroll + (fullHeight / (scrollBarBG.offsetHeight - nubHeight * 2) * (prevScrollOffset - e.clientY));
		//if(newScroll < -1 * fullHeight) {
		if(newScroll <= -(fullHeight - contentHeight)) {
			//newScroll = -1 * fullHeight;
			newScroll = -(fullHeight - contentHeight)
			_check_on_bottom();
		}
		if(newScroll > 0) 
			newScroll = 0;
		prevScrollOffset = e.clientY;
		scroll = newScroll;
		_validate();
	}
	
	function _onScroll() {
		var newScroll = scroll + (scrollDir * SCROLL_DELTA);
		//if(newScroll > 0 || newScroll < -1 * fullHeight){
		/*if(newScroll > 0 || (newScroll <= -(fullHeight - contentHeight))){
			_onMouseUp();
			//scroll = Math.min(0, Math.max(newScroll, -1 * fullHeight));
			_check_on_bottom();
		}else
			scroll = newScroll;*/
			
		if(newScroll <= -(fullHeight - contentHeight)) {
			_onMouseUp();
			newScroll = -(fullHeight - contentHeight)
			_check_on_bottom();
		}
		if(newScroll >= 0)  {
			newScroll = 0;
		}
		
		scroll = newScroll;
			
		_validate();
	}
	
	function _check_on_bottom() {
		if(scroll == (-1 * fullHeight)) on_bottom();
	}
	
	function _validate() {
		scrollArea.style.top = scroll + "px";
		//scrollBar.style.top =  nubHeight + -1 * ((scroll * (scrollBarBG.offsetHeight - scrollBar.offsetHeight - nubHeight * 2)) / fullHeight) + "px";
		scrollBar.style.top =  nubHeight + -1 * ((scroll * (scrollBarBG.offsetHeight - scrollBar.offsetHeight - nubHeight * 2)) / (fullHeight - contentHeight)) + "px";
	}
	
	function _onBarReady() {
		if(scrollBarMiddle == null || fullHeight == 0) return;
		var barHeight = ((scrollBarBG.offsetHeight - nubHeight * 2) * contentHeight) / fullHeight;
		barHeight -= (scrollBar.offsetHeight - scrollBarMiddle.offsetHeight);
		barHeight = Math.round(Math.min((scrollBarBG.offsetHeight - nubHeight * 2) - scrollBar.offsetHeight, barHeight));
		if(barHeight < 0) barHeight = 0;
		if(!isNaN(barHeight)) 
			//scrollBarMiddle.style.height = barHeight + (isIE ? 10 : 0)+ "px";
			scrollBarMiddle.style.height = barHeight + "px";
	}
	
	function _initArgs(args) {
		for(var arg in DEFAULT_ARGS){
			if(!(arg in args))
				args[arg] = DEFAULT_ARGS[arg];
		}
	}
	
	function _checkAnchors(div) {
		var anchors = div.parentNode.getElementsByTagName("a");
		for(var i = 0, len = anchors.length;i < len;i++)
			if(anchors[i].href.search("#") != -1) anchors[i].onclick = _onAnchorClick;
	}
	
	
	function _onAnchorClick() {
		scrollArea.style.top = "0px";
		var scrollTo = document.getElementById(this.href.replace(/.*#/, ""));
		var newScroll = (-1 * _posInScrollArea(scrollTo).y) / scrollAreaMultiplier;
		scroll = Math.min(0, Math.max(newScroll, -1 * fullHeight));
		_validate();
		return false;
	}
	
	function _setScrollArea(div, args) {
		scrollArea = document.createElement("div");
		var parent = div.parentNode;
		content_area = parent;
		fullHeight = parent.offsetHeight + 20;
		parent.style.overflow = "hidden";
		parent.style.position = "relative";
		parent.style.height = args.content_height + "px";
		document.body.appendChild(div);
		scrollArea.innerHTML = parent.innerHTML;
		scrollArea.style.position = "relative";
		parent.innerHTML = "";
		parent.appendChild(scrollArea);
		_checkAnchors(scrollArea);
		scrollAreaMultiplier = Math.max(.81, (1 - (contentHeight / fullHeight))) 
	}
	
	function _buildABCScroll(div, args, onBarReady) {
		div.style.textIndent = "0px";
		div.style.margin = args.bg_margin;
		div.style.backgroundRepeat = "no-repeat";
		_buildABCBar(args, onBarReady);
		var top = document.createElement("div");
		var bottom = document.createElement("div");
		div.style.position = "absolute";
		div.style.top = _pos(div.parentNode).y + "px";
		div.style.left = _pos(div.parentNode).x + div.parentNode.offsetWidth + "px";
		scrollBar.style.top = args.nub_height + "px";
		bottom.style.position =
		top.style.position = "relative";
		bottom.style.height =
		top.style.height = args.nub_height + "px";
		_disableSelection(div);
		_disableSelection(top);
		_disableSelection(scrollBar);
		_disableSelection(bottom);
		_setBackgroundImage(div, args.imgurl + "/home/scrollbars/sb_background_"+args.style+".png",
		function(width, height){
			top.style.width = width + "px";	
			bottom.style.width = width + "px";
			bottom.style.top = (height - args.nub_height * 2) + "px";
			onBarReady();
		});
		top.onmousedown = _onTopNubDown;
		bottom.onmousedown = _onBottomNubDown;
		div.appendChild(top);
		div.appendChild(bottom);
		div.appendChild(scrollBar);
		onBarReady();
	}
	
	function _buildABCBar(args, onBarReady) {
		scrollBar = document.createElement("div");
		scrollBarTop = document.createElement("div");
		scrollBarMiddle = document.createElement("div");
		scrollBarBottom = document.createElement("div");
		scrollBar.style.margin = args.nub_margin;
		
		
		scrollBarMiddle.style.backgroundRepeat = "repeat-y";
		scrollBarMiddle.style.height = "100%";
		scrollBarTop.style.backgroundRepeat = "no-repeat";
		scrollBarBottom.style.backgroundRepeat = "no-repeat";
		
		//scrollBarTop.style.paddingRight = "1px";
		//scrollBarBottom.style.paddingRight = "5px";
		//scrollBarMiddle.style.paddingRight = "5px";
		
		_setBackgroundImage(scrollBarTop, args.imgurl + "/home/scrollbars/sb_top_"+args.style+".png", onImageLoaded);
		_setBackgroundImage(scrollBarBottom, args.imgurl + "/home/scrollbars/sb_bottom_"+args.style+".png", onImageLoaded);
		_setBackgroundImage(scrollBarMiddle, args.imgurl + "/home/scrollbars/sb_middle_"+args.style+".png", onImageLoaded);
		scrollBar.appendChild(scrollBarTop);
		scrollBar.appendChild(scrollBarMiddle);
		scrollBar.appendChild(scrollBarBottom);
		scrollBar.style.position = "absolute";
		scrollBar.style.left = "1px";
		scrollBar.onmousedown = _onScrollBarMouseDown;
		_disableSelection(scrollBar);
		_disableSelection(scrollBarTop);
		_disableSelection(scrollBarMiddle);
		_disableSelection(scrollBarBottom);
		//if(isIE)
			//scrollBarTop.style.marginBottom = "-10px";
		
		function onImageLoaded(width, height) { onBarReady(); }
	}
	
	function _setBackgroundImage(div, src, onready) {
		var img = new Image();
		var loaded = false;
	//	img.src = src + "?" + escape(new Date());
		img.src = src;
		if(img.height == 0 && img.width == 0)
			img.onload = onLoad;
		else {
			onLoad();
		}
			
		function onLoad() {
			if(loaded) return;
			loaded = true;
			div.style.backgroundImage = "url('"+src+"')";
			div.style.height = img.height +  "px";
			div.style.width = img.width + "px";
			if(onready) onready(img.width, img.height);
		}
	}
	
	
	function _onWindowResize() {
		if(content_area)
			scrollBarBG.style.left = _pos(content_area).x + content_area.offsetWidth + "px";
	}
	
	function _disableSelection(target){
		if (typeof target.onselectstart != "undefined") 
			target.onselectstart=function(){return false};
		else if (typeof target.style.MozUserSelect!="undefined")
			target.style.MozUserSelect="none";
		else 
			target.onmousedown=function(){return false};
		target.style.cursor = "default";
	}
	
	function _pos(node){
		var x = 0, y = 0;
		while(node){
			x += node.offsetLeft;
			y += node.offsetTop;
			node = node.offsetParent;
		}
		return {x: x, y: y};
	}
	
	function _posInScrollArea(node){
		var x = 0, y = 0;
		while(node){
			x += node.offsetLeft;
			y += node.offsetTop;
			node = node.offsetParent;
			if(node == scrollArea) break;
		}
		return {x: x, y: y};
	}
	
	return {setup: setup, resetWindowListeners: resetWindowListeners};
})();
