jt_DialogBox = function(isModal) {
  if (arguments.length==0) return;
  this.isModal = isModal;
  if (isModal) jt_DialogBox.veilInit();

  this.container = document.createElement('div');
  this.container.className = jt_DialogBox.className;
  this.container.dialogBox = this;

  var mainTable = document.createElement('table');
  mainTable.setAttribute('cellSpacing', '0');
  mainTable.setAttribute('cellPadding', '0');
  mainTable.setAttribute('border', '0');

  var tBodyM = document.createElement('tbody');
  var rowM = document.createElement('tr');
  var cellM = document.createElement('td');

  //*********** BEGIN Title TABLE ***********
  var titleTable = document.createElement('table');
  titleTable.setAttribute('cellSpacing', '0');
  titleTable.setAttribute('cellPadding', '0');
  titleTable.setAttribute('border', '0');
  titleTable.setAttribute('width', '100%');

  var tBodyT = document.createElement('tbody');
  var rowT = document.createElement('tr');
  var cellT = document.createElement('td');
  cellT.className = "tbLeft";
  rowT.appendChild(cellT);

  this.titleCell = document.createElement('td');
  this.titleCell.className = "Title";
  rowT.appendChild(this.titleCell);

  cellT = document.createElement('td');
  cellT.className = "tbRight";

  jt_DialogBox.initCloseIcon();
  var closeIcon = document.createElement('img');
  closeIcon.src = jt_DialogBox.closeIcon.src;
  closeIcon.setAttribute('border','0');
  closeIcon.dialogBox = this;

  var aLink = document.createElement('A');
  aLink.setAttribute('href','#');
  aLink.appendChild(closeIcon);
  aLink.onclick = jt_DialogBox.closeBox;

  cellT.appendChild(aLink);
  rowT.appendChild(cellT);

  tBodyT.appendChild(rowT);
  titleTable.appendChild(tBodyT);
  //*********** END Title TABLE ***********

  cellM.appendChild(titleTable);
  rowM.appendChild(cellM);
  tBodyM.appendChild(rowM);

  rowM = document.createElement('tr');
  cellM = document.createElement('td');
  cellM.className = "MainPanel";

  this.contentArea = document.createElement('div');
  this.contentArea.className = "ContentArea";
  cellM.appendChild(this.contentArea);

  rowM.appendChild(cellM);
  tBodyM.appendChild(rowM);
  mainTable.appendChild(tBodyM);
  this.container.appendChild(mainTable);
  document.body.appendChild(this.container);

  Drag.init(this.titleCell, this.container, 0, null, 0);
  }


/************ BEGIN: Public Methods ************/
jt_DialogBox.imagePath = ""; // set by application; directory path to 'window_close.gif' in titleBar

jt_DialogBox.prototype.show = function() {
  this.container.style.display = "block";
  this.topZ();
  jt_divOnScrn(this.container);
  if (this.isModal) jt_DialogBox.veilShow(true);
  }

jt_DialogBox.prototype.hide = function(ok) {
  this.container.style.display = "none";
  if (this.isModal) jt_DialogBox.veilShow(false);
  var posInList = this.listPos();
  if (posInList != -1) {
    jt_DialogBox.openList[posInList] = jt_DialogBox.openList[jt_DialogBox.openList.length-1];
    jt_DialogBox.openList.pop();
    } 
  
  if (ok) {
    if (this.callOK) {
      if (this.returnData) this.callOK(this.returnData);
      else {this.callOK();}
    }    
  }
  else if (this.callCancel) this.callCancel();
  }

jt_DialogBox.prototype.moveTo = function(x, y) {
  this.container.style.left = x + "px";
  this.container.style.top = y + "px";
  }

jt_DialogBox.prototype.setTitle = function(title) {
  this.titleCell.innerHTML = title;
  }

jt_DialogBox.prototype.setContent = function(htmlContent) {
  this.contentArea.innerHTML = htmlContent;
  }

jt_DialogBox.prototype.setWidth = function(width) {
  this.contentArea.style.width = width + "px";
  }

jt_DialogBox.prototype.setCallOK = function(callOK) {
  // set by application as needed
  this.callOK = callOK;
  }

