//<script language="javascript">
/*=============================================================================
 WebSolvers Framework Library
 Copyright 2003, WebSolvers, Inc., All Rights Reserved.

 Library 
 Cross-Browser/Platform common library

 Revision History:
 6-26-03 Created

 Public Functions:
	cint(num)		- Casts a variable to an integer.
	cdbl(num)		- Casts a variable to a floating point.
	cnum(num)		- Casts a variable to etiher an int or float depending
						on the contents.
	writeDHTML(src)	- Writes the source HTML to the browser in a hopefully
						compatable way.
	initDHTML()		- Used to manually initialize code when auto-init does not
						work.

 Public Object:
	dhtml			- Provides basic cross/browser code base for other functions
	
=============================================================================

 The WebSolvers Framework Library may be used and/or modified by anyone owning
 the original work as it was incorporated into an original development project
 so long as this copyright notice and the comments above remain intact.

 By using this code you agree to indemnify WebSolvers, Inc. from any liability
 that might arise from its use.

 This code may not be sold exclusively or as a part of other code without prior
 written consent and is expressly forbidden.

 Obtain permission before redistributing this software over the Internet or
 in any other medium. In all cases the copyright and header must remain intact.
============================================================================= */

function cint(num) {
	var cmp = '-0123456789,';
	var cmp2 = ',';
	if(!num && num != 0)
		return NaN;
		
	if(cmp.diff(num.toString()).length)
		return NaN;
	else
		return parseInt(cmp2.diff(num.toString()), 10);
}

function cdbl(num) {
	var cmp = '-0123456789.,$';
	var cmp2 = '$,';
	var per = num.toString().indexOf('%');

	if(!num && num != 0)
		return NaN;

	if(per > -1) {
		num = num.toString().substr(0, per) + num.toString().substr(per+1);
	}
	
	if(cmp.diff(num.toString()).length)
		return NaN;
	else if(per > -1)
		return parseFloat(cmp2.diff(num.toString()))/100;
	else
		return parseFloat(cmp2.diff(num.toString()));
}

function cnum(num) {
	var cmp = ".$%";

	if(!num && num != 0)
		return NaN;

	if(cmp.diff(num.toString()).length)
		return cdbl(num);
	else
		return cint(num);
}

if (typeof((new String()).trim) == "undefined") {
	String.prototype.trim = function(lr) {
		var start=0; end=this.length;

		if(lr != 0)
			while((this.substring(start, start+1) == ' ') && (start < end))
				start++;
				
		if(!lr)
			while((this.substring(end-1, end) == ' ') && (end > start))
				end--;
		
		return this.substring(start, end);
	}
	
	String.prototype.ltrim = function anonymous() { return this.trim(1); };
	String.prototype.rtrim = function anonymous() { return this.trim(0); };
}

if (typeof((new String()).diff) == "undefined") {
	String.prototype.diff = function (compare, lc) {
		var diff = "";
		var cmp = this, cmp2 = compare;
		if(lc) {
			cmp = this.toLowerCase();
			cmp2 = compare.toLowerCase();
		}
	
		for(var i = 0; i < cmp2.length; i++)
			if(!lc && cmp.indexOf(cmp2.substr(i, 1)) == -1)
				diff += compare.substr(i, 1);
	
		return diff;
	}
}

if (typeof((new String()).toNumber) == "undefined") {
	String.prototype.toNumber = function() {
		return cnum(this);
	}
}

//--- Some version of IE for the mac forgot how to push.
if (typeof((new Array()).push) == "undefined") {
 Array.prototype.push = function() {
    for (var i = 0 ; i < arguments.length ; i++) {
      this[this.length] = arguments[i];
    }
  }
}

//--- Some version of IE for the mac forgot how to pop as well.
if (typeof((new Array()).pop) == "undefined") {
 Array.prototype.pop = function() {
    var res = this[0];
     		
    for(var i = 1 ; i < arguments.length; i++) {
      this[i-1] = this[i];
    }
    this.length--;
     		
    return res;
  }
}

