/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
 * Name script, v1.0
 * (c) 2004 timallen.com
 * created by bivia of bivia.com, July 22 2004
 * $Id: global.js,v 1.3 2005/01/31 01:52:04 bcurtis Exp $
 *
 * blah blah blah
 *~~~~*/

/* bv_utilities.js $Id: bv_utilities.js,v 1.5 2005/02/01 01:49:47 bcurtis Exp $ */
/******** standard * utilities ********/


/*
	the ondocload "event" is triggered by a script call before the closing body tag:
		<script type="text/javascript">window.ondocload();</script>
		</body>

	it is the event before onload that indicates the document is done downloading;
	after the func declaration we set two handlers to make sure events assigned to
	docload are triggered onload if the author forgets to put the call in the doc.
*/
	function bv_addListener(el, evt, fn) {
		if (typeof el == "string") el = document.getElementById(el);
		if (!el) return;
		if (window.addEventListener && evt != 'docload') { // DOM
			el.addEventListener(evt, fn, false); // false, because IE can't handle the truth
		} else if (window.attachEvent && evt != 'docload') { // MS, incl Opera
			el.attachEvent('on'+ evt, fn);
		} else { // Mac IE and the ondocload event
			var prevHandler = (typeof el['on'+ evt] == 'function') ? el['on'+ evt] : function () {};
			el['on'+ evt] = function() { prevHandler(); fn(); } 
		}
	}
	bv_addListener(window, 'docload', function () { window.bv_docInited = true; });
	bv_addListener(window, 'load', function () { if (!window.bv_docInited) window.ondocload(); });
/* END bv_addListener */



	function sortRandom(a,b) {
		if (Math.random() > 0.5) return 1;
		else return -1;
	}
	function bv_arrayShuffle(a) {
		var Last = a[a.length -1];
		do a = a.sort(sortRandom);
		while (Last == a[0]);
		return a;
	}



	function bv_trim(s,internal) {
// Mac IE chokes on the ?
//		s = s.replace(/^\s*(.*?)\s*$/, '$1');
		s = s.replace(/^\s+/g, '');
		s = s.replace(/\s+$/g, '');
		if (internal) s = s.replace(/\s+/g, ' ');
		return s;
	}



	function bv_getElementsByClassName(TagsIn,Class) {
		var It = "\\b"+Class+"\\b";
		var rtn = new Array();
		var Tags = TagsIn.split(",");
		for (var xx=0; xx<Tags.length; xx++) {
			var Els = (this.getElementsByTagName) ? this.getElementsByTagName(Tags[xx]) : this.all;
			for (var ii=0; ii<Els.length; ii++) {
				if (Els[ii].className.match(It))
					rtn[rtn.length] = Els[ii];
			}
		}
		return rtn;
	}
	document.getElementsByClassName = bv_getElementsByClassName;



	function bv_addClassName(el, nm) {
		var regex = new RegExp("\\b"+nm+"\\b", "gi");
		if (el.className.match(regex)) {
		} else el.className = bv_trim(el.className +" "+ nm, 1);
	}
	function bv_removeClassName(el, nm) {
		var regex = new RegExp("\\b"+nm+"\\b", "gi");
		el.className = bv_trim(el.className.replace(regex, ''), 1);
	}



	function bv_getOffsetFromParent(El,XY) {
		var Type = (XY == "top") ? "offsetTop" : "offsetLeft";
	// IE will treat the offset as to the parentNode; Moz refers all to the body element
		return (El.offsetParent == El.parentNode) ? 
				El[Type] : 
				El[Type] - El.parentNode[Type];
	}
	function bv_getOffsetFromRoot(El,XY) {
		var Type = (XY == "top") ? "offsetTop" : "offsetLeft";
		var offset = 0;
		while (El) {
			offset += El[Type];
			El = El.offsetParent;
		}
		return offset;
	}


	function bv_attachNewWindows(prefix, allowedTypes, viewerLocation) {
		var pfx = (prefix && prefix.length) ? prefix : "bv_";
		var AllowPop = (/\bpopview\b/.test(allowedTypes) && (viewerLocation && viewerLocation.length));
		var AllowNew = /\bnewwin\b/.test(allowedTypes);
		var As = document.getElementsByTagName('a');
		for (var xx=0; xx<As.length; xx++) {
			if (AllowPop && As[xx].getAttribute('rel') == "popview") {
				As[xx].onclick = function () { window.open(viewerLocation+this.href,pfx+'viewer','resizable,scrollbars=0'); return false; }
			} else if (AllowNew && As[xx].getAttribute('rel') == "newwin") {
				As[xx].onclick = function () { window.open(this.href,pfx+'newwin'); return false; }
			}
		}
	}


	function bv_setOpacity(el, Alpha) {
		if (Alpha < 0)   Alpha = 0;
		if (Alpha >= 100) Alpha = 99.999;
		if (el.filters)
			el.filters.alpha.opacity = Alpha;
		AlphaPct = Alpha /100;
		el.style.KHTMLOpacity = AlphaPct;
		el.style.MozOpacity = AlphaPct;
		el.style.opacity = AlphaPct;
	}