jt_DialogBox.prototype.setCallCancel = function(callCancel) {
  // set by application as needed
  this.callCancel = callCancel;
  }

jt_DialogBox.prototype.getContentNode = function() {
  // expose 'contentArea' DOM node for direct manipulation
  return this.contentArea;
  }

jt_DialogBox.prototype.setComponentId = function(componentId) {
  	this.componentId = componentId;
  }  
  
jt_DialogBox.prototype.getComponentId = function() {
  	return this.componentId;
  } 
  
/************ NOTE: 'initCloseIcon()', 'veilInit()' and 'veilShow()' are used internally by modal dialog boxes ************/
jt_DialogBox.initCloseIcon = function() {
  // pre-fetch this icon so it doesn't distort dialog box size
  if (jt_DialogBox.closeIcon == null) {
    jt_DialogBox.closeIcon = new Image();
    jt_DialogBox.closeIcon.src = jt_DialogBox.imagePath + "/easyfaces/resources/dialog/icons/window_close.gif";
    }
  }

jt_DialogBox.veilInit = function() {
  if (jt_DialogBox.veilOverlay == null) { // once per page
    jt_DialogBox.veilOverlay = document.createElement('div');
    jt_DialogBox.veilOverlay.className = "jtDialogBoxVeil"; // CSS className
    jt_DialogBox.veilOverlay.style.zIndex = jt_DialogBox.veilZ;
    jt_DialogBox.veilOverlay.innerHTML = "&nbsp;";
    document.body.appendChild(jt_DialogBox.veilOverlay);
    jt_DialogBox.addListener(window, "resize", jt_DialogBox.veilSetWidth);
    }
  }

jt_DialogBox.veilInit = function(element) {
	if (jt_DialogBox.veilOverlay == null) { // once per page
		jt_DialogBox.divModal = element;
	    jt_DialogBox.veilOverlay = document.createElement('div');
	    jt_DialogBox.veilOverlay.className = "jtDialogBoxVeil"; // CSS className
	    jt_DialogBox.veilOverlay.style.zIndex = jt_DialogBox.veilZ;
	    jt_DialogBox.veilOverlay.innerHTML = "&nbsp;";
	    document.body.appendChild(jt_DialogBox.veilOverlay);
	    jt_DialogBox.addListener(window, "resize", jt_DialogBox.veilSetWidth);
    }
  }


jt_DialogBox.veilControl = "none";

jt_DialogBox.veilShowClassName = function(showIt, divModal) {
	if (jt_DialogBox.veilControl == "none") {
		jt_DialogBox.veilOverlay.className = (showIt ? "jtDialogBoxVeilNone" : "jtDialogBoxVeil");
		if (showIt) {
			jt_DialogBox.veilSetWidth();
			jt_DialogBox.verifyIE(showIt, divModal, true);
		} else {
			jt_DialogBox.verifyIE(showIt, divModal, true);
		}
	}	
 }

jt_DialogBox.veilShow = function(showIt) {
    jt_DialogBox.veilSetWidth();
    jt_DialogBox.veilControl = jt_DialogBox.veilOverlay.style.display = showIt ? "block" : "none";
 }
 
jt_DialogBox.veilShow = function(showIt, divModal) {
	jt_DialogBox.veilControl = showIt ? "block" : "none";
    jt_DialogBox.veilSetWidth();
  	jt_DialogBox.verifyIE(showIt, divModal, false);
 }
 
jt_DialogBox.verifyIE = function(showIt, divModal, hileOnlyUpperModal) {
 	jt_DialogBox.veilOverlay.style.display = showIt ? "block" : "none";
 	
    // On IE, controls such as SELECT, OBJECT
	// are window based controls.  So, if the sub menu and these
	// controls overlap, sub menu would be hidden behind them.  Thus
	// one needs to turn the visibility of these controls off when the
	// sub menu is showing, and turn their visibility back on
	// when the sub menu is hiding.
	//
	if (document.all)	// it is IE
	{
		if (showIt) {
			if (!jt_DialogBox.cmOverlap)
				jt_DialogBox.cmOverlap = new Array ();
			
			jt_DialogBox.cmHideControl ("SELECT", jt_DialogBox, divModal, hileOnlyUpperModal);
			jt_DialogBox.cmHideControl ("OBJECT", jt_DialogBox, divModal, hileOnlyUpperModal);
		} else {
			if (!jt_DialogBox.cmOverlap)
				jt_DialogBox.cmOverlap = new Array ();

			jt_DialogBox.cmShowControl(jt_DialogBox);
		}
	}
 }
 
