//	menuInvokeME - Used to call function given menu entry #
var menuForm = null ;
function menuInvokeSetForm(formName) {
   menuForm = document.forms[formName] ;
}
function menuInvokeME(mEntry) {
  var x = new Object() ; x.mEntry = 0 ; x.argCount = 1 ; x.func = 2 ; x.confirm = 3 ; x.v4 = 4 ; x.otherArgs = 5 ;
  var me ; for(me=0;me<mEntryList.length;me++) { if (mEntry == mEntryList[me][x.mEntry]) break ; } ;
  if (mEntryList[me][x.confirm].length > 0) { if (!window.confirm(mEntryList[me][x.confirm])) return(false) ; } ;
  if (mEntryList[me][x.argCount] == 0) {  menuForm._AltFunc.value = mEntryList[me][x.func] ; }
   else { menuForm._AltFunc.value = 'menuJobSetupDriver' ; mEntryList[me][x.otherArgs] += ' func:' + mEntryList[me][x.func] ;
	} ;
  menuForm._V4.value = (mEntryList[me][x.v4].length > 0 ? mEntryList[me][x.v4] : "Process") ;
  if (mEntryList[me][x.otherArgs].length > 0) { menuForm.otherArgs.value = mEntryList[me][x.otherArgs] ; menuForm.otherArgs.disabled = false ; }
   else if (mEntryList[me][x.argCount] > 0) { menuForm.otherArgs.disabled = false ; }
   else { menuForm.otherArgs.disabled = true ; } ;
  menuForm.submit() ;
  return false ;
}
function fsurEval(fsur) {	//Evaluate predefined func setup
  menuForm._AltFunc.value = 'xlbRunPredefJob' ;
  menuForm.otherArgs.value = 'fsur:'+fsur ;
  menuForm._V4.value = 'Process' ;
  menuForm.submit() ;
}

//	menuGoToDiv - Javascript to ensure that menu 'goto' shortcuts always appear at same position in window
var mgtCount = 0 ;
function menuSetupFloatingGoto()
{ var startX = 500, startY = 250;
  var ns = (navigator.appName.indexOf("Netscape") != -1);
  function menuRepositionDiv(id)
	{ var el = document.getElementById(id) ;
	  el.menuStayPut = function(x,y) { this.style.left =x ; this.style.top = y ; } ;
	  el.x = startX ; el.y = startY ;
	  return(el) ;
	}
  window.menuGotoKeepInPlace=function()
	{ ftlObj = (document.getElementById("menuGotoDiv").style.display == "none" ? menuRepositionDiv("menuGotoDivMinimized") :  menuRepositionDiv("menuGotoDiv")) ;
	  var pY = ns ? window.pageYOffset : document.documentElement.scrollTop ;
	  ftlObj.y += (pY + startY - ftlObj.y) ;
	  ftlObj.menuStayPut(ftlObj.x, ftlObj.y) ;
	  setTimeout("menuGotoKeepInPlace()", 10) ;
	}
	menuGotoKeepInPlace() ;
}

//	md5Hash - MD5 Hash Functions
/* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/* Configurable variables. You may need to tweak these to be compatible with the server-side, but the defaults work in most cases. */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/* These are the functions you'll usually want to call They take string arguments and return either hex or base-64 encoded strings */
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }

/* Perform a simple self-test to see if the VM is working */
function md5_vm_test() { return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; }

/* Calculate the MD5 of an array of little-endian words, and a bit length */
function core_md5(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a =  1732584193, b = -271733879, c = -1732584194, d =  271733878;
  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a, oldb = b, oldc = c, oldd = d;

    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return Array(a, b, c, d);

}

/* These functions implement the four basic operations the algorithm uses. */
function md5_cmn(q, a, b, x, s, t) { return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); }
function md5_ff(a, b, c, d, x, s, t) { return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); }
function md5_gg(a, b, c, d, x, s, t) { return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); }
function md5_hh(a, b, c, d, x, s, t) { return md5_cmn(b ^ c ^ d, a, b, x, s, t); }
function md5_ii(a, b, c, d, x, s, t) { return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); }

/* Calculate the HMAC-MD5, of a key and some data */
function core_hmac_md5(key, data)
{ var bkey = str2binl(key);
  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5C5C5C5C; }
  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
  return core_md5(opad.concat(hash), 512 + 128);
}

/* Add integers, wrapping at 2^32. This uses 16-bit operations internally to work around bugs in some JS interpreters. */
function safe_add(x, y)
{ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/* Bitwise rotate a 32-bit number to the left. */
function bit_rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); }

/* Convert a string to an array of little-endian words. If chrsz is ASCII, characters >255 have their hi-byte silently ignored. */
function str2binl(str)
{ var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  return bin;
}

/* Convert an array of little-endian words to a string  */
function binl2str(bin)
{ var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
  return str;
}

/* Convert an array of little-endian words to a hex string. */
function binl2hex(binarray)
{ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  { str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF); }
  return str;
}

