/*
scroller.js 
pausing up-down message scroller

Note: This has been written fairly early in my process 
of learning to code using custom objects. Code from 
brainjar (Mike Hall, www.brainjar.com) and bratta 
(Thomas Brattli, www.dhtmlcentral.com) provided models. 
Many thanks to them both for their inspiring
contributions in the field of dhtml.


This code is from Dynamic Web Coding 
www.dyn-web.com 
Copyright 2001 by Sharon Paine 
Permission granted to use this code as long as this 
entire notice is included.
*/
dom = (document.getElementById) ? true : false;
ns5 = ((navigator.userAgent.indexOf("Gecko")>-1) && dom) ? true: false;
ie5 = ((navigator.userAgent.indexOf("MSIE")>-1) && dom) ? true : false;
ns4 = (document.layers && !dom) ? true : false;
ie4 = (document.all && !dom) ? true : false;
nodyn = (!ns5 && !ns4 && !ie4 && !ie5) ? true : false;

var scrlAr = new Array(); // hold scrollers

// constructor for scroller container
function scrollerObj(wd,ht,lft,tp,pt) {
	this.wd=wd; this.ht=ht; 
	this.tp=tp; this.lft=lft;	this.pt=pt;
	
	// defaults
	this.pause 	= 2500;	// how long to pause on messages
	this.spd 		= 55;		// frequency of calls to scroll
	this.inc 		= 2;		// how much to scroll per call
	this.fontFamily = "verdana, helvetica, arial, sans-serif";
	this.fontSize 	= "10pt";
	this.fontColor  = "#000000";
	this.bgClr 			= "";
	this.bdClr			= "";
	this.bdWd				= 0;
	this.pad				= 2;
	
	// methods
	this.items=new Array(); this.addItem=addScrollerItem;
	this.create=createScroller;
	this.setBg_Bd=setScrollerBgClr_border;
	this.setFont=setScrollerFont; this.setTiming=setScrollerTiming;
	this.buildN4=buildN4; this.buildIEN5=buildIEN5;
}

function addScrollerItem(url,txt) {
	this.items[this.items.length] = new Array(url,txt);
}

function setScrollerBgClr_border(bgClr,bdClr,bdWd,pad) {
	this.bgClr=bgClr; this.bdClr=bdClr; this.bdWd=bdWd; this.pad=pad;
}

function setScrollerFont(fam,sz,clr) {
	this.fontFamily=fam; this.fontSize=sz; this.fontColor=clr;
}

function setScrollerTiming(pause,spd,inc) {
	this.pause=pause; this.spd=spd; this.inc=inc;
}

// build scroller layers and content
function createScroller() {
	// rewrite 1st item to last
	this.items[this.items.length] = this.items[0];
	scrlAr[scrlAr.length] = this;	// add it to global list of scrollers
	// separate functions for assembling content
	if (ns4) this.buildN4();
	else if (ie4||ie5||ns5) this.buildIEN5();
}

function buildN4() {
	// create outer layer (border)
	this.scrBase = new Layer(this.wd);
	this.scrBase.resizeTo(this.wd,this.ht);
	if (this.bdClr) this.scrBase.bgColor = this.bdClr;
	if (this.pt){ this.lft=getPgLeft(this.pt); this.tp=getPgTop(this.pt); }
	this.scrBase.moveTo(this.lft,this.tp);
	
	// create wndo layer inside 
	this.scrWndo = new Layer(this.wd-2*this.bdWd,this.scrBase);
	this.scrWndo.resizeTo(this.wd-2*this.bdWd,this.ht-2*this.bdWd);
	if (this.bgClr) this.scrWndo.bgColor = this.bgClr;
	this.scrWndo.moveTo(this.bdWd,this.bdWd);
	this.scrWndo.visibility = "inherit";
	
	// create the scrolling content layer 
	this.scrCont = new Layer(this.wd-2*this.bdWd,this.scrWndo);
	
	// assemble scroller content html
	var str = '<table width="' + (this.wd-2*this.bdWd) + '" cellpadding="'+this.pad+'" cellspacing="0" border="0">';
	var itemStart = '<tr><td align="center" height="' + (this.ht-2*this.bdWd) + '" valign="middle"><a style="text-decoration:none; font-family:'+this.fontFamily+'; font-size:'+this.fontSize+'; color:'+this.fontColor+'" href="';
	for (var i=0; i<this.items.length; i++) {
  	str += itemStart + this.items[i][0] + '">' + this.items[i][1] + '</a></td></tr>';
  }
	str += '</table>';
	
	// write content to scrolling layer, size, show
	writeLyr(this.scrCont,str);
	this.scrCont.resizeTo(this.wd-2*this.bdWd,this.scrCont.document.height);
	this.scrCont.visibility = "inherit";	
	this.scrBase.visibility = "show";	// show the whole package

	// create scrolling layer object - call scrLyrObj constructor
	this.scrLyr=new scrLyrObj(this.scrCont.name, this.ht,this.bdWd, this.items,this.pause,this.spd,this.inc);
	// start scrolling
	setTimeout(this.scrLyr.obj+".controlScroll()",this.pause);	
}