/************ END: Public Methods ************/


/************ BEGIN: Private Methods ************/
jt_DialogBox.className = "jtDialogBox"; // CSS className
jt_DialogBox.closeIcon = null;
jt_DialogBox.veilOverlay = null;
jt_DialogBox.veilZ = 10000;
jt_DialogBox.openList = new Array();
jt_DialogBox.maxDepth = 5; // optimize search of parent nodes
jt_DialogBox.cmOverlap = null;

jt_DialogBox.closeBox = function(e) {
  if (!e) e = window.event;
  var node = e.target ? e.target : e.srcElement;
  var count = 0;
  while ((node != null) && (count < jt_DialogBox.maxDepth)) {
    if (node.dialogBox) {
      node.dialogBox.hide();
      return false;
      }
    node = node.parentNode;
    count++;
    }
  return false;
  }

jt_DialogBox.prototype.listPos = function() {
  var posInList = -1;
  for (var i=0; i<jt_DialogBox.openList.length; i++)
    if (jt_DialogBox.openList[i] == this) {
      posInList = i;
      break;
      }
  return posInList;
  }

jt_DialogBox.prototype.topZ = function() {
  var posInList = this.listPos();
  if (posInList == -1) jt_DialogBox.openList[jt_DialogBox.openList.length] = this; // add to list
  else if (posInList < jt_DialogBox.openList.length-1) {
    for (var i=posInList; i<jt_DialogBox.openList.length-1; i++) jt_DialogBox.openList[i] = jt_DialogBox.openList[i+1];
    jt_DialogBox.openList[jt_DialogBox.openList.length-1] = this; // move to end
    var newZ = jt_DialogBox.veilZ;
    for (var i=jt_DialogBox.openList.length-1; i>0; i--) {
      newZ--;
      jt_DialogBox.openList[i].style.zIndex = newZ;
      }
    }

  this.container.style.zIndex = jt_DialogBox.veilZ+1;
  }

jt_DialogBox.veilSetWidth = function() {
  	jt_DialogBox.veilOverlay.style.width = document.body.clientWidth;
  	if (document.body.clientHeight > document.body.scrollHeight) {
	  	jt_DialogBox.veilOverlay.style.height = document.body.clientHeight;
    } else {
	  	jt_DialogBox.veilOverlay.style.height = document.body.scrollHeight;
    }
  }

jt_DialogBox.addListener = function(obj, evType, fn) {
  if (obj.addEventListener) {
    obj.addEventListener(evType, fn, false);
    return true;
    }
  else if (obj.attachEvent) return obj.attachEvent('on' + evType, fn);
  else return false;
  }

jt_DialogBox.cmHideControl = function(tagName, element, divModal, hileOnlyUpperModal)
{
	var x = jt_DialogBox.cmGetX (element);
	var y = jt_DialogBox.cmGetY (element);
	var w = document.body.clientWidth;
	var h = document.body.clientHeight;
	
	if (hileOnlyUpperModal) {
		x = jt_DialogBox.cmGetX (divModal);
		y = jt_DialogBox.cmGetY (divModal);
		w = divModal.offsetWidth;
		h = divModal.offsetHeight;
	}

	var i;
	for (i = 0; i < document.all.tags(tagName).length; ++i)
	{
		var obj = document.all.tags(tagName)[i];
		if (!obj || !obj.offsetParent)
			continue;
			
		var ox = jt_DialogBox.cmGetX (obj);
		var oy = jt_DialogBox.cmGetY (obj);
		var ow = obj.offsetWidth;
		var oh = obj.offsetHeight;

		if (ox > (x + w) || (ox + ow) < x)
			continue;
		if (oy > (y + h) || (oy + oh) < y)
			continue;
			
		/*if ((ox > dx && ox < dx+dw) && (oy > dy && dy < dy+dh))*/

		if (divModal != null && jt_DialogBox.isParent(divModal, obj))
			continue;

		if(obj.style.visibility == "hidden")
			continue;

		element.cmOverlap[element.cmOverlap.length] = obj;
		obj.style.visibility = "hidden";
	}
}  

