function goToKcsWeb(dest) {
    window.location = location.protocol + '//' + location.hostname + dest;
}
// Don't allow backing into .jsp
window.history.forward(1);
function focusAndSelectField(field){
	field.select();
	field.focus();
}
var formSubmitted = false;
addEvent(window, "abort", aborted);
function aborted(){
	formSubmitted = false;
}
function submitForm(formName, action){
	//Submit form once and prevent multiple submits
	if (!formSubmitted){
		var form = findObj(formName);
		if (form == null){
			alert(messagesWebCmn[language][15] + formName + messagesWebCmn[language][16]);
			return false;
		}
		formSubmitted = true;
		if (action != null){
			form.action = action;
		}
		form.submit();
		makeDocumentReadOnly();
	}
	return false;
}
function displayHourGlassPointer(){ 
	//Turned off by RJM because it is not cross-browser compatible, unreliable and may be taking a very long time on certain forms
	//if (document.all) 	{
	//	for (var i=0;i < document.all.length; i++) 		{
	//		document.all(i).style.cursor = 'wait'; 
	//	}
	//}
}
function displayDefaultPointer(){ 
	//Turned off by RJM because it is not cross-browser compatible, unreliable and may be taking a very long time on certain forms
	//if (document.all)	{
	//	for (var i=0;i < document.all.length; i++)		{
	//		document.all(i).style.cursor = 'default';
	//	}
	//}
}
function executeWithHourGlass(operation){
	displayHourGlassPointer();
	operation.call();
	displayDefaultPointer();
}
function makeDocumentReadOnly(){
	//Just disable the form elements for efficiency
	var forms = document.getElementsByTagName("form");
    for (var i = 0; i < forms.length; i++) {
    	makeElementReadOnly(forms[i]);
    }
}
function disableAllFormElements(aForm) {
	for (var i = 0; i < aForm.length; i++) {
    	disableWidget(aForm.elements[i]);
	}
}
function makeElementReadOnly(widget) {
	widget.style.background='#D6D3CE';
	widget.readOnly = true;
	if(widget.length != null) {
		for (var i = 0; i < widget.length; i++) {
			makeElementReadOnly(widget[i]);
		}
	}
}
function disableWidget(widget) {
	widget.style.background='#D6D3CE';
	switch(widget.type){
		case "text": case "password": case "textarea":
		widget.readOnly = true;
		break;
		
		case "select-one":
		widget.disabled = true;
		break;

		default:
		if(widget.length != null) {
			for (var i = 0; i < widget.length; i++) {
				widget[i].disabled = true;
			}	
		} else {
			widget.disabled = true;
		}
		break;
	}
}
function enableWidget(widget) {
	widget.style.background='white';
	switch(widget.type) {
		case "text":
		widget.readOnly = false;
		break;

		case "password":
		widget.readOnly = false;
		break;

		case "textarea":
		widget.readOnly = false;
		break;
		
		case "select-one":
		widget.disabled = false;
		break;

		default:
		if(widget.length != null) {
			for (var i = 0; i < widget.length; i++) {
				widget[i].disabled = false;
			}	
		} else {
			widget.disabled = false;
		}
		break;
	}
}

function clearWidget(widget) {
	switch(widget.type) 	{
		case "text":
		widget.value="";
		break;

		case "radio":
		widget.checked = false;
		break;

		case "checkbox":
		widget.checked = false;
		break;

		case "select-one":
		widget.selectedIndex = -1;
		break;

		case "textarea":
		widget.value = "";
		break;

		default:
		alert(messagesWebCmn[language][17] + widget.type + messagesWebCmn[language][18]);
		break;
	}
}

/**
 * Use this if formatting the field after the data has been entered i.e. onBlur or OnChange.
 */