function buildIEN5() {
	// set up scrBase div
	if (ie4) {
		var str = '<div id="scrBase'+scrlAr.length+'" style="position:absolute;"></div>';
		document.body.insertAdjacentHTML("beforeEnd",str);
		this.scrBase = eval(document.all['scrBase'+scrlAr.length]);
		this.scrBase.css = this.scrBase.style;
	} else {
		this.scrBase = document.createElement("div");
		this.scrBase.id = "scrBase"+scrlAr.length;
		document.body.appendChild(this.scrBase);
		this.scrBase = document.getElementById(this.scrBase.id);
		this.scrBase.css = this.scrBase.style;
		this.scrBase.css.position = "absolute";
	}
	with (this.scrBase.css) {
		zIndex=1;	width = this.wd; height = this.ht;
		clip = "rect(0px "+this.wd+"px "+this.ht+"px "+"0px)";
		backgroundColor = this.bdClr;
	}
	// set left, top
	if (this.pt){ this.lft=getPgLeft(this.pt); this.tp=getPgTop(this.pt); }
	shiftTo(this.scrBase.css,this.lft,this.tp);
	
	// set up scrWndo div 
	if (ie4) {
		var str = '<div id="scrWndo'+scrlAr.length+'" style="position:absolute;"></div>';
		this.scrBase.innerHTML = str;
		this.scrWndo = eval(document.all["scrWndo"+scrlAr.length]);
		this.scrWndo.css = this.scrWndo.style;
	} else {
		this.scrWndo = document.createElement("div");
		this.scrWndo.id = "scrWndo"+scrlAr.length;
		this.scrBase.appendChild(this.scrWndo);
		this.scrWndo = document.getElementById(this.scrWndo.id);
		this.scrWndo.css = this.scrWndo.style;
		this.scrWndo.css.position = "absolute";
	}
	with (this.scrWndo.css) {
		visibility = "inherit"; zIndex=1;
		width = this.wd-2*this.bdWd; height = this.ht-2*this.bdWd;
		clip = "rect(0px "+(this.wd-2*this.bdWd)+"px "+(this.ht-2*this.bdWd)+"px "+"0px)";
		left = this.bdWd+"px"; top = this.bdWd+"px";
		backgroundColor = this.bgClr;
	}
	// set up scrolling content layer
	if (ie4) {
		var str = '<div id="scrCont'+scrlAr.length+'" style="position:absolute;"></div>';
		this.scrWndo.innerHTML = str;
		this.scrCont = eval(document.all["scrCont"+scrlAr.length]);
		this.scrCont.css = this.scrCont.style;
	} else {
		this.scrCont = document.createElement("div");
		this.scrCont.id = "scrCont"+scrlAr.length;
		this.scrWndo.appendChild(this.scrCont);
		this.scrCont = document.getElementById(this.scrCont.id);
		this.scrCont.css = this.scrCont.style;
		this.scrCont.css.position = "absolute";
	}
	with (this.scrCont.css) {
		visibility = "inherit"; zIndex=1;
		width = this.wd-2*this.bdWd;
		left = "0px"; top = "0px";
	}
	// assemble scroller content html 
	var str = '<div style="width:' + (this.wd-2*this.bdWd) + '">';
	var itemStart = '<table align="center" width="' + (this.wd-2*this.bdWd) + '" cellpadding="'+this.pad+'" cellspacing="0" border="0"><tr><td align="center" valign="middle" height="' + (this.ht-2*this.bdWd) + '"><a style="text-decoration:none; font-family:'+this.fontFamily+'; font-size:'+this.fontSize+'; color:'+this.fontColor+'" href="';
	for (var i=0; i<this.items.length; i++) {
  	str += itemStart + this.items[i][0] + '">' + this.items[i][1] + '</a></td></tr></table>';
  }
	str += '</div>';
	this.scrCont.innerHTML = str;
	this.scrBase.visibility = "visible";	// show whole package
	// create scrolling layer object - call scrLyrObj constructor
	this.scrLyr=new scrLyrObj("scrCont"+scrlAr.length, this.ht,this.bdWd,this.items,this.pause,this.spd,this.inc);
	// start scrolling
	setTimeout(this.scrLyr.obj+".controlScroll()",this.pause);	
}