jt_DialogBox.isParent = function(divModal, obj)
{
	return (obj.name.indexOf(divModal.name) != -1);
}

jt_DialogBox.cmGetY = function(obj)
{
	var y = 0;
	do
	{
		y += obj.offsetTop;
		obj = obj.offsetParent;
	}
	while (obj);
	return y;
}

jt_DialogBox.cmGetX = function(obj)
{
	var x = 0;

	do
	{
		x += obj.offsetLeft;
		obj = obj.offsetParent;
	}
	while (obj);
	return x;
}

jt_DialogBox.cmShowControl = function(element)
{
	if (element.cmOverlap)
	{
		var i;
		for (i = 0; i < element.cmOverlap.length; ++i) {
			element.cmOverlap[i].style.visibility = "";
		}
	}
	element.cmOverlap = null;
}


/**
 * jt_AppDialogs.js - extends jt_DialogBox.js with 3 specific types of dialog boxes,
 * based on JavaScript equivalents: 'jt_AppAlert', 'jt_AppConfirm' and 'jt_AppPrompt'
 *
 * @version 9 Apr 2005
 * @author  Joseph Oster, wingo.com, Copyright (c) 2005-2006
 */

jt_AppAlert = function(icon) {
  // CONSTRUCTOR for 'jt_AppAlert' object - EXTENDS 'jt_DialogBox'
  if (arguments.length==0) return;
  this.base = jt_DialogBox;
  this.base(true);

  var dialogTable = document.createElement('table');
  dialogTable.setAttribute('cellSpacing', '0');
  dialogTable.setAttribute('cellPadding', '0');
  dialogTable.setAttribute('border', '0');

  var tBody = document.createElement('tbody');
  var row = document.createElement('tr');
  var cell = document.createElement('td');
  cell.setAttribute("vAlign", "top");

  this.iconImage = document.createElement('img');
  this.iconImage.style.margin = "0px 10px 0px 0px";
  this.setIcon(icon);
  cell.appendChild(this.iconImage);
  row.appendChild(cell);

  this.contentCell = document.createElement('td');
  this.contentCell.className = "ContentArea";
  row.appendChild(this.contentCell);
  tBody.appendChild(row);
  dialogTable.appendChild(tBody);
  this.contentArea.appendChild(dialogTable);

  this.buttonDIV = document.createElement('div');
  this.buttonDIV.setAttribute("align", "center");
  this.buttonDIV.style.margin = "10px 0px 0px 0px";
  this.contentArea.appendChild(this.buttonDIV);
  
  jt_AppAlert.lblOK = (this instanceof jt_AppConfirm ? jt_AppAlert.lblDefaultSim : jt_AppAlert.lblDefaultOK );
  
  jt_AppAlert.addButton(this, jt_AppAlert.lblOK, 1);
}

jt_AppAlert.prototype = new jt_DialogBox();

/************ BEGIN: 'jt_AppAlert' Public Methods ************/
jt_AppAlert.Warning = "/easyfaces/resources/dialog/icons/warning.gif"; // 'icon' param to 'jt_AppAlert' constructor
jt_AppAlert.Error = "/easyfaces/resources/dialog/icons/error.gif";     // 'icon' param to 'jt_AppAlert' constructor
jt_AppAlert.Info = "/easyfaces/resources/dialog/icons/info.gif";       // 'icon' param to 'jt_AppAlert' constructor
jt_AppAlert.Question = "/easyfaces/resources/dialog/icons/question.gif";       // 'icon' param to 'jt_AppAlert' constructor
jt_AppAlert.lblDefaultOK = "Ok"; // label for "OK" button (for i18N)
jt_AppAlert.lblDefaultSim = "Sim"; // label for "OK" button (for i18N)
jt_AppAlert.lblCancel = "Não"; // label for "Cancel" button (for i18N)

jt_AppAlert.prototype.setContent = function(htmlContent) {
  this.contentCell.innerHTML = htmlContent;
  }

jt_AppAlert.prototype.setIcon = function(icon) {
  this.iconImage.src = jt_DialogBox.imagePath + icon;
  }

