var scrollSpeed = 0; // Used for onmouseover scroll effect for arrows on page.  May nix if I use event listeners.
var scrollTarget; // Used for onmouseover scroll effect for arrows on page.  May nix if I use event listeners.
var unpauseScroll = new Array();
var scroller = getElementsByClassName("scroller"); // Array to reference linked scrollable elements in the document, or "scrollers".

//	This section defines the namespace structure for working with the scrollers.  It is as follows:
//
// Static variables, these should not change unless the window itself changes:
//	scroller[x] = Array that holds all scrollable elements (should be DIVs)
//		scroller[x].line[y] = An array of individual lines, or individual sets of lines of text from the scroller element.
//			scroller[x].line[y].classArray[z] = An Array version of scroller.line.className - Breaks up multiple classNames to evaluate them easier.
//			scroller[x].line[y].number = The actual associative line number for the scroller[x].line[y] element.  This is how the scrolling is synchronized.
//			scroller[x].line[y].pixelTop = The actual top of the element within the scroller.
//			scroller[x].line[y].pixelBottom = The actual bottom of the element within the scroller.
//			scroller[x].line[y].pixelHeight = The actual height that the element displaces within the scroller.  Measured from offset height of itself to offset height of the next element.
//
// Dynamic variables:  These are temporary and created / used in the scrollerSync() function.
//		scroller[x].focusLine = For activeScroller, this is the line that was scroleld into the focal area of the scroller, for other scrollers, this is the coresponding line that *will* be scrolled into the focal area of the scroller.
//			scroller[x].focusLine.percent = For the activeScroller, this is the percentage of the way through the focal line that the current focal line sits.  For other scrollers, this is the percentage of the coresponding line that *will* be scrolled into the focal area of the scroller.
//			scroller[x].focusLine.focusPixel = How many pixels into the focus line, the current focus pixel is.
//		scroller[x].previousLine = The lime immediatly preceeding the current focusLine.  If the current focusLine is the first line, this is given false values of all zeros, and a line number of the linestart value.
//		scroller[x].perciseLineFocus = for activeScroller, this is the exact number of pixels from the focal line that the scroller has been scrolled.  For other scrollers, this is the exact number of pixels from the focal line that the scroller *will* be scrolled.
//		scroller[x].scrollTo = target for the scroller to scroll to.  Final pixel value.

for (var scrollerId in scroller)
{
	scroller[scrollerId].scrollerStart = getElementsByClassName("scrollerstart", null, scroller[scrollerId])[0]; // Looks for the first HTML element with the "scrollerstart" class (there should only be one) amd uses it to define what line number the scroller starts at.
	scroller[scrollerId].scrollerStart.style.display = "none";
	scroller[scrollerId].scrollerStart.classArray = scroller[scrollerId].scrollerStart.className.split(' '); // Creates an array of all class names for scrollerStart.  This is how determine the line number to start with.
	for (var classId in scroller[scrollerId].scrollerStart.classArray) // Evaluate each class name for the line, determine if it is a number.  If it is, then that will be the line.number
	{
		if (isNaN(scroller[scrollerId].scrollerStart.classArray[classId]))
		{
			
		}
		else
		{
			scroller[scrollerId].scrollerStart.number = scroller[scrollerId].scrollerStart.classArray[classId];
		}
	}

	scroller[scrollerId].line = getElementsByClassName("scrollerline", null, scroller[scrollerId]); // Makes each HTML element that contains the class "scrollerline" a line element.

	
	scroller[scrollerId].onscroll = function() {scrollerSync(this.id)}; // This automatically assigns an onscroll function to each "scroller".
	
	for (var lineId in scroller[scrollerId].line) // Set up the child properties and attributes for each line in the scroller.
	{
		scroller[scrollerId].line[lineId].classArray = scroller[scrollerId].line[lineId].className.split(' '); // Creates an array of all class names for each line.  This is how we seperate the line numbers from any other class naes.
		for (var classId in scroller[scrollerId].line[lineId].classArray) // Evaluate each class name for the line, determine if it is a number.  If it is, then that will be the line.number
		{
			if (isNaN(scroller[scrollerId].line[lineId].classArray[classId]))
			{
				
			}
			else
			{
				scroller[scrollerId].line[lineId].number = scroller[scrollerId].line[lineId].classArray[classId];
			}
		}
		
		// Evaluates the "true" top and bottom for the line and assigns that value to scroller[x].line[y].pixelTop and scroller[x].line[y].pixelBottom
		if (lineId==0) // The first element is a special case because there may be padding above the element to account for.
		{
			scroller[scrollerId].line[lineId].pixelTop = 0;
			scroller[scrollerId].line[lineId].previousLineNumber = scroller[scrollerId].scrollerStart.number-1;
		}
		else
		{
			scroller[scrollerId].line[lineId].pixelTop = scroller[scrollerId].line[lineId].offsetTop;
			scroller[scrollerId].line[lineId].previousLineNumber = scroller[scrollerId].line[lineId-1].number;
		}
		
		if (lineId==scroller[scrollerId].line.length-1) // The last element is a special case because there is no next element to use for evaluation.  offsetTop + offsetHeight must be used instead.
		{
			scroller[scrollerId].line[lineId].pixelBottom = scroller[scrollerId].line[lineId].offsetTop + scroller[scrollerId].line[lineId].offsetHeight;
		}
		else // all other cases use the comparative method of evaluating it's own offsetTop and the next offsetTop.
		{
			scroller[scrollerId].line[lineId].pixelBottom = scroller[scrollerId].line[Number(lineId)+1].offsetTop-1;
		}
		scroller[scrollerId].line[lineId].pixelHeight = scroller[scrollerId].line[lineId].pixelBottom - scroller[scrollerId].line[lineId].pixelTop; // Evaluates the "true" height for the line and assigns that value to scroller[x].line[y].pixelHeight
	}
}