/******** /standard * utilities ********/

function bv_flip(I,Trg) {
	var To = (Trg) ? Trg :
	         (I.src.indexOf('_off') +1) ? 'on' : 'off';
	if (I[To]) I.src = I[To].src;
}


function bv_preload(I) {
	if (!I.loaded && I.src) {
		var Args = (arguments.length > 1) ? arguments : ["null","on","off"];
		I.loaded = false;
		var Srcs = I.src.match(/^(.*\/)([^\/]+)_(on|off|down)\.(\w{3,4})$/);
		for (var xx=1; xx<Args.length; xx++) {
			I[Args[xx]] = new Image();
			I[Args[xx]].src = Srcs[1] + Srcs[2] +"_"+ Args[xx] +"."+ Srcs[4];
		}
		if (bv_RolloverStickyImgs[Srcs[2]]) {
			I[bv_RolloverStickyImgs[Srcs[2]]["from"]] = I[bv_RolloverStickyImgs[Srcs[2]]["to"]];
			bv_flip(I, "off");
		}
		I.loaded = true;
	}
}


var bv_RolloverStickyImgs = {};
function setRolloverStickyOn() {
	for (var idx=0; idx<arguments.length; idx++)
		bv_RolloverStickyImgs[arguments[idx]] = { "from":"off", "to":"on" };
}
function setRolloverStickyOff() {
	for (var idx=0; idx<arguments.length; idx++)
		bv_RolloverStickyImgs[arguments[idx]] = { "from":"on", "to":"off" };
}


/*~~~~~~~~~~~~~~~~~*/


function bv_prepRollover(I,OffSuf,OnSuf,DownSuf) {
	if (typeof(I) != "object") return;
	if (I.loaded) return;
	var Off = (OffSuf) ? OffSuf : "off";
	var On = (OnSuf) ? OnSuf : "on";
	var Down = (DownSuf) ? DownSuf : false;
	
	if (Down) bv_preload(I,Off,On,Down);
	else bv_preload(I,Off,On);

// store existing event handlers so you don't override them
	I.bv_AfterRolloverMouseover = (I.onmouseover) ? I.onmouseover : function() {};
	I.bv_AfterRolloverMouseout  = (I.onmouseout)  ? I.onmouseout  : function() {};
	I.bv_AfterRolloverMousedown = (I.onmousedown) ? I.onmousedown : function() {};
	I.bv_AfterRolloverMouseup   = (I.onmouseup)   ? I.onmouseup   : function() {};
	
	I.onmouseover = function () { if (window.bv_flip) bv_flip(this,On);  this.bv_AfterRolloverMouseover(); };
	I.onmouseout  = function () { if (window.bv_flip) bv_flip(this,Off); this.bv_AfterRolloverMouseout();  };
	if (Down) {
		I.onmousedown = function () { if (window.bv_flip) bv_flip(this,Down); this.bv_AfterRolloverMousedown(); };
		I.onmouseup   = function () { if (window.bv_flip) bv_flip(this,On);   this.bv_AfterRolloverMouseup();   };
	}
	
}