function formatPhoneNumber(field, allowExtension) {
	var strippedMIN = field.value == null ? '' : field.value.replace(/\D/gi, '');
	if (!isValueNumeric(strippedMIN)){
		return false;
	}
	if (allowExtension == null || !allowExtension){
		if (strippedMIN.length != 10) {
			return false;
		} else {
			field.value = "("+strippedMIN.substring(0,3)+")"+strippedMIN.substring(3,6)+"-"+strippedMIN.substring(6,10);
			return true;
		}
	} else {
		if (strippedMIN.length < 10) {
			return false;
		} else {
			field.value = "("+strippedMIN.substring(0,3)+")"+strippedMIN.substring(3,6)+"-"+strippedMIN.substring(6,10)+" x"+strippedMIN.substring(11);
			return true;
		}
	}
}
function lTrim(str){
	if (str == null){
		return '';
	} else if (isStringRoot(str)){
		for (var k=0; k<str.length && str.charAt(k)<=" " ; k++);
		return str.substring(k,str.length);
	} else {
		return str;
	}
}
function rTrim(str){
	if (str == null){
		return '';
	} else if (isStringRoot(str)){
		for (var j=str.length-1; j>=0 && str.charAt(j)<=" " ; j--);
		return str.substring(0,j+1);
	} else {
		return str;
	}
}
function trim(str){
	return rTrim(lTrim(str));
}
String.prototype.lTrim = new Function('return lTrim(String(this));');
String.prototype.rTrim =  new Function('return rTrim(String(this));');
String.prototype.trim = new Function('return trim(String(this));');
function isEmptyString(str) {	
	return str == null ? false : str.trim().length == 0;
}
function isValueInNumericRange(aValue, minValue, maxValue) {
	if (!isValueNumeric(aValue)) {
		return false;
	}
	return aValue >= minValue && (aValue <= maxValue);
}
function isValueInNumericRangeIfNotNull(aValue, minValue, maxValue) {
	if (aValue == null || isEmptyString(aValue)) {
		return true;
	}
	return aValue >= minValue && (aValue <= maxValue);
}
function isValueNumeric(aValue) {
	if (aValue == null || isEmptyString(aValue)) {
		return false;
	} else{
		return !isNaN(aValue);
	}
}
function isValueNumericIfNotNull(aValue) {
	if (aValue == null || isEmptyString(aValue)) {
		return true;
	} else{
		return !isNaN(aValue);
	}
}
function isValueIntIfNotNull(aValue) {
	if (aValue == null || isEmptyString(aValue)) {
		return true;
	} else{
		return isInt(aValue);
	}
}
function isInt(obj) {
	obj = getRootValue(obj);
	if (obj == null || isEmptyString(obj)) {
		return false;
	}
	for (var i=0; i<obj.length; i++){
		var c = obj.charAt(i);
		if (c < '0' || c > '9') {
			return false;
		}
	}
	return true;
}
function isZero(aValue){
	return isInt(aValue) && new Number(aValue) == 0;
}
function checkAll(theForm, cName, check) {
	for (var i = 0, n = theForm.elements.length; i < n; i++) 	{
        if (theForm.elements[i].className.indexOf(cName) != -1) {
            theForm.elements[i].checked = check;
        }
    }
}

function emailCheck (field) 
{
	emailStr = field.value; 
	var checkTLD=1;
	var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/i;
	var emailPat=/^(.+)@(.+)$/;
	var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
	var validChars="\[^\\s" + specialChars + "\]";
	var quotedUser="(\"[^\"]*\")";
	var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
	var atom=validChars + '+';
	var word="(" + atom + "|" + quotedUser + ")";
	var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
	var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
	var matchArray=emailStr.match(emailPat);

	if (matchArray == null) 
	{
		alert(messagesWebCmn[language][19]);
		//focusAndSelectField(field);
		return false;
	}

	var user=matchArray[1];
	var domain=matchArray[2];

	// Start by checking that only basic ASCII characters are in the strings (0-127).

	for (var i=0; i<user.length; i++) 
	{
		if (user.charCodeAt(i)>127) 
		{
			alert(messagesWebCmn[language][20]);
			//focusAndSelectField(field);
			return false;
	   	}
	}

	for (i=0; i<domain.length; i++) 
	{
		if (domain.charCodeAt(i)>127) 
		{
			alert(messagesWebCmn[language][21]);
			//focusAndSelectField(field);
			return false;
	   	}
	}

	// See if "user" is valid 
	
	if (user.match(userPat) == null) 
	{
		alert(messagesWebCmn[language][22]);
		//focusAndSelectField(field);
		return false;
	}

	/* if the e-mail address is at an IP address (as opposed to a symbolic
	host name) make sure the IP address is valid. */

	var IPArray=domain.match(ipDomainPat);
	if (IPArray != null) 
	{
		for (i=1;i<=4;i++) 
		{
			if (IPArray[i]>255) 
			{
				alert(messagesWebCmn[language][23]);
				//focusAndSelectField(field);
				return false;
	   		}
		}
		return true;
	}

	// Domain is symbolic name.  Check if it's valid.
	 
	var atomPat=new RegExp("^" + atom + "$");
	var domArr=domain.split(".");
	var len=domArr.length;
	for (i=0;i<len;i++) 
	{
		if (domArr[i].search(atomPat) == -1) 
		{
			alert(messagesWebCmn[language][24]);
			//focusAndSelectField(field);
			return false;
	   	}
	}

	/* domain name seems valid, but now make sure that it ends in a
	known top-level domain (like com, edu, gov) or a two-letter word,
	representing country (uk, nl), and that there's a hostname preceding 
	the domain or country. */
	
	if (checkTLD && domArr[domArr.length-1].length!=2 && 
	domArr[domArr.length-1].search(knownDomsPat) == -1) 
	{
		alert(messagesWebCmn[language][25]);
		//focusAndSelectField(field);
		return false;
	}

	// Make sure there's a host name preceding the domain.
	
	if (len<2) 
	{
		alert(messagesWebCmn[language][26]);
		//focusAndSelectField(field);
		return false;
	}

	// If we've gotten this far, everything's valid!
	return true;
}