/* Convert an array of little-endian words to a base-64 string */
function binl2b64(binarray)
{ var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  { var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    { if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
       else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

//	slpLogin - Hash password for secure application login
function slpLogin() {
  var formNandP = document.forms['slpNandPForm'] ;
  if (formNandP.wwwUserName.value.length == 0 || formNandP.wwwUserPWHash.value.length == 0)
   { alert("Please enter user name and password.") ; return(false) ; } ;
  var formXmit = document.forms['slpXmitForm'] ;
  formXmit.wwwUserPWHash.value = hex_md5(sesKey+formNandP.wwwUserPWHash.value) ;
  formXmit.wwwUserName.value = formNandP.wwwUserName.value ;
  formXmit.wwwBrowserProps.value = 
		"Height=" + document.body.clientHeight + "|Width=" + document.body.clientWidth + "|"
		+ "Browser=" + navigator.appName + "|Cookies=" + navigator.cookieEnabled + "|"
		+ "Language=" + navigator.systemLanguage + "|Platform=" + navigator.platform + "|"
  formXmit.submit() ;
  return(true) ;
}
function slpClearNandP() {
  var form = document.forms['slpNandPForm'] ; 
  form.wwwUserName.value = '' ; form.wwwUserPWHash.value = '' ;
  form.wwwUserName.focus() ;
}

//	jsuSubmit - 'Submit' code for job-setup pages
function jsuSubmit() {
    var form = document.forms['jsuForm'] ;
//  First make sure that all required inputs have been filled
    for(var i=0;i<argInfo.length;i++)
     { var arg = argInfo[i] ;
       if (arg[aiObj.optional]) continue ; if (arg[aiObj.type].toLowerCase() == 'logical') continue ;
       if (formGetElValue(form,arg[aiObj.name]).length > 0) continue ;
       alert("Required value for argument ("+arg[aiObj.prompt]+") is missing") ; form.elements[arg[aiObj.name]].focus() ; return(false) ;
     } ;
//  OK to submit, let's go
    form.submit() ;
    return(false) ;
}

//	formClearElValue - Clears form element
function formClearElValue(el) {
     switch (el.type)
      { case 'button':
	   return(false) ;			//Can't set button value
	case 'radio':
        case 'checkbox':
	   el.checked = false ; return(true) ;
	case 'select-one':
	case 'select-multiple':
	   el.selectedIndex = -1 ;
	   for (var j=0;j<el.options.length;j++)
	    { if (!el.options[j].defaultSelected) continue ;
	      el.options[j].selected = true ; if (el.selectedIndex < 0) el.selectedIndex = j ;
	    } ;
	   if (el.selectedIndex < 0) el.selectedIndex = 0 ;
	   return(true) ;
	case 'text': case 'textarea':
	   el.value = '' ; return(true) ;
      } ;
     return(false) ;
}

//	formSetElValue - Sets form element to 'val' based on el.type, returns true if OK, false if problems
function formSetElValue(el,val) {		//Set form element to val based on element type
     switch (el.type)
      { case 'button':
	   return(false) ;			//Can't set button value
	case 'radio':
        case 'checkbox':
	   switch ((val+"").substring(0,0))
	    { case 'y': case 'Y': case 't': case 'T': case '1':		el.checked = true ; return(true) ;
	      default:							el.checked = false ; return(true) ;
	    } ;
	   break ;
	case 'select-one':
	case 'select-multiple':
	   for (var j=0;j<el.options.length;j++)
	    { if (el.options[j].text.toLowerCase() == val.toLowerCase()) { el.selectedIndex = j ; el.options[j].selected = true ; } ; } ;
	   return(true) ;
	case 'text': case 'textarea':
	   el.value = val ; return(true) ;
      } ;
     return(false) ;
}

//	formGetElValue - Returns value of element within form
//	getFormElVal(elObj), getFormElVal(form,elname)
function formGetElValue() {
  var inpFld ;
  if (arguments.length == 1) { inpFld = arguments[0] ; }
   else { if (typeof arguments[1] == 'object') { inpFld = arguments[1] ; }
	   else { var form = (typeof arguments[0] == 'object' ? arguments[0] : document.forms[arguments[0]]) ;
		  inpFld = form.elements[arguments[1]] ;
		} ;
	} ;
  if (typeof inpFld == 'undefined') { alert("inpFld undefined, form:"+arguments[0]+", elname:"+arguments[1]) ; return("") ; } ;
  switch (inpFld.type)
   { case 'button':
	break ;
     case 'radio':
     case 'checkbox':
	return(inpFld.checked ? true : false) ;
     case 'select-one':
	return(inpFld.options[inpFld.selectedIndex].value.length > 0 ? inpFld.options[inpFld.selectedIndex].value : inpFld.options[inpFld.selectedIndex].text) ;
     case 'select-multiple':
	var res = '' ;
	for (var j=0;j<inpFld.options.length;j++)
	 { if (!inpFld.options[j].selected) continue ;
	   if (res.length > 0) res += ',' ; res += (inpFld.options[j].value.length > 0 ? inpFld.options[j].value : inpFld.options[j].text) ;
	 } ;
	return(res) ;
     case 'text': case 'textarea': case 'hidden': case 'file':
	return(inpFld.value) ;
   } ;
}

//	formIsElChanged - Returns true if form element has changed, false if the same
//	formIsElChanged(elObj), getFormElVal(form,elname)
function formIsElChanged() {
  var inpFld ;
  if (arguments.length == 1) { inpFld = arguments[0] ; }
   else { if (typeof arguments[1] == 'object') { inpFld = arguments[1] ; }
	   else { var form = (typeof arguments[0] == 'object' ? arguments[0] : document.forms[arguments[0]]) ;
		  inpFld = form.elements[arguments[1]] ;
		} ;
	} ;
  switch (inpFld.type)
   { default:
	return(false) ;
     case 'button':
	return(false) ;
     case 'radio':
     case 'checkbox':
	return(inpFld.checked != inpFld.defaultChecked) ;
     case 'select-one':
	if (inpFld.selectedIndex < 0) return(false) ;
	return(!inpFld.options[inpFld.selectedIndex].defaultSelected) ;
     case 'select-multiple':
	for (var j=0;j<inpFld.options.length;j++)
	 { if (inpFld.options[j].checked != inpFld.options[j].defaultSelected) return(true) ;
	 } ;
	return(false) ;
     case 'text': case 'textarea': case 'hidden':
	return(!(inpFld.value === inpFld.defaultValue)) ;
   } ;
}

//	formToXML - Converts HTML form inputs to XML string
function formToXML(formObj,formWrapper,wantOnlyChanged) {
  var msg = '' ;
  for(var i=0; i < formObj.elements.length ; i++)
   { var feObj = formObj.elements[i] ;
     if (wantOnlyChanged ? formIsElChanged(feObj) : true)
      msg += '<'+feObj.name+'>'+formGetElValue(feObj)+'</'+feObj.name+'>'
   } ;
  if (msg.length > 0 && formWrapper.length > 0) msg = "<" + formWrapper + ">" + msg + "</" + formWrapper + ">" ;
  return(msg) ;
}

//	htmlTableToXML - Converts HTML table with rows of input into corresponding XML string, false if the same
  var xmlStr, rowNum ;
function htmlTableToXML(idTable,wantAll) {
  var tObj = document.getElementById(idTable) ;
  rowNum = 0 ;
  xmlStr = '' ;
  if (wantAll) { htmlTableToXMLAll(tObj) ; }
   else { htmlTableToXMLChanged(tObj) ; } ;
  if (xmlStr.length > 0) xmlStr =  '<'+idTable+'>' + xmlStr + '</'+idTable+'>' ;
  return(xmlStr) ;
}

function htmlTableToXMLAll(dobj) {
  for (var i=0;i<dobj.childNodes.length;i++)
   { if (dobj.childNodes[i].nodeType != 1) continue ;
     var nobj = dobj.childNodes[i] ;
     switch (nobj.nodeName)
      { case 'TBODY':
	   rowNum = 0 ; break ;		//Reset rowNum (don't want to count TR's in table header section)
        case 'TR':
//	   xmlStr += '<tr>' ;
	   rowNum++ ; xmlStr += '<rowNum>'+rowNum+'</rowNum>' ;
	   htmlTableToXMLAll(dobj.childNodes[i]);
//	   xmlStr += '</tr>' + '<br/>' ;
	   continue ;
	case 'INPUT':
	case 'SELECT':
	case 'TEXTAREA':
	   xmlStr += '<' + nobj.name + '>' + formGetElValue(nobj) + '</' + nobj.name + '>' ; break ;
      } ;
     htmlTableToXMLAll(dobj.childNodes[i]);
   } ;  
} 

  var rowHasChanged ;
function htmlTableToXMLChanged(dobj) {
  for (var i=0;i<dobj.childNodes.length;i++)
   { if (dobj.childNodes[i].nodeType != 1) continue ;
     var nobj = dobj.childNodes[i] ;
     switch (nobj.nodeName)
      { case 'TBODY':
	   rowNum = 0 ; break ;		//Reset rowNum (don't want to count TR's in table header section)
        case 'TR':
	   var xmlStrSave = xmlStr ; rowHasChanged = false ;
//	   xmlStr += '<tr>' ;
	   rowNum++ ; xmlStr += '<row rowNum='+rowNum+'>' ;
	   htmlTableToXMLChanged(dobj.childNodes[i]) ;
	   xmlStr += '</row>' ;
//	   xmlStr += '</tr>' + '<br/>' ;
	   if (!rowHasChanged) xmlStr = xmlStrSave ;
	   continue ;
	case 'INPUT':
	case 'SELECT':
	case 'TEXTAREA':
	    if(formIsElChanged(nobj))
	     { rowHasChanged = true ; xmlStr += '<' + nobj.name + '>' + formGetElValue(nobj) + '</' + nobj.name + '>' ; } ;
	   break ;
      } ;
     htmlTableToXMLChanged(dobj.childNodes[i]);
   } ;  
} 

//	verifyNum - Returns true if input field is a valid (floating) number, false otherwise
function verifyNum(field)
{ if (field.type != 'text') return ;
  if (field.value.length == 0) field.value = '0' ;
  var DotDotList = field.value.split("..") ;
  for (i = 0 ; i < DotDotList.length ; i++)
   { var CommaList = DotDotList[i].split(",") ;
     for (j = 0 ; j < CommaList.length ; j++)
       { 
         if (isNaN(CommaList[j]))
          { alert("Not a valid number - " + CommaList[j]) ; field.value = field.defaultValue ; return(false) ; }
       }
   }
  return(true) ;
}

//	verifyTime - Returns true if input field is a valid time, false otherwise
function verifyTime(field)
{ if (field.type != 'text') return ;
  if (field.value.length == 0) field.value = '0:00' ;
  var timeList = field.value.split(":") ;
  if (timeList.length == 1) { field.value = "00:" + field.value + ":00" ; timeList = field.value.split(":") ; } ;
  for (j = 0 ; j < timeList.length ; j++)
   { if (isNaN(timeList[j]))
      { alert("Not a valid time - " + field.value) ; field.value = field.defaultValue ; return(false) ; }
   } ;
  return(true) ;
}

//	verifyUSD - Returns true if input field is a valid (US) dollar amount, false otherwise
function verifyUSD(field)
{ if (field.type != 'text') return ;
  if (field.value.length == 0) field.value = '0' ;
  if (isNaN(field.value))
   { alert("Not a valid USD amount - " + field.value) ; field.value = field.defaultValue ; return(false) ; } ;
  field.value = parseFloat(field.value).toFixed(2) ;
  return(true) ;
}

//	verifyUDate - Returns true if input field is a valid Date, false otherwise
//	no definition supplied

//	verifyUDT - Returns true if input field is a valid UDT, false otherwise
function verifyUDate(field)
{ if (field.type != 'text') return ;
  var DotDotList = field.value.split("..") ;
  for (i = 0 ; i < DotDotList.length ; i++)
   { var CommaList = DotDotList[i].split(",") ;
     for (j = 0 ; j < CommaList.length ; j++)
       { if (verifyUDate1(field,CommaList[j])) continue ;
         field.value = field.defaultValue ; return(false) ;
       }
   }
  return(true) ;
}
function verifyUDate1(field,val)
{ var m, d, y, maxday, dmy ;
	if (val == 'none' || val == 'NONE') return(true) ;
	if (val.search('/') >= 0)
	 { mdy = val.split('/') ;
	   if (mdy.length != 3)
	    { alert('Date ('+val+') must be of form(1) mm/dd/yy or dd-mmm-yy - ' + field.name) ; return(false) ; } ;
	   d = (isNaN(parseInt(mdy[1],10)) ? 0 : parseInt(mdy[1],10)) ;
	   m = (isNaN( parseInt(mdy[0],10)) ? 0 : parseInt(mdy[0],10)) ;
	   if (m < 1 || m > 12)
	    { alert('Month (' + m + ') must be 1-12 - ' + field.name) ; return(false) ; } ;
	   y = (isNaN(parseInt(mdy[2])) ? -1 : parseInt(mdy[2],10)) ;
	 } else
	 { dmy = val.split('-') ;
	   if (dmy.length != 3)
	    { alert('Date ('+val+') must be of form(2) mm/dd/yy or dd-mmm-yy - ' + field.name) ; return(false) ; } ;
	   d = (isNaN(parseInt(dmy[0],10)) ? 0 : parseInt(dmy[0],10)) ;
	   m = dmy[1] ;
	   if ("jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec,".search(m.toLowerCase() + ",") < 0)
	    { alert('Month (' + m + ') not a recognized month - ' + field.name) ; return(false) ; } ;
	   y = (isNaN(parseInt(dmy[2],10)) ? -1 : parseInt(dmy[2],10)) ;
	 } ;
	switch(m)
	 { case 1: case 3: case 5: case 7: case 8: case 10: case 12:
		maxday = 31 ; break ;
	   case 2:
		maxday = ((y % 4) == 0 ? 29 : 28) ; break ;
	   case 4: case 6: case 9: case 11:
		maxday = 30 ; break ;
	 } ;
	if (d < 1 | d > maxday) { alert('Day must be 1 thru ' + maxday + ' - ' + field.name) ; return(false) ; } ;
	if (y < 0 || (y > 99 && y < 1990) || y > 2050)
	 { alert('Year must be 00-99 or 1990-2050 - ' + field.name) ; return(false) ; } ;
	return(true) ;
}

//	verifyInt - Returns true if field is valid integer value, false otherwise
function verifyInt(field)
{ if (field.type != 'text') return ;
  var val = formGetElValue(field) ;
  if (val.length == 0) field.value = '0' ;
  var DotDotList = val.split("..") ;
  for (i = 0 ; i < DotDotList.length ; i++)
   { var CommaList = DotDotList[i].split(",") ;
     for (j = 0 ; j < CommaList.length ; j++)
       { 
         if (isNaN(CommaList[j]))
          { alert("Not a valid number - " + CommaList[j]) ; field.value = field.defaultValue ; return(false) ; }
       }
   }
  return(true) ;
}

//	ajax - Routines for calling via AJAX and getting response
var ajaxRetryCount ;
var ajaxCallOK ;
var ajaxCallFail ;
var ajaxObj ;
var ajaxArgs ;
var jObj ;

function ajax(v4Mod, v4Args, callOK, callFail) { 
  ajaxRetryCount = 5 ;		//Max number of retries if send error
  try { 
	if (window.ActiveXObject) { ajaxObj = new ActiveXObject("Microsoft.XMLHTTP") ; }
	 else if (window.XMLHttpRequest) { ajaxObj = new XMLHttpRequest() ; }
	 else { alert("Cannot process request, XMLHttpRequest not implemented") ; return(false) ; } ;
      } catch(ex) { alert("Error in Ajax Init:"+ex.description) ; } ;

  ajaxCallOK = callOK ; ajaxCallFail = callFail ;	//Save these for response handler
  ajaxObj.onreadystatechange = function() { ajaxResponseFunc(ajaxCallOK, ajaxCallFail)  ; }
  ajaxArgs = "_Func=ajaxDriver&_v4=ajax&ajaxMod=" + v4Mod ;
  if (v4Args.substr(0,1) != '&') ajaxArgs += '&' ;
  ajaxArgs += v4Args ;
//Delete following line when running for real - this is ONLY for testing ********************
//  ajaxArgs += "&_Area=1&_leKey=12333" ;
  try {	ajaxObj.open('POST', ajaxAction, true) ; }
	catch(ex) { alert("Error in Ajax Open POST:"+ex.description) ; } ;
  try {
	ajaxObj.setRequestHeader("Content-length", ajaxArgs.length);
	ajaxObj.send(ajaxArgs) ;
      } catch(ex) { alert("Error in Ajax Send:"+ex.description) ; } ;
  return(true) ;
}
function ajaxResponseFunc(callOK,callFail) { 
  if (ajaxObj.readyState != 4) return ;
  if (ajaxObj.status != 200)		//If not 200 then got HTTP/network error
   { if (ajaxRetryCount <= 0) return ;
     alert("Waiting for server... ("+ajaxObj.status+"). CLICK OK.  "+ajaxRetryCount) ;
     ajaxRetryCount-- ;
     if (window.ActiveXObject) { ajaxObj = new ActiveXObject("Microsoft.XMLHTTP") ; }
      else if (window.XMLHttpRequest) { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); ajaxObj = new XMLHttpRequest() ; }
      else { alert("Cannot process request, XMLHttpRequest not implemented") ; return(false) ; } ;
     ajaxObj.onreadystatechange = function() { ajaxResponseFunc(ajaxCallOK, ajaxCallFail)  ; } ;
     ajaxObj.open('POST', ajaxAction, true) ;
     ajaxObj.setRequestHeader("Content-length", ajaxArgs.length);
     ajaxObj.send(ajaxArgs) ;
   } ;
//AJAX returns, linkup OK, let's see if V4 also OK
  ajaxArgs = '' ;
  try {jObj = eval("("+ajaxObj.responseText+")") ;
      }
  catch(ex) { alert('Server processsing errors?\n'+ex.description) ; alert(ajaxObj.responseText) ; return ; } ;
  if (jObj.meta.status == 'fail' || jObj.meta.status == 'error' || jObj.meta.status == 'warn') 
   { var failList, ix ;
     try
      { if (callFail.length > 0)
	 { failList = callFail.split(";") ;
	   for(var ix=0;ix<failList.length;ix++)
	    { eval(failList[ix]) ; } ;
	 } else { alert("ERROR: "+jObj.meta.msg) ; }
      } catch(ex) { alert("Problem in AJAX fail handler: "+failList[ix]+": "+ex.description+"\nPlease WRITE IT DOWN and report to MKS.") ; }
     return ;
   } ;
//Here if AJAX call to V4 OK
  var ix, okList ;   
  try
   { 	 
     if (callOK.length > 0)
      { okList = callOK.split(";") ; 
        for(ix=0;ix<okList.length;ix++)
         { eval(okList[ix]) ; } ;
      } ;
   } catch(ex) { alert("Problem in ajax OK handler "+okList[ix]+": "+ex.description+"\nPlease WRITE IT DOWN and report to MKS.") ; }
}

//	ddMenuV4 - Routines for Implementing V4 Logo/DropDown Menu
var ddMenu={
msMenuGoneOnMouseOut: 250, 
//ddIndicatorImg: '<img src="downarrow.gif" border="0" />',
stepsAnimateShowMenu: 10, //If > 0 then animate menu display in x number of steps

objDropMenu: null, asscmenuitem: null, supportForDOM: document.all || document.getElementById, standardbody: null, iframeshimadded: false, revealtimers: {},

getposOffset:function(what, offsettype){
  var totaloffset = (offsettype == "left") ? what.offsetLeft : what.offsetTop ;
  var parentEl = what.offsetParent ;
  for (;parentEl!=null;)
   { totaloffset=(offsettype=="left")? totaloffset+parentEl.offsetLeft : totaloffset+parentEl.offsetTop; parentEl=parentEl.offsetParent; } ;
  return(totaloffset) ;
},
cssModify:function(el, targetclass, action){
  var needle=new RegExp("(^|\\s+)"+targetclass+"($|\\s+)", "ig") ;
  switch (action)
   { case "check":	return(needle.test(el.className)) ;
     case "remove":	el.className = el.className.replace(needle, "") ; break ;
     default:		if (action == "add" && !needle.test(el.className)) { el.className += " "+targetclass ; } ; break ;
   } ;
},
menuShow:function(dropmenu, e){
  if (this.stepsAnimateShowMenu > 0)
   { if (!dropmenu._trueheight || dropmenu._trueheight<10) dropmenu._trueheight=dropmenu.offsetHeight ;
     clearTimeout(this.revealtimers[dropmenu.id])
     dropmenu.style.height=dropmenu._curheight = 0 ;  dropmenu.style.overflow = "hidden" ; dropmenu.style.visibility = "visible" ;
     this.revealtimers[dropmenu.id]=setInterval(function(){ddMenu.menuReveal(dropmenu)}, 10) ;
   } else{ dropmenu.style.visibility="visible" ; } ;
  this.cssModify(this.asscmenuitem, "selected", "add")
},
menuReveal:function(dropmenu, dir) {
  var curH=dropmenu._curheight, maxH=dropmenu._trueheight, steps=this.stepsAnimateShowMenu ;
  if (curH<maxH){ var newH=Math.min(curH, maxH) ; dropmenu.style.height=newH+"px" ; dropmenu._curheight= newH + Math.round((maxH-newH)/steps) + 1 ; }
   else { dropmenu.style.height="auto" ; dropmenu.style.overflow="hidden" ; clearInterval(this.revealtimers[dropmenu.id]) ; } ;
},
clearbrowseredge:function(obj, whichedge){
	var edgeoffset=0
	if (whichedge=="rightedge"){
		var windowedge=document.all && !window.opera? this.standardbody.scrollLeft+this.standardbody.clientWidth-15 : window.pageXOffset+window.innerWidth-15
		var dropmenuW=this.objDropMenu.offsetWidth
		if (windowedge-this.objDropMenu.x < dropmenuW)  //move menu to the left?
			edgeoffset=dropmenuW-obj.offsetWidth
	}
	else{ var topedge=document.all && !window.opera? this.standardbody.scrollTop : window.pageYOffset ;
	      var windowedge=document.all && !window.opera? this.standardbody.scrollTop+this.standardbody.clientHeight-15 : window.pageYOffset+window.innerHeight-18
		var dropmenuH=this.objDropMenu._trueheight
		if (windowedge-this.objDropMenu.y < dropmenuH){ //move up?
			edgeoffset=dropmenuH+obj.offsetHeight
			if ((this.objDropMenu.y-topedge)<dropmenuH) //up no good either?
				edgeoffset=this.objDropMenu.y+obj.offsetHeight-topedge
		}
	}
	return edgeoffset
},
dropMenu:function(obj, e, idDropMenu){
  if (this.objDropMenu != null)	this.hideMenu() ; //hide menu
  this.clearhidemenu() ;
  this.objDropMenu=document.getElementById(idDropMenu) ;
  this.asscmenuitem=obj ;
  this.menuShow(this.objDropMenu, e) ;
  this.objDropMenu.x = this.getposOffset(obj, "left") ;
  this.objDropMenu.y = this.getposOffset(obj, "top") ;
  this.objDropMenu.style.left=this.objDropMenu.x-this.clearbrowseredge(obj, "rightedge")+"px" ;
  this.objDropMenu.style.top=this.objDropMenu.y-this.clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+1+"px" ;
},
isContained:function(m, e){
  var e = window.event || e ;
  var c = e.relatedTarget || ((e.type=="mouseover") ? e.fromElement : e.toElement) ;
  for (;c && c != m;) { try { c = c.parentNode ; } catch(e) {c = m ; } ; } ;
  return (c == m) ;
},
hideDynamic:function(m, e){
 if (!this.isContained(m,e)) this.hideMenuDelayed() ;
},
hideMenuDelayed:function(){ this.objHideTimer = setTimeout("ddMenu.hideMenu()", this.msMenuGoneOnMouseOut) ;
},
hideMenu:function(){
 this.cssModify(this.asscmenuitem, "selected", "remove") ;
 this.objDropMenu.style.visibility = 'hidden' ;
 this.objDropMenu.style.left = this.objDropMenu.style.top = "-1000px" ;
},
clearhidemenu:function(){ if (this.objHideTimer != "undefined") clearTimeout(this.objHideTimer) ;
},
addEvent:function(target, functionref, tasktype){
  if (target.addEventListener) { target.addEventListener(tasktype, functionref, false) ; }
  else if (target.attachEvent) { target.attachEvent('on'+tasktype, function(){return functionref.call(target, window.event)}); } ;
},
menuV4Init:function(){
  if (!this.supportForDOM) return ;
  this.standardbody=(document.compatMode=="CSS1Compat")? document.documentElement : document.body
  for (var ids=0; ids<arguments.length; ids++)
   { var menuitems=document.getElementById(arguments[ids]).getElementsByTagName("a")
     for (var i=0; i<menuitems.length; i++)
      {	if (menuitems[i].getAttribute("rel"))
	 { var relvalue=menuitems[i].getAttribute("rel") ;
	   var asscdropdownmenu=document.getElementById(relvalue) ;
	   this.addEvent(asscdropdownmenu, function(){ddMenu.clearhidemenu()}, "mouseover") ;
	   this.addEvent(asscdropdownmenu, function(e){ddMenu.hideDynamic(this, e)}, "mouseout") ;
	   this.addEvent(asscdropdownmenu, function(){ddMenu.hideMenuDelayed()}, "click")
	   if (typeof this.ddIndicatorImg != "undefined") menuitems[i].innerHTML=menuitems[i].innerHTML+" "+this.ddIndicatorImg ;
	   this.addEvent(menuitems[i],
		 function(e){ //show drop down menu when main menu items are mouse over-ed
		   if (!ddMenu.isContained(this, e))
		    { var evtobj=window.event || e ; ddMenu.dropMenu(this, evtobj, this.getAttribute("rel")) ; } ;
		  }, "mouseover")
	   this.addEvent(menuitems[i], function(e){ddMenu.hideDynamic(this, e)}, "mouseout") //hide drop down menu when main menu items are mouse out
	   this.addEvent(menuitems[i], function(){ddMenu.hideMenuDelayed()}, "click") //hide drop down menu when main menu items are clicked on
	 } ;
      } ;
   } ;
 } 
}

//	balloonTooltips - Initialization JS for Balloon Help Tool Tips
// This function adds the default configuration and also custom configuration sets, specified in 'case' stanzas
BalloonConfig = function(balloon, set) {
  set = set || '';
  if (!balloon.configured || set == 'GBubble') {
    balloon.fontColor = 'black';
    balloon.fontFamily = 'Times';
    balloon.fontSize = '10pt';
    balloon.minWidth = 100;
    balloon.maxWidth = 400;
    balloon.delayTime = 750;
    balloon.vOffset = 10;
    balloon.hOffset = 10;
    balloon.stem = true;
    balloon.images = 'http://www.mksinc.com/scripts/jcdstatic/balloonTooltips/GBubble/';
    balloon.ieImage = 'balloon_ie.png';
    balloon.balloonImage = 'balloon.png';
    balloon.upLeftStem = 'up_left.png';
    balloon.downLeftStem = 'down_left.png';
    balloon.upRightStem = 'up_right.png';
    balloon.downRightStem = 'down_right.png';
    balloon.closeButton = 'close.png';
    balloon.closeButtonWidth = 16;
    balloon.allowAJAX = true;
    balloon.allowIframes = true;
    balloon.trackCursor = true;
    balloon.shadow = 20;
    balloon.padding = 10;
    balloon.stemHeight = 32;
    balloon.stemOverlap = 3;
    balloon.vOffset = 1;
    balloon.hOffset = 1;
    balloon.opacity = 0.9;
    balloon.configured = set || true;
  }

  switch(set) {

    // A formatted box (no background image)
    case('GBox') : 
      balloon.bgColor     = 'whitesmoke';
      balloon.borderStyle = '2px solid gray'; 
      balloon.padding     = 5;
      balloon.shadow      = 0;
      balloon.stem        = false;
      balloon.opacity     = 0.8;
      balloon.hOffset     = 1;
      balloon.vOffset     = 1;
      balloon.allowFade   = false;
      break;

    // A simpler balloon
    case('GPlain') : 
      balloon.padding     = 5;  
      balloon.images      = '/images/balloons/GPlain';
      balloon.ieImage     = null;
      balloon.shadow      = 0;  
      balloon.stemHeight  = 15;
      balloon.stemOverlap = 1;
      balloon.opacity     = 0.85;
      break;

    // The default cartoon bubble with a fade-in effect
    case('GFade') :
      balloon.allowFade   = true;
      balloon.fadeIn      = 1000;
      balloon.faedOut     = 200;
      break;
  }
}

//	calRoutines - Calendar Drawing Routines
var cal = new Object() ;
 cal.theMonths=['January','February','March','April','May','June', 'July','August','September','October','November','December']

function calShowMonth(m,y)
{
  var dim=[31,0,31,30,31,30,31,31,30,31,30,31] ;
  var oD = new Date(y, m-1, 1) ;
  oD.od = oD.getDay() + 1 ;

  var todaydate = new Date()
  var isToday = ((y == todaydate.getFullYear() && m == todaydate.getMonth() +1 ) ? todaydate.getDate() : 0) ;

  dim[1] = ((((oD.getFullYear() % 100 != 0) && (oD.getFullYear() % 4 == 0)) || (oD.getFullYear() % 400 == 0)) ? 29 : 28) ;
  var t = '<table class="calTable" align="center" cols="7" cellpadding="0" border="0" cellspacing="0">' ;

//  t += '<tr align="center"><td colspan="7">' ;
//  t += '<select id="calSelectMonth" onChange="calUpdateMonth(this.options)">' ;
//  for (var i=1; i<=12; i++) //display option for 12 months of the year
//   { t += '<option value="' + i + '"' + (i == cal.curMonth ? ' selected="yes"' : '') + '">' + cal.theMonths[i-1] + '</option>' ; } ;
//  t += '</select>' ;
//  t += '<select id="calSelectYear" onChange="calUpdateYear(this.options)">'
//  for (var i=cal.baseYear;i<=cal.maxYear;i++)
//   { t += '<option value="' + i + '"' + (i == cal.curYear ? ' selected="yes"': '') + '">' + i + '</option>' ; } ;
//  t += '</td></tr>' ;

  t += '<tr align="center"><td onclick="calPriorMonth()" class="calMonth">-</td>' ;
//  t += '<td colspan="5" align="center" class="calMonth">'+cal.theMonths[m-1]+' - '+y+'</td>' ;

  t += '<td colspan="5"><select id="calSelectMonth" onChange="calUpdateMonth(this.options)">' ;
  for (var i=1; i<=12; i++) //display option for 12 months of the year
   { t += '<option value="' + i + '"' + (i == cal.curMonth ? ' selected="yes"' : '') + '">' + cal.theMonths[i-1] + '</option>' ; } ;
  t += '</select>' ;
  t += '<select id="calSelectYear" onChange="calUpdateYear(this.options)">'
  for (var i=cal.baseYear;i<=cal.maxYear;i++)
   { t += '<option value="' + i + '"' + (i == cal.curYear ? ' selected="yes"': '') + '">' + i + '</option>' ; } ;
  t += '</select></td>' ;
  
  t += '<td onclick="calNextMonth()" class="calMonth">+</td>' ;
  t += '</tr><tr align="center">' ;
  for(s=0;s<7;s++) { t += '<td class="calDaysOfWeek">'+"SMTWTFS".substr(s,1)+'</td>'; } ;
  t += '</tr><tr align="center">' ;
  for(i=1;i<=42;i++)
   { 
//   Is this 'day' within range of month we are displaying?
     var isOK = ((i - oD.od >= 0) && (i - oD.od<dim[m-1])) ;
     if (isOK)
      { var curDay = (i-oD.od + 1) ;
        t += '<td class="calDays" onclick="'+cal.funcClickDay+'(' + y + ',' + m + ',' + curDay + ');"' + '>' +
		(curDay == isToday ? '<span class="calIsToday">' : '') + curDay + (curDay == isToday ? '</span>' : '') + '</td>' ;
      } else		//Either month before or month after - adjust and display appropriately
      { if (i < 10)	//Month before
         { var pm = m - 1 ; if (pm == 0) pm = 12 ;
           var py = (pm == 12 ? y - 1 : y) ;
           var curDay = (i-oD.od + 1) + dim[pm-1] ;
	   t += '<td class="calDaysBA" onclick="'+cal.funcClickDay+'(' + py + ',' + pm + ',' + curDay + ');"' + '>' + curDay + '</td>' ;
         } else		//Month after
         { var nm = m + 1 ; if (nm > 12) nm = 1 ;
           var ny = (nm == 1 ? y + 1 : y) ;
           var curDay = (i-oD.od + 1) - dim[m-1] ;
	   t += '<td class="calDaysBA" onclick="'+cal.funcClickDay+'(' + ny + ',' + nm + ',' + curDay + ');"' + '>' + curDay + '</td>' ;
         } ;
      } ;
     if ((i % 7== 0) && (i < 36)) t+='</tr><tr align="center">';
   } ;
  return(t+='</tr></table>') ;
}
function calUpdateMonth(theselection)
{
  cal.curMonth=parseInt(theselection[theselection.selectedIndex].value) ;
  document.getElementById(cal.divId).innerHTML = calShowMonth(cal.curMonth, cal.curYear) ;
}

function calPriorMonth()
{
  cal.curMonth -= 1 ; if (cal.curMonth <= 0) { cal.curYear -= 1 ; cal.curMonth = 12 ; } ;
  if (cal.curYear < cal.baseYear) { cal.curYear = cal.baseYear ; cal.curMonth = 1 ; } ;
  document.getElementById('calSelectYear').selectedIndex = cal.curYear - cal.baseYear ;
  document.getElementById('calSelectMonth').selectedIndex = cal.curMonth - 1 ;
  document.getElementById(cal.divId).innerHTML = calShowMonth(cal.curMonth, cal.curYear) ;
}

function calNextMonth()
{
  cal.curMonth += 1 ; if (cal.curMonth > 12) { cal.curYear += 1 ; cal.curMonth = 1 ; } ;
  if (cal.curYear > cal.maxYear) { cal.curMonth = 12 ; cal.curYear = cal.maxYear ; } ;
  document.getElementById('calSelectYear').selectedIndex = cal.curYear - cal.baseYear ;
  document.getElementById('calSelectMonth').selectedIndex = cal.curMonth - 1 ;
  document.getElementById(cal.divId).innerHTML = calShowMonth(cal.curMonth, cal.curYear) ;
}

function calUpdateYear(theselection)
{
  cal.curYear=parseInt(theselection[theselection.selectedIndex].value) ;
  document.getElementById(cal.divId).innerHTML = calShowMonth(cal.curMonth, cal.curYear) ;
}

function calInitWithCurrentDate(divId,funcClickDay) {
  var todaydate=new Date() ;
  cal.curMonth=todaydate.getMonth()+1 ;
  cal.curYear=todaydate.getFullYear() ;		//Get current date, month & year
  cal.baseYear = cal.curYear - 3 ;
  cal.maxYear = cal.curYear + 12 ;
  cal.funcClickDay = funcClickDay ;
  cal.divId = divId ;
//  alert(calShowMonth(cal.curMonth,cal.curYear)) ;
  document.getElementById(divId).innerHTML = calShowMonth(cal.curMonth,cal.curYear) ;
}

//	selRoutines - Drop-Down Selection Routines (move from one to another, reorder, ...)
// Add colList (a string of comma-separated elements) to srcSelect, remove any elements from tgtSelect
function colSelectorReset(colList,srcSelect,tgtSelect) {
  for(i=srcSelect.length-1;i>=0;i--) { srcSelect.options[0] = null ; } ; //Clear out both lists
  if (tgtSelect != null)
   { for(i=tgtSelect.length-1;i>=0;i--) { tgtSelect.options[0] = null ; } ; }
  var optlist = colList.split(",")
  for(i=0;i<optlist.length;i++)
   { var option = optlist[i]
     textvallist = option.split("=")
     var text = textvallist[0] ; var value = (textvallist.length > 1 ? textvallist[1] : text)
     srcSelect.options[srcSelect.options.length] = new Option(text,value)
   }
}
function colUnselect(tgtSelect) {	//Unselects all options in dropdown
  for(i=0;i<tgtSelect.length;i++)
   { if (tgtSelect.options[i].selected) tgtSelect.options[i].selected = false
   }
}
function colSelectorLoadPredefined(colList,srcSelect,preListIndex,tgtSelect) {
  for(i=srcSelect.length-1;i>=0;i--) { srcSelect.options[0] = null ; } ; //Clear out both lists
  for(i=tgtSelect.length-1;i>=0;i--) { tgtSelect.options[0] = null ; }
//Load tgt with preList, make string of exclusions for main list
  var excList = ''
  var preList = colNamePredefined[preListIndex].split('=')[1]
  var optlist = preList.split(",")
  for(i=0;i<optlist.length;i++)
   { var option = optlist[i]
     textvallist = option.split("=") ; excList += (textvallist + ",")
     var text = textvallist[0] ; var value = (textvallist.length > 1 ? textvallist[1] : text)
     tgtSelect.options[tgtSelect.options.length] = new Option(text,value)
   }
//Now load src with colList minus anything in preList (via excList string)
  var optlist = colList.split(",")
  for(i=0;i<optlist.length;i++)
   { var option = optlist[i]
     textvallist = option.split("=") ; if (excList.search(textvallist+",") >= 0) continue
     var text = textvallist[0] ; var value = (textvallist.length > 1 ? textvallist[1] : text)
     srcSelect.options[srcSelect.options.length] = new Option(text,value)
   }
}
//	Move selected items in src to tgt
function colSelectorMove(srcSelect,tgtSelect) {
  var cnt = 0
  for(i=0;i<srcSelect.length;i++)
   { if (!srcSelect.options[i].selected) continue
     var text = srcSelect.options[i].text ; var value = srcSelect.options[i].value
     tgtSelect.options[tgtSelect.options.length] = new Option(text,value)
     srcSelect.options[i] = null ; i-- ; cnt++
   }
  if (cnt == 0) alert("Please select one or more items to move")
}

//	Move selected items in dropdown 'up' one
function selMoveItemsUp(selobj) {
  var collist = new Array() ; var cnt = 0 ;
  for (i=1;i<selobj.length;i++)
   { if (!selobj.options[i].selected) continue ;
     var temp1 = selobj.options[i-1] ;
     var temp2 = selobj.options[i] ;
     selobj.options[i-1] = new Option(temp2.text,temp2.value) ;
     selobj.options[i] = new Option(temp1.text,temp1.value) ;
     selobj.options[i-1].selected = true ; cnt++ ;
   } ;
  if (cnt == 0) alert("Please select one or more items from the list to move") ;
}
//	Move selected items in dropdown 'down' one
function selMoveItemsDown(selobj) {
  var collist = new Array() ; var cnt = 0 ;
  for (i=selobj.length-2;i>=0;i--)
   { if (!selobj.options[i].selected) continue ;
     var temp1 = selobj.options[i] ;
     var temp2 = selobj.options[i+1] ;
     selobj.options[i] = new Option(temp2.text,temp2.value) ;
     selobj.options[i+1] = new Option(temp1.text,temp1.value) ;
     selobj.options[i+1].selected = true ; cnt++ ;
   } ;
  if (cnt == 0) alert("Please select one or more items from the list to move") ;
}

//	cookieRoutines - Routines for setting/getting cookies
//setCookie - creates cookies to expire in 'days', if 0 then cookies dies when browser session dies
function setCookie(name, value, days) {
  var curCookie = name + "=" + escape(value) ;
  if (days > 0)
   { var expDate = new Date() ;
     expDate = new Date(expDate.getTime() + (days * 1000*60*60*24)) ;
     curCookie += ';expires=' + expDate.toGMTString() ;
   } ;
  document.cookie = curCookie;
}
function delCookie(name) {
  document.cookie = 'name'+'=' ;
}
function getCookie(name) {
  var dc = document.cookie;
  var prefix = name + "=";
  var begin = dc.indexOf("; " + prefix);
  if (begin == -1) { begin = dc.indexOf(prefix); if (begin != 0) return null; }
   else { begin += 2; } ;
  var end = document.cookie.indexOf(";", begin);
  if (end == -1) end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}

//	mainMenuVertLHS - Routines for Main Menu (Vertical LHS)
function mSectDisplay(mSect) {
  var div = document.getElementById('div'+mSect) ;
  var h = '' ;
  var mx ;
  for (var mx=0;mx<mSectEntries.length;mx++)
   { if (mSectEntries[mx][0] == mSect)
//      { h += '<ul onclick="mSectHide(\''+mSect+'\')"><p>'+mSectEntries[mx][1]+'</p>' ; break ; } ;
      { h += '<div class="cmHdr"><div class="cmHdrCap">'+mSectEntries[mx][1]+'</div><div class="cmHdrClose"><a href="javascript:mSectHide(\''+mSect+'\')">x</a></div></div><ul>' ; break ; } ;
   } ;
  if (mx >= mSectEntries.length) 
   { alert('Menu section ('+mSect+') no longer exists, resetting defaults') ; delCookie('upmCookie') ; return ; } ;
  for(var i=0;i<mSectEntries[mx][2].length;i++)
   { var x = mSectEntries[mx][2][i] ;
     h += '<li><a href="javascript:menuInvokeME('+mEntryList[x][0]+')">'+mEntryList[x][6]+(mEntryList[x][1] > 0 ? '&hellip;' : '')+'</a></li>' ;
   } ;
  h += '</ul>' ;
  div.innerHTML = h ;
  div.style.display = 'block' ;
//Save this in a cookie
  var pmenu = getCookie('upmCookie') ; if (pmenu == null) pmenu = '' ;
  pmenu = pmenu.replace(mSect+',','') ; pmenu += mSect+',' ;
  setCookie('upmCookie',pmenu,1000) ;
}

function mSectHide(mSect) {
  document.getElementById('div'+mSect).style.display = 'none' ;
  var pmenu = getCookie('upmCookie') ; if (pmenu == null) pmenu = '' ;
  pmenu = pmenu.replace(mSect+',','') ;
  setCookie('upmCookie',pmenu,1000) ;
}

var menuids=new Array("vMenuLHS") ;	//Enter comma delimited id(s) of vertical menus
var subMenuOffset = -2 ;		//Offset of submenus from main menu. Default is -2 pixels.

function vMenuInit(){
  for (var i=0; i<menuids.length; i++)
   { var ultags=document.getElementById(menuids[i]).getElementsByTagName("ul")
     for (var t=0;t<ultags.length;t++)
      {	var spanref=document.createElement("span")
	spanref.className="arrowdiv" ; spanref.innerHTML="&nbsp;&nbsp;" ;
	ultags[t].parentNode.getElementsByTagName("a")[0].appendChild(spanref)
	ultags[t].parentNode.onmouseover=function() { this.getElementsByTagName("ul")[0].style.left=this.parentNode.offsetWidth+subMenuOffset+"px" ; this.getElementsByTagName("ul")[0].style.display="block" } ;
	ultags[t].parentNode.onmouseout=function() { this.getElementsByTagName("ul")[0].style.display="none" ; } ;
      } ;
   } ;
//Do we have a saved cookie for RHS ?
  var pmenu = getCookie('upmCookie') ; if (pmenu == null) pmenu = '' ;
  if (pmenu.indexOf(',,') != -1) { pmenu = '' ; delProcCookie('upmCookie') ; } ;	//Temp to fix startup problems
  if (pmenu.length > 0)
   { var msList = pmenu.split(',') ;
     for (var i=0;i<msList.length;i++)
      { if (msList[i].length == 0) continue ;	//Ignore empty sections
        mSectDisplay(msList[i]) ;
      } ;
   } ;
}

var timerShowHide = null ;
function hideRHS() {
  document.getElementById('divRHS').className = 'dimRHS' ;
  if (timerShowHide) { clearTimeout(timerShowHide) ; timerShowHide = null ; } ;
}
function showRHS() {
  timerShowHide = window.setTimeout("document.getElementById('divRHS').className = ''",200) ;
}

//	slspLib - Javascript for Summary Lookup Stuff
var alreadySelOptVals = '' ;	//List of already-used select option values
var parTable ;
var dbTblSRList = '' ;		//Holds list of dbTbl's in 1 or more scrolling edit regions
function selCreateTextNode(obNode,defValue,funcVerify,initPrompt) {
  var node = document.createElement('input')
    node.setAttribute('type','text') ; node.setAttribute('size','20') ; node.value = defValue
    if (initPrompt != null)
     { node.value = "- " + initPrompt + " -" ; node.onfocus = function(){funcClearInitPrompt(this)}
     }
  obNode.appendChild(node)
}
function funcClearInitPrompt(txtInpField) {
  if (txtInpField.value.search(/^- .* -$/) >= 0) txtInpField.value = ''
}
function selCreateCheckBoxNode(obNode,isChecked,textValue,promptText,funcVerify) {
  var node = document.createElement('input')
    node.setAttribute('type','checkbox') ; node.value = textValue
  obNode.appendChild(node)
  obNode.appendChild(document.createTextNode(promptText)) ; node.defaultChecked = isChecked ; node.checked = isChecked
  return(node)
}
function selCreateSelectNode(obNode,obId,defValue,exValList,listElements,allowMultiple,funcVerify) {
  var selobj = document.createElement('select')
  if (obId != null) selobj.setAttribute('id',obId)
  if (funcVerify != null) selobj.onchange = function(){funcVerify()}

  var optlist = listElements.split(",")
  for(i=0;i<optlist.length;i++)
   { var option = optlist[i]
     textvallist = option.split("=")
     var text = textvallist[0] ; var value = (textvallist.length > 1 ? textvallist[1] : text)
     if (exValList != null) { if (exValList.search(value+",") >= 0) continue ; } ;	//If excluded then don't include
     selobj.options[selobj.options.length] = new Option(text,value)
   }
  obNode.appendChild(selobj)
  return(selobj)

}
 var globalSelRowNum = 0
 var globalSelOptionList = ''
function selSelectOption(idNum) {
  var selobj = document.getElementById('sel' + idNum) ;
  for(i=0;i<selobj.length;i++)
   { if (selobj.options[i].selected) break ;
   } ; if (i >= selobj.length) return(false) ;	//Should not get this
//disable this option
  selobj.setAttribute('disabled',true) ;
  var tdobj = document.getElementById('tdlhs'+idNum) ;
  var objValue = (selobj.options[i].value + ",") ;
  tdobj.ondblclick = function(){rmvSelectOption(0+idNum,objValue)} ;
//create selection input on rhsColList
  var tdrhs = document.getElementById('tdrhs' + idNum) ;
  alreadySelOptVals += objValue ;
  
  var svIndex = parseInt(selobj.options[i].value) - 1 ;
  var rptArgList = selDefArray[svIndex].split('	') ;
  switch (rptArgList[2])
   { case 'T':
	selCreateTextNode(tdrhs,rptArgList[3],null,rptArgList[5]) ; break ;
     case 'C':
	selCreateCheckBoxNode(tdrhs,true,'ok',rptArgList[5],null) ; break ;
     case 'D':
	selCreateSelectNode(tdrhs,null,null,null,rptArgList[5],true,null) ; break ;
   }
  createSelRow() ;
}
function rmvSelectOption(idNum,valText) {
  alreadySelOptVals = alreadySelOptVals.replace(valText,'') ;	//remove value from alreadySelOptVals string
  var trobj = document.getElementById('tr'+idNum) ;
  trobj.parentNode.removeChild(trobj) ;
}
function createSelRow() {
  globalSelRowNum++ ;
  var newtr = document.createElement('tr') ; newtr.setAttribute('id','tr'+globalSelRowNum) ;
  var newtd = document.createElement('td') ; newtd.setAttribute('id','tdlhs'+globalSelRowNum) ;
    var selNode = selCreateSelectNode(newtd,'sel'+globalSelRowNum,null,alreadySelOptVals,globalSelOptionList,false,function(){selSelectOption(0+globalSelRowNum)}) ;
  newtr.appendChild(newtd) ;
  var newtd = document.createElement('td') ; newtd.setAttribute('id','tdrhs'+globalSelRowNum) ;
  newtr.appendChild(newtd) ;
  parTable.appendChild(newtr) ;
}
function buildSelArgumentString() {
//First the colNameStr that have been selected
  var ssSetup = document.forms['ssSetup'] ; 
  var objCol = document.forms['ssArgs'].rhsColList ;
  var arg = '' ;
  for(i=0;i<objCol.length;i++) { arg += objCol.options[i].value ; arg += ',' ; } ;
  ssSetup.colNameStr.value = arg ;
//Any sorting options
  arg = '' ;
  var objsort = document.getElementById('sortColList') ;
  for(i=0;i<objsort.length;i++) { if (objsort.options[i].selected) { arg += objsort.options[i].value ; arg += ',' ; } ; } ;
  ssSetup.sorting.value = arg ;
//Now the selection arguments
  arg = '' ;
  var objsel = document.getElementById('selTable') ;
//  if (navigator.appVersion.indexOf('MSIE') != -1) objsel = objsel.firstChild ;
  for(i=0;i<objsel.childNodes.length;i++)
   { var trobj = objsel.childNodes[i] ;
     var lhtd = trobj.childNodes[0] ; rhtd = trobj.childNodes[1] ;
     if (lhtd == null || rhtd == null) continue ;
     var rowSel = lhtd.firstChild ; var rowVal = rhtd.firstChild ; if (rowVal == null) continue ;
     for(j=0;j<rowSel.length;j++)
      { if (!rowSel.options[j].selected) continue ;
	k = parseInt(rowSel.options[j].value) - 1 ;
	var selentry = selDefArray[k].split('	')[0].split('=') ;
	arg += selentry[selentry.length-1] ;
	break ;
      }
     arg += ':' ;
     if (rowVal.nodeName == "INPUT") { arg += rowVal.value ; }
      else if (rowVal.nodeName == "SELECT")
	    { for(k=0,comma=false;k<rowVal.length;k++)
	       { if (rowVal.options[k].selected) { arg += ((comma ? "," : "") + rowVal.options[k].value) ; comma = true ; } ; } ;
	    }
      else { arg += 'unknown' ; } ;
     arg += '|' ;
   }
//  ssSetup._AltFunc.value = 'slsDriver' ; //ssSetup.target = '' ;	//Clear these if set by prior call for help
  ssSetup.selection.value = arg ;
  ssSetup.submit() ;
  return(true) ;
}

function parseDefArray() {
  globalSelOptionList = 'choose option=0,' ;
  for(i=0;i<selDefArray.length;i++)
   { var rptArgList = selDefArray[i].split('	')[0].split('=') ;
     globalSelOptionList += (rptArgList[0] + "=" + (i+1) + ",") ; //alert(globalSelOptionList) ;
   }
}

function displayHelpWindow() {
  var form = document.forms['ssArgs'] ;
  window.open(form.helpURL.value,"helpWindow","width=550,height=700, scrollbars=yes,menubar=no,toolbar=no") ;
//  ssSetup._AltFunc.value = 'SumScreenGenHelp' ; ssSetup.target = 'helpWindow' ;
//  ssSetup.submit() ;
}

function setupEverything() {
  var ssArgs = document.forms['ssArgs'] ; 
  colSelectorReset(colNameList,ssArgs.lhs,ssArgs.rhsColList) ;
  colSelectorReset(colSortList,ssArgs.sortColList,null) ;
  parseDefArray() ;
  parTable = document.getElementById('selTable') ;
//  if (navigator.appVersion.indexOf('MSIE') != -1) parTable = parTable.firstChild ;
  setupPredefined() ;
  createSelRow() ;
}
function selPredefined() {
  var ssArgs = document.forms['ssArgs'] ; 
  var selobj = document.getElementById('selPredefinedLayout') ;
  for(i=0;i<selobj.length;i++) { if (selobj.options[i].selected) break ; } ;
  if (i >= selobj.length || selobj.options[i].value == '0') return ;
  colSelectorLoadPredefined(colNameList,ssArgs.lhs,parseInt(selobj.options[i].value)-1,ssArgs.rhsColList) ;
}
function setupPredefined() {
  var selobj = document.getElementById('selPredefinedLayout') ;
  for(i=0;i<colNamePredefined.length;i++)
   { seltext = colNamePredefined[i].split('=')[0] ;
     selobj.options[selobj.options.length] = new Option(seltext,i+1) ;
   } ;
}

function eesVerifyAndInsertSave(btnObj,formSubmit,formData,xmlField,funcName)
{  formSubmit.elements[xmlField].value = formToXML(formData,"dwrap",true) ;
   formSubmit._Func.value = funcName ;
// If we have any scrolling regions then set up changes for them
   if (dbTblSRList.length > 0)
    { slsSRIUSaveChanges(formSubmit,dbTblSRList,false) ; return ;} ;
  if(false)
   { formSubmit.submit() ; }
   else { var args = '' ;
	  if (formSubmit.dbXML2.value.length > 0) args += '&dbXML2='+escape(formSubmit.dbXML2.value) ;
	  if (formSubmit.dbSRDelList.value.length > 0) args += '&dbSRDelList='+escape(formSubmit.dbSRDelList.value) ;
	  ajax('dbUpdateSingleFromXML','&dbTbl='+formSubmit.dbTbl.value+'&dbXML='+escape(formSubmit.dbXML.value)+args,'slsUpdateSaveChangesOK()','slsUpdateSaveChangesFail()') ;
	} ;
}
function slsUpdateSaveChangesOK() {
  alert(jObj.updRes) ;
  window.location.reload() ;
}
function slsUpdateSaveChangesFail() {
  alert('There was a problem saving the information: '+jObj.meta.msg) ;
}
function eesConfirmDeleteOK(formSubmit,formData,xmlField,funcName)
{  if (window.confirm("Are you sure you want to delete this?"))
    { formSubmit.elements[xmlField].value = formToXML(formData,"dwrap",true) ;
      formSubmit._Func.value = funcName ; formSubmit.submit() ;
    } ;
}

//	adminRAE - Main Application Component Rebuild Routine
function adminRAE(mode) {
    var form = document.forms['craForm']
    switch(mode)
     { default:
       case 1: /* Install */
	document.cookie = '_Area=1' ; form._Func.value = 'xxx' ; form._V4.value = 'install' ; break ;
       case 2: /* Keep Old */
	document.cookie = '_Area=1' ; form._Func.value = 'mainMenu' ; break ;
       case 3: /* Test New */
	document.cookie = '_Area=2' ; form._Func.value = 'mainMenu' ; break ;
     } ;
    form.submit() ;
    return ;
}

//	ccpRFFC - Sets all files with given extension
function SetFilesWithExt() {
  var form = document.forms[0] ;
  if (arguments.length == 0)		//Want to set all of them
   { for(var i=0;i<form.length;i++)
      { var el = form.elements[i] ;
        if (el.type == 'checkbox') el.checked = true ;
      } ;
     return ;
   } ;
  for(var ax=0;ax<arguments.length;ax++)
   { for(var i=0;i<form.length;i++)
      { var el = form.elements[i] ;
        if (el.type == 'checkbox' && el.value == arguments[ax]) el.checked = true ;
      } ;
   } ;
}

//	ccpRSCF - Verifies CCP Review form
function VerifyCPReviewForm(form) {
  var num = form.length ;
  var i, cb=0, radio=0 ;
  for(i=0;i<num;i++)
   { el = form[i] ;
     if (el.type == 'checkbox' ? el.checked : false)
      { cb += 1 ; form._AltFunc.value = 'ccpRevCompare' ; } ;
     if (el.type == 'radio' ? el.checked : false)
      { radio += 1 ;
        if (el.name == 'ccpRevRestore') { form._AltFunc.value = 'ccpRevRestore' ; }
         else { form._AltFunc.value = 'ccpRevRetrieve' ; form._V4.value = 'FilePassThru' ; } ;
      } ;
   } ;
  if (cb + radio == 0) { alert("No action selected?") ; return false ; } ;
  if (cb > 0 && cb != 2) { alert("You must select 2 checkboxes for a file comparison") ; return false ; } ;
  if (radio > 0 && radio != 1) { alert("You can either restore a file or retrieve it, not both") ; return false ; } ;
  if (radio > 0 && cb > 0) { alert("Please select only one action- either Restore, Retrieve, or Compare") ; return false ; } ;
}
function ReplaceCurrentFile(form) {
  form._AltFunc.value = 'adminCompRepFromClientSetup' ;
  form.submit() ;
}

//	showCusConDetail - Displays selected contract division, hides the remaining
var oldCusRef = 0 ;
function showCusConDetail(cus) {
  if (oldCusRef != 0) { document.getElementById('cd'+oldCusRef).style.display = 'none' ; } ;
  document.getElementById('cd'+cus).style.display = 'block' ; 
  oldCusRef = cus ;
}

//	pacStation - Packer (V4) Javascript Routines
 var numRemain = 0		//Number of items remaining in order

var jObj ;			//jV4Res object back from V4 - contains the following elements-
 // itemList & itemDesc = arrays with item code/desc for each item in current order
 // itemQty = Number to pick for each item
 // itemIsBO = If true then the item is back-ordered and is not required to be picked
 // itemPicked = Number picked so far
 // upcCodes = List of UPCs in this order (may include several UPCs for same SKU if alternates allowed)
 // upcIndex = Corresponding index into itemList/itemDesc/itemQty/itemPicked for each UPC

// jV4Res - JSON returned string result from V4
var jV4Res ;
jV4Res = "{'meta': {'status':'ok'},'itemList':[4775,4641,4640,4937,4632,5286,5281,5296,4970,4888],'itemDesc':['Adjust. 18-22 Slvr Neck/Ear W/Black Bds','Heart Key Chain','Silver Stretch Bracelet','Footprints - Story Bracelet','Cinnamon Rolls W/White Icing','Reindeer Votive Holder','Glass Coaster Set','Bartons Choc Cov. Almond Butter Toffee','Greeting Card Set W/Organizer','Snowman Cake Pan'],'itemQty':[1,2,1,2,1,1,1,1,1,1],'itemIsBO':[false,false,true,false,false,false,false,false,false,false],'itemPicked':[0,0,0,0,0,0,0,0,0,0],'upcCodes':['4775','4641','4640','4937','4632','5286','5281','5296','4970','4888'],'upcIndex':[1,2,3,4,5,6,7,8,9,10]}" ;


var totalOrders = 0 ;
var totalPicks = 0 ;

var lastItemIndex = -1 ;	//Index (into itemPicked) of last item scanned

var orderToggle = false ;

var mObj = Object() ;
 mObj.msgNeedOrderFirst = 'Scan order label first!' ;
 mObj.msgFinishOrder = 'Finish/Clear Current Order!' ;
 mObj.msgItemNotInOrder = 'Item not in Order' ;
 mObj.msgOnlyOneMistake = "Can only clear last scan. Use 'Clear' button and restart order" ;
 mObj.msgNoSuchOrder = 'No such order, scan again' ;
 mObj.msgInvScan = 'Invalid barcode scan (incorrect length)' ;
 mObj.msgInvCommand = 'Invalid barcode command' ;
 mObj.msgLoginFirst = 'Scan employee badge first' ;
 mObj.msgLogoutEmp = 'Logout current packer before logging in' ;
 mObj.msgInvalidEmp = 'Invalid employee scan' ;
 mObj.msgOKToContinue = 'OK to continue' ;
 mObj.msgStationIdle = 'Station idle' ;
 mObj.msgOrderDoneOK = 'OK' ;
 mObj.msgOrders = 'orders' ;
 mObj.msgItems = 'items' ;
 mObj.msgRanking = 'Current ranking #' ;
 mObj.hdrQuantity = 'Quantity' ;
 mObj.hdrPicked = 'Picked' ;
 mObj.hdrNeed = 'Need' ;
 mObj.hdrItem = 'Item' ;
 mObj.hdrDescription = 'Description' ;

var currentOrder = 0 ;
var currentPEmp = 0 ;
var currentPLI = 0 ;	//Current employee login-in ref #
var currentRanking = '--' ;

var errOK = 0 ;
var errItemNotInOrder = 1 ;
var errTooManyInOrder = 2 ;
var errItemIsBO = 3 ;

function packerInit() {
  bcInputFocus() ;
}
function bcInputFocus() {
  var form = document.forms['bcForm'] ;
  form.bcInput.focus() ;
  return(form.bcInput)
}

function setRemain(numShow) {
  var el = document.getElementById('divDetailArea') ;
  if (currentOrder == 0) { el.innerHTML = '' ; return ; } ;
  el.innerHTML = '<div class="remainToPick">'+numShow+'</div>' ;
//  el.setAttribute('className','remainToPick') ;
//  while (el.hasChildNodes()) { el.removeChild(el.firstChild) ; } ;
//  var pNode = document.createElement('p') ;
//  var tNode = document.createTextNode(numShow) ;
//  pNode.appendChild(tNode) ; el.appendChild(pNode) ;
  orderToggle = false ;
}
function orderDoneOK() {
  var el = document.getElementById('divDetailArea') ;
  el.innerHTML = '<div class="orderDoneOK">'+mObj.msgOrderDoneOK+'</div>' ;
//  el.setAttribute('className','orderDoneOK') ;
//  while (el.hasChildNodes()) { el.removeChild(el.firstChild) ; } ;
//  var pNode = document.createElement('p') ;
//  var tNode = document.createTextNode(mObj.msgOrderDoneOK) ;
//  pNode.appendChild(tNode) ; el.appendChild(pNode) ;
  ajax('finishOrder', '&pli='+currentPLI+'&orderId='+currentOrder, 'refreshRank()', '') ;
  currentOrder = 0 ;
}

function refreshRank() {
  currentRanking = jObj['currentRanking'] ;
  showProductivity() ;
}

function parseInput() {
  var res ; var form = document.forms['bcForm'] ;
  var input = form.bcInput.value ;
  form.bcInput.value = '' ;
  form.xxx.focus() ;
  switch (input.length)
   { default:	msgDisplay(mObj.msgInvScan) ; break ;
     case 3:	//Command (Mistake, Clear, Logout, ...)
	switch(input)
	 { default:	msgDisplay(mObj.msgInvCommand) ; break ;
	   case '001':	handleMistake() ; break ;	//Mistake
	   case '002':	clearCurrentOrder() ; break ;	//Clear
	   case '003':	showOrder() ; break ;		//Order
	   case '004':	logoutEmp() ; break ;		//Logout
	     break ;
	 } ;
	break ;
     case 5:	//User Id - login
	if (currentPEmp != 0) 
	 { msgDisplay(mObj.msgLogoutEmp) ; return ; } ;
	currentPEmp = input ;
	ajax('pEmpLogin', '&userBadge='+currentPEmp, 'newEmpSetup()', 'newEmpFail()') ;
	break ;
     case 9:	//CAPS group+student code
	if (currentPEmp == 0) 
	 { msgDisplay(mObj.msgLoginFirst) ; return ; } ;
	if (currentOrder != 0)
	 { msgDisplay(mObj.msgFinishOrder) ; return ; } ;
//	currentOrder = input ;
	ajax('getCAPSOrder', '&orderId='+input, 'newOrderSetup("'+input+'")', 'newOrderFail()') ;
	break ;
     case 1:
     case 2:	//Temp for debuging - take input as index to order
	if (currentOrder == 0)
	 { msgDisplay(mObj.msgNeedOrderFirst) ; return ; } ;
	if (numRemain <= 0)
	 { msgDisplay(mObj.msgItemNotInOrder) ; return ; } ;
	input = jObj['upcCodes'][parseInt(input,10)-1] ;
     case 10:
     case 11:
     case 12:
     case 13:	//UPC Codes
	if (currentOrder == 0)
	 { msgDisplay(mObj.msgNeedOrderFirst) ; return ; } ;
	if (numRemain <= 0)
	 { msgDisplay(mObj.msgItemNotInOrder) ; return ; } ;
	var res ;
	switch (res = scanUPC(input))
	 { case errOK:
	     showProductivity() ;
	     if (numRemain > 0) { setRemain(numRemain) ; }
	      else { orderDoneOK() ; } ;
	     break ;
	   case errItemIsBO:
	   case errItemNotInOrder:
	   case errTooManyInOrder:
	     msgDisplay(mObj.msgItemNotInOrder) ; break ;
	   default:
	     alert('Unhandled error: '+res) ;
	 } ;
	break ;
   } ;
  bcInputFocus() ;
}

function newOrderSetup(orderId) {
  var el = document.getElementById('topRow') ;
  el.innerHTML = '<p class="orderId">'+currentOrder+'</p>' ;
  while (el.hasChildNodes()) { el.removeChild(el.firstChild) ; } ;
//  var pNode = document.createElement('p') ; pNode.setAttribute('className','orderId') ;
//  var tNode = document.createTextNode(currentOrder) ;
//  pNode.appendChild(tNode) ; el.appendChild(pNode) ;
//  var pNode = document.createElement('p') ; pNode.setAttribute('className','school') ;
//  var tNode = document.createTextNode('The Teaching School') ;
//  pNode.appendChild(tNode) ; el.appendChild(pNode) ;
  numRemain = 0 ; 
     
  for(var i=0;i<jObj['itemQty'].length;i++) { if(!jObj['itemIsBO'][i]) numRemain += jObj['itemQty'][i] ; } ;
  for(var i=0;i<jObj['itemPicked'].length;i++) { jObj['itemPicked'][i] = 0 ; } ;
  currentOrder = orderId ;
  setRemain(numRemain) ;
  totalOrders++ ; showProductivity() ;
  lastItemIndex = -1 ;
  showPackaging(jObj.imgURLBoxPrefix,jObj.boxList) ;
  bcInputFocus() ;
}

function newOrderFail() {
  currentOrder = 0 ;
  msgDisplay(mObj.msgNoSuchOrder) ; return ;
}

function newEmpSetup() {
  currentPLI = jObj['pli'] ;
  totalOrders = jObj['totalOrders'] ;
  totalPicks = jObj['totalPicks'] ;		//Maybe pick up prior work from same login
  ajax('getMsgErrs', '&pli='+currentPLI, 'newEmpSetup2()', '') ;
}
function newEmpSetup2() {
  mObj = jObj ;			//Copy jObj because it now has all the message (error & otherwise)
  var el = document.getElementById('divDetailArea') ;
  el.innerHTML = '<div class="empLoginOK">'+mObj.msgOKToContinue+'</div>' ;
//  el.setAttribute('className','empLoginOK') ;
//  while (el.hasChildNodes()) { el.removeChild(el.firstChild) ; } ;
//  var pNode = document.createElement('p') ;
//  var tNode = document.createTextNode(mObj.msgOKToContinue) ;
//  pNode.appendChild(tNode) ; el.appendChild(pNode) ;
//Don't forget to change the buttons on the RHS
  document.getElementById('btnMistake').childNodes[0].nodeValue = mObj.btnMistake ;
  document.getElementById('btnClear').childNodes[0].nodeValue = mObj.btnClear ;
  document.getElementById('btnOrder').childNodes[0].nodeValue = mObj.btnOrder ;
  document.getElementById('btnLogout').childNodes[0].nodeValue = mObj.btnLogout ;
}
function newEmpFail() {
  currentPEmp = 0 ;
  msgDisplay(jObj.meta.msg) ; return ;
}

function logoutEmp() {
  if (currentPEmp == 0) { msgDisplay(mObj.msgLoginFirst) ; return ; } ;
  ajax('pEmpLogout', '&pli='+currentPLI, 'logoutEmpOK()', '') ;
  currentPEmp = 0 ; currentPLI = 0 ;
}

function logoutEmpOK() {
  var el = document.getElementById('divDetailArea') ;
  el.innerHTML = '<div class="empLoginOK">'+mObj.msgStationIdle+'</div>' ;
//  el.setAttribute('className','empLoginOK') ;
//  while (el.hasChildNodes()) { el.removeChild(el.firstChild) ; } ;
//  var pNode = document.createElement('p') ;
//  var tNode = document.createTextNode(mObj.msgStationIdle) ;
//  pNode.appendChild(tNode) ; el.appendChild(pNode) ;
}

function msgDisplay(msg) {
  var el = document.getElementById('divDetailArea') ;
  el.innerHTML = '<div class="'+(msg.length > 15 ? 'msgLong' : 'msgShort')+'">'+msg+'</div>' ;
//  el.setAttribute('className',(msg.length > 15 ? 'msgLong' : 'msgShort')) ;
//  while (el.hasChildNodes()) { el.removeChild(el.firstChild) ; } ;
//  var pNode = document.createElement('p') ;
//  var tNode = document.createTextNode(msg) ;
//  pNode.appendChild(tNode) ; el.appendChild(pNode) ;
  bcInputFocus() ;
}

function handleMistake() {
  if (currentOrder == 0) return ;
  if (lastItemIndex == -1) { msgDisplay(mObj.msgOnlyOneMistake) ; return ; } ;
  jObj['itemPicked'][lastItemIndex]-- ; lastItemIndex = -1 ;
  numRemain++ ; setRemain(numRemain) ;
  bcInputFocus() ;
}

function scanUPC(upcId) {
  for(var upcX=0;upcX<jObj['upcCodes'].length;upcX++)
   { if (jObj['upcCodes'][upcX] != upcId) continue ;
     var itemX = jObj['upcIndex'][upcX] ;
     if (jObj['itemIsBO'][upcX]) return(errItemIsBO) ;
     if (jObj['itemPicked'][upcX] >= jObj['itemQty'][upcX]) return(errTooManyInOrder) ;
     totalPicks++ ; jObj['itemPicked'][upcX]++ ; numRemain-- ;
     lastItemIndex = upcX ; return(errOK) ;
   } ;
//Look for possible substituted items
  for(var subX=0;subX<jObj['subNewUPC'].length;subX++)
   { if (jObj['subNewUPC'][subX] != upcId) continue ;
//   Found a sub - see if this order can use it
     for(var upcX=0;upcX<jObj['upcCodes'].length;upcX++)
      { if (jObj['upcCodes'][upcX] != jObj['subOldUPC'][subX]) continue ;
//	Matches item in this order - see if we still need it, if not don't error but continue
//	(since it can be many-to-many mapping we may be able to match on another)
        var itemX = jObj['upcIndex'][upcX] ;
        if (jObj['itemIsBO'][upcX]) continue ;
        if (jObj['itemPicked'][upcX] >= jObj['itemQty'][upcX]) continue ;
        totalPicks++ ; jObj['itemPicked'][upcX]++ ; numRemain-- ;
        lastItemIndex = upcX ; return(errOK) ;
      } ;
   } ;
  return(errItemNotInOrder) ;
}

function showOrder() {
  if (currentOrder == 0)
   { msgDisplay(mObj.msgNeedOrderFirst) ; return ; } ;
  if (orderToggle)
   { orderToggle = false ; setRemain(numRemain) ; return ;
   } ;
  var el = document.getElementById('divDetailArea') ;
  el.innerHTML = '' ;
//  while (el.hasChildNodes()) { el.removeChild(el.firstChild) ; } ;
  var html = '<table class="orderDetail">' ;
  html += '<thead><tr><th>'+mObj.hdrQuantity+'</th><th>'+mObj.hdrPicked+'</th><th>'+mObj.hdrNeed+'</th><th>'+mObj.hdrItem+'</th><th>'+mObj.hdrDescription+'</th></tr></thead>' ;
  html += '<tbody>' ;
  for(var ix=0;ix<jObj['itemList'].length;ix++)
   { 
     html += '<tr>' ;
     html += '<td class="'+(jObj['itemIsBO'][ix] ? 'boItem' : 'orderQty')+'">'+jObj.itemQty[ix]+'</td>' ;
     if (jObj['itemIsBO'][ix]) { html += '<td class="boItem">--</td>' ; }
      else { html+= '<td class="orderQty">'+jObj['itemPicked'][ix]+'</td>' } ;
     if (jObj['itemIsBO'][ix]) { html += '<td class="boItem">--</td>' ; }
      else if (jObj['itemPicked'][ix] == jObj['itemQty'][ix]) { html += '<td class="orderQty">&nbsp;</td>' ; } 
      else { html += '<td class="missingQty">'+(jObj['itemQty'][ix] - jObj['itemPicked'][ix])+'</td>' ; } ;
     html += '<td'+(jObj['itemIsBO'][ix] ? ' class="boItem"' : '')+'>'+jObj['itemList'][ix]+'</td>' ;
     html += '<td'+(jObj['itemIsBO'][ix] ? ' class="boItem"' : '')+'>'+jObj['itemDesc'][ix]+'</td>' ;
     html += '</tr>' ;
   } ;
  html += '</tbody>' ;
  html += '</table>' ;
  el.innerHTML = html ;
//  var table = document.createElement('table') ; table.setAttribute('className','orderDetail') ;
//  var thead = document.createElement('thead') ;
//  var tr = document.createElement('tr') ; thead.appendChild(tr) ;
//  var th = document.createElement('th') ; th.innerHTML = mObj.hdrQuantity ; tr.appendChild(th) ;
//  th = document.createElement('th') ; th.innerHTML = mObj.hdrPicked ; tr.appendChild(th) ;
//  th = document.createElement('th') ; th.innerHTML = mObj.hdrNeed ; tr.appendChild(th) ;
//  th = document.createElement('th') ; th.innerHTML = mObj.hdrItem ; tr.appendChild(th) ;
//  th = document.createElement('th') ; th.innerHTML = mObj.hdrDescription ; tr.appendChild(th) ;
//  table.appendChild(thead) ;
//  var tbody = document.createElement('tbody') ; table.appendChild(tbody) ;
//  for(var ix=0;ix<jObj['itemList'].length;ix++)
//   { var tr = document.createElement('tr') ;
//     var td = document.createElement('td') ; td.innerHTML = jObj.itemQty[ix] ; tr.appendChild(td) ; td.setAttribute('className',(jObj['itemIsBO'][ix] ? 'boItem' : 'orderQty')) ;
//     td = document.createElement('td') ;
//       if (jObj['itemIsBO'][ix]) { td.innerHTML = '--' ; tr.appendChild(td) ; td.setAttribute('className','boItem') ; }
//        else { td.innerHTML = jObj['itemPicked'][ix] ; tr.appendChild(td) ; td.setAttribute('className','orderQty') ; } ;
//    td = document.createElement('td') ;
//      if (jObj['itemIsBO'][ix]) { td.innerHTML = '--' ; td.setAttribute('className','boItem') ; }
//       else if (jObj['itemPicked'][ix] == jObj['itemQty'][ix]) { td.innerHTML = '' ; td.setAttribute('className','orderQty') ; }
//       else { td.innerHTML = jObj['itemQty'][ix] - jObj['itemPicked'][ix] ; td.setAttribute('className','missingQty') ; } ;
//      tr.appendChild(td) ;
//     td = document.createElement('td') ; td.innerHTML = jObj['itemList'][ix] ; if (jObj['itemIsBO'][ix]) td.setAttribute('className','boItem') ; tr.appendChild(td) ;
//     td = document.createElement('td') ; td.innerHTML = jObj['itemDesc'][ix] ; if (jObj['itemIsBO'][ix]) td.setAttribute('className','boItem') ; tr.appendChild(td) ;
//     tbody.appendChild(tr) ;
//   } ;
//  el.appendChild(table) ;
  orderToggle = true ;
}
function showProductivity() {
  var el = document.getElementById('divProductivity') ;
  while (el.hasChildNodes()) { el.removeChild(el.firstChild) ; } ;
  var pNode = document.createElement('p') ; pNode.setAttribute('className','picks') ;
     var tNode = document.createTextNode(totalOrders+' '+mObj.msgOrders+', '+totalPicks+' '+mObj.msgItems) ;
     pNode.appendChild(tNode) ; el.appendChild(pNode) ;
     var pNode = document.createElement('p') ; pNode.setAttribute('className','rankHigh') ;
     var tNode = document.createTextNode(mObj.msgRanking+currentRanking) ;
     pNode.appendChild(tNode) ; el.appendChild(pNode) ;
}
function showPackaging(urlPrefix,imgArray) {
  var el = document.getElementById('divPackaging') ;
  while (el.hasChildNodes()) { el.removeChild(el.firstChild) ; } ;
  for(i=0;i<imgArray.length;i++)
   { var iNode = document.createElement('img') ; iNode.setAttribute('src',urlPrefix+imgArray[i]) ;
     el.appendChild(iNode) ;
   } ;
}
function clearCurrentOrder() {
  var el = document.getElementById('divDetailArea') ;
  el.innerHTML = '' ;
//  while (el.hasChildNodes()) { el.removeChild(el.firstChild) ; } ;
  if (currentOrder != 0) totalOrders-- ;
  var ip = jObj['itemPicked'] ;
  if (ip != null)
   { for(var i=0;i<ip.length;i++)
      { totalPicks -= ip[i] ; ip[i] = 0 ; } ;
   } ;
  el = document.getElementById('topRow') ;
  while (el.hasChildNodes()) { el.removeChild(el.firstChild) ; } ;
  showPackaging('',Array()) ;
  showProductivity() ;
  currentOrder = 0 ; lastItemIndex = -1 ;
  bcInputFocus() ;
} ;