//--- indexOf is so usefull, why did they not include it?.
if (typeof((new Array()).indexOf) == "undefined") {
 Array.prototype.indexOf = function(search,lc) {
    var idx = -1;
      		
    for(idx = 0; idx < this.length; idx++) {
      if(lc && this[idx].toString().toLowerCase() == search.toString().toLowerCase())
        return idx;
      else if(this[idx] == search)
        return idx;
    }
      		
    return -1;
  }
}

//======================================================================================
//                         Netscape 4 compatability functions
//======================================================================================
function dhtml_NN4Resize(e) {
	if(window.innerWidth != window.oInnerWidth || window.innerHeight != window.oInnerHeight)
		window.history.go(0);
		
	if(JS_OnResize)
		JS_OnResize(e);
}

var JS_OnResize = window.onresize;
if(document.layers) {
	window.oInnerWidth = window.innerWidth;
	window.oInnerHeight = window.innerHeight;
	window.onresize = dhtml_NN4Resize;
}	

//======================================================================================
//							Basic DHTML Setup and compatability
//======================================================================================

function writeDHTML(src) {
	document.open();
	if(window.dhtml)
		document.write(dhtml.process(src));
	else
		document.write(src);
	document.close();
}

//This is just a stub for backwards compatability it is no longer used.
function initDHTML() { }

function debugObj(obj, nw, level, padd) {
	var so = '' + obj;
	var h = '', i = "";
	if(!padd)
		padd="";
		
	if(so.substr(0, 7) == '[object') {
		h = padd+so.substr(8, so.length-9) + " {\n";
		if(level > 0) {
			for(i in obj) {
				try {
					h += padd + i + ': ' + debugObj(obj[i], 0, level - 1, padd+"\t") + "\n";
				} catch(e) {
					h += padd + i + ': ' + e + "\n";
				}
			}
		}
		h += padd+"}\n";
	} else {
		h = obj;
	}

	if(nw) {
		var w = window.open();
		if(!w)
			w = window;
		w.document.open();
		w.document.write("<pre>" + h + "</pre>");
		w.document.close();
	} else if(nw != 0)
		alert(h);
	else
		return h;
}

function dhtml() {
  dhtml._resync();
}

dhtml._init = function() {
  var win = window;
  
  if(this.__inited)
    return;

  this.__inited = 1;

  //cannot virully propigate becase of XSS security, so we limit to ourselves.
  while(win.dhtml && win.parent != win && win.document.domain == win.parent.document.domain)
    win = win.parent;

  this._rootWin = win;
  this._rootDoc = win.document;
  if(!this._rootDoc.parentWindow)
    this._rootDoc.parentWindow = this._rootWin;
	this._experimental = false;

  this.sharedPath = "";
	this.compMode = 0;

	if(document.all) {
		this._dhtml = true;
		this._DOM = true;
		this._IE = true;

		if(navigator.platform.indexOf("Mac") > -1)
			this._mac = true;
		else if(navigator.platform.indexOf("nix") > -1)
			this._unix = true;
		else
			this._windows = true;

		if((dhtmlIdx = navigator.appVersion.indexOf("MSIE 5.0;")) > -1) {
			this._major = 5;
			this._minor = 0;
		} else {
			this._major = 6;
			this._minor = 0;
		}

		this._build = dhtml._buildDOM;
	} else if(document.getElementById) {
		this._DOM = true;
		this._W3C = true;

		if(navigator.product == "Gecko") {
			this._mozilla = true;
			this._major = 1
			this._minor = parseInt(navigator.productSub);
		} else {
			this._major = 0;
			this._minor = 0;
		}

		if(navigator.platform.indexOf("Mac") > -1)
			this._mac = true;
		else if(navigator.platform.indexOf("nix") > -1)
			this._unix = true;
		else
			this._windows = true;

		this._build = dhtml._buildDOM;
	} else if(document.layers) {
		this._dhtml = true;
		this._NN4 = true;

		if(navigator.platform.indexOf("Mac") > -1)
			this._mac = true;
		else if(navigator.platform.indexOf("nix") > -1)
			this._unix = true;
		else
			this._windows = true;

		this._major = 4;
		this._minor = 0;

//		this._build = dhtml._build;
	} else if(document.images) {
		this._dhtml = true;
		this._basic = true;
		this._major = 3;
		this._minor = 0;

//		this._build = dhtml._build;
	}
	
	this._dhtmlID = new Array();
	this._basic = new Array();
	this._doc = new Array();
	this._docInit = new Array();
	this._norm = new Array();
	this._quick = null;
	
	this._filterTags = new Array("*");
	this._filterHtmlTags = new Array("DIV", "SPAN", "A", "IMG");

  this._preload = win.onload;
  this._preloadCheck = function(e) { dhtml._onLoad(e); };
  if(win.addEventListener)
    win.addEventListener("load", this._preloadCheck, false);
  else if(win.attachEvent)
    win.attachEvent("onload", this._preloadCheck);
  else {
    win.onload = this._preloadCheck;
    this._checkLoad();
  }

};