//<!--HPB_SCRIPT_ROV_50
//
//  Licensed Materials - Property of IBM
//  (C) Copyright IBM Corp. 1998, 2001 All Rights Reserved.
//  US Government Users Restricted Rights -
//  Use, duplication or disclosure restricted
//  by GSA ADP Schedule Contract with IBM Corp.
//

function RefreshReport(imgName, imgSrc) {
  var appVer=parseInt(navigator.appVersion);
  var isNC=false,isN6=false,isIE=false;
  if (document.all && appVer >= 4) {
  	isIE=true;
  } else if (document.getElementById && appVer > 4){
  	isN6=true;
  } else if (document.layers && appVer >= 4) {
  	isNC=true;
  }
  if (isNC||isN6||isIE&&document.images) {
      var img = document.images[imgName];
      if (!img) {
      	img = HpbImgFind(document, imgName);
      }
      if (img) {
      	img.src = imgSrc;
      }
  }
}

// HpbImgPreload:
//
function HpbImgPreload() {
  var appVer=parseInt(navigator.appVersion); 
  var isNC=false,isN6=false,isIE=false;
  if (document.all && appVer >= 4) {
  	isIE=true;
  } else if (document.getElementById && appVer > 4) {
  	isN6=true;
  } else if (document.layers && appVer >= 4) {
  	isNC=true;
  }
  if (isNC||isN6||isIE&&document.images)  {
	  var imgName = HpbImgPreload.arguments[0];
	  var cnt;
	  swImg[imgName] = new Array;
	  for (cnt = 1; cnt < HpbImgPreload.arguments.length; cnt++)  {
	    swImg[imgName][HpbImgPreload.arguments[cnt]] = new Image();
	    swImg[imgName][HpbImgPreload.arguments[cnt]].src = HpbImgPreload.arguments[cnt];
	  }
  }
}
// HpbImgFind:
//
function HpbImgFind(doc, imgName) {
  for (var i=0; i < doc.layers.length; i++) {
    var img = doc.layers[i].document.images[imgName];
    if (!img) {
    	img = HpbImgFind(doc.layers[i], imgName);
    }
    if (img) {
    	return img;
    }
  }
  return null;
}
// HpbImgSwap:
//
function HpbImgSwap(imgName, imgSrc)
{
  var appVer=parseInt(navigator.appVersion);
  var isNC=false,isN6=false,isIE=false;
  if (document.all && appVer >= 4) {
  	isIE=true;
  } else if (document.getElementById && appVer > 4) {
  	isN6=true;
  } else if (document.layers && appVer >= 4) {
  	isNC=true;
  }
  if (isNC||isN6||isIE&&document.images)  {
	  var img = document.images[imgName];
	  if (!img) {
	  	img = HpbImgFind(document, imgName);
	  }
      if (img) {
      	img.src = imgSrc;
      }
  }
}
var swImg; swImg=new Array;
//-->
//<!--HPB_SCRIPT_PLD_50
HpbImgPreload('_HPB_ROLLOVER1', 'images/for_customer.gif', 'images/for_customer_on.gif');
HpbImgPreload('_HPB_ROLLOVER2', 'images/for_investor.gif', 'images/for_investor_on.gif');
HpbImgPreload('_HPB_ROLLOVER3', 'images/for_employee.gif', 'images/for_employee_on.gif');
HpbImgPreload('_HPB_ROLLOVER4', 'images/for_media.gif', 'images/for_media_on.gif');
HpbImgPreload('_HPB_ROLLOVER5', 'images/for_safety.gif', 'images/for_safety_on.gif');
HpbImgPreload('_HPB_ROLLOVER6', 'images/online_off.gif', 'images/online_on.gif');
HpbImgPreload('_HPB_ROLLOVER7', 'images/for_industrial.gif', 'images/for_industrial_on.gif');
//-->

