function popupWindow(url,width,height,windowName){
	if (!width) width=540;
  if (!height) height=400;
	if (!windowName) windowName='PopupWin';
	var popup = window.open(url,windowName,'height='+height+',width='+width+',scrollbars=1,resizable=1,status=0,toolbar=0,location=1,menubar=0');
	popup.moveTo(0,0);
	popup.focus();
}

document.getElementsByClassName = function(strClass, strTag, objContElm) {
  strTag = strTag || "*";
  objContElm = objContElm || document;    
  var objColl = (strTag == '*' && document.all) ? document.all : objContElm.getElementsByTagName(strTag);
  var arr = new Array();                              
  var delim = strClass.indexOf('|') != -1  ? '|' : ' ';   
  var arrClass = strClass.split(delim);    
  for (i = 0, j = objColl.length; i < j; i++) {                         
    var arrObjClass = objColl[i].className.split(' ');   
    if (delim == ' ' && arrClass.length > arrObjClass.length) continue;
    var c = 0;
    comparisonLoop:
    for (k = 0, l = arrObjClass.length; k < l; k++) {
      for (m = 0, n = arrClass.length; m < n; m++) {
        if (arrClass[m] == arrObjClass[k]) c++;
        if (( delim == '|' && c == 1) || (delim == ' ' && c == arrClass.length)) {
          arr.push(objColl[i]); 
          break comparisonLoop;
        }
      }
    }
  }
  return arr; 
}

// fix a deficiency in the woefully inadequate IE

Array.prototype.indexOf = function(val) {
	for(var i=0, len=this.length; i<len; i++){
		if(this[i] == val) return i;
	}
	return -1;
}

// class Dynamic
// a little collection of commonly used functions
// for making dynamic pages.  The constructor can take
// either 1 or 3 arguments - only the id if the element already
// exists in the page, or id, tag name, and the parent to append
// it to if it does not exist.

function Dynamic(el,tag,parent,popup,autoClose) {
  if(arguments.length == 1) {
    if(typeof el == "string" && el != "") {
      this.el = document.getElementById(el);
      this.id = el;
    } else {
      this.el = el;
    }
  } else if(arguments.length >= 3) {
    this.el = document.createElement(tag);
    parent.appendChild(this.el);
    this.el.setAttribute("id",el);
    if(popup) {
      this.hide();
      this.el.style.position = "absolute";
      this.el.style.zIndex = "100";
    }
  } else {
    throw new Error("Dynamic - incorrect number of arguments");
  }
//  this.figureDimensions();
  this.descendants = new Array();
}

Dynamic.prototype.figureDimensions = function() {
	this.top = this.findY();
	this.bottom = this.top + this.el.offsetHeight;
	this.left = this.findX();
	this.right = this.left + this.el.offsetWidth;
}

// method setPos
// sets the position of the element using the top
// and left coordinates.  elTop and elLeft must be
// a number followed by "px".

Dynamic.prototype.setPos = function(elTop,elLeft) {
	this.el.style.top = elTop;
	this.el.style.left = elLeft;
}

Dynamic.prototype.getAllDescendants = function(n) {
  this.fillDesc(n);
  return this.descendants;
}

Dynamic.prototype.fillDesc = function(n) {
	if(n) {
		var node = n;
	} else {
		var node = this.el;
		this.descendants = new Array();
	}
	for(var c=node.firstChild; c != null; c = c.nextSibling) {
		if(c.nodeType == 1 && this.descendants.indexOf(c) == -1) {
			this.descendants.push(c);
		}
		if (c.firstChild != null) {
			this.getAllDescendants(c);
		}
	}
}

// method empty
// empties the element

Dynamic.prototype.empty = function() {
	while(this.el.firstChild) {
		//start with the first child of the element to be emptied
		var object = this.el.firstChild;
		while(object != this.el) {
			//the object has a child or a sibling
			while(object.firstChild || object.nextSibling) {
				//if a child, move there
				if(object.firstChild) {
					object = object.firstChild;
				//otherwise, if the next sibling has a child, move there
				} else if(object.nextSibling.firstChild) {
					object = object.nextSibling.firstChild;
				//if all else fails, just move to the next sibling.
				} else {
					object = object.nextSibling;
				}
			}
			//we have now gone to the last sibling at the lowest level of this branch,
			//so remove all siblings
			while(object.previousSibling) {
				object.parentNode.removeChild(object.previousSibling);
			}
			//then move to the parent and remove the node in question
			object = object.parentNode;
			object.removeChild(object.firstChild);
		}
	}
}

// method hide
// makes visibility = "hidden"

Dynamic.prototype.hide = function() {
	this.el.style.visibility = "hidden";
}

// method show
// makes visibility = "visible"

Dynamic.prototype.show = function() {
	this.el.style.visibility = "visible";
}

