// Custom scroll

var _scrollerObject = null;
var _pathObject = null;
var _scrollableObject = null;
var _contentObject = null;

function InitScroll() {
	_scrollerObject = document.getElementById("_scroller");
	_pathObject = document.getElementById("_path");
	_scrollableObject = document.getElementById("_scrollable");
	_contentObject = document.getElementById("_scrollcontent");
	// Size the scrollpath
	_pathObject.style.height = document.getElementById("_scrollbar").offsetHeight - 22;
	// Size the scroller
	var scrollerSizes = CalculateScrollerHeight();
	if (scrollerSizes.scroller == 0) {
		document.getElementById("_scrollbar").innerHTML = "&nbsp;";
	} else {
		_scrollerObject.style.height = scrollerSizes.scroller + "px";
		_scrollerObject.onmousedown = ScrollerPressed;
		_scrollerObject._scrolled = 0;
		_scrollableObject.maxScroll = scrollerSizes.content;
		buttonScrollInt = window.setInterval(ButtonScroll,50);
		if (document.all) {
			_scrollableObject.onmousewheel = HandleWheel;
		} else {
			_scrollableObject.addEventListener('DOMMouseScroll', HandleWheel, false);
		}
	}
}

function CalculateScrollerHeight() {
	var h = {scroller:0, content:0};
	// Count objects
	var allContentItems = _contentObject.childNodes;
	var effectiveItems = 0;
	for (var i=0;i<allContentItems.length;i++) {
		if (typeof allContentItems[i].tagName != "undefined" && allContentItems[i].tagName.toLowerCase() == "div") effectiveItems++;
	}
	if (effectiveItems > 10) {
		var effectiveHeight = Math.ceil(effectiveItems / 5) * 212 + 20;
		var containerHeight = _scrollableObject.offsetHeight;
		// This is the percent of the invisible portion, so will be the "free" part of the scroll path
		var diffPercent = (effectiveHeight - containerHeight) / effectiveHeight;
		h.scroller = Math.floor(_pathObject.offsetHeight * (1 - diffPercent));
		h.content = effectiveHeight - containerHeight;
	}
	return h;
}

/* Handlers */

var grabPoint = 0;
var buttonScrollInt = null;
var buttonScrollDirection = 0;
var wheelDirection = 0;

function ButtonScrollClicked(dir) {
	buttonScrollDirection = dir;
	document.onmouseup = CancelScroll;
}

function ButtonScroll() {
	if (buttonScrollDirection != 0) {
		var nextTop = _scrollerObject._scrolled + buttonScrollDirection;
		var nextBottom = nextTop + _scrollerObject.offsetHeight;
		if (nextTop < 0) nextTop = 0; else 
		if (nextBottom >= _pathObject.offsetHeight) nextTop = _pathObject.offsetHeight - _scrollerObject.offsetHeight;
		_scrollerObject.style.top = nextTop + "px";
		// Calculate percentage
		var effectivePath = _pathObject.offsetHeight - _scrollerObject.offsetHeight;
		var scrollPercent = nextTop / effectivePath;
		// Scroll
		_scrollableObject.scrollTop = Math.round(_scrollableObject.maxScroll * scrollPercent);
		_scrollerObject._scrolled = nextTop;
	}
	if (wheelDirection != 0) {
		var nextTop = _scrollerObject._scrolled + wheelDirection;
		var nextBottom = nextTop + _scrollerObject.offsetHeight;
		if (nextTop < 0) nextTop = 0; else 
		if (nextBottom >= _pathObject.offsetHeight) nextTop = _pathObject.offsetHeight - _scrollerObject.offsetHeight;
		_scrollerObject.style.top = nextTop + "px";
		// Calculate percentage
		var effectivePath = _pathObject.offsetHeight - _scrollerObject.offsetHeight;
		var scrollPercent = nextTop / effectivePath;
		// Scroll
		_scrollableObject.scrollTop = Math.round(_scrollableObject.maxScroll * scrollPercent);
		_scrollerObject._scrolled = nextTop;
		wheelDirection = 0;
	}
}

function ScrollerPressed(ev) {
	var caller = getEventObject(ev);
	var xy = getEventXY(ev);
	var scrollerxy = _getRealXY(_scrollerObject);
	grabPoint = xy.y;
	if (caller == null) return;
	// prep for dragging
	document.onmouseup = CancelScroll;
	document.onmousemove = MoveScroller;
}

function MoveScroller(ev) {
	var xy = getEventXY(ev);
	var diff = xy.y - grabPoint;
	// Calculate the future position
	var nextTop = _scrollerObject._scrolled + diff;
	var nextBottom = _scrollerObject.offsetHeight + nextTop;
	// Check if it overflows from either end
	if (nextTop < 0) nextTop = 0; else 
	if (nextBottom >= _pathObject.offsetHeight) nextTop = _pathObject.offsetHeight - _scrollerObject.offsetHeight;
	// Place the scroller
	_scrollerObject.style.top = nextTop + "px";
	// Calculate percentage
	var effectivePath = _pathObject.offsetHeight - _scrollerObject.offsetHeight;
	var scrollPercent = nextTop / effectivePath;
	// Scroll
	_scrollableObject.scrollTop = Math.round(_scrollableObject.maxScroll * scrollPercent);
	// Remove selection
	try { document.selection.empty(); }
	catch(eee) {
		window.getSelection().removeAllRanges();
	}
}

function CancelScroll(ev) {
	document.onmouseup = null;
	document.onmousemove = null;
	var pTop = _getRealXY(_pathObject);
	var sTop = _getRealXY(_scrollerObject);
	var newOffset = sTop.y - pTop.y;
	_scrollerObject._scrolled = newOffset;
	buttonScrollDirection = 0;
}

function HandleWheel(ev) {
	if (typeof ev == "undefined") {
		var delta = -event.wheelDelta/120;
		var caller = event.srcElement;
		event.cancelBubble = true;
	} else {
		var delta = ev.detail/3;
		var caller = ev.target;
		ev.stopPropagation();
		ev.preventDefault();
	}
	wheelDirection = delta * (Math.floor(_pathObject.offsetHeight / 25));
	return false;
}


/* Helpers */

function getEventObject(ev) {
	var retobj = null;
	if (typeof ev == "undefined" || typeof ev.target == "undefined" || ev == null) {
		try {
			retobj = event.srcElement;
		} catch(e) {}
	} else {
		try {
			retobj = ev.target;
		} catch(e) {}
	}
	return retobj;
}

function getEventXY(ev) {
	var retobj = null;
	if (typeof ev == "undefined" || typeof ev.target == "undefined" || ev == null) {
		try {
			retobj = {x:event.clientX + document.body.scrollLeft, y:event.clientY + document.body.scrollTop};
		} catch(e) {}
	} else {
		try {
			retobj = {x:ev.clientX, y:ev.clientY + document.body.scrollTop};;
		} catch(e) {}
	}
	return retobj;
}

function _getRealXY(who) {
	// Returns the true X (from left 0) of an object.
	// The parameter can be either reference of an ID of the object
	var obj = (typeof who == "string")?document.getElementById(who):who;
	var resx = 0;
	var resy = 0;
	var t = who;
	while (1 == 1) {
		if (typeof t.offsetLeft != "undefined") {
			resx += t.offsetLeft;
			resy += t.offsetTop;
		}
		t = t.offsetParent;
		if (t == document.body) return {x:resx, y:resy};
	}
	return {x:resx, y:resy};
}