//TABLE FUNCTIONS
function getTableBodyRows(table){
	//Answer the rows in the table body. Assuming only one table body
	return table.tBodies[0].rows;
}
function getTableHeadRows(table){
	//Answer the rows in the table head.
	if (table.tHead){
		return table.tHead.rows;
	} else {
		return new Array();
	}
}
function getTableBodyRowCount(table){
	//Answer the number of rows in the table body. Assuming only one table body
	return getTableBodyRows(table).length;
}
function getTableBodyRow(table, rowIntPosition){
	//Answer the row in the specified position of the table body. Assuming only one table body
	return getTableBodyRows(table)[rowIntPosition];
}
function getCell(row, colIntPosition){
	return getCellsOrChildren(row)[colIntPosition];
}
function getCellsOrChildren(row){
	if (row.cells){
		//Firefox includes whitespace in its childNodes, so position is unreliable. cells is the array of HTMLTableCellElements
		return row.cells;
	} else {
		return row.childNodes;
	}
}
function getCellIndex(cell){
	//Answer the cell index of this cell.
	//(Bad name, btw. Should have been called columnIndex)
	//Firefox counts hidden columns. IE does not. So the cellIndex attribute is unreliable
	//Match this up with getCell()
	return indexOf(getCellsOrChildren(getRowForCell(cell)), cell);
}
function getRowIndex(row){
	//Answer the row index of this row. Only works for body
	//See getCellIndex() comments. Has the same issues. Inefficient code
	return indexOf(getTableBodyRows(getTableForRow(row)), row);
}
function getCellCount(row){
	if (row.cells){
		return row.cells.length;
	} else {
		return row.childNodes.length;
	}
}
function getTableBodyCell(table, rowIntPosition, colIntPosition){
	//Answer the cell in the specified position of the table body. Assuming only one table body
	return getCell(getTableBodyRow(table, rowIntPosition), colIntPosition);
}
function getCellData(cellInTable){
	//Answer the data in the table cell
	if (cellInTable.childNodes.length == 0){
		return null;
	} else if (cellInTable.childNodes.length == 1){
		return cellInTable.childNodes[0].data;
	} else {
		var answer = '';
		for (var i = 0; i < cellInTable.childNodes.length; i++){
			answer = answer + cellInTable.childNodes[i].data;
		}
		return answer;
	}
}
function getCellDataInRow(row, colIntPosition){
	return getCellData(getCell(row, colIntPosition));
}
function getTableBodyCellData(table, rowIntPosition, colIntPosition){
	//Answer the data in the table body at the specified row/col position.
	return getCellData(getTableBodyCell(table, rowIntPosition, colIntPosition));
}
function getRowForCell(cell){
	//Not sure I trust the type HTMLTableRowElement in cross-browser mode, so just looking for the TR tag
	var parent = cell.parentNode;
	if (parent == null){
		return null;
	} else if (parent.tagName.toUpperCase() == "TR"){
		return parent;
	} else {
		return getRowForCell(parent);
	}
}
function getTableForRow(row){
	//Not sure I trust the type HTMLTableElement in cross-browser mode, so just looking for the TABLE tag
	var parent = row.parentNode;
	if (parent == null){
		return null;
	} else if (parent.tagName.toUpperCase() == "TABLE"){
		return parent;
	} else {
		return getTableForRow(parent);
	}
}
function getTableForCell(cell){
	var row = getRowForCell(cell);
	return row == null ? null : getTableForRow(row);
}
//END TABLE FUNCTIONS