Dynamic.prototype.toggleVis = function() {
	if(this.el.style.visibility == "hidden") {
		this.show();
	} else {
		this.hide();
	}
}

// method collapse
// makes display = "none"

Dynamic.prototype.collapse = function() {
	this.el.style.display = "none";
}

// method showBlock
// makes display = "block"

Dynamic.prototype.showBlock = function() {
	this.el.style.display = "block";
}

// method showInline
// makes display = "inline";

Dynamic.prototype.showInline = function() {
  this.el.style.display = "inline";
}

Dynamic.prototype.toggleBlock = function() {
  if(this.el.style.display == "none") {
    this.showBlock();
  } else {
    this.collapse();
  }
}

Dynamic.prototype.toggleInline = function() {
  if(this.el.style.display == "none") {
    this.showInline();
  } else {
    this.collapse();
  }
}

// method listen
// cross browser method of adding an event
// listener.  name is the name of the event in Mozilla
// style, ie. "load" and not "onload". Observer is the
// function that fires when the event happens

Dynamic.prototype.listen = function(name,observer) {
  if (this.el.addEventListener) {
    this.el.addEventListener(name, observer, false);
  } else if (this.el.attachEvent) {
    this.el.attachEvent('on' + name, observer);
  }
}

Dynamic.prototype.ignore = function(name,observer) {
  if(this.el.removeEventListener) {
    this.el.removeEventListener(name, observer, false);
  } else if (this.el.detachEvent) {
    this.el.detachEvent('on' + name, observer);
  }
}

Dynamic.prototype.getRealChildren = function() {
	var realChildren = new Array();
	for(var w=0, len=this.el.childNodes.length; w<len; w++) {
		if(this.el.childNodes[w].nodeType == 1) {
			realChildren.push(this.el.childNodes[w]);
		}
	}
	return realChildren;
}

// method appendChildren
// supposed to append multiple children, but it doesn't work

Dynamic.prototype.appendChildren = function() {
	for(var u=0, len=arguments.length; u<len; u++) {
		if(typeof arguments[u] == "string") {
			this.el.appendChild(document.createTextNode(arguments[u]));
		} else {
			this.el.appendChild(arguments[u]);
		}
	}
}

// method addClass
// adds a className to the element w/o erasing
// already added classNames

Dynamic.prototype.addClass = function(name) {
  var prevClass = this.el.className;
  if(prevClass == "") {
    var classArray = new Array();
  } else {
    var classArray = prevClass.split(" ");
  }
  classArray.push(name);
  var newClass = classArray.join(" ");
  this.el.className = newClass;
}

// method removeClass
// removes a specific className

Dynamic.prototype.removeClass = function(name) {
  var prevClass = this.el.className;
  if(prevClass.indexOf(name) != -1) {
    var classArray = prevClass.split(" ");
    var nameIndex = classArray.indexOf(name);
    classArray.splice(nameIndex,1);
    var newClass = classArray.join(" ");
    this.el.className = newClass;
  }
}

// method findX
// finds the "left" style attribute of the element,
// relative to the page

Dynamic.prototype.findX = function() {
	var obj = this.el;
	var curleft = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curleft += obj.offsetLeft;
			if(!obj.offsetParent)
       	break;
			obj = obj.offsetParent;
		}
	}
	else if (obj.x) {
		curleft += obj.x;
	}
	return curleft;
}

// method findY
// finds the "top style attribute of the element,
// relative to the page

Dynamic.prototype.findY = function() {
	var obj = this.el;
	var curtop = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curtop += obj.offsetTop;
			if(!obj.offsetParent)
       	break;
			obj = obj.offsetParent;
		}
	}
	else if (obj.y) {
		curtop += obj.y;
	}
	return curtop;
}

Dynamic.prototype.toggleSelects = function(done) {
	if (navigator.appName == 'Microsoft Internet Explorer') {
		this.top = this.findY();
		this.bottom = this.top + this.el.offsetHeight;
		this.left = this.findX();
		this.right = this.left + this.el.offsetWidth;
		for(var u=0, len=document.forms.length; u<len; u++) {
			var els = document.forms[u].elements;
			for(var w=0, len2=document.forms[u].elements.length; w<len2; w++) {
				if(els[w].type && els[w].type.substr(0,6) == "select") {
					var currSelect = new Dynamic(els[w]);
					var selLeft = currSelect.findX();
					var selRight = selLeft + currSelect.el.offsetWidth;
					var selTop = currSelect.findY();
					var selBottom = selTop + currSelect.el.offsetHeight;
					if(selLeft < this.right && selRight > this.left && selTop < this.bottom && selBottom > this.top) {
						done ? currSelect.show() : currSelect.hide();
					} else {
						currSelect.show();
					}
				}
			}
		}
	}
}