// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// 
// Coded by Travis Beckham
// http://www.squidfingers.com | http://www.podlob.com
// If want to use this code, feel free to do so, but please leave this message intact.
//
// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// --- version date: 01/24/03 ---------------------------------------------------------


// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//
// Adapted by Korneel Bouman @ squaretangle >> http://www.squaretangle.com
//
// Now horizontal as wel as vertical, allowment for encapsulation in container layer, and jumping to objects within scroller by ID.
//
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Cross-Browser Functions

var dom = document.getElementById;
var iex = document.all;
var ns4 = document.layers;

function addEvent(event,method){
	this[event] = method;
	if(ns4) this.captureEvents(Event[event.substr(2,event.length).toUpperCase()]);
}
function removeEvent(event){
	this[event] = null;
	if(ns4) this.releaseEvents(Event[event.substr(2,event.length).toUpperCase()]);
}
function getElement(name,nest){
	nest = nest ? "document."+nest+"." : "";
	var el = dom ? document.getElementById(name) : iex ? document.all[name] : ns4 ? eval(nest+"document."+name) : false;
	el.css = ns4 ? el : el.style;
	el.getTop = function(){return parseInt(el.css.top) || 0};
	el.setTop = function(y){el.css.top = ns4 ? y: y+"px"};
	el.getHeight = function(){return ns4 ? el.document.height : el.offsetHeight};
	el.getClipHeight = function(){return ns4 ? el.clip.height : el.offsetHeight};
	el.getLeft = function(){return parseInt(el.css.left) || 0};							// HZ addy
	el.setLeft = function(y){el.css.left = ns4 ? y: y+"px"};							// HZ addy
	el.getWidth = function(){return ns4 ? el.document.width : el.offsetWidth};			// HZ addy
	el.getClipWidth = function(){return ns4 ? el.clip.width : el.offsetWidth};			// HZ addy
	el.hideVis = function(){el.css.visibility="hidden"};
	el.showVis = function(){el.css.visibility="visible"};
	el.addEvent = addEvent;
	el.removeEvent = removeEvent;
	return el;
}

function getYMouse(e){
	return iex ? event.clientY : e.pageY;
}
function getXMouse(e){
	return iex ? event.clientX : e.pageX;
}