function showHide(obj, showBoolean) {
	//Show or Hide the obj
    if( obj.style ) { //DOM & proprietary DOM
	    obj.style.display = showBoolean ? (isExplorer() ? 'block' : 'table-row') : 'none';
    } else if( obj.visibility ) { //Netscape
        obj.visibility = showBoolean ? 'show' : 'hide';
    } else {
        //window.alert('Sorry. This browser does not support the necessary capabilities.');
        return false;
    }
    return true;
}
//BROWSER DETECTION
//http://www.quirksmode.org/js/detect.html
var userAgent = navigator.userAgent.toLowerCase();
var OS,browser,version,total,thestring;	
if (checkVersion('konqueror')) {
	browser = "Konqueror";
	OS = "Linux";
} else if (checkVersion('safari')) {
	browser = "Safari";
} else if (checkVersion('omniweb')) {
	browser = "OmniWeb";
} else if (checkVersion('opera')) {
	browser = "Opera";
} else if (checkVersion('webtv')) {
	browser = "WebTV";
} else if (checkVersion('icab')) {
	browser = "iCab";
} else if (checkVersion('msie')) {
	browser = "Internet Explorer";
} else if (!checkVersion('compatible')) {
	browser = "Netscape Navigator";
	version = userAgent.charAt(8);
} else {
	browser = "An unknown browser";
}
if (!version) {
	version = userAgent.charAt(place + thestring.length);
}
if (!OS) {
	if (checkVersion('linux')) {
		OS = "Linux";
	} else if (checkVersion('x11')) {
		OS = "Unix";
	} else if (checkVersion('mac')) {
		OS = "Mac";
	} else if (checkVersion('win')) {
		OS = "Windows";
	} else {
		OS = "an unknown operating system";
	}
}
function checkVersion(string) {
	place = userAgent.indexOf(string) + 1;
	thestring = string;
	return place;
}
function isExplorer(){
	return browser == "Internet Explorer";
}
function isNetscape(){
	return browser == "Netscape Navigator";
}
//  RELIABLE OBJECT GETTER
function hasObj( oName, oFrame, oDoc ) {
	return findObj(oName, oFrame, oDoc) != null;
}
function findObj( oName, oFrame, oDoc ) {
	//   http://www.howtocreate.co.uk/tutorials/index.php?tut=0&part=15
	//	 Reference by name or id
	//   RJM. Cleanup to eliminate duplicate expensive calls
	if(!oDoc){
		if(oFrame){
			oDoc = oFrame.document;
		} else {
			oDoc = window.document;
		}
	}
	var tmp = oDoc[oName];
	if(tmp){
		return tmp;
	}
	if(oDoc.all){
		tmp = oDoc.all[oName];
		if (tmp){
			return tmp;
		}
	}
	if(oDoc.getElementById){
		tmp = oDoc.getElementById(oName);
		if (tmp){
			return tmp;
		}
	}
	for(var i = 0; i < oDoc.forms.length; i++){
		tmp = oDoc.forms[i][oName];
		if(tmp){
			return tmp;
		}
	}
	for(i = 0; i < oDoc.anchors.length; i++){
		tmp = oDoc.anchors[i];
		if(tmp.name == oName){
			return tmp;
		}
	}
	for(i = 0; document.layers && i < oDoc.layers.length; i++){
		tmp = MWJ_findObj(oName, null, oDoc.layers[i].document);
		if(tmp){
			return tmp;
		}
	}
	if (!oFrame){
		tmp = window[oName];
		if (tmp){
			return tmp;
		}
	}
	if (oFrame){
		tmp = oFrame[oName];
		if (tmp){
			return tmp;
		}
	}
	for(i = 0; oFrame && oFrame.frames && i < oFrame.frames.length; i++){
		tmp = oFrame.frames[i];
		tmp = MWJ_findObj(oName, tmp, tmp.document);
		if(tmp){
			return tmp;
		}
	}
	return null;
}
function isShiftKeyPressed(e)  {
	// http://www.javascripter.net/faq/ctrl_alt.htm
	if (e == null){
		return false;
	} else if (e.modifiers) {
	   var mString =(e.modifiers+32).toString(2).substring(3,6);
	   return mString.charAt(0)=="1";
	   //ctrlPressed =(mString.charAt(1)=="1");
	   //altPressed  =(mString.charAt(2)=="1");
	} else if (e.shiftKey){
		return true;
	} else {
		return false;
	}
}
function isRightButtonPressed(e) {
	if (e == null) {
		e = window.event;
	}
	if (e.which) {
		return e.which == 3;
	} else if (e.button) {
		return e.button == 2;
	}
	return false;
}
function getEvent(){
	if (window.event){
		return window.event;
	} else {
		return null;
	}
}
function setSelectValue(selectControl, valueToSelect, selectIndexIfMissing){
	//assuming a single-select widget. Anal property settings to ensure no inconsistency
	selectControl.selectedIndex = selectIndexIfMissing;
	var selIndex = -1;
	var options = selectControl.options;
	for (var i=0;i<options.length;i++){
		if (selIndex == -1 && options[i].value == valueToSelect){
			options[i].selected = true;
			selectControl.selectedIndex = i;
			selIndex = i;
		} else {
			options[i].selected = false;
		}
	}
	return selIndex;
}
function setSelectValues(selectControl, valuesToSelect, selectIndexIfMissing){
	//assuming a multi-select widget.
	selectControl.selectedIndex = selectIndexIfMissing;
	var options = selectControl.options;
	for (var i=0;i<options.length;i++){
		options[i].selected = contains(valuesToSelect, options[i].value);
	}
}
function getSelectValue(selectControl){
	return selectControl.options[selectControl.selectedIndex].value;
}
function arraycopy(array){
	var answer = new Array();
    for (var i=0;i<array.length;i++) {
	    answer[i] = array[i];
    }
    return answer;
}
function indexOf(array, item){
	for (var i=0; i<array.length;i++){
		if (array[i] == item){
			return i;
		}
	}
	return -1;
}
function contains(array, item){
	//Could make this an array prototype
	return indexOf(array, item) != -1;
}
function setOnClick(widget, operation, parameter){
	//firefox allows you to set the attribute directly, e.g., widget.setAttribute("onclick", "operation(parameter);return false")
	//IE does not support this. Both browsers support the following
	//Note: The event is passed along as an argument because it is near impossible to write cross-browser code to get it back (Firefox does not support the window.event)
	//For cross-browser compatibility, get the event from IE (which neglects to pass it along)	
	widget.onclick = function(evt) {
		return operation(evt ? evt : window.event, parameter);
	}
}
function getInnerText(obj) {
	//Answer a string that is the text content of this object
	//WARNING: Strips all "nonvisible" content, such as line breaks
	if (isStringRoot(obj)) {
		return obj.trim();
	} else if (isUndefinedRoot(obj)) {
		return obj;
	} else if (obj.innerText) {
		return obj.innerText;
	} else if (obj.type && obj.type.indexOf("select") != -1) {
		return obj.value;
	} else if (obj.type && obj.type.indexOf("text") != -1) {
		return obj.value; //TODO RJM: May need to check other types as well, as we encounter them
	} else {
		var str = "";	
		var cs = obj.childNodes;
		for (var i = 0; i < cs.length; i++) {
			switch (cs[i].nodeType) {
				case 1: //ELEMENT_NODE
					str += getInnerText(cs[i]);
					break;
				case 3:	//TEXT_NODE
					str += cs[i].nodeValue.trim();
					break;
			}
		}
	}
	return str;
}
function addEvent(obj, e, fcn) {
// addEvent and removeEvent
// cross-browser event handling for IE5+,  NS6 and Mozilla
// By Scott Andrew
  if (obj.addEventListener){
    obj.addEventListener(e, fcn, false);
    return true;
  } else if (obj.attachEvent){
    var r = obj.attachEvent("on"+e, fcn);
    return r;
  } else {
    return false;
  }
} 
function openModalWindow(url, name, height, width, top, left, resizable, scrollable) {
	//Use IE features by default. Are translated to Mozilla features if necessary
	var allowResize = resizable ? "yes" : "no";
	var allowScroll = scrollable ? "yes" : "no";
	if (window.showModalDialog) {
		var features = 'dialogHeight:'+height+'px;dialogWidth:'+width+'px;dialogTop:'+top+'px;dialogLeft:'+left+'px;resizable:'+allowResize+';scroll:'+allowScroll;
		window.showModalDialog(url,name,features);
	} else {
		var features = 'height='+height+',width='+width+',top='+top+',left='+left+',resizable='+allowResize+',scrollbars='+allowScroll+',modal=yes';
		window.open(url,name,features);
	}
	return false;
}
function screenAvailableHeight(){
	if (screen.availheight){
		return screen.availheight;
	} else if (screen.availHeight){
		return screen.availHeight;
	} else {
		return 480;
	}	
}
function screenAvailableWidth(){
	if (screen.availwidth){
		return screen.availwidth;
	} else if (screen.availWidth){
		return screen.availWidth;
	} else {
		return 640;
	}	
}
function removeHidden(anArray){
	//Answer a new array with all hidden objects removed
	var answer = new Array();
	for (var i = 0;i<anArray.length;i++) {
		var item = anArray[i];
		if (item.style.display != 'none'){
			answer.push(item);
		}
	}
	return answer;
}
// --------- StringBuffer code, in an attempt to speedup html write methods. Unfortunately, this proved much slower in Firefox, so currently unused
function StringBuffer(){
	this.buf=[];
};
StringBuffer.prototype.append=function(src){
	this.buf[this.buf.length]=src.toString();
};
StringBuffer.prototype.clear=function(){
	this.buf.length=0;
};
StringBuffer.prototype.getLength=function(){
	var lgth = 0;
	for (var i = 0;i<buf.length;i++) {
		lgth += buf[i].length;
	}
	return lgth;
};
StringBuffer.prototype.toString=function(){
	return this.buf.join('');
};
// ---------  End StringBuffer code ---------------