/************ END: 'jt_AppAlert' Public Methods ************/


jt_AppConfirm = function(icon, callOK, callCancel) {
  // CONSTRUCTOR for 'jt_AppConfirm' object - EXTENDS 'jt_AppAlert'
  if (arguments.length==0) return;
  
  this.base = jt_AppAlert;
  this.base(icon);
  this.callOK = callOK;
  this.callCancel = callCancel;
  jt_AppAlert.addButton(this, jt_AppAlert.lblCancel, 2);
  }

jt_AppConfirm.prototype = new jt_AppAlert();


/************ BEGIN: 'jt_AppConfirm' Public Methods ************/
jt_AppConfirm.prototype.askUser = function(htmlContent) {
  this.setContent(htmlContent);
  this.show();
  }
/************ END: 'jt_AppConfirm' Public Methods ************/



jt_AppPrompt = function(icon, callOK, callCancel, cssClass) {
  // CONSTRUCTOR for 'jt_AppPrompt' object - EXTENDS 'jt_AppConfirm'
  if (arguments.length==0) return;
  this.base = jt_AppConfirm;
  this.base(icon, callOK, callCancel);
  this.returnData = new Object();
  this.fInput = document.createElement('input');
  this.fInput.type = "text";
  if (cssClass) this.fInput.className = cssClass;
  this.fInput.appDialog = this;
  this.fInput.onkeypress = jt_AppPrompt.keyPress;
  }

jt_AppPrompt.prototype = new jt_AppConfirm();
jt_AppPrompt.superClass = jt_AppConfirm.prototype;


/************ BEGIN: 'jt_AppPrompt' Public Methods ************/
jt_AppPrompt.prototype.askUser = function(htmlContent, stDefault) {
  this.setContent(htmlContent);
  this.fInput.value = stDefault;
  this.contentCell.appendChild(this.fInput);
  this.show();
  this.fInput.focus();
  }

jt_AppPrompt.prototype.focus = function() {
  this.fInput.focus();
  }

jt_AppPrompt.prototype.hide = function(ok) {
  if (ok) this.returnData.value = this.fInput.value;
  jt_AppPrompt.superClass.hide.call(this, ok);
  }
/************ END: 'jt_AppPrompt' Public Methods ************/



/************ BEGIN: 'jt_AppAlert' Private Methods ************/
jt_AppAlert.addButton = function(parent, buttonText, buttonNum) {
  var button = document.createElement("button");
  button.style.fontSize = "8pt";
  button.style.width = "60px";
  button.style.margin = "0px 5px";
  button.className = "jtButton";
  button.innerHTML = buttonText;
  button.linkNum = buttonNum;
  button.appDialog = parent;
  button.onclick = jt_AppAlert.clickLink;
  parent.buttonDIV.appendChild(button);
  }
  
jt_DialogBox.prototype.setAlertType = function(alertType) {
  	this.setIcon(alertType);
  }  

jt_AppAlert.clickLink = function(e) {
  if (!e) e = window.event;
  var node = e.target ? e.target : e.srcElement;
  var linkNum = node.linkNum;
  var count = 0;
  while ((node != null) && (count < jt_DialogBox.maxDepth)) {
    if (node.appDialog) {
      switch (linkNum) {
        case 1: {
          node.appDialog.hide(true);
          break;
          }
        case 2: {
          node.appDialog.hide();
          break;
          }
        }
      return false;
      }
    node = node.parentNode;
    count++;
    }
  return false;
  }

jt_AppPrompt.keyPress = function(e) {
  if (!e) e = window.event;
  var node = e.target ? e.target : e.srcElement;
  var key = e.keyCode ? e.keyCode : e.which;
  if (key == 13) node.appDialog.hide(true);
  if (key == 27) node.appDialog.hide();
  }

jt_AppAlert.prototype.trace = function() {
  alert(objToString(this.contentArea));
  }

// default instance.  
alertBox = new jt_AppAlert(jt_AppAlert.Info);


/**
 * jt_utils.js - Misc. JavaScript utility functions
 *
 * @version 16 Feb 2006
 * @author  Joseph Oster, wingo.com, Copyright (c) 2005-2006
 */

/* GENERIC FUNCTIONS */
String.prototype.trim = function () {
  return this.replace(/^\s+/g, '').replace(/\s+$/g, '');
  }