function findPosY(obj){  // by Peter-Paul Koch > http://www.quirksmode.org
	var curtop = 0;
	if (obj.offsetParent){
		while (obj.offsetParent){
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}

document.addEvent = addEvent;
document.removeEvent = removeEvent;

// ||||||||||||||||||||||||||||||||||||||||||||||||||
// Scroller Class

ScrollObj = function(mainContainerObj, speed, scrollControlObj, upObj, downObj, contentMaskObj, contentObj, dragObj, trackObj, dragHeight, trackHeight){
	this.doDrag = (typeof(dragObj) != "undefined");
	this.speed = speed;
	this.scrollControlObj = getElement(scrollControlObj);
	this.upObj = getElement(upObj);
	this.downObj = getElement(downObj);
	this.contentMaskObj = getElement(contentMaskObj); 
	this.contentObj = getElement(contentObj,contentMaskObj);
	if (this.doDrag){	
    this.dragHeight = dragHeight; // opt
  	this.trackHeight = trackHeight;  // opt
  	this.trackObj = getElement(trackObj);  // opt
  	this.dragObj = getElement(dragObj);  // opt
  	this.dragObjTop = this.dragObj.getTop();  // opt
  }	
  this.mainContainerObj = getElement(mainContainerObj);
	this.obj = contentObj+"Object";
	eval(this.obj+"=this");
	
	this.contentMaskHeight = this.contentMaskObj.getClipHeight();
	this.contentHeight = this.contentObj.getHeight();
	this.contentLength = this.contentHeight-this.contentMaskHeight;
	if (this.doDrag){	
  	this.trackTop = this.dragObj.getTop();  // opt
  	this.trackLength = this.trackHeight-this.dragHeight;  // opt
  	this.trackBottom = this.trackTop+this.trackLength; // opt
  	this.scrollLength = this.trackLength/this.contentLength;  // opt
  }	
	this.scrollTimer = null;
	
	if(this.contentHeight <= this.contentMaskHeight){
		this.scrollControlObj.hideVis();
	/*	this.downObj.hideVis();
		if (this.doDrag){	
  		this.dragObj.hideVis();
  		this.trackObj.hideVis();
    } */
	}else{
		var self = this;
		this.upObj.addEvent("onmousedown", function(){self.scroll(self.speed);return false});
		this.upObj.addEvent("onmouseup", function(){self.stopScroll()});
		this.upObj.addEvent("onmouseout", function(){self.stopScroll()});
		this.downObj.addEvent("onmousedown", function(){self.scroll(-self.speed);return false});
		this.downObj.addEvent("onmouseup", function(){self.stopScroll()});
		this.downObj.addEvent("onmouseout", function(){self.stopScroll()});
    if (this.doDrag){	
			this.dragObj.addEvent("onmousedown", function(e){self.startDrag(e);return false}); // opt
  		this.dragObj.setTop(this.dragObjTop); // opt
  		this.trackObj.addEvent("onmousedown", function(e){self.scrollJump(e);return false}); // opt
  		if(iex) this.dragObj.addEvent("ondragstart", function(){return false}); // opt
	  }
	}
}

  ScrollObj.prototype.startDrag = function(e){
    if (this.doDrag){	
  	  this.dragStartMouse = getYMouse(e);
    	this.dragStartOffset = this.dragObj.getTop();
    	var self = this;
    	document.addEvent("onmousemove", function(e){self.drag(e)});
    	document.addEvent("onmouseup", function(){self.stopDrag()});
	
	  }
  }

  ScrollObj.prototype.stopDrag = function(){
    if (this.doDrag){	
    	document.removeEvent("onmousemove");
    	document.removeEvent("onmouseup");
    }
  }

  ScrollObj.prototype.drag = function(e){
    if (this.doDrag){	
    	var currentMouse = getYMouse(e);
    	var mouseDifference = currentMouse-this.dragStartMouse;
    	var dragDistance = this.dragStartOffset+mouseDifference;
    	var dragMovement = (dragDistance<this.trackTop) ? this.trackTop : (dragDistance>this.trackBottom) ? this.trackBottom : dragDistance;
    	this.dragObj.setTop(dragMovement);
    	var contentMovement = -(dragMovement-this.trackTop)*(1/this.scrollLength);
    	this.contentObj.setTop(contentMovement);
    }
  }

  ScrollObj.prototype.scrollJump = function(e){
    if (this.doDrag){	
    	var currentMouse = getYMouse(e) - this.mainContainerObj.getTop();
    	var dragDistance = currentMouse-(this.dragHeight/2);
    	var dragMovement = (dragDistance<this.trackTop) ? this.trackTop : (dragDistance>this.trackBottom) ? this.trackBottom : dragDistance;
    	this.dragObj.setTop(dragMovement);
    	var contentMovement = -(dragMovement-this.trackTop)*(1/this.scrollLength);
    	this.contentObj.setTop(contentMovement);
    }
  }

  ScrollObj.prototype.initTop = function(topJumpObj){
    this.topJumpObj = getElement(topJumpObj);  
		var self = this;
		this.topJumpObj.addEvent("onclick", function(){self.goTop();});
  }

ScrollObj.prototype.goTop = function(e){
  this.contentObj.setTop(0);
}

ScrollObj.prototype.scroll = function(speed){
	var contentMovement = this.contentObj.getTop()+speed;
	var dragMovement = (this.doDrag)?this.trackTop-Math.round(this.contentObj.getTop()*(this.trackLength/this.contentLength)):false;
	if(contentMovement > 0){
		contentMovement = 0;
	}else if(contentMovement < -this.contentLength){
		contentMovement = -this.contentLength;
	}
	if(dragMovement && dragMovement < this.trackTop){
		dragMovement = this.trackTop;
	}else if(dragMovement && dragMovement > this.trackBottom){
		dragMovement = this.trackBottom;
	}
	this.contentObj.setTop(contentMovement);
	if (this.doDrag) this.dragObj.setTop(dragMovement);
	this.scrollTimer = window.setTimeout(this.obj+".scroll("+speed+")",25);
}

ScrollObj.prototype.stopScroll = function(){
	if(this.scrollTimer){
		window.clearTimeout(this.scrollTimer);
		this.scrollTimer = null;
	}
}

  ScrollObj.prototype.resetObj = function(){
    this.contentObj.setTop(0);
	this.contentMaskHeight = this.contentMaskObj.getClipHeight();
	this.contentHeight = this.contentObj.getHeight();
	this.contentLength = this.contentHeight-this.contentMaskHeight;
	if (this.doDrag){	
    this.dragObj.setTop(this.dragObjTop); //opt
  	this.trackTop = this.dragObj.getTop(); //opt
  	this.trackLength = this.trackHeight-this.dragHeight; //opt 
  	this.trackBottom = this.trackTop+this.trackLength; //opt
  	this.scrollLength = this.trackLength/this.contentLength; //opt
  }
	this.scrollTimer = null;

	if(this.contentHeight <= this.contentMaskHeight){
	  this.scrollControlObj.hideVis();
		/*
		this.upObj.hideVis();
		this.downObj.hideVis();
		if (this.doDrag){	
  		this.dragObj.hideVis();
  		this.trackObj.hideVis();
    }  */
	}else{
	  this.scrollControlObj.showVis();
    /*
	  if (this.doDrag){	
  		this.dragObj.showVis();
  		this.trackObj.showVis();
    }
		this.upObj.showVis();
		this.downObj.showVis();*/
	}	    
  }
  
  
ScrollObj.prototype.moveTo = function(obj){
	obj = document.getElementById(obj);
	var moveToDist = findPosY(obj) - this.contentObj.getTop() - this.contentMaskObj.getTop() - this.mainContainerObj.getTop();
	moveToDist = (moveToDist>this.contentHeight-this.contentMaskHeight) ? this.contentHeight-this.contentMaskHeight: (moveToDist<0) ? 0: moveToDist;
	
	if (this.doDrag){	
		var dragPosition = moveToDist*this.scrollLength+(this.dragHeight/2);;
	  var dragMovement = (dragPosition<this.trackTop) ? this.trackTop : (dragPosition>this.trackBottom) ? this.trackBottom : dragPosition;
  }

	this.contentObj.setTop(-moveToDist);
	if (this.doDrag) this.dragObj.setTop(dragMovement);
}
  

// And now... for something completely horizontal

ScrollObjHz = function(mainContainerObj, speed, scrollControlObj, leftObj, rightObj, contentMaskObj, contentObj, dragObj, trackObj, dragWidth, trackWidth){
	this.doDrag = (typeof(dragObj) != "undefined");
	this.speed = speed;
	this.scrollControlObj = getElement(scrollControlObj);
	this.leftObj = getElement(leftObj);
	this.rightObj = getElement(rightObj);
	this.contentMaskObj = getElement(contentMaskObj);
	this.contentObj = getElement(contentObj,contentMaskObj);
	if (this.doDrag){	
  	this.dragWidth = dragWidth; // opt
  	this.trackWidth = trackWidth; // opt
  	this.trackObj = getElement(trackObj); // opt
  	this.dragObj = getElement(dragObj); // opt
  	this.dragObjLeft = this.dragObj.getLeft(); // opt
  }
	this.mainContainerObj = getElement(mainContainerObj);
	this.obj = contentObj+"Object";
	eval(this.obj+"=this");
	
	this.contentMaskWidth = this.contentMaskObj.getClipWidth();
	this.contentWidth = this.contentObj.getWidth();
	this.contentLength = this.contentWidth-this.contentMaskWidth;
	if (this.doDrag){	
  	this.trackLeft = this.dragObj.getLeft(); // opt
  	this.trackLength = this.trackWidth-this.dragWidth; // opt
  	this.trackRight = this.trackLeft+this.trackLength; // opt
  	this.scrollLength = this.trackLength/this.contentLength; // opt
	}
	this.scrollTimer = null;
	
	if(this.contentWidth <= this.contentMaskWidth){
	  this.scrollControlObj.hideVis();
	/*	this.leftObj.hideVis();
		this.rightObj.hideVis();
		if (this.doDrag){	
  		this.dragObj.hideVis();
  		this.trackObj.hideVis();
		} */
	}else{
		var self = this;
		this.leftObj.addEvent("onmousedown", function(){self.scroll(self.speed);return false});
		this.leftObj.addEvent("onmouseup", function(){self.stopScroll()});
		this.leftObj.addEvent("onmouseout", function(){self.stopScroll()});
		this.rightObj.addEvent("onmousedown", function(){self.scroll(-self.speed);return false});
		this.rightObj.addEvent("onmouseup", function(){self.stopScroll()});
		this.rightObj.addEvent("onmouseout", function(){self.stopScroll()});
		if (this.doDrag){	
  		this.trackObj.addEvent("onmousedown", function(e){self.scrollJump(e);return false}); // opt
  		this.dragObj.addEvent("onmousedown", function(e){self.startDrag(e);return false}); // opt
  		this.dragObj.setLeft(this.dragObjLeft); // opt
  		if(iex) this.dragObj.addEvent("ondragstart", function(){return false}); // opt
    }
	}
}

ScrollObjHz.prototype.startDrag = function(e){
	if (this.doDrag){	
  	this.dragStartMouse = getXMouse(e);
  	this.dragStartOffset = this.dragObj.getLeft();
  	var self = this;
  	document.addEvent("onmousemove", function(e){self.drag(e)});
  	document.addEvent("onmouseup", function(){self.stopDrag()});
  }
}

ScrollObjHz.prototype.stopDrag = function(){
	if (this.doDrag){	
	  document.removeEvent("onmousemove");
	  document.removeEvent("onmouseup");
  }
}

ScrollObjHz.prototype.drag = function(e){
	if (this.doDrag){	
  	var currentMouse = getXMouse(e);
  	var mouseDifference = currentMouse-this.dragStartMouse;
  	var dragDistance = this.dragStartOffset+mouseDifference;
  	var dragMovement = (dragDistance<this.trackLeft) ? this.trackLeft : (dragDistance>this.trackRight) ? this.trackRight : dragDistance;
  	this.dragObj.setLeft(dragMovement);
  	var contentMovement = -(dragMovement-this.trackLeft)*(1/this.scrollLength);
  	this.contentObj.setLeft(contentMovement);
  }
}

ScrollObjHz.prototype.scrollJump = function(e){
	if (this.doDrag){	
  	var currentMouse = getXMouse(e) - this.mainContainerObj.getLeft();
  	var dragDistance = currentMouse-(this.dragWidth/2);
  	var dragMovement = (dragDistance<this.trackLeft) ? this.trackLeft : (dragDistance>this.trackRight) ? this.trackRight : dragDistance;
  	this.dragObj.setLeft(dragMovement);
  	var contentMovement = -(dragMovement-this.trackLeft)*(1/this.scrollLength);
  	this.contentObj.setLeft(contentMovement);
  }
}

ScrollObjHz.prototype.scroll = function(speed){
	var contentMovement = this.contentObj.getLeft()+speed;
	var dragMovement = (this.doDrag)?this.trackLeft-Math.round(this.contentObj.getLeft()*(this.trackLength/this.contentLength)):false;
	if(contentMovement > 0){
		contentMovement = 0;
	}else if(contentMovement < -this.contentLength){
		contentMovement = -this.contentLength;
	}
	if(dragMovement && dragMovement < this.trackLeft){
		dragMovement = this.trackLeft;
	}else if(dragMovement && dragMovement > this.trackRight){
		dragMovement = this.trackRight;
	}
	this.contentObj.setLeft(contentMovement);
	if (this.doDrag) this.dragObj.setLeft(dragMovement);
	this.scrollTimer = window.setTimeout(this.obj+".scroll("+speed+")",25);
}
ScrollObjHz.prototype.stopScroll = function(){
	if(this.scrollTimer){
		window.clearTimeout(this.scrollTimer);
		this.scrollTimer = null;
	}
}



// ||||||||||||||||||||||||||||||||||||||||||||||||||
// Misc Functions

function fixNetscape4(){
	if(ns4origWidth != window.innerWidth || ns4origHeight != window.innerHeight){
		window.location.reload();
	}	
}
if(document.layers){
	ns4origWidth = window.innerWidth;
	ns4origHeight = window.innerHeight;
	window.onresize = fixNetscape4;
}
