/*
 * scroller.js
 *
 * Revision History:
 *
 * Oct-15-2007.  Joel Stevick.  Generalized using objects.
 *
 * Oct-11-2007.  Original version. missionmedia.com
 *
 * Copyright (c) 2007, CorData, Inc
 * Program Name: C.H.I.P. - CorData Hierarchical Inference Program
 */

/*
 * Class constructor
 */
function Scroller(contentClipId, contentId, clipRectWithScroll, widthWithScroll)
{
	/*
	 * Store IDs for content
	 */
	this.contentClipId = contentClipId;
	this.contentId = contentId;
	this.id = 'scroller' + Scroller.id++;
	
	this.content = document.getElementById(contentId);
	this.contentClip = document.getElementById(contentClipId);
	
	/*
	 * Compute the height of the scroll bar from the content clipping region
	 */
	var contentClip = document.getElementById(contentClipId);
	this.scrollH = contentClip.style.height - 2*(16); 
	
	/*
	 * Don't create a scroller if the content height does not need it
	 */
	var maxHeight = parseInt(this.content.offsetHeight);
	for(var m = this.content.firstChild; m != null; m = m.nextSibling) {
		/*
		 * Skip if this element has no CSS attributes
		 */
		if  (m.style == null)
			continue;
			
		/*
		 * If this element is not currently displayed, then display it now so that
		 * we can compute the client height, but keep it invisible
		 */
		var needRestoreDisplay = false;
		
		if (m.style.display == 'none') {
			m.style.visibility='hidden';
			m.style.display='block';
			
			needRestoreDisplay = true;
		}
		
		/*
		 * Compare height
		 */
		if (maxHeight < m.offsetHeight)
			maxHeight = m.offsetHeight;
			
		/*
		 * Restore display attributes if they were changed
		 */
		if (needRestoreDisplay == true) {
			m.style.visibility='visible';
			m.style.display='none';
		}
	}
	if (maxHeight <=  parseInt(this.contentClip.offsetHeight)) {
		return;
	}
	
	/*
	 * Do adjustments for scroll if requested
	 */
	if (clipRectWithScroll != undefined) {
		this.contentClip.style.clip = clipRectWithScroll;
		this.contentClip.style.width = widthWithScroll;
	}
	 
	/*
	 * Initialize instance variables
	 */
	this.mouseY; // Mouse Y position onclick
	this.mouseX; // Mouse X position onclick
	this.clickUp = false; // If click on up-arrow
	this.clickDown = false; // If click on down-arrow
	this.clickDrag = false; // If click on scrollbar
	this.clickAbove = false; // If click above scrollbar
	this.clickBelow = false; // If click below scrollbar
	this.timer = setTimeout("",500); // Repeat variable

	/*
	 * Static variables
	 */
	this.upH = 16; // Height of up-arrow
	this.upW = 16; // Width of up-arrow
	this.downH = 16; // Height of down-arrow
	this.downW = 16; // Width of down-arrow
	this.dragH = 38; // Height of scrollbar
	this.dragW = 14; // Width of scrollbar
	this.speed = 4; // Scroll speed

	//Create DOM elements for the scrolling controls

	/*
	 * Scrollbar background (ruler)
	 */
	this.ruler = document.createElement("div");
	this.ruler.id="ruler";
	this.ruler.style.position="absolute";
	this.ruler.style.left=(parseInt(contentClip.style.width) + parseInt(contentClip.style.left)) + 'px';
	this.ruler.style.top=(parseInt(contentClip.style.top) + this.downH) + 'px';
	this.ruler.style.height=(parseInt(this.contentClip.style.height) - 2*this.downH) + 'px';
	this.ruler.style.width=this.upW + 'px';
	this.ruler.zIndex=1;
	this.ruler.style.backgroundImage='url(CustomScroller/images/scrollbar_slice.gif)';
	this.ruler.scroller = this;
	var text = document.createTextNode("");	
	this.ruler.appendChild(text);
	
	document.body.appendChild(this.ruler);


	/*
	 * Up
	 */
	this.up = document.createElement("div");
	this.up.style.position="absolute";
	this.up.style.left=(parseInt(this.contentClip.style.width) + parseInt(this.contentClip.style.left)) + 'px';
	this.up.style.top=this.contentClip.style.top;
	this.up.zIndex=2;
	this.up.scroller = this;

	var image = document.createElement("img");
	image.src="CustomScroller/images/scroller_up.jpg";
	image.border=0;
	image.id="up";
	image.scroller = this;
	
	this.up.appendChild(image);
	
	document.body.appendChild(this.up);
	
	/*
	 * Down
	 */
	this.down = document.createElement("div");
	this.down.style.position="absolute";
	this.down.style.left=(parseInt(this.contentClip.style.width) + parseInt(this.contentClip.style.left)) + 'px';
	this.down.style.top=(parseInt(this.contentClip.style.top) + parseInt(this.contentClip.style.height)  - this.downH) + 'px';
	this.down.zIndex=2;
	this.down.scroller = this;
	this.scroller = this;
	
	image = document.createElement("img");
	image.src="CustomScroller/images/scroller_down.jpg";
	image.border=0;
	image.id="down";
	image.scroller = this;
	
	this.down.appendChild(image);

	document.body.appendChild(this.down);
	
	/*
	 * Drag
	 */
	this.drag = document.createElement("div");
	this.drag.style.position="absolute";
	this.drag.style.left=(parseInt(this.contentClip.style.width) + parseInt(this.contentClip.style.left)) + 'px';
	this.drag.style.top=(parseInt(this.contentClip.style.top) + this.upH) + 'px';
	this.drag.zIndex=2;
	this.scroller = this;
	
	image = document.createElement("img");
	image.src="CustomScroller/images/scroller_tab.jpg";
	image.border=0;
	image.id="drag";
	image.scroller = this;
	
	this.drag.appendChild(image);

	document.body.appendChild(this.drag);

	// Up-arrow X and Y variables
	this.upL = parseInt(this.up.style.left);
	this.upT = parseInt(this.up.style.top);
	// Down-arrow X and Y variables
	this.downL = parseInt(this.down.style.left);
	this.downT = parseInt(this.down.style.top);
	// Scrollbar X and Y variables
	this.dragL = parseInt(this.drag.style.left);
	this.dragT = parseInt(this.drag.style.top);
	this.startY = this.dragT; // Keeps track of offset between mouse and span	
	
	// Ruler Y variable
	this.rulerT = parseInt(this.ruler.style.top);
	
	// Height of content layer and clip layer
	this.contentH = maxHeight;
	this.contentClipH = parseInt(this.contentClip.offsetHeight);
	
	// Number of pixels scrollbar should move
	this.scrollH = parseInt(this.ruler.style.height);
	this.scrollLength = ((this.scrollH-this.dragH)/(this.contentH-this.contentClipH));
	/*
	 * Store this scroller object so that we can look it up by ID
	 */
	Scroller.objects[this.id] = this;	
	 
}