bv_enableRollover = function() {
	var Imgs = document.getElementsByTagName('img');
	for (var xx=0; xx<Imgs.length; xx++) {
		if ( // if it has a className that starts with bvEnable and has ":roll-" in it:
			Imgs[xx].className &&
			Imgs[xx].className.indexOf('bvEnable') == 0 &&
			/:roll-/.test(Imgs[xx].className)
		) { // then enable the rollover for that image
			if (/:roll-all/.test(Imgs[xx].className))
				bv_prepRollover(Imgs[xx],"off","on","down");
			else
				bv_prepRollover(Imgs[xx],"off","on");
		}
	}
}


if (!window.ToLoad) window.ToLoad = new Array();

window.ToLoad[window.ToLoad.length] = bv_enableRollover;
window.onload = function() {
	for (var xx = window.ToLoad.length -1; xx >= 0; xx--) {
		window.ToLoad[xx]();
	}
}




var bv_last_active_menu = null;
var bv_default_menu = null;

function setDropMenuDefault(Id) {
	bv_default_menu = Id;
// this function may be called before the page finishes loading, so stall the result...
	setTimeout('bv_showMenu(document.getElementById("'+Id+'"));',1000);
}



function bv_showMenu(M) { // alert('showing menu '+ M.id);
//document.getElementById('debug').innerHTML+=" | showing "+M.id;
	if (M && M.timer) clearTimeout(M.timer);
	if (bv_last_active_menu && bv_last_active_menu != M.id)
		bv_hideMenuNow(bv_last_active_menu, false);
	bv_last_active_menu = M.id;
	M.style.visibility = "visible";
}

function bv_hideMenu(M) { // alert('hiding menu '+ M.id);
// slight delay to prevent simultaneous off-on triggers
	M.timer = setTimeout('bv_hideMenuNow("'+ M.id +'", true);',25);
}

function bv_hideMenuNow(Id, TimedFlag) { // alert('now hiding menu '+ Id);
	var M = document.getElementById(Id);
	M.style.visibility = "hidden";
	if (M && M.timer) clearTimeout(M.timer);
	bv_last_active_menu = null;
	if (TimedFlag && bv_default_menu) {
		bv_showMenu(document.getElementById(bv_default_menu));
	}
}

function bv_flipMenu(M) {
	if (M.style.visibility == "visible")
		bv_hideMenuNow(M.id, false);
	else bv_showMenu(M);
}




bv_PrepDropMenuTriggers = function(I,Id,clickable) { // alert('prepping drop menu triggers for '+ Id);
	var M = document.getElementById(Id);
	if (M.bv_AfterMenuMouseover) return;
// store existing event handlers so you don't override them
	I.bv_AfterMenuMouseover = (I.onmouseover) ? I.onmouseover : function() {};
	I.bv_AfterMenuMouseout  = (I.onmouseout)  ? I.onmouseout  : function() {};
	I.bv_AfterMenuClick     = (I.onclick)     ? I.onclick     : function() {};
// attach the menu functions to the image events
	I.onmouseover = function () { document.getElementById(Id).show(); I.bv_AfterMenuMouseover(); };
	I.onmouseout  = function () { document.getElementById(Id).hide(); I.bv_AfterMenuMouseout();  };
	if (clickable)
	   I.onclick  = function () { document.getElementById(Id).flip(); I.bv_AfterMenuClick();     };
}