function getRootValue(obj){
	//Recurse through the value property to return the root value
	//Useful for polymorphism between widgets and primitives
	if (obj == null){
		return null;
	} else if (isUndefinedRoot(obj.value)){
		return obj;
	} else {
		return getRootValue(obj.value);
	}
}
//http://www.crockford.com/javascript/remedial.html -----------------------------
//Renamed to avoid conflict with other methods (e.g., isNull) which first recurse to the root object
function isAlien(a) {
   return isAlienRoot(getRootValue(a));
}
function isAlienRoot(a) {
   return isObjectRoot(a) && typeof a.constructor != 'function';
}
function isArray(a) {
   return isArrayRoot(getRootValue(a));
}
function isArrayRoot(a) {
    return isObjectRoot(a) && a.constructor == Array;
}
function isBoolean(a) {
   return isBooleanRoot(getRootValue(a));
}
function isBooleanRoot(a) {
    return typeof a == 'boolean';
}
function isEmpty(a) {
   return isEmptyRoot(getRootValue(a));
}
function isEmptyRoot(o) {
    if (isObjectRoot(o)) {
        for (var i in o) {
            var v = o[i];
            if (isUndefinedRoot(v) && isFunctionRoot(v)) {
                return false;
            }
        }
    }
    return true;
}
function isFunction(a) {
   return isFunctionRoot(getRootValue(a));
}
function isFunctionRoot(a) {
    return typeof a == 'function';
}
function isNull(obj){//by rjm. ToDo: is isNullRoot() a better check?
	obj = getRootValue(obj);
	return (obj == null || isEmptyString(obj));
}
function isNullRoot(a) {
    return typeof a == 'object' && !a;
}
function isNumber(a) {
   return isNumberRoot(getRootValue(a));
}
function isNumberRoot(a) {
    return typeof a == 'number' && isFinite(a);
}
function isObject(a) {
   return isObjectRoot(getRootValue(a));
}
function isObjectRoot(a) {
    return (a && typeof a == 'object') || isFunction(a);
}
function isString(a) {
   return isStringRoot(getRootValue(a));
}
function isStringRoot(a) {
    return typeof a == 'string';
}
function isUndefined(a) {
   return isUndefinedRoot(getRootValue(a));
}
function isUndefinedRoot(a) {
    return typeof a == 'undefined';
}
//-----------------------------
function isCheckbox(widget) {
    return widget && widget.type && widget.type=='checkbox';
}
function exists(name){
	return findObj(name) != null;
}