/*
 * Static id
 */
Scroller.id = 0;
Scroller.objects = new Object;

/*
 * Lookup a scroller by ID
 */
Scroller.Lookup = function (id)
{
	return Scroller.objects[id];	
}
/*
 * Browser detection
 */
var dom = document.getElementById ? true:false;
var nn4 = document.layers ? true:false;
var ie4 = document.all ? true:false;

/*
 * Get the scroller from the event object
 */
function GetScrollerFromEvent(e)
{
	/*
	 * Get the scroller object
	 */
	var evt, scroller;
	if (e == null || e == undefined)
		evt = window.event; // fits both event models
	else 
		evt = e;
	
	if (evt.target == null || evt.target == undefined)
		scroller = evt.srcElement.scroller;
	else
		scroller = evt.target.scroller;
		
	return scroller;
}
/*
 * Mousedown
 */
function down(e){
	if((document.layers && e.which!=1) || (document.all && event.button!=1)) return true; // Enables the right mousebutton
	/*
	 * Get the scroller object
	 */
	var scroller = GetScrollerFromEvent(e);
	
	if (scroller == undefined)
		return true;
	
	// Get the mouse click parameters
	getMouse(scroller, e);
	
	scroller.startY = (scroller.mouseY - scroller.dragT);
	
	// If click on up-arrow
	if(scroller.mouseX >= scroller.upL && 
	   (scroller.mouseX <= (scroller.upL + scroller.upW)) && scroller.mouseY >= scroller.upT 
	    && (scroller.mouseY <= (scroller.upT + scroller.upH))){
		scroller.clickUp = true;
		return scrollUp(scroller.id);
	}	
	// Else if click on down-arrow
	else if( (scroller.mouseX >= scroller.downL && scroller.mouseX <= (scroller.downL + scroller.downW)) 
		&& scroller.mouseY >= scroller.downT && (scroller.mouseY <= (scroller.downT + scroller.downH))){
		scroller.clickDown = true;
		return scrollDown(scroller.id);
	}
	// Else if click on scrollbar
	else if(scroller.mouseX >= scroller.dragL && 
			(scroller.mouseX <= (scroller.dragL + scroller.dragW)) && scroller.mouseY >= scroller.dragT 
			&& (scroller.mouseY <= (scroller.dragT + scroller.dragH))){
		scroller.clickDrag = true;
		return false;
	}
	else if(scroller.mouseX >= scroller.dragL && (scroller.mouseX <= (scroller.dragL + scroller.dragW)) 
			&& scroller.mouseY >= scroller.rulerT && (scroller.mouseY <= (scroller.rulerT + scroller.scrollH))){
		// If click above drag
		if(scroller.mouseY < scroller.dragT){
			scroller.clickAbove = true;
			scroller.clickUp = true;
			return scrollUp(scroller.id);
		}
		// Else click below drag
		else{
			scroller.clickBelow = true;
			scroller.clickDown = true;
			return scrollDown(scroller.id);
		}
	}
	// If no scrolling is to take place
	else{
		up();
		return true;
	}
}