dhtml._resync = function() {
  this._init();

  this.rootWin = this._rootWin;
  this.rootDoc = this._rootDoc;
  
  this.dhtml = this._dhtml;
  this.DOM = this._DOM;
  this.W3C = this._W3C;
  this.mozilla = this._mozilla;
  this.IE = this._IE;
  this.NN4 = this._NN4;
  this.unix = this._unix;
  this.windows = this._windows;
  this.mac = this._mac;
  this.major = this._major;
  this.minor = this._minor;

	this.toString = this._toString;

	this.checkVersion = this._checkVersion;

	this.normDoc = this._normDoc;
	this.normalize = this._normalize;
	this.quickNorm = this._quickNorm;

	this.addDHTML = this.addTag = this._addDHTML;
	this.addHTML = this._addHTML;
	this.addBasicInit = this._addBasicInit;
	this.runBasic = this._runBasic;
	this.addDocInit = this._addDocInit;
	this.addNormDoc = this._addNormDoc;
	this.addNorm = this._addNorm;
	this.process = this._Process;
	this.grepTags = this._grepTags;
	this.grepAttributes = this._grepAttributes;
	this.setType = this._setType;

	this.procAlign = this._procAlign;
	
	this.getKeycode = this._getKeycode;
};

dhtml._toString = function() {
  this._resync();

  return this.dhtml;
};

dhtml._getKeycode = function(e) {
  this._resync();

	if(!e && event)
		e = event;

	return (e.which ? e.which : e.keyCode);
}

dhtml._onLoad = function(e) {
  if(this._timer)
    window.clearTimeout(this._timer);

  this._resync();

  if(!this.__init) {  
		this.__init = 1;
		
		if(this.rootWin.dhtmlShared && this.rootWin.dhtmlShared.length)
			this._sharedDir = this.rootWin.dhtmlShared;

		if(this._preload)
			this._preload(e);

    this._procWin(this._rootWin);

		if(this._onload)
			this._onload(e);
	}
};

dhtml._checkLoad = function() {
  // This needs to be set to tell wether or no 
  // the onload event has fired, unfortunatly
  // there is no real way to check.
  var loaded = false;

  if(this._DOM && !this._rootDoc.body) {
    window.setTimeout("dhtml._checkLoad();", 10);
    return;
  }

  if(!loaded && this._preloadCheck != this._rootWin.onload) {
    this._onload = this._rootWin.onload
    this._rootWin.onload = this._preloadCheck;
    this._timer = window.setTimeout("dhtml._onload = null; dhtml._onLoad();", 100);
    return;
  }
}

dhtml._procWin = function(win) {
  var i = 0;
  var vir = false;
  
  this._resync();

  vir = (win.document.domain == this.rootDoc.domain);
  
  if(!vir)
    return;

  if(!win.dhtml)
    win.dhtml = this;

	this._build(win.document);
		
	if(vir && win.frames && win.frames.length) {
	  for(i = 0; i < win.frames.length; i++) {
	    if(win.document.domain == win.frames[i].document.domain)
		    this._procWin(win.frames[i]);
	  }
	}
}