function scrollerSync(source)
{
	var targetScroller = null; // This is the provate array which will contain all the scrollers that will be scroleld programatically.
	targetScroller = scroller.slice(); // Creates a new private array from the global array of scrollers.  We can work with this without changing the global array.
	var activeScroller = document.getElementById(source); // Defines the scroller that called the function through it's onscroll event as the "active" scroller.
	
	activeScroller.scrollPercent = activeScroller.scrollTop / (activeScroller.scrollHeight - activeScroller.offsetHeight);
	activeScroller.focalPoint = activeScroller.scrollPercent * activeScroller.offsetHeight + activeScroller.scrollTop;
	
	for (var scrollerId in targetScroller) // Loop through until you find the scroller element that matches the activeScroller.
	{
		if (targetScroller[scrollerId].id == activeScroller.id) // If the current scroller is the one that called the onScroll event, remove it from the array, because we do not need to scroll it programatically.
		{
			targetScroller.splice(scrollerId,1); // Remobe the activeScroller from the targetScroller array.
		}
	}
	
	for (var lineId in activeScroller.line) // Go through all the lines in the activeScroller.  Set the focus line, focus factor, and the exact focus.
	{
		if (activeScroller.line[lineId].pixelTop<=activeScroller.focalPoint)
		{
			activeScroller.focusLine = activeScroller.line[lineId];
			activeScroller.focusLine.percent = (activeScroller.focalPoint - activeScroller.focusLine.pixelTop) / activeScroller.focusLine.pixelHeight;
			activeScroller.perciseLineFocus = Number(activeScroller.line[lineId].previousLineNumber) + ((activeScroller.focusLine.number - Number(activeScroller.line[lineId].previousLineNumber)) * activeScroller.focusLine.percent);
		}
	}
	
	for (var scrollerId in targetScroller) // Loop through each non-scrolled (target) scroller.
	{
		targetScroller[scrollerId].perciseLineFocus = activeScroller.perciseLineFocus;
		// Loop through lines until you find the coresponding line to the scrolled element's focus line.  Then set the exact pixel target.
		for (lineId in targetScroller[scrollerId].line)
		{
			if (activeScroller.perciseLineFocus>targetScroller[scrollerId].line[lineId].previousLineNumber)
			{
				targetScroller[scrollerId].focusLine = targetScroller[scrollerId].line[lineId];
			
				targetScroller[scrollerId].focusLine.percent = (targetScroller[scrollerId].perciseLineFocus-targetScroller[scrollerId].focusLine.previousLineNumber)/(targetScroller[scrollerId].focusLine.number-targetScroller[scrollerId].focusLine.previousLineNumber);
				targetScroller[scrollerId].focusLine.focusPixel = targetScroller[scrollerId].focusLine.percent * targetScroller[scrollerId].line[lineId].pixelHeight;
				targetScroller[scrollerId].focalPoint = targetScroller[scrollerId].focusLine.focusPixel + targetScroller[scrollerId].focusLine.pixelTop;
				targetScroller[scrollerId].scrollPercent = activeScroller.scrollPercent;
				targetScroller[scrollerId].scrollTo	= Math.floor(targetScroller[scrollerId].focalPoint - (targetScroller[scrollerId].offsetHeight * activeScroller.scrollPercent));
			}
		}
		unpauseScroll[targetScroller[scrollerId].id] = targetScroller[scrollerId].scrollTo;
		targetScroller[scrollerId].onscroll = function() {pauseScroll(this.id)};
		targetScroller[scrollerId].scrollTop = targetScroller[scrollerId].scrollTo;
	}
}


function pauseScroll(scrollerId) // This function is called to prevent infinite loops where one divs will scroll each other.
{
	// There are other, probably better methods of restoring the onscroll event, however many of them do not work reliably in IE6, I am forced to use this method.  In testing it worked well.
	setTimeout(checkActualPosition,100)
	function checkActualPosition()
	{
		document.getElementById(scrollerId).onscroll = function() {scrollerSync(this.id)};
	}
}


function hoverScroll()  // This function is what handles the scrolling by hovering over arrows on the document.
{
	if (scrollSpeed!=0)
	{
		document.getElementById(scrollTarget).scrollTop = document.getElementById(scrollTarget).scrollTop+scrollSpeed;
	}
}

document.getElementById("gradient").height = document.getElementById("main_table").offsetHeight; // This sets the background gradient on the table to be the proper height.
setInterval("hoverScroll()",100) // This continuously calls hoverScroll, and is how it's magic works.

