// JavaScript Document


function getClientTop(obj)
{
	var tot = 0;
	if (obj.offsetParent) {
	  while (obj.offsetParent) {
		tot += obj.offsetTop;
		obj  = obj.offsetParent;
	  }
	}
	return tot;
}
function getClientLeft(obj)
{
	var tot = 0;
	if (obj.offsetParent) {
	  while (obj.offsetParent) {
		tot += obj.offsetLeft;
		obj  = obj.offsetParent;
	  }
	}
	return tot;
}

function Scroller (stopdiv, sbardiv, shandlediv, sbottomdiv, vwdiv, contentdiv, vertical, lines)
{

	if (vertical && vwdiv.offsetHeight < contentdiv.offsetHeight)
	{
		stopdiv.style.visibility = 'visible';
		sbardiv.style.visibility = 'visible';
		shandlediv.style.visibility = 'visible';
		sbottomdiv.style.visibility = 'visible';
	}
	if (!vertical && vwdiv.offsetWidth < contentdiv.scrollWidth)
	{
		stopdiv.style.visibility = 'visible';
		sbardiv.style.visibility = 'visible';
		shandlediv.style.visibility = 'visible';
		sbottomdiv.style.visibility = 'visible';
	}
	//divs
	var scrolltop = stopdiv;
	var scrollbar = sbardiv;
	var scrollhandle = shandlediv;
	var scrollbottom = sbottomdiv;
	var viewport = vwdiv;
	var content = contentdiv;
	var hasCapture; //holds div that has mousecapture
	var direction = ''; //scrolling direction
	var dragstartoffset = 0;
	var oldY = 0;
	var oldX = 0;
	
	//positions
	var curPosY = 0;
	var minPosY = 0;
	var maxPosY = (vwdiv.offsetHeight<contentdiv.offsetHeight) ? 
					scrollbar.offsetHeight - 3*scrollhandle.offsetHeight : minPosY; //maximum possible movement
	var curPosX = scrolltop.offsetWidth;
	var minPosX = scrolltop.offsetWidth;
	var maxPosX = (vwdiv.offsetWidth < contentdiv.scrollWidth) ? 
	                scrollbar.offsetWidth - 2*scrollhandle.offsetWidth : minPosX; //maximum possible movement
	//document.getElementById('footer').innerHTML = 'scrollwidth: ' + contentdiv.scrollWidth;
	//document.getElementById('footer').innerHTML += '<br/>overflow: ' + contentdiv.style.overflow;
	//client relative locations
	scrollhandle.relposX = parseInt(scrollhandle.style.left);
	scrollhandle.initY = getClientTop(scrollhandle);
	scrollhandle.initX = getClientLeft(scrollhandle);
	
	//scroller to content data
	var ratioY = (content.offsetHeight-viewport.offsetHeight*0.9)/maxPosY;
	var ratioX = (content.scrollWidth-viewport.offsetWidth*0.9)/maxPosX;
	var pagesY = (content.offsetHeight-viewport.offsetHeight*0.9)/viewport.offsetHeight;
	var pagesX = (content.scrollWidth-viewport.offsetWidth*0.9)/viewport.offsetWidth;
	var linesPerPageY = vertical ? lines : 16; //assume 16 lines per page
	var linesPerPageX = !(vertical) ? lines : 4;
	var lineHeightY = maxPosY/(linesPerPageY*pagesY);
	var lineHeightX = maxPosX/(linesPerPageX*pagesX);
	var scrollerInterval = 0; //save to clear interval on mouseup
	var dragstartoffset = 0;
		
	//set mouse event handlers
	scrolltop.onmousedown = endmousedown;
	scrollbar.onclick = barclick;
	scrollhandle.onmousedown = handlemousedown;
	scrollbottom.onmousedown = endmousedown;
	if (window.addEventListener) window.addEventListener('DOMMouseScroll', barwheel, false);
	else vwdiv.attachEvent('onmousewheel',barwheel);
	
	function ScrollContent(newPos)
	{
		if (vertical)
		{
			content.style.top = -(newPos*ratioY) + 'px';
		}
		else
		{
			content.style.left = -(newPos*ratioX) + 'px';
		}
	}
	function endmouseup(e)
	{
		window.clearInterval(scrollerInterval);
		if (document.removeEventListener)
		{
			document.removeEventListener('mouseup',endmouseup,true);
			document.removeEventListener('losecapture',endmouseup,true);
		}
		else
		{
			hasCapture.detachEvent('onlosecapture',endmouseup);
			hasCapture.detachEvent('onmouseup',endmouseup);
			hasCapture.releaseCapture();
		}
		hasCapture = null;
		
		if (e.preventDefault) e.PreventDefault();
		else e.returnValue = false;	
		if (e.stopPropagation) e.stopPropagation();
		else e.cancelBubble = true;
	}
	
	function handlemouseup(e)
	{
		window.clearInterval(scrollerInterval);
		if (document.removeEventListener)
		{
			document.removeEventListener('mouseup',handlemouseup,true);
			document.removeEventListener('mousemove',handlemove,true);
			document.removeEventListener('losecapture',handlemouseup,true);
		}
		else
		{
			hasCapture.detachEvent('onlosecapture',handlemouseup);
			hasCapture.detachEvent('onmouseup',handlemouseup);
			hasCapture.detachEvent('onmousemove',handlemove);
			hasCapture.releaseCapture();
		}
		hasCapture = null;
		
		if (e.preventDefault) e.PreventDefault();
		else e.returnValue = false;	
		if (e.stopPropagation) e.stopPropagation();
		else e.cancelBubble = true;
	}
	//click on end
	function endmousedown(e)
	{
		e = fixE(e);
		//which end has event?
		if (vertical && e.clientY < getClientTop(scrollhandle)) 
		{
			hasCapture = scrolltop;
			direction = 'up';
		}
		else if (vertical) 
		{
			hasCapture = scrollbottom;
			direction = 'down';
		}
		else if(e.clientX < getClientLeft(scrollhandle))
		{
			hasCapture = scrolltop;
			direction = 'left';
		}
		else
		{
			hasCapture = scrollbottom;
			direction = 'right';
		}
		
		//now register event listeners
		if (document.addEventListener)
		{
			document.addEventListener('mouseup',endmouseup,true);
			document.addEventListener('losecapture',endmouseup,true);
		}
		else
		{
			hasCapture.setCapture();
			hasCapture.attachEvent('onmouseup',endmouseup);
			hasCapture.attachEvent('onlosecapture',endmouseup);
		}
		if (vertical)
		{
			if (direction == 'up') scrollerInterval = window.setInterval(scrollup,70);
			else scrollerInterval = window.setInterval(scrolldown,70);
		}
		else
		{
			if (direction == 'left') scrollerInterval = window.setInterval(scrollup,70);
			else scrollerInterval = window.setInterval(scrolldown,70);
		}
		if (e.preventDefault) e.PreventDefault();
		else e.returnValue = false;	
		if (e.stopPropagation) e.stopPropagation();
		else e.cancelBubble = true;
	}
	
	function barwheel(e)
	{
		e = fixE(e);
		//barwheel should only respond to scrolling in the content div
		//for some reason e.target.id doesn't work consistently so find by location
		if (clickin(e.clientX, e.clientY, getClientLeft(viewport), getClientTop(viewport), 
					viewport.offsetWidth, viewport.offsetHeight))
			{
			if (e.wheelDelta)
			{
				if (e.wheelDelta >= 120) ScrollLine(true);
				else if (e.wheelDelta <= -120) ScrollLine(false);
			}
			else if(e.detail)
			{
				if (e.detail >= 3) ScrollLine(false);
				else if (e.detail <= -3) ScrollLine(true);
			}
			
			if (e.preventDefault) e.PreventDefault();
			else e.returnValue = false;	
			if (e.stopPropagation) e.stopPropagation();
			else e.cancelBubble = true;
		}
	}
	
	function barclick(e)
	{
		e = fixE(e);
		//end mouseup does not stop the bar click so check if click is in end
		//if click is on handle then do nothing
		if (clickin(e.clientX, e.clientY, getClientLeft(scrollhandle), getClientTop(scrollhandle), 
					scrollhandle.offsetWidth, scrollhandle.offsetHeight) ||
			clickin(e.clientX, e.clientY, getClientLeft(scrolltop), getClientTop(scrolltop), 
					scrolltop.offsetWidth, scrolltop.offsetHeight) ||
			clickin(e.clientX, e.clientY, getClientLeft(scrollbottom), getClientTop(scrollbottom), 
					scrollbottom.offsetWidth, scrollbottom.offsetHeight))
		{
			//do nothing
		}
		else
		{
			if (vertical)
			{
				if (e.clientY < getClientTop(scrollhandle)) ScrollPage(true);
				else ScrollPage(false);
			}
			else
			{
				if (e.clientX < getClientLeft(scrollhandle)) ScrollPage(true);
				else ScrollPage(false);
			}
		}
		if (e.stopPropagation) e.stopPropagation();
		else e.cancelBubble = true;
		if (e.preventDefault) e.PreventDefault();
		else e.returnValue = false;	
	}
	
	function handlemove(e)
	{
		var newPos;
		var delta;
		var atLeftEnd = false;
		e = fixE(e);
		if (vertical)
		{
			newPos = curPosY + (e.clientY - oldY);
			if (newPos < minPosY)
			{
				newPos = minPosY;
				oldY = scrollhandle.initY + dragstartoffset;
			}
			else 
			{
				if(newPos > maxPosY)
				{
					newPos = maxPosY;
					oldY = scrollhandle.initY + maxPosY + dragstartoffset;
				}
				else oldY = e.clientY;
			}
			curPosY = newPos;
			//now move the handle
			scrollhandle.style.top = newPos + 'px';
			//now scroll the content
			ScrollContent(newPos);
		}
		else
		{
			newPos = curPosX + (e.clientX - oldX);
			if (newPos < (minPosX))
			{
				newPos = minPosX;
				oldX = scrollhandle.initX + dragstartoffset;
				atLeftEnd = true;
			}
			else 
			{
				atLeftEnd = false;
				if(newPos > maxPosX)
				{
					newPos = maxPosX;
					oldX = scrollhandle.initX + maxPosX + dragstartoffset - scrollhandle.relposX;
				}
				else oldX = e.clientX;
			}
			curPosX = newPos;
			//now move the handle
			scrollhandle.style.left = newPos + 'px';
			//now scroll the content
			atLeftEnd ? ScrollContent(0) : ScrollContent(newPos);
		}
		if (e.stopPropagation) e.stopPropagation();
		else e.cancelBubble = true;
		if (e.preventDefault) e.PreventDefault();
		else e.returnValue = false;	
	}
	
	function handlemousedown(e)
	{
		e = fixE(e);
		hasCapture = scrollhandle;
		oldY = e.clientY;
		oldX = e.clientX;
		//now register event listeners
		if (document.addEventListener)
		{
			document.addEventListener('mouseup',handlemouseup,true);
			document.addEventListener('mousemove',handlemove,true);
			document.addEventListener('losecapture',handlemouseup,true);
		}
		else
		{
			hasCapture.setCapture();
			hasCapture.attachEvent('onmouseup',handlemouseup);
			hasCapture.attachEvent('onlosecapture',handlemouseup);
			hasCapture.attachEvent('onmousemove',handlemove);
		}
		if (vertical)
		{
			dragstartoffset = e.clientY - getClientTop(hasCapture);
		}
		else
		{
			dragstartoffset = e.clientX - getClientLeft(hasCapture);
		}
		if (e.stopPropagation) e.stopPropagation();
		else e.cancelBubble = true;
		if (e.preventDefault) e.PreventDefault();
		else e.returnValue = false;	
	}
	
	function clickin(x,y,divX,divY,divW,divH)
	{
		return ((x >= divX && x <= (divX + divW)) && (y >= divY && y <= (divY + divH)))
	}
	
	function scrollup()
	{
		ScrollLine(true);
	}
	function scrolldown()
	{
		ScrollLine(false);
	}
	
	function fixE(e)
	{
		if (typeof e == 'undefined') e = window.event;
		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
		return e;
	}
	
	function ScrollLine(up)
	{
		var newPos;
		var atLeftEnd = false;
		if (vertical)
		{
			newPos = curPosY;
			if (up)
			{ //scroll up 1 page
				newPos -= lineHeightY;
				newPos = newPos < minPosY ? minPosY : newPos;
			}
			else
			{ //scroll down 1 page
				newPos += lineHeightY;
				newPos = newPos > maxPosY? maxPosY : newPos;
			}
			curPosY = newPos;
			//now move the handle
			scrollhandle.style.top = newPos + 'px';
			//now scroll content
			ScrollContent(newPos);
		}
		else
		{
			newPos = curPosX;
			if (up)
			{ //scroll up 1 page
				newPos -= lineHeightX;
				if (newPos < (minPosX))
				{
					atLeftEnd = true;
					newPos = minPosX;
				}
				else atLeftEnd = false;
			}
			else
			{ //scroll down 1 page
				newPos += lineHeightX;
				newPos = newPos > maxPosX? maxPosX : newPos;
			}
			curPosX = newPos;
			//now move the handle
			scrollhandle.style.left = newPos + 'px';
			//now scroll content
			atLeftEnd ? ScrollContent(0) : ScrollContent(newPos);
		}
	}
	
	function ScrollPage(up)
	{
		var newPos;
		var atLeftEnd = false;
		if (vertical)
		{
			newPos = curPosY;
			if (up)
			{ //scroll up 1 page
				newPos -= lineHeightY*(linesPerPageY-1); //leave 1 line for user reference
				newPos = newPos < minPosY ? minPosY : newPos;
			}
			else
			{ //scroll down 1 page
				newPos += lineHeightY*(linesPerPageY-1); //leave 1 line for user reference;
				newPos = newPos > maxPosY? maxPosY : newPos;
			}
			curPosY = newPos;
			//now move the handle
			scrollhandle.style.top = newPos + 'px';
			//now scroll content
			ScrollContent(newPos);
		}
		else
		{
			newPos = curPosX;
			if (up)
			{ //scroll up 1 page
				newPos -= lineHeightX*(linesPerPageX-1); //leave 1 line for user reference
				if (newPos < (minPosX))
				{
					atLeftEnd = true;
					newPos = minPosX;
				}
				else atLeftEnd = false;
			}
			else
			{ //scroll down 1 page
				newPos += lineHeightX*(linesPerPageY-1); //leave 1 line for user reference;
				newPos = newPos > maxPosX? maxPosX : newPos;
			}
			curPosX = newPos;
			//now move the handle
			scrollhandle.style.left = newPos + 'px';
			//now scroll content
			atLeftEnd ? ScrollContent(0) : ScrollContent(newPos);
		}
	}
}

function setFooter(footer,wrapper)
{
	var hb = getClientTop(wrapper) + wrapper.offsetHeight;
	var vdim = viewportDim();
	var ddim = docDim();
	var highest = Math.min(hb,ddim['height']) + 80;
	var lowest = Math.max(ddim['height'],vdim['height']);
	//set footer top
	footer.style.top = (0.92*lowest < highest) ? (highest + 5) + 'px' : (0.92*lowest) + 'px';
}
	