bv_PrepDropMenu = function(Id,clickable) { // alert('prepping drop menu '+ Id);
	var M = document.getElementById(Id);
	if (M.bv_AfterMenuMouseover) return;
	M.timer = false;
	M.show = function () { if (window.bv_showMenu) bv_showMenu(M); }
	M.hide = function () { if (window.bv_hideMenu) bv_hideMenu(M); }
	M.flip = function () { if (window.bv_flipMenu) bv_flipMenu(M); }
// store existing event handlers so you don't override them
	M.bv_AfterMenuMouseover = (M.onmouseover) ? M.onmouseover : function() {};
	M.bv_AfterMenuMouseout  = (M.onmouseout)  ? M.onmouseout  : function() {};
	M.bv_AfterMenuClick     = (M.onclick)     ? M.onclick     : function() {};
// attach the menu functions to the div events
	M.onmouseover = function () { M.show(); M.bv_AfterMenuMouseover(); };
	M.onmouseout  = function () { M.hide(); M.bv_AfterMenuMouseout();  };
	if (clickable)
	   M.onclick  = function () { M.flip(); M.bv_AfterMenuClick();     };
}




bv_enableDropMenu = function() { // alert('enabling drop menus');
	var Imgs = document.getElementsByTagName('img');
	for (var xx=0; xx<Imgs.length; xx++) {
		if ( // if it has a className that starts with bvEnable and has ":menu-" in it:
			Imgs[xx].className &&
			Imgs[xx].className.indexOf('bvEnable') == 0 &&
			/:menu-\w+/.test(Imgs[xx].className)
		) { // then enable the menu triggered by that image
			var parts = /:menu-(\w+)-?(\w+)?/.exec(Imgs[xx].className);
			var clickIt = (parts[2] == "click") ? true : false;
			bv_PrepDropMenuTriggers(Imgs[xx], parts[1], clickIt);
			bv_PrepDropMenu(parts[1], clickIt);
		}
	}
}


if (!window.ToLoad) window.ToLoad = new Array();

window.ToLoad[window.ToLoad.length] = bv_enableDropMenu;
window.onload = function() {
	for (var xx = window.ToLoad.length -1; xx >= 0; xx--) {
		window.ToLoad[xx]();
	}
}


/*~~~~CSS~Select~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
 * CSS Select:
 * $Id: bv_cssSelect.js,v 1.3 2005/02/01 02:09:42 bcurtis Exp $
 * version 1.0
 * (c) bivia, bivia.com 2005
 *
 * This script is current hardwired for only one list per page.
 * Don't know why, but Ineternet Explorer wouldn't respond to "this"
 * in an anonymous function declaration.
 *~~~~*/


function debug(Msg,Clr) {
	var D = document.getElementById('debug');
	var Pre = (Clr) ? "" : D.innerHTML;
	D.innerHTML = Pre +"<br />"+ Msg;
}


function bv_clip(Side, To) {
	if (Side == "Top") {
		this.clipBox.top = To;
		this.clipper.style.top = (this.clipper.baseTop + To) +"px";
		this.style.marginTop = (-1 * To) +"px";
	} else if (Side == "Bottom") {
		this.clipBox.bottom = To;
		this.clipper.style.height = (parseInt(this.style.marginTop) + To) +"px";
	}
}



function bv_openDHTMLSelect(ID) { var ID = 0; //temp. solution
	var L = bv_DHTMLSelectLists[ID];
//for (var Prop in L) debug(Prop +" : "+ L[Prop]);
//debug(L.selected.innerHTML +":::> opening class:'"+ L.selected.className +"'");
	bv_removeClassName(L.selected, "cssSelectListSelected");
	if (L.timer) clearTimeout(L.timer);
	var TopClip = L.clipBox.top;
	var BotClip = L.clipBox.bottom;
	if (TopClip >= 0) {
		TopClip = Math.floor(TopClip *0.8) -1;
		L.timer = setTimeout('bv_openDHTMLSelect('+ID+')', 15);
	}
	if (BotClip <= L.offsetHeight) {
		BotClip += Math.ceil((L.offsetHeight - BotClip) *0.2) +2;
		if (L.timer) clearTimeout(L.timer);
		L.timer = setTimeout('bv_openDHTMLSelect('+ID+')', 15);
	}
	if (L.timer) {
		L.clip("Top",TopClip);
		L.clip("Bottom",BotClip);
	}
}