dhtml._checkVersion = function(major, minor) {
  this._resync();

	return (parseInt(this.major, 10) >= parseInt(major, 10)) && (parseInt(this.minor, 10) >= parseInt(minor, 10));
}

dhtml._addDHTML = function(tag, func, bfunc, prefunc, block) {
	var idx = this._dhtmlID.length;

  this._resync();

	this._dhtmlID[idx] = new tagObject(tag, func, bfunc, prefunc, block);
}

function tagObject(tag, func, bfunc, prefunc, block) {
	this.name = tag;
	this.proc = func;
	this.basic = bfunc;
	this.init = prefunc;
	this.block = block;
}

dhtml._addHTML = function(tag) {
  var idx = this._filterHtmlTags.length;
  
  this._filterHtmlTags[idx] = tag;
}

dhtml._addBasicInit = function(object, func) {
	var idx = this.basic.length;
	var param = new Array();
	var i = 0;

  this._resync();

	for(i = 2; i < arguments.length; i++) {
		param[param.length] = arguments[i];
	}
	this.basic[idx] = new basicInitObject(object, func, param);
}

function basicInitObject(object, func, params) {
	this.object = object;
	this.func = func;
	this.params = params;
}

dhtml._process = function(html) {
	var tags = null;
	var rsrc = "";
	var src = "";
	var re = null;
	var re2 = null;
	var m = null;
	var m2 = null;
	var l = 0;
	var osrc = "";
	var nsrc = "";
	var refix = 0;
	tags = new Array();

  this._resync();

//	alert("Processing - " + html);
	if(this.dhtml) {
		var rsrc = "";
		for(var i = 0; i < this.tag.length; i++) {
			tag = this.tag[i];
			if(tag.init && !(this.DOM && tag.proc)) {
				html = dhtml.grepTags(tag.name, html, tag.block, tag.init, false);
			}
		}
	}
//	alert("Processed - " + html);

	return html;
}

dhtml._grepTags = function(tag, html, block, func) {
	var src = '';
	var re = null;
	var re2 = null;
	var re3 = null;
	var m = null;
	var refix = 0;
	var attr = null;
	var args = new Array();
	var html2 = "";
	var m2 = null;
	var start = 0;
	var cut = 0;

  this._resync();

	if(!tag.pop)
		tag = new Array(tag);
	if(!func.pop)
		func = new Array(func);

//alert("Grepping Tags - " + tag);

	if(arguments.length > 4)
		for(re = 5; re < arguments.length; re++)
			args[args.length] = arguments[re];

	src = '<\\s*(' + tag.join('|') + ')\\s*([^>]*)(/)?>'
	re = new RegExp(src, "i");

	m = re.exec(html);
	if(refix || !re.lastIndex && re.lastIndex != 0) {
		re.lastIndex = RegExp.lastIndex;
		refix = 1;
	}
	while(re.lastIndex > -1 && m && m.length) {
		attr = dhtml.grepAttributes(m[2]);
		if(!block || m[3] == "/")
			html = html.substr(0, re.lastIndex - m[0].length) + func[tag.indexOf(m[1], true)](attr, '', args) + html.substr(re.lastIndex);
		else if(block) {
			src = '<\\s*' + m[1] + '\\s*([^>]*)(/)?>'
			re2 = new RegExp(src, "i");
			src = '<\\s*/\\s*' + m[1] + '\\s*>';
			re3 = new RegExp(src, "i");

			start = re.lastIndex;
			cut = 0;
			html2 = html.substr(start);
			re2.exec(html2);
			if(refix)
				re2.lastIndex = RegExp.lastIndex;
			m2 = re3.exec(html2);
			if(refix)
				re3.lastIndex = RegExp.lastIndex;
			while(re2.lastIndex > 0 && re2.lastIndex < re3.lastIndex) {
				cut += re3.lastIndex;
				html2 = html.substr(cut);
				re2.exec(html2);
				if(refix)
					re2.lastIndex = RegExp.lastIndex;
				m2 = re3.exec(html2);
				if(refix)
					re3.lastIndex = RegExp.lastIndex;
			}
			if(m2)
				cut += re3.lastIndex - m2[0].length;
			html2 = html.substr(start, cut);
			if(m2)
				cut += m2[0].length;
			html = html.substr(0, start - m[0].length) + func[tag.indexOf(m[1], true)](attr, html2, args) + html.substr(start + cut);
		}
		m = re.exec(html);
		if(refix)
			re.lastIndex = RegExp.lastIndex;
	}

//alert("Done Grepping Tags - " + tag);

	return html;
}