// Drag function
function move(e){
	/*
	 * Get the scroller object
	 */
	var scroller = GetScrollerFromEvent(e);
	if (scroller == undefined || scroller == null) {
		up();
		return;
	}
		
	if(scroller.clickDrag && scroller.contentH >= scroller.contentClipH){
		getMouse(scroller, e);
		scroller.dragT = (scroller.mouseY - scroller.startY);
		if(scroller.dragT < (scroller.rulerT))
			scroller.dragT = scroller.rulerT;		
		if(scroller.dragT > (scroller.rulerT + scroller.scrollH - scroller.dragH))
			scroller.dragT = (scroller.rulerT + scroller.scrollH - scroller.dragH);
		
		scroller.contentT = ((scroller.dragT - scroller.rulerT)*(1/scroller.scrollLength));
		scroller.contentT = eval('-' + scroller.contentT);
		moveTo(scroller);
		
		// So ie-pc doesn't select gifs
		if(ie4)
			return false;
	}
}

function up(e){
	/*
	 * Enumerate the scroller objects
	 */
	for (id in Scroller.objects) {
		
		var scroller = Scroller.objects[id];
		
		clearTimeout(scroller.timer);
		
		// Resetting variables
		scroller.clickUp = false;
		scroller.clickDown = false;
		scroller.clickDrag = false;
		scroller.clickAbove = false;
		scroller.clickBelow = false;
	}
	return true;
}

// Reads content layer top
function getT(scroller){
	/*
	 * Get the scroller object
	 */
	scroller.contentT = parseInt(scroller.content.style.top);
}

// Reads mouse X and Y coordinates
function getMouse(scroller, e){
	if(ie4){
		scroller.mouseY = event.clientY + document.body.scrollTop;
		scroller.mouseX = event.clientX + document.body.scrollLeft;
	}
	else if(nn4 || dom){
		scroller.mouseY = e.pageY;
		scroller.mouseX = e.pageX;
	}
}

// Moves the layer
function moveTo(scroller){
	scroller.content.style.top = scroller.contentT + "px";
	scroller.drag.style.top = scroller.dragT + "px";
}

// Scrolls up
function scrollUp(scrollerid){
	
	var scroller = Scroller.Lookup(scrollerid);
	
	getT(scroller);
	
	if(scroller.clickAbove){
		if(scroller.dragT <= (scroller.mouseY-(scroller.dragH/2)))
			return up();
	}
	
	if(scroller.clickUp){
		if(scroller.contentT < 0){		
			scroller.dragT = scroller.dragT - (scroller.speed*scroller.scrollLength);
			
			if(scroller.dragT < (scroller.rulerT))
				scroller.dragT = scroller.rulerT;
				
			scroller.contentT = scroller.contentT + scroller.speed;
			if(scroller.contentT > 0)
				scroller.contentT = 0;
			
			moveTo(scroller);
			scroller.timer = setTimeout("scrollUp('" + scroller.id + "')",25);
		}
	}
	return false;
}

// Scrolls down
function scrollDown(scrollerid){
	var scroller = Scroller.Lookup(scrollerid);
	getT(scroller);	
	if(scroller.clickBelow){
		if(scroller.dragT >= (scroller.mouseY-(scroller.dragH/2))) {
			return up();
		}
	}
	if(scroller.clickDown){
		if(scroller.contentT > -(scroller.contentH - scroller.contentClipH)){			
			scroller.dragT = scroller.dragT + (scroller.speed*scroller.scrollLength);
			if(scroller.dragT > (scroller.rulerT + scroller.scrollH - scroller.dragH))
				scroller.dragT = (scroller.rulerT + scroller.scrollH - scroller.dragH);
			
			scroller.contentT = scroller.contentT - scroller.speed;
			if(scroller.contentT < -(scroller.contentH - scroller.contentClipH))
				scroller.contentT = -(scroller.contentH - scroller.contentClipH);
			
			moveTo(scroller);
			scroller.timer = setTimeout("scrollDown('" + scroller.id + "')",25);
		}
	}
	return false;
}

// reloads page to position the layers again
function reloadPage(){
	location.reload();
}