function bv_closeDHTMLSelect(ID) { var ID = 0; //temp. solution
	var L = bv_DHTMLSelectLists[ID];
	if (L.timer) clearTimeout(L.timer);
	var TopClip = L.clipBox.top;
	var BotClip = L.clipBox.bottom;
	if (TopClip < L.selectedOffsetTop) {
		TopClip += Math.ceil((L.selectedOffsetTop - TopClip) *0.2);
		L.timer = setTimeout('bv_closeDHTMLSelect('+ID+')', 15);
	}
	if (BotClip >= L.selectedOffsetBottom +1) {
		BotClip -= Math.ceil((BotClip - L.selectedOffsetBottom) *0.2);
		if (L.timer) clearTimeout(L.timer);
		L.timer = setTimeout('bv_closeDHTMLSelect('+ID+')', 15);
	}
	if (L.timer) {
		L.clip("Top",TopClip);
		L.clip("Bottom",BotClip);
	}
//debug(L.selected.innerHTML +":::> closing class:'"+ L.selected.className +"'");
	if (TopClip == L.selectedOffsetTop) bv_addClassName(L.selected, "cssSelectListSelected");
}


var bv_DHTMLSelectLists = new Array();

function bv_initDHTMLSelect() {
	var Lists = document.getElementsByClassName('ul,ol','cssSelectList');
	for (var xx=0; xx<Lists.length; xx++) {
		Lists[xx].listID = xx;
		Lists[xx].timer = null;
		Lists[xx].getElementsByClassName = bv_getElementsByClassName;
		var Sel = Lists[xx].getElementsByClassName('li','cssSelectListSelected');
		if (Sel.length) {
			Lists[xx].selected = Sel[Sel.length -1];
		} else {
			Sel = Lists[xx].getElementsByTagName('li');
			Lists[xx].selected = Sel[0];
			bv_addClassName(Lists[xx].selected, "cssSelectListSelected");
		}
		Lists[xx].selectedOffsetTop = Lists[xx].selected.offsetTop;
		Lists[xx].selectedOffsetBottom = Lists[xx].selectedOffsetTop + Lists[xx].selected.offsetHeight;
		Lists[xx].clipBox = {
				top : 0,
				right : Lists[xx].offsetWidth,
				bottom : Lists[xx].offsetHeight,
				left : 0
			}
		Lists[xx].clipper = Lists[xx].offsetParent;
		Lists[xx].clipper.baseTop = Lists[xx].clipper.offsetTop - Lists[xx].selectedOffsetTop;
		Lists[xx].clipper.style.top = (Lists[xx].clipper.baseTop) +"px";
		Lists[xx].clip = bv_clip;
		Lists[xx].clip("Top", Lists[xx].selectedOffsetTop);
		Lists[xx].clip("Bottom", Lists[xx].selectedOffsetBottom);
		bv_addListener(Lists[xx], "mouseover", function () { bv_openDHTMLSelect(0); });
		bv_addListener(Lists[xx], "mouseout", function () { bv_DHTMLSelectLists[0].timer = setTimeout('bv_closeDHTMLSelect(0)',50); });
		bv_DHTMLSelectLists[xx] = Lists[xx];
	}
}
bv_addListener(window, "load", bv_initDHTMLSelect);

//~~/CSS~Select



/* sets ability to open links in new windows via rel="" */
bv_addListener(window, 'docload', 
		function () { bv_attachNewWindows('ta', 'popview,newwin', '/_popviewer.php?i='); }
	);