function jt_ShowHideElm(elm, showIt) {
  if (elm) elm.style.visibility = (showIt) ? "visible" : "hidden";
  }

function jt_ShowNoneElm(elm, showIt, showStyle) {
  if (!showStyle) showStyle = "";
  if (elm) elm.style.display = (showIt) ? showStyle : "none";
  }

function jt_ShowHide(divName, showIt) {
  jt_ShowHideElm(document.getElementById(divName), showIt);
  }

function jt_ShowNone(divName, showIt, showStyle) {
  jt_ShowNoneElm(document.getElementById(divName), showIt, showStyle);
  }


/********** BEGIN: Event handling **********/
function jt_AddListener(obj, evType, fn) {
  if (obj.addEventListener) {
    obj.addEventListener(evType, fn, false);
    return true;
    }
  else if (obj.attachEvent) return obj.attachEvent('on' + evType, fn);
  else return false;
  }

function jt_fixE(ev) {
  var e = ev ? ev : window.event;
  return e;
  }
/********** END: Event handling **********/


/********** BEGIN: screen handling **********/
function jt_Point(x, y) {
  // returns a "Point" object with '.x' and '.y' properties
  this.x = x;
  this.y = y;
  }

function jt_getOffsetXY(obj, findID) {
  // returns an object with both '.x' and '.y' offsets of 'obj' relative 
	//to 'findID' (or page if 'findID' doesn't exist)
  // usage: "var point = jt_getOffsetXY(obj); var left=3Dpoint.x; var =
	//top=3Dpoint.y;"
  var xPos = obj.offsetLeft;
  var yPos = obj.offsetTop;
  var parent = obj.offsetParent;
  if (typeof findID == 'undefined') findID = '!@#$%^&*()';
  while ((parent != null) && (parent.id != findID)) {
    xPos += parent.offsetLeft;
    yPos += parent.offsetTop;
    parent = parent.offsetParent;
    }
  return new jt_Point(xPos, yPos);
  }

function jt_moveTo(obj, x, y) {
  // moves 'obj' to x/y coordinates
  obj.style.left = x + "px";
  obj.style.top = y + "px";
  }

function jt_getOffsetX(obj) {
  // returns 'x' coordinate of 'obj'
  var xPos = obj.offsetLeft;
  var parent = obj.offsetParent;
  while (parent != null) {
    xPos += parent.offsetLeft;
    parent = parent.offsetParent;
    }
  return xPos;
  }

function jt_getOffsetY(obj) {
  // returns 'y' coordinate of 'obj'
  var yPos = obj.offsetTop;
  var parent = obj.offsetParent;
  while (parent != null) {
    yPos += parent.offsetTop;
    parent = parent.offsetParent;
    }
  return yPos;
  }

function jt_windowOffsetX() {
  // returns X-offset of window (for positioning popups)
  if (window.screenX) return window.screenX + 
(window.outerWidth-window.innerWidth) - window.pageXOffset;
  else return document.body.scrollLeft + window.screenLeft;
  }

function jt_windowOffsetY() {
  // returns Y-offset of window (for positioning popups)
  if (window.screenY) return window.screenY + 
(window.outerHeight-24-window.innerHeight) - window.pageYOffset;
  else return document.body.scrollTop + window.screenTop;
  }

function jt_getChromeY() {
  // return height of browser "chrome" ('screenTop' offset)
  return window.screenTop ? window.screenTop : (window.outerHeight - 
window.innerHeight - 24);
  }

/********** END: screen handling **********/
// also see: =
http://www.mattkruse.com/javascript/anchorposition/source.html


/********** BEGIN: FORM handling **********/
function jt_setRadio(radioFld, val) {
  // set 'radioFld' button with value == val and return 'true' (if =
	//not disabled!)
  for (var i=0; i<radioFld.length; i++)
    if (radioFld[i].value == val)
      if (!radioFld[i].disabled) {
        radioFld[i].checked = true;
        return true;
        }
  return false;
  }

function jt_getRadio(radioFld) {
  // return value of selected 'radioFld' button
  var st = "";
  for (var i=0; i<radioFld.length; i++)
    if (radioFld[i].checked) {
      st = radioFld[i].value;
      break;
      }
  return st;
  }

