/* NOTE: To disable print, use this style sheet: */
/* @media print {body {display:none;}} */

/* static variables */

/* Data type values */
_FT_BOOL = 16;
_FT_CHAR = 253;
_FT_DATE = 10;
_FT_TIME = 11;
_FT_INT = 3;
_FT_UINT = 3.1;
_FT_DEC1 = 0.1;
_FT_DEC2 = 0.2;
_FT_DEC3 = 0.3;


// field control constants
_CT_REQ = 101;   /* non-null value is required */
_CT_PULL = 102;  /* pulldown field with following 2 array elements: table-name, "field-val,field-desc" */

/* Ajax fill_fields constants */
_AX_FD = '\x01';
_AX_UNCK = '\x02';
_AX_CK = '\x03';
_AX_SLC = '\x04';
_AX_SLC_CK = '\x05';
_AX_SLC_DIV = '\x06';
_AX_DISABLE = '\x07';
_AX_ENABLE = '\x08';
_AX_HIDE = '\x0E';
_AX_VISIBLE = '\x0F';
_AX_CMD = '\x10';
_AX_DISP_YES = '\x11';
_AX_DISP_NO = '\x12';

/* ======================================================================= */
/* add escape "\" for quote, double-quote and backwards slash */
function addslashes(textval) {
   return(textval.replace(/['"\\]/g, '\\$&'));
}
/* ======================================================================= */
/* Abbreviation for getElementById */
/* Also allows the element id object to be passed (just returns it) */
function eid(element)
{
if (typeof(element) == "string")
   return(document.getElementById(element));
else
    return(element);
}

/* ======================================================================= */
/* add a selection option, optionally selecting it */
/* can specify a start position (assumes from beginning if not passed)  */
/* if ordered = true, assumes that option list is text ordered and insert into correct position  */
/* otherwise just adds to the end  */
/* if select = true, mark as selected  */
function addSlcOption(slcobj, value, text, ordered, startpos, select) {
   var optelem = document.createElement('option');
   optelem.value = value;
   optelem.text = text;
   var optadded = false;
   var i = slcobj.options.length;
   if (typeof(ordered) != 'undefined' && ordered) {   // put in correct position
      i = 0;
      if (typeof(startpos) != 'undefined')
         i = startpos;
      while (i < slcobj.options.length) {
         if (slcobj.options[i].text > text) {
            try { slcobj.add(optelem, slcobj.options[i]); }
            catch(e) { slcobj.add(optelem, i) }   // IE not DOM compliant
            optadded = true;
            break;
         }
         ++i;
      }
   }
   if (!optadded) {   // add to end of options
      try { slcobj.add(optelem, null); }
      catch(e) { slcobj.add(optelem, i) }   // IE not DOM compliant
   }
   if (typeof(select) != 'undefined' && select)   // mark as selected
      slcobj.selectedIndex = i;
}

/* ======================================================================= */
/* remove a selection option */
/* pass the value to be removed (duplicate values will be removed) */
/* returns true if removed  */
function rmvSlcOption(slcobj, value) {
   var rtnsts = false;
   for (var i = 0; i < slcobj.options.length; i++) {
      if (slcobj.options[i].value == value) {
         slcobj.remove(i);
         rtnsts = true;
      }
   }
   return rtnsts;
}

/* ======================================================================= */
/* set a select element to its passed selection */
function set_select(element, matchvalue)
{
try {
    var i=0;
    var x = eid(element);
    while(i < x.length) {
         if (x.options[i].value == matchvalue)
         break;
         ++i;
    }
    x.selectedIndex = i;
}
catch(e) {
}
}
/* ======================================================================= */
/* set a radio or checkbox element to its passed checked status */
/* (use the group name; must be in order with initial value = 0) */
function set_radio(elementname, pos)
{
try {
    var x = document.getElementsByName(elementname);
    x[pos].checked = true;
}
catch(e) {
}
}
/* ======================================================================= */
/* clears all radio buttons in a group */
function clr_radio(radioname)
{
try {
   var x = document.getElementsByName(radioname);
   for (var i = 0; i < x.length; i++) {
      if (x[i].checked)
         x[i].checked = false;
   }
}
catch(e) {
}
}
/* ======================================================================= */
/* return the value of the radio button that is checked */
/* return an empty string if none are checked, or */
/* there are no radio buttons */
function getCheckedValue(radioObjName) {
    if (typeof(radioObjName) == 'string')
       var radioObj = document.getElementsByName(radioObjName);
    else
       var radioObj = radioObjName;
	if(!radioObj)
		return '';
	var radioLength = radioObj.length;
	if(radioLength == undefined) {
		if(radioObj.checked)
			return radioObj.value;
		else
			return '';
    }
	for(var i = 0; i < radioLength; i++) {
		if(radioObj[i].checked)
			return radioObj[i].value;
	}
	return '';
}
/* ======================================================================= */
/* set the radio button with the given value as being checked  */
/* do nothing if there are no radio buttons */
/* if the given value does not exist, all the radio buttons */
/* are reset to unchecked */
function setCheckedValue(radioObjName, newValue) {
    if (typeof(radioObjName) == 'string')
       var radioObj = document.getElementsByName(radioObjName);
    else
       var radioObj = radioObjName;
	if(!radioObj)
		return;
	var radioLength = radioObj.length;
	if(radioLength == undefined) {
		radioObj.checked = (radioObj.value == newValue.toString());
		return;
	}
	for(var i = 0; i < radioLength; i++) {
		radioObj[i].checked = false;
		if(radioObj[i].value == newValue.toString()) {
			radioObj[i].checked = true;
		}
	}
}
/* ======================================================================= */
/* clear related checkboxes if element is checked */
/* call this routine with onclick=
/* pass the element object (this) followed by any number of related checkbox ids */
function clr_rel_ck(elemobj, related1, related2 /* ... */)
{
   if (elemobj.checked) {
      for (var i = 1; i < arguments.length; i++)
         eid(arguments[i]).checked = false;
   }
}
/* ======================================================================= */
/* set related checkboxes if element is checked */
/* call this routine with onclick=
/* pass the element object (this) followed by any number of related checkbox ids */
function set_rel_ck(elemobj, related1, related2 /* ... */)
{
   if (elemobj.checked) {
      for (var i = 1; i < arguments.length; i++)
         eid(arguments[i]).checked = true;
   }
}
/* ======================================================================= */
/* changes a property of all child nodes */
function chg_node_prop(elem, propstr)
{
   if (typeof(elem) == 'string')
      var par = document.getElementById(elem);
   else
      var par = elem;
   for (var i = 0; i < par.childNodes.length; i++) {
      var node = par.childNodes[i];
      var propset = 'node.' + propstr;
//      alert(node.id + ' ' + propset);
      eval(propset);
   }
}
/* ======================================================================= */
/* convert rgb to hex equivalent */
function rgb(red, green, blue)
{
var decColor = blue + 256 * green + 65536 * red;
return decColor.toString(16);
}
/* ======================================================================= */
/* get the absolute X coordinate of an element */
function getX(e)
{
var x = 0;
while(e) {
x += e.offsetLeft;
e = e.offsetParent;
}
return x;
}
/* ======================================================================= */
/* get the absolute Y coordinate of an element */
function getY(e)
{
var y = 0;
while(e) {
y += e.offsetTop;
e = e.offsetParent;
}
return y;
}
/* ======================================================================= */
//  This function resizes an IFrame object to fit its content.
//  The IFrame tag must have a unique ID attribute.
//  Include the following in the <iframe> statement:
//    width="100%" height="0" onload="resizeIframeToFitContent(this)"
function resizeIframeToFitContent(iframe) {
   var iframes = document.getElementsByTagName('iframe');
   for (var i=0;i<iframes.length;i++) {
      if (iframe.id == iframes[i].id) {
         iframe.height = parent.frames[i].document.body.scrollHeight;
         iframe.width = parent.frames[i].document.body.scrollWidth;
         break;
      }
   }  
}
/* ======================================================================= */
function Trim(str)
/* PURPOSE: Remove leading and trailing blanks from our string. */
/* IN: str - the string we want to Trim */
{
var whitespace = new String(" \t\n\r");
var s = new String(str);
if (whitespace.indexOf(s.charAt(0)) != -1) {
   /* We have a string with leading blank(s)... */
   var j=0, i = s.length;
   /* Iterate from the far left of string until we */
   /* don't have any more whitespace... */
   while (j < i && whitespace.indexOf(s.charAt(j)) != -1)
         j++;
   /* Get the substring from the first non-whitespace */
   /* character to the end of the string... */
   s = s.substring(j, i);
}
/* Remove trailing blanks */
i = s.length - 1;
while (i >= 0 && whitespace.indexOf(s.charAt(i)) != -1)
      i--;
if (i >= 0)
   s = s.substr(0, i + 1);
else
    s = "";
return s;
}
/* ======================================================================= */
/* Only allow number keys to be accepted */
/* Optionally may allow decimal point and minus sign and forward slash */
/* to call: onkeypress = return(isNumberKey(event)); */
function isNumberKey(evt, allowdecpoint, allowsign, allowslash)
{
   var keynum = 0;
   if(window.event) // IE
     keynum = evt.keyCode;
   else if(evt.which) // Netscape/Firefox/Opera
     keynum = evt.which;
   if (keynum < 32) /* accept control codes */
      return true;
   if (allowdecpoint && keynum == 46)  /* decimal point allowed */
      return true;
   if (allowsign && keynum == 45)   /* minus sign allowed */
      return true;
   if (allowslash && keynum == 47)   /* forward slash allowed */
      return true;
   if (keynum > 31 && (keynum < 48 || keynum > 57)) /* invalid character */
      return false;
   return true;
}
/* ======================================================================= */
/* Verify characters entered, only allowing specific characters */
/* to call: onkeypress = return(verifyChar(event, valid-chars)); */
function verifyChar(evt, valchars)
{
   var arrSpecialChars = new Array(0, 8, 9, 35, 36, 37, 38, 39, 40, 46);
   var keynum = 0;
   if(window.event) // IE
     keynum = evt.keyCode;
   else if(evt.which) // Netscape/Firefox/Opera
     keynum = evt.which;
   if (InArray(arrSpecialChars, keynum) >= 0) /* special characters OK */
      return true;
   var strChar = String.fromCharCode(keynum);
   return ((valchars.indexOf(strChar)) >= 0);
}
/* ======================================================================= */
/* return position of requested key in array */
/* returns -1 if not found */
function InArray(arr, key)
{
   for (var i=0; i<arr.length; i++) {
      if (arr[i] == key)
         return i;
   }
   return -1;
}

/* ======================================================================= */
/* Rounds a number to a specific number of digits after the decimal point */
/* Returns NaN if an invalid number */
function numRound(num, digits)
{
   var q = num - 0;   /* forces type to a number */
   return q.toFixed(digits);
}
/* ======================================================================= */
/* Validates/rounds a numeric field, returning FALSE if invalid */
/* The field is updated with the rounded number unless 'digits' is not numeric */
/* Optionally changes the color or background color of the element if invalid/valid */
/* (Pass '' to restore color, omit or pass null for no change) */
function numfldValidate(numfld, digits, errColor, validColor, errBkgColor, validBkgColor)
{
   var n = eid(numfld);
   if (typeof digits == 'number')
      var q = numRound(n.value, digits);
   else
      var q = n.value;
   if (isNaN(q)) {
      if (typeof errColor == 'string')
         n.style.color = errColor;
      if (typeof errBkgColor == 'string')
         n.style.backgroundColor = errBkgColor;
      return false;
   }
   else {
      if (typeof validColor == 'string')
         n.style.color = validColor;
      if (typeof validBkgColor == 'string')
         n.style.backgroundColor = validBkgColor;
      n.value = q;
      return true;
   }
}
/* ======================================================================= */
/* Checks if a number is between a range of numbers (returns true or false) */
/* Number should be validated first */
/* Optionally changes the color of the element if inrange or not */
/* (Pass '' to restore color, omit or pass null for no change) */
function numfldRange(numfld, minval, maxval, errColor, validColor, errBkgColor, validBkgColor)
{
   var n = eid(numfld);
   var nv = n.value - 0;
   if (nv >= minval && nv <= maxval) {
      if (typeof validColor == 'string')
         n.style.color = validColor;
      if (typeof validBkgColor == 'string')
         n.style.backgroundColor = validBkgColor;
      return true;
   }
   else {
      if (typeof errColor == 'string')
         n.style.color = errColor;
      if (typeof errBkgColor == 'string')
         n.style.backgroundColor = errBkgColor;
      return false;
   }
}
/* ======================================================================= */
/* Sets or clears the error text following an input field in a table element */
/* The field ID or object must be passed; can change the color and/or background color of the field */
/* (Pass '' to restore color, omit or pass null for no change) */
function setTblFldErr(fld, errText, errColor, validColor, errBkgColor, validBkgColor)
{
   var fset = eid(fld);
   var fv = fset.value;
   var fid = fset.id;
   var tset = fset.parentNode;
   var ihtml = tset.innerHTML;
   var ip = ihtml.toLowerCase().lastIndexOf('<input'); /* find end of last <input> element */
   if (ip == -1)
      ihtml = '';
   else {
      ip = ihtml.toLowerCase().indexOf('>', ip);
      if (ip == -1)
         ihtml = '';
      else
         ihtml = ihtml.substr(0, ip + 1);
   }
   if (errText == '') {  /* clear error */
      tset.innerHTML = ihtml;
      fset = eid(fid);
      fset.value = fv;  /* restore value */
      if (typeof validColor == 'string')
         fset.style.color = validColor;
      if (typeof validBkgColor == 'string')
         fset.style.backgroundColor = validBkgColor;
   }
   else {   /* set error */
      tset.innerHTML = ihtml + '<B style="color:red;"><I><small>&nbsp;&nbsp;' + errText + '</small></I></B>';
      fset = eid(fid);
      fset.value = fv;  /* restore value */
      if (typeof errColor == 'string')
         fset.style.color = errColor;
      if (typeof errBkgColor == 'string')
         fset.style.backgroundColor = errBkgColor;
   }
}
/* ======================================================================= */
/* Validates a list of fields passed in two arrays */
/* Returns true if all are valid; otherwise returns false */
/* (to restore colors to original value, use ''; to not change, use null) */
/* Parm 1: Array of required fields: */
/*    0 = field text color if error */
/*    1 = field text color if okay */
/*    2 = field background color if error */
/*    3 = field background color if okay */
/*  The following entries repeat for each field  */
/*    4 = field ID or object, 5 = error text if field is empty, 6 = repeat . . . */
/* Parm 2: Array of numeric fields: */
/*    0 to 3 = color settings (same as above) */
/*    4 = field ID or object, 1 = true if empty value is allowed, and keep empty, */
/*    5 = decimal positions to round to (if not a number, no rounding is done) */
/*    6 = error text if validation fails, */
/*    7 = minimum value, 5 = maximum value, */
/*    8 = error text if outside of allowed min-max (if empty string, use previous error text) */
/*    9 = repeat . . . */
function fldsValidate(reqarr, numarr)
{
   var allvalid = true;
   if (reqarr) {
      var errColor = reqarr[0];
      var okColor = reqarr[1];
      var errBkgColor = reqarr[2];
      var okBkgColor = reqarr[3];
      for (var i = 4; i < reqarr.length; i++) {
         var errtext = '';
         var f = eid(reqarr[i++]);
         f.value = Trim(f.value);
         if (f.value.length == 0) {  /* trimmed field is empty */
            allvalid = false;
            errtext = reqarr[i];
         }
         setTblFldErr(f, errtext, errColor, okColor, errBkgColor, okBkgColor);
      }
   }
   if (numarr) {
      var errColor = numarr[0];
      var okColor = numarr[1];
      var errBkgColor = numarr[2];
      var okBkgColor = numarr[3];
      for (var i = 4; i < numarr.length; i++) {
         errtext = '';
         f = eid(numarr[i++]);  /* field id or reference */
         f.value = Trim(f.value);
         if (numarr[i++] && f.value.length == 0) {  /* if empty & empty keep = true, skip field */
            i += 4;
            continue;
         }
         if (!(numfldValidate(f, numarr[i++], errColor, okColor, errBkgColor, okBkgColor))) {   /* validate & round */
            allvalid = false;
            errtext = numarr[i++];
            i += 2;
         }
         else if (!(numfldRange(f, numarr[++i], numarr[++i], errColor, okColor, errBkgColor, okBkgColor))) {   /* check range */
            allvalid = false;
            errtext = numarr[++i];
            if (errtext == '')    /* if no min-max error, use validation error */
               errtext = numarr[i - 3];
         }
         else
            ++i;
         setTblFldErr(f, errtext, errColor, okColor, errBkgColor, okBkgColor);
      }
   }
   return allvalid;
}
/* ======================================================================= */
/* Change the text of a node's first child */
/* Adds a text node if no child */
function updnodetxt(node, text) {
   if (node.firstChild == null) {
      var textnode = document.createTextNode(text);
      node.appendChild(textnode);
   } else
      node.firstChild.nodeValue = text;
}
/* ======================================================================= */
/* Replace HTML in a table row with IE workaround */
/* Each table row (<tr>) must be enclosed by <tbody> tags */
/* The <tbody> node is referenced by tbnode */
/* Htmlstr contains all HTML for the row, including the <tr> tag */
function replaceHTML(tbnode, htmlstr) {
   try {  // try innerHTML which works with Firefox, but not IE6
      tbnode.innerHTML = htmlstr;
   }
   catch(e) {   // build a temp node used to replace updated table row
      var tempnode = document.createElement("span");
      tempnode.style.visibility = 'hidden';
      tempnode.innerHTML = '<table><tbody id="tb_replace">' + htmlstr + '</tbody></table>';
      var tid = tbnode.id;
      tbnode.parentNode.replaceChild(tempnode.firstChild.firstChild, tbnode);
      var rnode = document.getElementById('tb_replace');
      rnode.id = tid;
   }
}
/* ======================================================================= */
/* Build radio selection entries, returning the table HTML */
/* First entry is 'clr' which will clear all entries if clicked */
/*   Parm 1 = name of radio group */
/*   Parm 2 = group description  */
/*   Parm 3 = group description style (default is vertical-align:top;border:0px none;) */
/*   Parm 4 = name of class to describe each table element */
/*    (example: .tradio {border:0px none;padding:0px;width:20px;text-align:center;font-size:75%;}) */
/*   Parm 5 = minimum value of entries (0 or greater) */
/*   Parm 6 = maximum value of entries */
/*   Parm 7 = value that should be selected (optional) */
/*   Parm 8 = style parameter of table (optional) */
function bldRadioslc(groupname, groupdesc, groupdescstyle, tclassname, minvalue, maxvalue, slcvalue, tblstyle) {
   var rhtml = '<table';
   if (tblstyle != undefined && tblstyle != '')
      rhtml += ' style="' + tblstyle + '"';
   rhtml += ' border="0" cellpadding="0" cellspacing="0"><tbody><tr>';
   if (groupdesc != '') {
      rhtml += '<td style="';
      if (groupdescstyle != '')
         rhtml += groupdescstyle + '">';
      else
         rhtml += 'vertical-align:top;border:0px none;">';
      rhtml += groupdesc + '</td>';
   }
   for (var i = minvalue; i <= maxvalue; i++) {
      rhtml += '<td class="' + tclassname + '"><input name="' + groupname + '" value="' +
               i + '" type="radio"';
      if (slcvalue != undefined && slcvalue == i)
         rhtml += ' checked="checked"';
      rhtml += '><br>' + i + '</td>';
   }
   rhtml += '<td class="' + tclassname + '"><input style="padding:0px;font-weight:bold;font-size:90%;color:yellow;background-color:rgb(255,128,128);" type="button" onclick="clr_radio(\'' + groupname + '\');" value="Clr"></td>';
   rhtml += '</tr></tbody></table>';
   return(rhtml);
}
/* ======================================================================= */
/* Returns an array of Date objects from an ISO date array */
function ISO_to_Date(ISOdates) {
   var a = new Array();
   for (var i = 0; i < ISOdates.length; i++) {
      var ISOdt = ISOdates[i];
      var d = new Date();
      d.setHours(0,0,0,0);
      d.setFullYear(ISOdt.substr(0,4));
      d.setMonth(ISOdt.substr(5,2) - 1);
      d.setDate(ISOdt.substr(8,2));
      a[i] = d;
   }
   return a;
}
/* ======================================================================= */
/* Returns an array of ISO dates from an array of Date objects */
function Date_to_ISO(Dates) {
   var a = new Array();
   for (var i = 0; i < Dates.length; i++) {
      d = Dates[i];
      dm = d.getMonth() + 1;
      if (dm <= 9)
         dm = '0' + dm.toString();
      dd = d.getDate();
      if (dd <= 9)
         dd = '0' + dd.toString();
      a[i] = d.getFullYear() + '-' + dm + '-' + dd;
   }
   return a;
}
/* ======================================================================= */
/* Converts date formats */
/* Returns FALSE if invalid date (check with ===) */
/* infmt = mm/dd/yyyy, isodate, dateobj */
/* outfmt = mm/dd/yyyy, isodate, dateobj (if not passed, just validate and return TRUE if valid) */
function convDate(indate, infmt, outfmt) {
   switch(infmt) {
      case 'mm/dd/yyyy':
         var datepatt = /^([01]?[0-9])\/([0-3]?[0-9])\/([12][901][0-9][0-9])$/;
         var prs = indate.match(datepatt);
         if (prs == null)
            return false;
         var y = prs[3];
         var m = prs[1];
         var d = prs[2];
         break;
      case 'isodate':
         var datepatt = /^([12][901][0-9][0-9])-([01][0-9])-([0-3][0-9])$/;
         var prs = indate.match(datepatt);         
         if (prs == null)
            return false;
         var y = prs[1];
         var m = prs[2];
         var d = prs[3];
         break;
      case 'dateobj':
         var y = indate.getFullYear();
         var m = indate.getMonth() + 1;
         var d = indate.getDate();
         break;
      default:
         return false;
   }         
   var wdate = new Date(y, m-1, d);
   if (wdate.getMonth() != m-1 || wdate.getDate() != d || wdate.getFullYear() != y)
      return false;
   if (typeof(outfmt) == 'undefined')
      return true;
   switch(outfmt) {
      case 'mm/dd/yyyy':
         return (m + '/' + d + '/' + y);
      case 'isodate':
         if (m.length == 1)
            m = '0' + m;
         if (d.length == 1)
            d = '0' + d;
         return (y + '-' + m + '-' + d);
      case 'dateobj':
         return wdate;
      default:
         return false
   }
}

/* ======================================================================= */
/* Load external script from a URL */
function LoadScript(url) {
   var e = document.createElement("script");
   e.setAttribute('type', 'text/javascript');
   e.setAttribute('src', url);
   document.getElementsByTagName('head')[0].appendChild(e);
}
/* ======================================================================= */
function copy_to_clipboard(f) {

   // Copies passed text to the clipboard, from which it may be pasted

   // Firefox notes:
   //   Under about:config, must set signed.applets.codebase_principal_support to true
   //   To grant access to a web site without a warning prompt, enter the following in file
   //   \Documents and Settings\user-name\Application Data\Mozilla\Firefox\Profiles\profile-name\pref.js:
   //      user_pref("capability.principal.codebase.p0.granted", "UniversalXPConnect");
   //      user_pref("capability.principal.codebase.p0.id", "http://www.nebcaucus.com");
   //      user_pref("capability.principal.codebase.p0.subjectName", "");
   //   Each following site increments p (i.e. p0, p1, p2)   

   if (window.clipboardData||window.netscape) {
      if (!window.netscape) {
         if (!window.clipboardData.setData("Text",f)) {
            alert("Text was not copied to clipboard!");
            return false;
         }
      } else {
         try {
            netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
         } catch(e) {
            alert("Your current Internet Security settings do not allow data copying to clipboard. Text was not copied to clipboard!");
            return false;
         }
         try { 
            e = Components.classes["@mozilla.org/widget/clipboard;1"].createInstance(Components.interfaces.nsIClipboard);
         } catch(e) {
            return false;
         }
         try {
            b = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
         } catch(e) {
            return false;
         }
         b.addDataFlavor("text/unicode");
         o = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
         o.data = f;
         b.setTransferData("text/unicode", o, f.length*2);
         try {
            t = Components.interfaces.nsIClipboard;
         } catch(e) {
            return false;
         }
         e.setData(b, null, t.kGlobalClipboard);
      }
   } else {
      alert("Your browser doesn't support copy to clipboard feature. Please select text and press CTRL+C.");
      return false;
   }
}
/* ======================================================================= */
/* Custom alert that allows HTML text */
/***** NOTE: THIS IS JUST TEST CODE AND SHOULD NOT BE USED *****/
/* Script execution does NOT wait after execution */
/* URL path must be the path of images required (tp.png, alert.png) and may be relative */
/* URL path must include ending '/' */
function alertHTML(msg, title, button_text, url_path) {
   if (typeof(title) == 'undefined' || typeof(title) == 'object' || title == '')
      var a_title = "Alert";
   else
      var a_title = title;
   if (typeof(button_text) == 'undefined' || typeof(button_text) == 'object' || button_text == '')
      var a_button_text = 'OK';
   else
      var a_button_text = button_text;
   if (typeof(url_path) == 'undefined' || typeof(url_path) == 'object' || url_path == '')
      var a_url_path = '';
   else
      var a_url_path = url_path;
   d = document;
   if (d.getElementById("modalContainer")) return;  /* An alert is already on the page */
   mObj = d.getElementsByTagName("body")[0].appendChild(d.createElement("div"));  /* create container over entire body */
   mObj.id = "modalContainer";
   mObj.style.height = d.documentElement.scrollHeight + "px";
   mObj.style.backgroundColor = 'transparent';
   mObj.style.position = 'absolute';
   mObj.style.width = '100%';
   mObj.style.height = '100%';
   mObj.style.top = '0px';
   mObj.style.left = '0px';
   mObj.style.zIndex = 10000;
   mObj.style.backgroundImage = 'url(' + a_url_path + 'tp.png)';
   alertObj = mObj.appendChild(d.createElement("div"));   /* create div for alert box */
   alertObj.id = "alertBox";
   h1 = alertObj.appendChild(d.createElement("h1"));
   h1.appendChild(d.createTextNode(a_title)); /* add title line */
   h1.style.margin = 0;
   h1.style.font = 'bold 0.9em verdana, arial';
   h1.style.backgroundColor = '#78919B';
   h1.style.color = '#FFF';
   h1.style.borderBottom = '1px solid #000';
   h1.style.padding = '2px 0 2px 5px';
   alertObj.innerHTML += '<p style="font:0.7em verdana,arial;height:50px;padding-left:5px;margin-left:55px;">' + msg + '</p>'; /* add message HTML text */
   alertObj.style.position = 'fixed';
   alertObj.style.width = '300px';
   alertObj.style.minHeight = '100px';
   alertObj.style.marginTop = '50px';
   alertObj.style.border = '2px solid #000';
   alertObj.style.backgroundColor = '#F2F5F6';
   alertObj.style.backgroundImage = 'url(' + a_url_path + 'alert.png)';
   alertObj.style.backgroundRepeat = 'no-repeat';
   alertObj.style.backgroundPosition = '20px 30px';
   if(d.all && !window.opera) alertObj.style.top = document.documentElement.scrollTop + "px";
   alertObj.style.left = (d.documentElement.scrollWidth - alertObj.offsetWidth)/2 + "px";
   alertObj.style.visiblity="visible";
   btn = alertObj.appendChild(d.createElement("a"));   /* build OK button */
   btn.id = "closeBtn";
   btn.appendChild(d.createTextNode(a_button_text));
   btn.href = "#";
   btn.style.display = 'block';
   btn.style.position = 'relative';
   btn.style.margin = '5px auto';
   btn.style.padding = '3px';
   btn.style.border = '2px solid #000';
   btn.style.width = '70px';
   btn.style.font = '0.7em verdana,arial';
   btn.style.textAlign = 'center';
   btn.style.color = '#FFF';
   btn.style.backgroundColor = '#78919B';
   btn.style.textDecoration = 'none';
   btn.focus();
   btn.onclick = function() { removeCustomAlert();return false; }
   alertObj.style.display = "block";
}
function removeCustomAlert() {
	document.getElementsByTagName("body")[0].removeChild(document.getElementById("modalContainer"));
}

/* ======================================================================= */
/* Convert string to base64 */

function encode_base64(input) {
	var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
	var output = "";
	var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
	var i = 0;
   var nc2 = false, nc3 = false;
   var inl = input.length;
	while (i < inl) {
		chr1 = input.charCodeAt(i++);
      if (i < inl) {
		   chr2 = input.charCodeAt(i++);
         if (i < inl)
		      chr3 = input.charCodeAt(i++);
         else
            nc3 = true;
      } else
         nc2 = true;   
		enc1 = chr1 >> 2;
		enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
		enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
		enc4 = chr3 & 63;
		if (nc2) {
			enc3 = enc4 = 64;
		} else if (nc3) {
			enc4 = 64;
		}
		output = output +
		_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
		_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
 
	}
 	return output;
}

/* ======================================================================= */
/* Decode base64 string */

function decode_base64(input) {
	var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
	var output = "";
	var chr1, chr2, chr3;
	var enc1, enc2, enc3, enc4;
	var i = 0;
 	input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
 	while (i < input.length) {
      enc1 = _keyStr.indexOf(input.charAt(i++));
		enc2 = _keyStr.indexOf(input.charAt(i++));
		enc3 = _keyStr.indexOf(input.charAt(i++));
		enc4 = _keyStr.indexOf(input.charAt(i++));
 		chr1 = (enc1 << 2) | (enc2 >> 4);
		chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
		chr3 = ((enc3 & 3) << 6) | enc4;
		output = output + String.fromCharCode(chr1);
		if (enc3 != 64) {
			output = output + String.fromCharCode(chr2);
		}
		if (enc4 != 64) {
			output = output + String.fromCharCode(chr3);
		}
	}
return output;
}

/* ======================================================================= */
/* encode to hex */
function encodeToHex(str){
    var r="";
    var e=str.length;
    var c=0;
    var h;
    while(c<e){
        h=str.charCodeAt(c++).toString(16);
        while(h.length<3) h="0"+h;
        r+=h;
    }
    return r;
}

/* ======================================================================= */
/* decode from hex */
function decodeFromHex(str){
    var r="";
    var e=str.length;
    var s;
    while(e>=0){
        s=e-3;
        r=String.fromCharCode("0x"+str.substring(s,e))+r;
        e=s;
    }
    return r;
}

/* ======================================================================= */
/* Disable all elements of the specified type
   within the specified object
-------------------------------- */
function disableAll(obj,type) {
  oInput = obj.getElementsByTagName(type);
  for (i=0;i<oInput.length ;i++) {
    oInput[i].disabled = true;
  }
}

/* ======================================================================= */ 
/* Enable all elements of the specified type
   within the specified object
--------------------------------  */   
function enableAll(obj,type) {
  oInput = obj.getElementsByTagName(type);
  for (i=0;i<oInput.length ;i++) {
    oInput[i].disabled = false;
  }
}

/* ======================================================================= */ 
/* Clear the values of all elements of the specified type
   within the specified object
--------------------------------  */   
function clearAll(obj,type) {
  oInput = obj.getElementsByTagName(type);
  for (i=0;i<oInput.length ;i++) {
    try{oInput[i].value = '';}
    catch(e) {}
    try{oInput[i].checked = false;}
    catch(e) {}
  }
}

/* ======================================================================= */ 
/* Disable entire body (pass unique DIV id; must use same to enable) */
/* May pass an optional background color in #RRGGBB format */
function disableBody(divid, dbgcolor) {
  var e = document.createElement("div");
  e.id = divid;
  e.style.opacity = ".5";                  
  e.style.MozOpacity = ".5";               
  e.style.KhtmlOpacity = ".5";
  e.style.filter = "alpha(opacity=50)";
  e.style.position = "absolute";
  e.style.top = "0px";
  e.style.left = "0px";
  e.style.height = "100%";
  e.style.width = "100%";
  e.style.zIndex = "1";
  if (typeof(dbgcolor) != "undefined")
     e.style.backgroundColor = dbgcolor;
  var oContainer = document.body.appendChild(e);
  // if the document is longer than the screen height 
  if (document.body.offsetHeight + 24 > oContainer.offsetHeight)
    e.style.height = (document.body.offsetHeight + 24) + "px";
  disableAll(document.body,"input");
  disableAll(document.body,"select");
  disableAll(document.body,"textarea");
}

/* ======================================================================= */ 
/* Enable disabled entire body (pass unique DIV id used to disable) */
function enableBody(divid) {
  oDiv = document.getElementById(divid);
  document.body.removeChild(oDiv);
  enableAll(document.body,"input");
  enableAll(document.body,"select");
  enableAll(document.body,"textarea");
} 

/* ======================================================================= */ 
/* Disables selection for an element (i.e. document.body for entire page) */
/* MUST call at the END of a document */
function disableSelect(elem) {
   if (typeof elem.onselectstart!="undefined") //IE route
	   elem.onselectstart=function(){return false}
   else if (typeof elem.style.MozUserSelect!="undefined") //Firefox route
	   elem.style.MozUserSelect="none"
   else //All other route (ie: Opera)
	   elem.onmousedown=function(){return false}
   elem.style.cursor = "default"
}

/* ======================================================================= */ 
/* enable and make visible a field that is disabled (generally an input field)  */
/* sets focus on the field and selects the field if selectable  */
/* optionally may disable a field (set disable = true)  */
/* may set the background color and disable/hide the element that calls this function (pass: this)  */ 
function enableFld(fldname, bgcolor, disable, disablecallelem) {
   var fo = eid(fldname);
   if (typeof(bgcolor) != 'undefined' && bgcolor != '')
      fo.style.backgroundColor = bgcolor;
   if (typeof(disable) != 'undefined' && disable)
      fo.disabled = 'disabled';
   else {
      fo.disabled = '';
      fo.style.visibility = 'visible';
   }      
   if (typeof(disablecallelem) != 'undefined') {
      disablecallelem.disabled = 'disabled';
      disablecallelem.style.visibility = 'hidden';
   }
   if (fo.disabled != 'disabled')
      setTimeout("var x=eid('" + fldname + "');try{x.focus();} catch(e) {};try{x.select();} catch(e){};", 1);
}

/* ======================================================================= */ 
/* disable a field (generally an input field)  */
/* may set the background color and disable/hide the element that calls this function (pass: this)  */ 
function disableFld(fldname, bgcolor, disablecallelem) {
   var fo = eid(fldname);
   fo.disabled = 'disabled';
   if (typeof(bgcolor) != 'undefined')
      fo.style.backgroundColor = bgcolor;
   if (typeof(disablecallelem) != 'undefined') {
      disablecallelem.disabled = 'disabled';
      disablecallelem.style.visibility = 'hidden';
   }
   setTimeout("var x=eid('" + fldname + "');x.focus();x.select();", 1);
}

/* ======================================================================= */ 
// Determine whether the specified element is a member of the specified
// class. This function is optimized for the common case in which the
// className property contains only a single classname. But it also
// handles the case in which it is a list of whitespace-separated classes.
function isClsMbr(element, classname) {
  var classes = element.className;  // Get the list of classes
  if (!classes) return false;             // No classes defined
  if (classes == classname) return true;  // Exact match

  // We didn't match exactly, so if there is no whitespace, then
  // this element is not a member of the class
  var whitespace = /\s+/;
  if (!whitespace.test(classes)) return false;

  // If we get here, the element is a member of more than one class and
  // we've got to check them individually.
  var c = classes.split(whitespace);  // Split with whitespace delimiter
  for(var i = 0; i < c.length; i++) { // Loop through classes
      if (c[i] == classname) return true;  // and check for matches
  }
  return false;  // None of the classes matched
}

/* ======================================================================= */ 
// Replace a class name with a new class name
// Can remove a class name if the new class is an empty string
function rplCls(elem, oldclass, newclass) {
   if (elem.className == oldclass) {  // single class
      elem.className = newclass;
      return;
   }
   var rxp =  RegExp(oldclass + '\\s');
   var newcls = elem.className.replace(rxp, newclass + ' ');
   if (newcls != elem.className) {
      elem.className = newcls;
      return;
   }
   rxp = RegExp('\\s' + oldclass);
   newcls = elem.className.replace(rxp, ' ' + newclass);
   elem.className = newcls;
}

/* ======================================================================= */
/*  logout the logged on user by AJAX call of logout.php  */
var logout_cb = {
    success: function(o) {
       document.body.innerHTML = o.responseText;
    },
    failure: function(o) {
       document.body.innerHTML = '<b style="color:red;">Request timed out. Log out may not have completed.</b>';
    },
    timeout: 12000
}
function logout(server_URL) {
   var randno = new Date().getTime();
   var httprqs = 'http://' + server_URL + '/logout.php?__rand=' + randno;
   var co = YAHOO.util.Connect.asyncRequest('GET', httprqs, logout_cb);
}

/* ======================================================================= */
/*  effectively disable the browser back button (call setnoBack)  */
/*  call in the <HEAD> section                                    */
function setnoBack() {
   noBack();
   window.onload=noBack;
   window.onpageshow=function(evt){if(evt.persisted)noBack()}
   window.onunload=function(){void(0)}
}
function noBack(){window.history.forward()}

/* ======================================================================= */
/*  parse and posts AJAX parameters created by a PHP script from a database record  */
/*  pass the HTTP object returned from AJAX call
/*  uses the AJAX _AX constants to divide the parameters  */
/*  if postparms = true, posts the parameters to related HTML fields
/*    may optionally include a prefix which is appended to the field name to get the HTML field ID  */
/*    and always adds an 'i' to the field name  */
/*    optionally set postparmerrstr to a string that if found as a parm, the parm value is returned instead of true  */ 
/*  if postparms = false, returns an array with alternating field names and values  */
/*  returns FALSE if no parameters found  */
function AX_parseParms(httpobj, postparms, fldprefix, postparmerrstr) {
   if (!postparms) {
      var a = new Array();
      var ai = 0;
   }
   var fp = '';
   if (typeof(fldprefix) != 'undefined')
      fp = fldprefix;
   var postparmerr = '';
   if (typeof(postparmerrstr) != 'undefined')
      postparmerr = postparmerrstr;
   var rtnsts = true;
   var p = httpobj.responseText.indexOf('\n');
   var parms = httpobj.responseText.slice(p+1).match(/[^\x01]*\x01/g);
   if (parms !== null) {
      p = parms.length;
      if (p % 2 == 1)
         --p;
      for (var i=0; i<p; i++) {
         var fld = parms[i++];
         fld = fld.substr(0, fld.length-1);
         var val = parms[i];
         val = val.substr(0, val.length-1);
         if (postparms) {
            if (postparmerr != '' && fld == postparmerr)
               rtnsts = val;        
            var fo = eid(fp + fld + 'i');        
            AX_postParm(fo, val);
         } else {
            a[ai++] = fld;
            a[ai++] = val;
         }
      }
      if (postparms)
         return rtnsts;
      else
         return a;
   }
   return false;
}

/* ======================================================================= */
/*  process an AJAX parm returned from an AJAX call  */
/*  fo = field object to process  */
/*  val = value to either set object to, or object status */
function AX_postParm(fo, val) {
   try {
      if (val == _AX_UNCK)
         fo.checked = false;
      else if (val == _AX_CK)
         fo.checked = true;
      else if (val == _AX_DISABLE)
         fo.disabled = 'disabled';
      else if (val == _AX_ENABLE)
         fo.disabled = '';
      else if (val == _AX_HIDE)
         fo.style.visibility = 'hidden';
      else if (val == _AX_VISIBLE)
         fo.style.visibility = 'visible';
      else if (val == _AX_DISP_YES)
         fo.style.display = '';
      else if (val == _AX_DISP_NO)
         fo.style.display = 'none';
      else if (val.substr(0,1) == _AX_SLC || val.substr(0,1) == _AX_SLC_CK) {
         var x = 0;
         var j = 0;
         fo.options.length = 0;
         if (val.length <= 1)  /* empty selection entry */
            x = -1;
         var rtna = new Array();
         while (x >= 0) {
            rtna = AX_parseSlc(val, x, fo, j++);
            x = rtna[0];
         }
      } else if (val.substr(0,1) == _AX_CMD)
         eval(val.substr(1));     
      else if (val >= ' ' || val == '')
         fo.value = val;
   } catch(e) {}
}


/* ======================================================================= */
/*  returns an AJAX http request from input fields, with a __rand field  */
/*  includes text, hidden, password, textarea and select fields  */
/*  password fields are encrypted  */
/*  may optionally pass a prefix which all field names must start with  */
function AX_input_httprqs(fldprefix) {
   var pf = '';
   var pflng = 0;
   if (typeof(fldprefix) != 'undefined') {
      pf = fldprefix;
      pflng = fldprefix.length;
   }
   var httprqs = '&__rand=' + new Date().getTime();
   var inflds = document.getElementsByTagName('input');   // input fields
   for (var i = 0; i < inflds.length; i++) {
      var inobj = inflds[i];
      if (!inobj.disabled) {
         if (pflng > 0 && (inobj.name.length < pflng || inobj.name.substr(0, pflng) != pf))
            continue;
         var iname = inobj.name.substr(pflng);
         var intype = inobj.type;
         if (intype == 'text' || intype == 'hidden')
            httprqs += '&' + iname + '=' + encodeURIComponent(inobj.value);
         else if (intype == 'password')
            httprqs += '&' + iname + '=' + encodeURIComponent(Encrypt(inobj.value));               
         else if (intype == 'checkbox') {
            var ckval = '0';
            if (inobj.checked)
               ckval = '1';
            httprqs += '&' + iname + '=' + ckval;
         }
      }
   }
         
   inflds = document.getElementsByTagName('textarea');  // textarea fields
   for (i = 0; i < inflds.length; i++) {
      var inobj = inflds[i];
      if (!inobj.disabled) {
         if (pflng > 0 && (inobj.name.length < pflng || inobj.name.substr(0, pflng) != pf))
            continue;
         var iname = inobj.name.substr(pflng);
         httprqs += '&' + iname + '=' + encodeURIComponent(inobj.value.replace(/\r/g, ''));  // IE inserted \r must be removed
      }
   }
         
   inflds = document.getElementsByTagName('select');  // select fields (repeats if multiple select)
   for (i = 0; i < inflds.length; i++) {
      var inobj = inflds[i];
      if (!inobj.disabled) {
         if (pflng > 0 && (inobj.name.length < pflng || inobj.name.substr(0, pflng) != pf))
            continue;
         var iname = inobj.name.substr(pflng);       
         if (!inobj.multiple)
            httprqs += '&' + iname + '=' + encodeURIComponent(inobj.value);
         else {
            for (var j = 0; j < inobj.options.length; j++) 
               if (inobj.options[j].selected)
                  httprqs += '&' + iname + '=' + encodeURIComponent(inobj.options[j].value);
         }
      }
   }
   return(httprqs);
}   

/* ======================================================================= */
/* Parses an AJAX Select string */
/* Each call returns a value, description, and whether selected or not, in an array */
/* If a select object is passed, options will be added to the Select element */
/* (select index is required for IE; start from 0) */
/* Return array: 0 = Returns the next position to start at, or -1 if done */
/*               1 = Value */
/*               2 = Description */
/*               3 = true, if selected */
/* NOTE: First position must be _AX_SLC or _AX_SLC_CK */
function AX_parseSlc(infld, infld_start, select_obj, select_obj_idx)
{
   var rtna = new Array(-1, '', '', false);
   var infld_lng = infld.length;
   if (infld_start >= infld_lng)
      return rtna;
   var prs = infld.substr(infld_start).match(/([\x04\x05])([^\x04\x05\x06]*)\x06?([^\x04\x05\x06]*)/);
   if (prs !== null) {
      if (prs[1] == _AX_SLC_CK)
         rtna[3] = true;
      rtna[1] = prs[2];
      rtna[2] = prs[3];
      rtna[0] = infld_start + prs[0].length;
      if (select_obj) {
         var xo = new Option(rtna[2], rtna[1], false, rtna[3]);     
         try {select_obj.add(xo, null);}
         catch(e) {select_obj.add(xo, select_obj_idx);}  /* IE requires index (not in compliance with DOM) */
      }
   }
   return rtna;
}