dhtml._grepAttributes = function(html) {
	var re = /(\w+)\s*=\s*('([^']+)'|"([^"]+)"|([^'"\s]+))/;
	var m = re.exec(html);
	var attr = new Array();
	var refix = 0;

  this._resync();

//alert("Grepping Attributes - " + html);
	
	if(refix || !re.lastIndex && re.lastIndex != 0) {
		re.lastIndex = RegExp.lastIndex;
		refix = 1;
	}
	while(re.lastIndex > -1 && m && m.length) {
		if(m[2].length && m[3].length)
			attr[attr.length] = new Array(m[0], m[1], m[3]);
		else if(m[2].length && m[4].length)
			attr[attr.length] = new Array(m[0], m[1], m[4]);
		else if(m[2].length && m[5].length)
			attr[attr.length] = new Array(m[0], m[1], m[5]);

		html = html.substr(0, re.lastIndex - m[0].length) + html.substr(re.lastIndex);

		m = re.exec(html);
		if(refix)
			re.lastIndex = RegExp.lastIndex;
	}

//alert("Done Grepping Attributes");

	return attr;		
}

dhtml._setType = function(elem, init) {
	var i = 0;
	var cmd = "";

  this._resync();

	elem._dhtmlInit = init;
	if(arguments.length > 2) {
		for(i = 2; i < arguments.length; i++)
			cmd += ", arguments["+i+"]";
		cmd = "elem._dhtmlInit(" + cmd.substr(1) + ");"; 
		eval(cmd);
	} else
		elem._dhtmlInit();
}

dhtml._build = function(doc) {
	var i = 0;
	var layer = null;
	var tag = null;
	var basic = null;

  this._resync();

	this.normDoc(doc);

	if(this.NN4) {
		for(i = 0; i < doc.layers.length; i++) {
			layer = this.quickNorm(doc.layers[i], doc);
			layer._layer = true;
			this.normDoc(layer.document);
			this._build(layer.document);
		}
	}

	this.runBasic(doc);

	for(i = 0; i < this._dhtmlID.length; i++) {
		tag = this._dhtmlID[i];
		if(tag.basic)
			tag.basic(doc);
	}
	
	for(i = 0; i < this._buildInit.length; i++)
	  this._buildInit[i](doc);
}

dhtml._runBasic = function(doc) {
	var document = doc;
	var i = 0;
	var j = 0;
	var cmd = "";
	var elem = null;
	
	for(i = 0; i < this._basic.length; i++) {
		basic = this._basic[i];

		if(basic.object && basic.func) {
			eval("elem = " + basic.object + ";");
			if(elem) {
				cmd = "";
				for(j = 0; j < basic.params.length; j++) {
					if(basic.params[j] && basic.params[j].toString().indexOf('[eval]') == 0)
						eval("basic.params['" + j + "'] = " + basic.params[j].substr(6) + ";");
					cmd += ", basic.params["+j+"]";
				}
				cmd = "dhtml.setType(elem, " + basic.func + cmd + ");";
				eval(cmd);
			}
		}
	}
	
}