function foSelected(pulldown) {
  // return value of selected item
  var st = "";
  for (var i=0; i<pulldown.options.length; i++)
  if (pulldown.options[i].selected) {
    if (pulldown.options[i].value) st = pulldown.options[i].value
    else st = pulldown.options[i].text;
    break;
    }
  return st;
  }

function foPosInList(pulldown, val) {
  // return position of 'val' in pulldown menu, -1 if not found
  if (val != "")
    for (var i=0; i<pulldown.options.length; i++) {
      var opVal = pulldown.options[i].value;
      if (opVal == "") opVal = pulldown.options[i].text;
      if (opVal == val) {
        return i;
        break;
        }
      }
  return -1;
  }

function foSetSelectVal(pulldown, val) {
  // set "SELECTED" for item in pulldown menu with 'value==3Dval'
  var p = foPosInList(pulldown,val);
  if (p != -1) pulldown.options.selectedIndex = p;
  }
/********** END: FORM handling **********/


function jt_parseQuery(queryString) {
  // converts name/value pairs in 'queryString' to JS object
  var qObj = new Object();
  var stQuery = (queryString) ? queryString : location.search; // use =
	//'location.search' if 'queryString' is null
  if (stQuery.indexOf("?") == 0) stQuery = stQuery.substring(1);
  if (stQuery) {
    var nvPairs = stQuery.split("&");
    for (var i=0; i < nvPairs.length; i++) {
      var posEq = nvPairs[i].indexOf("=");
      if (posEq != -1) eval( "qObj." + nvPairs[i].substring(0,posEq) + 
"='" + nvPairs[i].substring(posEq+1) + "'");
      }
    }
  return qObj;
  }