/////////////////////////////////////////////////////////////////////////
//	Constructor for scrolling content layer,	called from createScroller.
//	Scrolling content layer is nested inside ...
//	needs its own methods, etc.
/////////////////////////////////////////////////////////////////////////
function scrLyrObj(obj,ht,bdWd,items,pause,spd,inc) {
	this.ht=ht;	this.bdWd=bdWd; this.items=items; 
	this.pause=pause; this.spd=spd; this.inc=inc;
	this.ctr=1;
	this.css = (ns4)? getLyrRef(obj,document): (ie4)? document.all[obj].style: document.getElementById(obj).style;
	this.shiftBy=shiftBy_m;
	this.controlScroll=controlScroll; this.startOver=startOver;
	this.obj = obj + "Object"; 	eval(this.obj + "=this"); return this
}

function shiftBy_m(x,y) {
	if (ns4) this.css.moveBy(x,y);
	else { 
		this.css.left = parseInt(this.css.left)+x+"px";
		this.css.top = parseInt(this.css.top)+y+"px";
	}
}

function controlScroll() {
	if (this.ctr>this.items.length-1) this.startOver();
	else {
		var y = parseInt(this.css.top);
		if (y> -(this.ht-2*this.bdWd)*this.ctr) { 
			this.shiftBy(0,-this.inc);	
			setTimeout(this.obj+".controlScroll()",this.spd);	
		} else {
				this.ctr++;
				setTimeout(this.obj+".controlScroll()",this.pause);	
		}
	}
}

// restore scroller top to 0 and counter variable to 1
function startOver() {
	this.ctr = 1;
	shiftTo(this.css,0,0);
	this.controlScroll();	// call immediately to avoid sitting on msg
}

// write content
function writeLyr(lyr,txt) {
	if (ns4) {
  	lyr.document.write(txt);
		lyr.document.close();
  } else if (ie4||ie5||ns5) lyr.innerHTML = txt;
}

function shiftTo(obj,x,y) {
	if (ns4) {
  	obj.moveTo(x,y);
  } else if (ie4||ie5||ns5) {
		obj.left = x + "px";
    obj.top =  y + "px";
  }
}

// get reference to nested layer for ns4
// from dhtmllib.js by Mike Hall of www.brainjar.com
function getLyrRef(lyr,doc) {
	if (ns4) {
		var theLyr;
		for (var i=0; i<doc.layers.length; i++) {
	  	theLyr = doc.layers[i];
			if (theLyr.name == lyr) return theLyr;
			else if (theLyr.document.layers.length > 0) 
	    	if ((theLyr = getLyrRef(lyr,theLyr.document)) != null)
					return theLyr;
	  }
		return null;
  }
}

// adapted from dhtmllib.js by Mike Hall
// from www.brainjar.com
// gets left relative to document
// NOTE: Using offset positions to set style position 
// may not work accurately in Mac IE. 
function getPgLeft(lyr) {
	var elem = (ns4)? document.layers[lyr]: (ie4)? document.all[lyr]: (ie5||ns5)? document.getElementById(lyr): null;
	var x = 0;
	if (ns4) return x = elem.pageX;	  	
  else if (ie4 || ie5) {
		while (elem.offsetParent != null) {
      x += elem.offsetLeft;
      elem = elem.offsetParent;
    }
    x += elem.offsetLeft;
		return x;
  } else if (ns5) return x = elem.offsetLeft;
	return x;
}

function getPgTop(lyr) {
	var elem = (ns4)? document.layers[lyr]: (ie4)? document.all[lyr]: (ie5||ns5)? document.getElementById(lyr): null;
	var y = 0;
	if (ns4) return y = elem.pageY;	  	
  else if (ie4 || ie5) {
		while (elem.offsetParent != null) {
      y += elem.offsetTop;
      elem = elem.offsetParent;
    }
    y += elem.offsetTop;
		return y;
	} else if (ns5) return y = elem.offsetTop;
	return y;
}