dhtml._buildDOM = function(doc) {
	var i = 0, j = 0;
	var tag = null;
	var node = null;
	var elem = null;

  this._resync();

	this.normDoc(doc);

  // If no DHTML elements are defiend don't bother parsign the whole dom
  // This helps save time 
  if(this._dhtmlID.length && doc.getByAttr) {
    // Usually the tags that "should" have DHTML attributes is smaller that the 
    // total tags on a page. Filtering the getByAttr buy only expected tags should
    // help speed up processign time since now the whole dom tree does not need
    // to be scanned.
  	doc._filterTags = this._filterHtmlTags;
	  node = doc.getByAttr("dhtml");
	  for(i = 0; i < node.length; i++) {
	    elem = this.normalize(node[i], doc);
	    tag = null;
	    for(j = 0; j < this._dhtmlID.length && !tag; j++) {
	      if(this._dhtmlID[j].proc && elem.getAttribute("dhtml").toUpperCase().trim().split(',').indexOf(this._dhtmlID[j].name) > -1) {
	        tag = this._dhtmlID[j];
	        
	        elem = tag.proc(elem, doc);
        }
      }
	  }
	}

	doc._filterTags = this._filterTags;

	for(i = 0; i < this._docInit.length; i++)
	  this._docInit[i](doc);

/* I am replacing the old way with a hopefully more reliable apporach
   Instead of custom tags I will use custom attributes and rely on a
   dhtml attribute to define dhtml elements within a page.
   This had the advantage of any element being used as a dhtml element.
   
	  for(i = 0; i < this._dhtmlID.length; i++) {
	  	tag = this._dhtmlID[i];

	  	if(tag.proc) {
	  		node = doc.getElementsByTagName(tag.name);

	  		for(j = 0; j < node.length; j++) {
	  			cont = null;
	  			elem = this.normalize(node[j], doc);
	  			if(tag.block > 0)
	  				cont = this.makeContainer(elem);

	  			if(cont && cont != elem) {
	  				j--;
	  				elem = cont;
	  			}

	  			tag.proc(elem, doc);
	  		}
	  	} else if(tag.basic)
	  		tag.basic(doc);
	  }*/

	this.runBasic(doc);
}

dhtml._addNormDoc = function(func) {
  this._resync();

	if(!func)
		return;
		
	this._doc[this._doc.length] = func;
}

dhtml._normDoc = function(doc) {
	var i;
	
  this._resync();

	if(!doc)
		return null;

	if(doc._dhtmlNorm)
		return doc;

	doc._dhtmlNorm = 1;

	doc.root = this.rootDoc;

	for(i = 0; i < this._doc.length; i++) {
		this._doc[i](doc);
  }
		
	return doc;
}

dhtml._addNorm = function(func) {
  this._resync();

	if(!func)
		return;
		
	this._norm[this._norm.length] = func;
}

dhtml._normalize = function(elem, doc) {
	var i;
	
  this._resync();

	if(!elem)
		return null;

	if(elem.nodeType == 3)
		return elem;

	if(elem._dhtmlNorm)
		return elem;

	elem._dhtmlNorm = 1;

	if(!doc)
		doc = this.rootDoc;

	if(elem._layer)
		elem.nodeType = 1;

	if(!elem.document)
		elem.document = doc;
	else
		this.normDoc(elem.document);
		
	for(i = 0; i < this._norm.length; i++)
		this._norm[i](elem);
	
	return elem;
}

dhtml._quickNorm = function(elem, doc) {
	var i;
	
  this._resync();

	if(!elem)
		return null;

	if(elem._dhtmlNorm || elem._qdhtmlNorm)
		return elem;

	elem._qdhtmlNorm = 1;

	if(!doc)
		doc = this.rootDoc;

	if(elem._layer)
		elem.nodeType = 1;

	if(!elem.document)
		elem.document = doc;
	else
		this.normDoc(elem.document);
		
	if(this._quick)
		this._quick(elem, doc);
	
	return elem;
}

dhtml._addDocInit = function(func) {
  this._resync();

	if(!func)
		return;
		
	this._docInit[this._docInit.length] = func;
}

dhtml._procAlign = function(align) {
	var i = parseInt(align);

  this._resync();

	if(isNaN(i)) {
		i = -1;
		if(align && align.length) {
			switch(align.substring(0, 1).toLowerCase()) {
			case "c":
			case "m":
				i = 0;
				break;
			case "r":
			case "b":
			case "d":
			case "v":
				i = 1;
				break;
			}
		}
	} else if(i < -1)
		i = -1;
	else if (i > 1)
		i = 1;

	return i;
}

//======================================================================================
//                                Initialization code
//======================================================================================
dhtml._resync();