function jt_safeHTML(st) {
  // encode - same as 'u:htmlencode' tag
  if (st.length == 0) return "";
  st = st.replace(/</gi,"&lt;");
  st = st.replace(/>/gi,"&gt;");
  st = st.replace(/\"/gi,'&quot;');
  st = st.replace(/\'/gi,"&#39;");
  st = st.replace(/\\/gi,"&#92;");
  return st;
  }

function jt_unsafeHTML(st) {
  // decode - opposite of 'u:htmlencode' tag
  if (st.length == 0) return "";
  st = st.replace(/&lt;/gi,"<");
  st = st.replace(/&gt;/gi,">");
  st = st.replace(/&quot;/gi,'"');
  st = st.replace(/&#39;/gi,"'");
  st = st.replace(/&#92;/gi,"\\");
  return st;
  }

function jt_plural(qty, lbl) {
  // returns plural suffix or optional extended format if 'lbl' is =
	//present; example: qty=3D12, lbl="server", return value="12 servers"
  var stPlural = (qty == 1) ? "" : "s";
  if (lbl) stPlural = qty + " " + lbl + stPlural;
  return stPlural;
  }

function objToString(anObj, sep) {
  // convert any JS object to string of name:value pairs separated by =
  //optional 'sep'
  // NOTE: pass '<br />' for 'sep' to display as HTML
  if (!sep) sep = ' ][ '; // good for 'alert()' msgs
  var st = "";
  for(var prop in anObj) {
    if ((prop.charAt(0) == '$') || ((typeof anObj[prop]) == 
'function')) continue;
    if (st != "") st += sep;
    st += prop + ':' + anObj[prop];
    }
  return st;
  }

function jt_alignCorner(elmToMove, elmAnchor, TlTrBlBr, xOffset, 
yOffset) {
  // aligns 'elmToMove' with 'elmAnchor' based on 2-character 'TlTrBlBr' =
	//indicating corner: 'TL' | 'TR' | 'BL' | 'BR'
  xOffset = xOffset ? xOffset : 0; // optional param
  yOffset = yOffset ? yOffset : 0; // optional param
  var anchorXY = jt_getOffsetXY(elmAnchor);
  var xxOffset = (TlTrBlBr.indexOf('R') != -1) ? 
elmToMove.offsetWidth - elmAnchor.offsetWidth : 0;
  var yyOffset = (TlTrBlBr.indexOf('B') != -1) ? 
elmToMove.offsetHeight : 0;
  jt_moveTo(elmToMove, anchorXY.x - xxOffset + xOffset, anchorXY.y - 
yyOffset + yOffset);
  }

function jt_boxOverlap(objectA, objectB, mode) {
  // box collision detector; returns area of overlap (if any) in pixels 
	//between DOM elements 'objectA' and 'objectB'
  // adapted from =
	//http://www.gamedev.net/reference/articles/article754.asp
  // 'mode' is optional - two special modes are offered:
  //   mode='X' - test for overlap of X-coordinates only; ignore Y
  //   mode='Y' - test for overlap of Y-coordinates only; ignore X

  var xyA = jt_getOffsetXY(objectA);
  var xyB = jt_getOffsetXY(objectB);

  var objAxTL = xyA.x; // AX1 - xTopLeft
  var objAyTL = xyA.y; // AY1 - yTopLeft
  var objAxBR = xyA.x + objectA.offsetWidth; // AX2 - xBottomRight
  var objAyBR = xyA.y + objectA.offsetHeight; // AY2 - yBottomRight

  var objBxTL = xyB.x; // BX1
  var objByTL = xyB.y; // BY1
  var objBxBR = xyB.x + objectB.offsetWidth; // BX2
  var objByBR = xyB.y + objectB.offsetHeight; // BY2

  if (mode != 'Y') {
    if (objAxBR < objBxTL) return -1;
    if (objBxBR < objAxTL) return -1;
    }
  if (mode != 'X') {
    if (objAyBR < objByTL) return -1;
    if (objByBR < objAyTL) return -1;
    }


  var objCxTL;
  var objCyTL;
  var objCxBR;
  var objCyBR;

/*
If AX1<BX1 then CX1=3DBX1 and CX2=3DAX2, otherwise, CX1=3DAX1 and =
CX2=3DBX2
If AY1<BY1 then CY1=3DBY1 and CY2=3DAY2, otherwise, CY1=3DAY1 and =
CY2=3DBY2
*/

  if (objAxTL < objBxTL) {
    objCxTL = objBxTL;
    objCxBR = objAxBR;
    }
  else {
    objCxTL = objAxTL;
    objCxBR = objBxBR;
    }

  if (objAyTL < objByTL) {
    objCyTL = objByTL;
    objCyBR = objAyBR;
    }
  else {
    objCyTL = objAyTL;
    objCyBR = objByBR;
    }

  var olX = objCxBR - objCxTL;
  var olY = objCyBR - objCyTL;
  if (mode == 'X') return olX;
  else if (mode == 'Y') return olY;
  else return olX * olY;
  }


function jt_currStyle(divToRead) {
  // return current (derived) CSS style object
  var cs = divToRead.style;
  if (window.getComputedStyle) cs = 
window.getComputedStyle(divToRead,null);
  else if (divToRead.currentStyle) cs = divToRead.currentStyle;
  return cs;
  }

function jt_divOnScrn(divOnScrn) {
  var divPos = jt_getOffsetXY(divOnScrn);
  var newX = divPos.x;
  var newY = divPos.y;
  
  if (divOnScrn.style.left == "-1px") 
  {
  	newX = Math.round((document.body.clientWidth - divOnScrn.offsetWidth) / 2);
  }
  else 
  {
    if (divPos.x + divOnScrn.offsetWidth - document.body.scrollLeft > 
	document.body.clientWidth) newX = document.body.scrollLeft + 
	document.body.clientWidth - divOnScrn.offsetWidth;
	
	  if (divPos.x < document.body.scrollLeft) newX = 
	document.body.scrollLeft;
  }
  
  if (divOnScrn.style.top == "-1px")
  {
	newY = Math.round((document.body.clientHeight - divOnScrn.offsetHeight) / 2) + document.body.scrollTop
  }
  else
  {
  	if (divPos.y + divOnScrn.offsetHeight - document.body.scrollTop > 
	document.body.clientHeight) newY = document.body.scrollTop + 
	document.body.clientHeight - divOnScrn.offsetHeight;
	
	  if (divPos.y < document.body.scrollTop) newY = 
	document.body.scrollTop;
  }  
  if ((newX != divPos.x) || (newY != divPos.y)) 
  	jt_moveTo(divOnScrn, newX, newY);
  }