/******************************************************************************
  jsfunctions.js

  client-side variable & function definitions

  Revision History
  REC 1079  2005-03-30  Alina Gorelik    Original Version
  REC 1079  2005-08-15  John Hildebrand  added more Javascript code for this enhancement
  REC 1200  2008-01-03  John Hildebrand  Online Payments fix & redesigned web site enhancements
  REC 1398  2006-11-28  John Hildebrand  fix the shipping bill-to inputs
  REC 1423  2007-01-16  Kevin Majors     Added new functions
            2008-02-04  John Hildebrand  ViewImage update to fix FF & Safari display issues
  REC 1499  2008-11-14  John Hildebrand  blue bar unsecured port fix
  REC 1697  2010-02-03  John Hildebrand  multiple catalogs update
  REC 1192  2010-03-08  John Hildebrand  WILL CALL delivery option addition
  REC 1709  2010-07-30  John Hildebrand  navigation functions for dropdown links
  REC 1861  2010-08-04  Kevin Majors     Unsubscribe page functions
  REC 1861  2010-09-28  John Hildebrand  My Account Information page updates
  REC none  2011-06-17  John Hildebrand  dropdown & Quick Order Entry updates
  REC none  2011-07-11  John Hildebrand  remove +/- signs from the Blue Bar per Kathy Stevens
  REC none  2011-07-14  John Hildebrand  Quick Order Entry item number validation update
  REC none  2011-08-03  John Hildebrand  new Quick Order Entry error processing
  
*******************************************************************************/

//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//Global vairables
var gTAG_LEV = "Lev";                 //Level XML tag prefix (followed by level#)
var gTAG_NAM = "Name";                //Name  XML tag
var gTAG_OID = "oid";                 //oid   XML tag
var gTAG_ONE = "one";                 //one   XML tag
var gID_MENU = "MenuTree";            //ID name for the Menu Tree division
var gCOOKIE_PHOPNS = "OpenLines";     //Cookie name defining all open PH display lines
var gCOOKIE_PLSTATE = "LoadState";    //Cookie name for Page Load State
var gCOOKIE_NEXTPAGE  = "NextPage";   //Cookie name for Next Page
var gCOOKIE_DDIDCLK = "ddIDclk";      //Cookie name for clicked dropdown ID - 2011-08-03
var gMENU_OID_FILE = "ShowItems.asp"; //ASP source file to show items for an oid value
var gEXPIRE_PHOPNS = "90";            //Cookie expiration dur. minutes for open PH display lines
var gEXPIRE_PLOFFSTR = "0.06";        //Cookie expiration dur. for page load cookie - off (in minutes)
var gEXPIRE_PLONSTR = "480";          //Cookie expiration dur. for page load cookie - on  (in minutes)
var gEXPIRE_NEXTPAGE = "10";          //Cookie expiration dur. for next page navigation
var gEXPIRE_DDIDCLK = "0.02";         //Cookie expiration dur. for clicked dropdown ID - 2011-08-03
var gQUICK_INPUTS = 12;               //Number of item & quantity input textboxes for "Quick Order Entry"
var gLAST_PHS = "";                   //Last Product Hierarchy string opened
var gPH_STATE;                        //Product Hierarch display state string
var gWinImage;                        //Image Window
var gAjaxOutStr = "";                 //Ajax output string

// Global variables defined by the GetSysInfo function.
var gIE_flag = false;                 //Browser flags: Internet Explorer flag - defined by GetSysInfo
var gFF_flag = false;                 //Firefox flag - defined by GetSysInfo
var gSF_flag = false;                 //Safari flag - defined by GetSysInfo
var gMac_flag = false;                //Macintosh flag - defined by GetSysInfo
var gBrowserVersion;                  //Browser version number
var gBrowserName = "";                //Browser name
var gBrowserFullName = "";            //Full name of browser
var gQckErrAry = new Array(gQUICK_INPUTS);  //Error array for each Quick Order Entry textbox line
                                            // 0=no error;             1=item input error; 
                                            // 2=quantity input error; 3=item & quantity errors

var gOID_NONE="0";                    //Undefined value for oid (zero character)
var gPHR_NONE="0";                    //Undefined value for PH reference string
// PH string example: "1-1|1-2|2" means only the "Boxes" class (2) is open, "Barrier Bags" (1-1) and
//                    "Cellophane Bags" (1-2) are open but not displayed as such since the entire
//                    "Bags" class (1) is closed since it is not in this string.
// Note: "BBa" marks the Blue Bar All (open levels) update started on 2007-06-26.
var gPHR_DLIM="-";                    //Product hierarchy numeric value delimiter (between each level's seq#)
var gPHR_DLIM_RE = /\-/;              //Regular expression value for splitting the PH reference numbers
var gPHR_DLIM2="|";                   //Product hierarchy string delimiter (between each PH node's string) - BBa
var gPHR_DLIM2_RE = /\|/;             //Regular expression value for splitting the PH reference string     - BBa
var gPHR_OPEN="o";                    //Product hierarchy class & ref string open line indicator (closed if absent)
var gPHR_OPENOID="oo";                //PH class string for lines open w/ an oid value

var gMsg = "";                        //global message string for debug
var gPL_ON = "1";                     //Cookie value: ON  - Page Load
var gPL_OFF = "0";                    //Cookie value: OFF - Page Load
//Global vairables
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

function popUp(url) 
{
	sealWin=window.open(url,"win",'toolbar=0,location=0,directories=0,status=1,menubar=0,scrollbars=1,resizable=1,width=600,height=400');
	self.name = "mainWin";
}

//1423**
function popUpLarge(url) 
{
	sealWin=window.open(url,"win2",'toolbar=0,location=0,left=15,top=15,directories=0,status=0,menubar=0,scrollbars=1,resizable=1,width=700,height=450');
	self.name = "mainWin2";
}

//1423**
function popUpSmall(url) 
{
    var winOpts;   //window options    1200
    var win;       //window object     1200
    
//1200**sealWin=window.open(url,"win3",'toolbar=0,location=0,left=5,top=5,directories=0,status=0,menubar=0,scrollbars=1,resizable=1,width=500,height=270');
//1200**win.name = "mainWin3";
    //window.open arg1: url string; arg2: name string; arg3: window options string; arg4: replace window boolean.
    winOpts = "";
    winOpts = winOpts + "left=5,top=5";
    winOpts = winOpts + ",width=500,height=270";
    winOpts = winOpts + ",toolbar=no";
    winOpts = winOpts + ",location=no";
    winOpts = winOpts + ",directories=no";
    winOpts = winOpts + ",status=no";
    winOpts = winOpts + ",menubar=no";
    winOpts = winOpts + ",scrollbars=yes";
    winOpts = winOpts + ",resizable=yes";
    
    win = window.open(url, "win3", winOpts);
}

function ViewImage(ifile,ix,iy,ititle) //2007-12-12 - improve large image display
{ 
	var win;
	var winOpts;
	var xPad;
	var yPad;
	var xPad_IE = 8;
	var yPad_IE = 50;
	var xPad_FF = 4;
	var yPad_FF = 34;
	var xPad_SF = -40;
	var yPad_SF = -11;
	var xPad_FF_Mac = 0;
	var yPad_FF_Mac = 20;
	var xPad_SF_Mac = 0;  //was -48;
	var yPad_SF_Mac = 0;  //was -20;
	var img_html;
	var iWidth;
	var iHeight;
	var iWait;
	
	if (gIE_flag)
	{
	  xPad = xPad_IE;
	  yPad = yPad_IE;
	}
	else
	{
	  xPad = xPad_FF;
	  yPad = yPad_FF;
	  if (gMac_flag)
	  {
	    xPad = xPad_FF_Mac;
	    yPad = yPad_FF_Mac;
	  }
	  
	  if (gSF_flag)
	  {
	    xPad = xPad_SF;
	    yPad = yPad_SF;
	    if (gMac_flag)
	    {
	      xPad = xPad_SF_Mac;
	      yPad = yPad_SF_Mac;
	    }
	  }
	}
	
    iWidth = ix + xPad;
    iHeight = iy + yPad;
	
	//alert("ViewImage: image width=" + ix + ", image height=" + iy + ".");
	
    winOpts = "";
    winOpts = winOpts + "titlebar=yes";
    winOpts = winOpts + ",menubar=no";
    winOpts = winOpts + ",toolbar=no";
    winOpts = winOpts + ",directories=no";
    winOpts = winOpts + ",scrollbars=no";
    winOpts = winOpts + ",status=no";

    if (gIE_flag)
    {
      winOpts = winOpts + ",width="+ix;
      winOpts = winOpts + ",height="+iy;
    }
    else
    {
      winOpts = winOpts + ",innerWidth="+ix;
      winOpts = winOpts + ",innerHeight="+iy;
    }
    //    " onfocus=\"ViewImageResize();\" >" +   // 2008-02-04: switch to onload for FF & Safari
        
    //Define the HTML for the displayed image
    img_html = "<HTML><HEAD><TITLE>" + ititle + "</TITLE></HEAD>" +
        "<BODY ALIGN=\"CENTER\" LEFTMARGIN=\"0\" MARGINWIDTH=\"0\" TOPMARGIN=\"0\" MARGINHEIGHT=\"0\"" +
        " onload=\"ViewImageResize();\" >" +
        "<SCRIPT language=\"JavaScript\" src=\"/template2/jsfunctions.js\"></SCRIPT>" +
        "<div style=\"position:absolute;left:0px;top:0px;margin:0px 0px 0px 0px;\">" +
        "<IMG SRC=\"" + ifile + "\" ALT=\"" + ititle + "\" NAME=\"ViewImage\">" +
        "</div></BODY></HTML>";
        
	//**BAD for Safari**gWinImage = window.open("#","imageviewer",winOpts);
	gWinImage = window.open("","imageviewer",winOpts);
	gWinImage.defaultStatus = ititle;
	gWinImage.document.open();
    gWinImage.document.write(img_html);
    gWinImage.document.close();
    
    gWinImage.focus();

}  // end of ViewImage function

function ViewImageResize()
{
  var iWidth;
  var iHeight;
  var wPad;
  var hPad;
  var wNew;
  var hNew;
  
  GetSysInfo();

  iWidth = document.images[0].width;
  iHeight = document.images[0].height;
  
  if (gIE_flag)
  {
    wPad = 10;
    hPad = 49;
    if (gBrowserVersion > 6)
    {
      //hPad = 71;
      hPad = 29;
    }
  }
  else
  {
    wPad = window.outerWidth - window.innerWidth;
    hPad = window.outerHeight - window.innerHeight;
  }
  
  wNew = iWidth + wPad;
  hNew = iHeight + hPad;

  //**alert("ViewImageResize: Start: gBrowserName=" + gBrowserName + "\n" +
  //**  "    img width | height=" + iWidth + " | " + iHeight + "\n" +
  //**  "    pad width | height= " + wPad + " | " + hPad + "\n" +
  //**  "    new width | height= " + wNew + " | " + hNew + "\n");
  
  window.resizeTo(wNew, hNew);
  
  window.focus();
  
} //ViewImageResize function

function Check()
{
if (document.OrderSearch.keyword.value == "" && document.OrderSearch.From.value == "" && document.OrderSearch.To.value == "" )
	{
		return (false);
	}
else
	{
		return (true);
	}
}

//1192***function On_POButton()
function On_POButton(sShipMethodID)   //1192
{
    //**alert("On_POButton: sShipMethodID=" + sShipMethodID);  //1192
//1192**document.summary.action = "po.asp";
	document.summary.action = "po.asp?ship_method_id=" + sShipMethodID;   //1192
	document.summary.submit();			// Submit the page
	return (true);
}

//1192**function On_CCButton()
function On_CCButton(sShipMethodID)   //1192
{
    //**alert("On_CCButton: sShipMethodID=" + sShipMethodID);  //1192
//1192**document.summary.action = "crdtcard.asp";
	document.summary.action = "crdtcard.asp?ship_method_id=" + sShipMethodID;  //1192
	document.summary.submit();			// Submit the page
	return (true);
}

function skip () { this.blur(); }

function adjustTextFields(startName, endName)
{
  var tb_num;            //Textbox number
  var tb_nam;            //Textbox name
  var tb_nam_enable;     //Textbox name to enable
  var tagList;           //Tags with specified name (should have no more than one tag per name)
  var dis_flag;          //disable flag (true or false)
  
  //alert("adjustTextFields: tbox name = |" + startName + endName + "|");  //**TEMP**
  
  tb_nam_enable = startName + endName;
  
  for (tb_num=0; tb_num < 20; tb_num++)  //Loop through the Bill-To Account input text boxes (assumes 20 or less)
  {
    //alert("adjustTextFields: check text box#" + String(tb_num) + ".");   //**TEMP**
    
    tb_nam = startName + String(tb_num);
    //alert("adjustTextFields: looking for tbox with name = |" + tb_nam + "|");  //**TEMP**
    
    tagList = document.getElementsByName(tb_nam);
    //alert("adjustTextFields: tbox name=|" + tb_nam + "|, has length=" + String(tagList.length) + ".");  //**TEMP**
    
    if (tagList.length > 0)
    {
      dis_flag = true;
      if (tb_nam == tb_nam_enable)
      {
        dis_flag = false;  //Enable (disable=false) the Bill-To Account# text box for the selected shipping method
      }
      if (dis_flag == true)
      {
        document.getElementsByName(tb_nam)[0].value = '';         //Clear contents value of disabled text boxes
      }
      document.getElementsByName(tb_nam)[0].disabled = dis_flag;  //Set the disable flag for this text box
    }
    else
    {
      if (tb_num > 0)
      {
        //alert("adjustTextFields: text box#" + String(tb_num) + " was NOT found - exiting search loop.");   //**TEMP**
        break;  //stop search for bill-to account text boxes if none found after the 1st text box
      }
    }
    
  }
} // adjustTextFields

function displayAllMonths()
{
	if (document.CreditCard._cc_expmonth.size == 1)
	{
		document.CreditCard._cc_expmonth.size = 13;
	}
	else
	{
		document.CreditCard._cc_expmonth.size = 1;
	}
}

function displayAllMonthsPayOnline()
{
	if (document.PayOnline._cc_expmonth.size == 1)
	{
		document.PayOnline._cc_expmonth.size = 13;
	}
	else
	{
		document.PayOnline._cc_expmonth.size = 1;
	}
}

function displayAllMonthsNew(formname)
{	
	if (document.formname._cc_expmonth.size == 1)
	{
		document.formname._cc_expmonth.size = 13;
	}
	else
	{
		document.formname._cc_expmonth.size = 1;
	}
}
function checkAcrobatAdvanced()
{
	var p;
	var i;
	var ptext;
	var agent = navigator.userAgent.toLowerCase();
	var acrobatversion = 0;
	var detected = 0;
	
	if (navigator.plugins != null && navigator.plugins.length > 0)
	{
	  //alert("checkAcrobatAdvanced: navigator.plugins is defined.");  //***TESTING ***
	  
	 /* This works for NS3+, IE5+ MAC, Opera3+, etc. */
	 /*	confirm ("plugins found");    */
	    for (i=0; i < navigator.plugins.length; i++)
	    {
	      if ((navigator.plugins[i].description.indexOf('Adobe Acrobat') != -1) ||
	         (navigator.plugins[i].name.indexOf('Adobe Acrobat') != -1))
	      {
			/* confirm ("Acrobat detected"); - FF/PC */
			//alert("checkAcrobatAdvanced: description=|" + navigator.plugins[i].description + "|.");  //**TESTING**
			acrobatversion = parseFloat(plugin.description.substring(30));
			detected = 1;
		  }
		}
		if (navigator.mimeTypes["application/pdf"] != null)
		{
			/* confirm ("Acrobat detected with mimetype"); */
			//alert("checkAcrobatAdvanced: Acrobat mimetype detected.");  //**TESTING**
			detected = 1;
		}
		if ((acrobatversion != 0) || (detected == 1))
		{
		    //alert("checkAcrobatAdvanced: IE7/FF - returning True.");  //***TESTING***
			return(true);
		}
		else
		{
			/* confirm ("Acrobat not detected"); */
			return(false);
		}
	}
	else
	{	 	
        //alert("checkAcrobatAdvanced: navigator.plugins is NOT defined.");  //***TESTING *** - IE6,IE7
	  
		/* This works for Win IE4+ : attempt to create ActiveX object */	
		try {
		// 2007-11-08***p = new ActiveXObject('AcroExch.Document');
		p = new ActiveXObject('AcroPDF.PDF');  // 1200 - 2007-11-08
		}
		catch (e)
		{
		    //alert("checkAcrobatAdvanced: IE - returning FALSE - due to error.");  //***TESTING***
			return(false);
		}
		if (p) {
		    //alert("checkAcrobatAdvanced: IE - returning True.");  //***TESTING***
			return(true);	
		}	
		else {
		    //alert("checkAcrobatAdvanced: IE - returning FALSE - due to missing object.");  //***TESTING***
			return(false); 
		}	
	}
}	

// REC 1079 8/15/2005 updates vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

  var gbl_sClickType = "one";       //global str var indicates if one or all checkboxes are being processed
  var gbl_tl_col = 1;               //global total payment column number for PAY_TABLE

// Does processing when "Check All" button clicked.
function doCheckboxClick(cb_num, cb_group, pay_table, tb_group)
{
  // Args:  cb_num     I/   checkbox value for the checkbox clicked
  //        cb_group   I/   checkbox group object, input required for doUpdateTotal
  //        pay_table  I/O  payment table, looks at Amount Due value to define payment amount and updates total payment amount
  //        tb_group   I/O  textbox group object for row,  can update Payment textbox based on current value and checkbox setting

  var n;                 //checkbox & textbox row number (1st = zero)
  var cb_len;            //length of checkbox group
  var bDoUpdate          //Do update boolean var

  cb_len = cb_group.length;

  n = Number(cb_num);
  //alert("doCheckboxClick: cb_num=" + cb_num);   //**TEMP**

  if (cb_group[n].checked)         //If checkbox is checked
  {
    //alert("Checkbox checked.");   //**TEMP**
    //Let the doUpdateTotal function assign the payment amount
  }
  else                             //Else checkbox is unchecked
  {
    //alert("Checkbox unchecked.");  //**TEMP**
    tb_group[n].value = "";        //  Clear the applicable textbox
  }

  bDoUpdate = false;
  if (gbl_sClickType == "one")     //If only one checkbox
  {
    bDoUpdate = true;              //  Enable update of the payments & totals - single checkbox clicked
  }
  else if (n >= cb_len-1)          //Else if last checkbox
  {
    bDoUpdate = true;              //  Enable update of the payments & totals - last checkbox of group clicked
  }

  if (gbl_sClickType == "one")                     //If only one checkbox
  {
    doUpdateTotal(cb_group, pay_table, tb_group);  //  Update the total after check all
  }                                                //End if

  //alert("* * * Checkbox #" + cb_num + " of " + cb_len + " was clicked. * * *");   //**TEMP**

}  //doCheckboxClick function end

// Does processing when "Check All" button clicked.
function doCheckAll(cb_group, pay_table, tb_group)
{
  var cb_num;            //number of check boxes
  var n;                 //loop counter

  cb_num = cb_group.length;

  gbl_sClickType = "all";        //Disable checkbox onclick updates

  for (n = 0; n < cb_num; n++)   //Check boxes loop start
  {
    if (!cb_group[n].checked)    //  If not checked
    {
      cb_group[n].click();       //    Check this checkbox
    }
  }                              //Check boxes loop end

  gbl_sClickType = "one";        //Enable checkbox onclick updates

  doUpdateTotal(cb_group, pay_table, tb_group);  // Update the total after check all

  //**alert("* * * Check All buton was clicked. * * *" + " Button count = " + cb_num);

}  //doCheckall function end

// Does processing when "Clear All" button clicked.
function doClearAll(cb_group, pay_table, tb_group)
{
  var cb_num;            //number of check boxes
  var n;                 //loop counter

  cb_num = cb_group.length;

  gbl_sClickType = "all";        //Disable checkbox onclick updates

  for (n = 0; n < cb_num; n++)   //Check boxes loop start
  {
    if (cb_group[n].checked)     //  If checked
    {
      cb_group[n].click();       //    Uncheck this checkbox
    }

    tb_group[n].value = "";      //  Clear this textbox

  }                              //Check boxes loop end

  gbl_sClickType = "one";        //Enable checkbox onclick updates

  doUpdateTotal(cb_group, pay_table, tb_group);  // Update the total after clear all

  //**alert("* * * Clear All buton was clicked. * * *" + " Button count = " + cb_num);

}  //doClearall function end

// Does processing when "Update Total" button clicked.
function doUpdateTotal(cb_group, pay_table, tb_group)
{
  // Args:
  //       cb_group    I/O    checkbox object group
  //       pay_table   I/O    payment table object
  //       tb_group    I/O    text box object group for invoice payments
  //
  // This function updates the corresponding Payment textbox based on the
  // applicable checkbox setting, Amount Due, and current textbox value.

  var num;               //number elements in cb_group & tb_group; pay_table has +2 more rows (header & footer)
  var n;                 //loop counter
  var ad_col = 3;        //Amount Due column offset number
  var sDols;             //Dollars string

  var total = new Number(0);  //updated total amount
  var pAmt = new Number(0);   //Payment amount
  var subt = new Number(0);   //Subtotal amount
  var fSts = new Object();    //Format dollars status

  num = cb_group.length;

  for (n = 0; n < num; n++)     //Group loop start
  {
    //Set payment amount in the payment textbox.

    setPayment(pay_table.rows[n+1].cells[ad_col].innerHTML, cb_group[n], tb_group[n]);

    //alert("doUpdateTotal: calling formatDollars w/ tb_group[n].value");  //**TEMP**
    sDols = formatDollars(tb_group[n].value, fSts);
    if (sDols == "")
    {
      pAmt = 0;
    }
    else
    {
      pAmt = parseFloat(sDols);
    }

    subt += pAmt;
    total = parseFloat( subt.toFixed(2) );  //Note: this was done to remove a rounding & truncation error.
    subt = total;
    //alert("doUpdateTotal: pAmt=" + pAmt + "; subtotal=" + total);	   //**TEMP**
  }                              //Group loop end

  //pay_table.rows[num+1].cells[tl_col].innerHTML = "$" + formatDollars(""+total, fSts);  //Update total payment amount
  setTotal(total, num+1, gbl_tl_col, pay_table);  //Update total payment amount

}  //doUpdateTotal function end

// Checks payment total and returns true if greater than zero.
function checkPayTotal(cb_group, pay_table, tb_group)
{
  // Args:  pay_table   I/   table object with Total Payment amount


  var tLen;        //Number of rows in the payment table
  var htmlTotal;   //HTML total payment string (w/ FONT tags)
  var sTotal;      //Total payment string (w/o FONT tags)
  var nTotal;      //numeric total
  var chkSts;      //check status flag

  doUpdateTotal(cb_group, pay_table, tb_group);        //update done in textbox changes made w/o pressing update total

  tLen = pay_table.rows.length;

  htmlTotal = pay_table.rows[tLen-1].cells[gbl_tl_col].innerHTML;    //get the HTML total payment string
 
  sTotal = htmlTotal.replace(/(<FONT.*>)(.*)(<\/FONT>)/, "$2");      //get the total payment string w/o FONT tags
  sTotal = sTotal.replace(/(<font.*>)(.*)(<\/font>)/, "$2");         //get the total payment string w/o font tags
  sTotal = sTotal.replace(/\$/, "");                                 // remove 1st "$" char.

  //##alert("checkPayTotal: pay_table #rows=" + tLen + "; total=" + sTotal);

  chkSts = false;                       //Assume payment total is NOT more than zero

  if (!isNaN(sTotal))                   //If a number
  {
    if (Number(sTotal) > 0)             //  If number is greater than zero
    {
      chkSts = true;                    //    Set check payment total return to true
    }
  }

  if (!chkSts)
  {
   //**Show this message and don't advance to the credit card payment page.

   //alert("*** Payment total is not greater than zero; Total=" + sTotal + " ***");
  }

  return chkSts;  //Return boolean -  true   or false

}  //checkPayTotal function end

// Set payment amount in the payment textbox.
function setPayment(amtDue, cbox, tbox)
{
  // Args:  amtDue  I/   amount due string for row (has leading '$' character to remove)
  //        cbox    I/O  checkbox object for row, can check or uncheck based on input text
  //        tbox    I/O  textbox object for row,  can update text based on current value and checkbox setting

  var fDue;                 //formated amount due
  var fTxt;                 //formated string from textobx
  var fSts = new Object();  //format dollars status

  //alert("setPayment: START - amtDue=|" + amtDue + "|");  //**TEMP**

  //alert("setPayment: calling formatDollars w/ amtDue");  //**TEMP**
  fDue = formatDollars(amtDue, fSts);
  //alert("setPayment: calling formatDollars w/ tbox.value");  //**TEMP**
  fTxt = formatDollars(tbox.value, fSts);

  if (fSts.valid)                             // If valid input
  {
    if (fSts.zero)                            // --If zero payment entered
    {
      if (cbox.checked)                       // ----If checkbox checked
      {
        //alert("#1-1: valid, zero, checked; set payment to empty string, uncheck checkbox.");  //**TEMP**
        tbox.value = ""  ;                    //       Use amount due as payment
        cbox.click();                         //       Uncheck the checkbox
      }
      else                                    // ----Else (checkbox NOT checked)
      {
        //alert("#1-2: valid, zero, unchecked; set payment to empty string.");  //**TEMP**
        tbox.value = "";                      //       Use empty string as payment
      }
    }
    else                                      // --Else (valid, non-zero payment)
    {
      if (fTxt == "")                         // ----If formated payment is empty
      {
        if (cbox.checked)                     // ------If checkbox checked
        {
          //alert("#2-1: valid, empty, checked; set payment to amount due.");  //**TEMP**
          tbox.value = fDue;                  //         Use amount due as payment
        }
        else                                  // ------Else (checkbox NOT checked)
        {
          //alert("#2-2: valid, empty, unchecked; set payment to empty string.");  //**TEMP**
          tbox.value = "";                    //         Use empty string as payment
        }
      }
      else                                    // ----Else (formated payment is NOT empty)
      {
        if (Number(fTxt) > Number(fDue))      // ------If payment greater than amount due
        {
          //alert("#2-3: valid, non-zero, > amount due; set payment to amount due.");  //**TEMP**
          tbox.value = fDue;                  //         Use amount due as payment
        }
        else                                  // ------Else (payment <= amount due)
        {
          //alert("#2-4: valid, non-zero, <= amount due; set payment to reformated payment.");  //**TEMP**
          tbox.value = fTxt;                  //         Use input as payment
        }
        if (!cbox.checked)                    // ------If checkbox NOT checked
        {
          //alert("#2-5: valid, non-zero, unchecked; check the checkbox.");  //**TEMP**
          cbox.click();                       //         Check the checkbox
        }
      }
    }
  }
  else if (fSts.bad)                          // Else if bad input
  {
    //alert("#3-1: bad input; use amount due as payment.");  //**TEMP**
    tbox.value = fDue;                        //   Use amount due as payment
    if (!cbox.checked)                        // --If checkbox NOT checked
    {
      //alert("#3-2: bad input, unchecked; check the checkbox.");  //**TEMP**
      cbox.click();                           //     Check the checkbox
    }
  }

  //alert("setPayment: END");  //**TEMP**

}  //setPayment function end

// Sets the total payment amount after all other processing is done.
function setTotal(total, nRow, nCol, pay_table)
{
  var pre_tag;               //tag before the total payment amount
  var pst_tag;               //tag after the total payment amount
  var sTotal;                //new total in string format
  var old_sTotal;            //old total amount with font tags
  var fSts = new Object();   //format status object

                                         //vvvvvvvvvvvvv-- this string needs to match the FIELD_PAYMENT_TOTAL constant
  var pay_total = document.getElementById('payment_total');  // Get "payment_total" hidden input

  //alert("setTotal: old total = " + pay_total.value);         //***TEMP***

  pay_total.value = total;                                   // Set new value for the "payment_total" hidden input

  sTotal = "" + total;                                               //convert total amount to string

  old_sTotal = pay_table.rows[nRow].cells[nCol].innerHTML;   //**TEMP**           //get the old total payment amount
  //alert("old_sTotal=|" + old_sTotal + "|");
  //20060929**pre_tag = old_sTotal.replace(/(<FONT.*>)(.*)(<\/FONT>)/, "$1");    //get the leading font tag
  //20060929**pst_tag = old_sTotal.replace(/(<FONT.*>)(.*)(<\/FONT>)/, "$3");    //get the trailing font tag

  //20060929**sTotal = pre_tag + "$" + formatDollars(sTotal, fSts) + pst_tag;
  sTotal = "$" + formatDollars(sTotal, fSts);
  //alert("setTotal: pre_tag=|" + pre_tag + "|, pst_tag=|" + pst_tag + "|, sTotal=|" + sTotal + "|");   //**TEMP**
  pay_table.rows[nRow].cells[nCol].innerHTML = sTotal;             //define the new total payment amount

}  //setTotal function end

// Format a monetary amount string.
function formatDollars(iStr, fSts)
{
  // Args:   iStr  I/   input string of a dollar amount with or without a dollar sign (could have invalid characters)
  //         fSts   /O  output object with these boolean properties: valid, zero, bad
  //         
  // Return: oStr   /O  output string in n,nnn.nn format or empty string if <= zero or has invalid chars

  var  oStr;           //returned output of formatted monetary string
  var  temp;           //temporary work string
  var  temp1; //**TEMP**
  var  temp2; //**TEMP**

  oStr = "";           //assume an empty string result

  reset_fSts(fSts);    //initialize format status flags

  temp = iStr;

  temp = temp.replace(/(<FONT.*>)(.*)(<\/FONT>)/, "$2");  // remove FONT tags
  temp = temp.replace(/(<font.*>)(.*)(<\/font>)/, "$2");  // remove font tags (for FireFox)
  temp1 = temp;  //**TEMP**

  temp = temp.replace(/\$/, "");        // remove 1st "$" char.
  temp = temp.replace(/\,/g, "");       // remove all "," chars. - has /global switch
  temp = temp.replace(/\s/g, "");       // remove all whitespace
  temp = temp.replace(/\+/g, "");       // remove all "+" chars.
  temp2 = temp;  //**TEMP**

  if (temp == "")                           // if empty string
  {
    fSts.valid = true;
  }
  else if (isNaN(temp))                     // else if Not A Number, return empty string
  { 
    temp = "";
    fSts.bad = true;
    //alert("formatDollars: iStr=|" + iStr + "|; temp1=|" + temp1 + "|; temp2=|" + temp2 + "|");  //**TEMP**
  }
  else                                      // else (it is a number)
  {

    temp = temp.replace(/(\d*)(\.)(\d{2})(.*)/, "$1$2$3");  // remove least significant digits below a penny (.01)

    if (Number(temp) == 0)                  // --if zero
    {
      fSts.valid = true;
      fSts.zero = true;
      temp = "";
    }
    if (Number(temp) < 0)                   // --else if less than zero
    {
      fSts.bad = true;
      temp = "";
    }
    else                                    // --else (greater than zero)
    {
      fSts.valid = true;

      if (temp.search(/\./) < 0)            // ----if no period found (whole number)
      {
        temp = temp + ".00";                //       append period and double zeroes
      }
      else                                  // ----else (period was found)
      {
        temp = temp + "00";                                     // append double zeroes
        temp = temp.replace(/(\d*)(\.)(\d{2})(.*)/, "$1$2$3");  // remove least significant digits below a penny (.01)
      }

      if (temp.search(/^\./) >= 0)          // ----if 1st char is a period
      {
        temp = "0" + temp;                  //       insert leading zero
      }
    }
  }

  //alert("After < penny digits removed: " + temp);

  oStr = temp;
  
  //alert("formatDollars: oStr=|" + oStr + "|");  //**TEMP**

  return oStr;

} //formatDollars function end

// Reset the format status object to all false.
function reset_fSts(fSts)
{
  fSts.valid = false;
  fSts.zero  = false;
  fSts.bad   = false;
} //reset_fSts function end


// REC 1079 8/15/2005 updates ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

// REC 1200 02/27/2006 updates vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

// Get value of the specified hidden field - 2006-02-27
function get_hidden_value(fid, fvalue)
{
  fvalue = "";
  
  fvalue = document.getElementById(fid).innerHTML;
  
  if (fvalue == "") then
  {
    return (false);
  }
  return (true);
}

function GetXML_ProductHierarchy() {    //Gets the ProductHierarchy.xml file from the server.
  var xmlObj = new Object();
  var xmlfile = "/ProductHierarchy.xml";
  var secs;     //elapsed time in seconds
  var OK_flag;
  
  OK_flag = true;
  xmlObj = GetXmlHttpObject();
  
  if (xmlObj === false)  //Check for bad return status
  {
    alert("GetXML_ProductHiearchy: bad return status from GetXmlHttpObject call.");
    OK_flag = false;
  }
  
  if (OK_flag)
  {
    try {                                        //try to get the XML file synchronously
      var t1 = new Date();		                 //start time
      xmlObj.open("GET", xmlfile, false);
      xmlObj.send("");
      xmldoc = xmlObj.responseXML;
      var t2 = new Date();		                 //end time
      secs = (t2.getMinutes() - t1.getMinutes())*60 + (t2.getSeconds() - t1.getSeconds()) + (t2.getMilliseconds() - t1.getMilliseconds())/1000;
      //alert("GetXML_ProductHierarchy: Success getting the XML file; load time in seconds=" + secs);
    } catch (e) {
      OK_flag = false;
      alert("GetXML_ProductHierarchy: ERROR getting the XML file.");
    }
  }
  if (OK_flag)
  {
    return xmldoc;
  }
  return false;
  
}  //**End of function GetXML_ProductHierarchy

function GetXmlHttpObject()        //Define the XMLHttpRequest Object with returned status flag
{
  var obj;             //XMLHttpRequest object
  var Sts_flag;
  
  Sts_flag = false;
  
  if (window.XMLHttpRequest)
  {
    try {
      obj = new XMLHttpRequest();    //for IE7, Firefox and Safari
      Sts_flag = true;
      //alert("GetXmlHttpObject: Success with XMLHttpRequest();");
    } catch(e) {
      Sts_flag = false;
      alert("GetXmlHttpObject: ERROR with XMLHttpRequest();");
    }
  }
  else if (window.ActiveXObject)
  {
    try {
      obj = new ActiveXObject("Msxml2.XMLHTTP");           //for IE6 browsers
      Sts_flag = true;
      //alert("GetXmlHttpObject: Success with Msxml2.XMLHTTP");
    } catch (e) {
      try {
        obj = new ActiveXObject("Microsoft.XMLHTTP");      //for older IE browsers
        Sts_flag = true;
        //alert("GetXmlHttpObject: Success with Microsoft.XMLHTTP");
      } catch (e) {
        Sts_flag = false;
        alert("GetXmlHttpObject: ERROR with window.ActiveXObject");
      }
    }
  }
  
  if (Sts_flag)
  {
    return obj;
  }
  return false;
  
}   //**End of function GetXmlHttpObject

function Menu_Tree()   //Menu_Tree function
{
  var ns_port;         //Non-secure port number                       (Required Input)
  var phr_str;         //Product Hierarchy reference string           (Optional Input)
  var oid;             //Product Hierarchy location object identifier (Optional Input)
  //Note: when oid is specified, phr_str is required
  //      when oid > 0, then main page is to be updated
  //      when oid = 0 (or undefined), the product hierarchy menu tree is updated
  //      when neither phr_str & oid are specified, the top (1st) level of the product hierarchy is displayed

  var lnum;                      //Level#
  var click_flag;                //Clicked menu tree line flag
  var line_flag;                 //Line flag (true when node on menu tree matches clicked level line)
  var close_flag;                //Close flag (open line was clicked and is to be closed)
  var xmldoc;                    //Declare XML document object
  
  click_flag = false;           //assume that no menu line was clicked
  close_flag = false;           //assume that no open line is being closed
  
  GetSysInfo();                 //Get browser related information from system
  
  xmldoc = GetXML_ProductHierarchy();  //Read the Product Hierarchy XML file
  if (xmldoc === false)           //If boolean (not object) returned and is false
  {
    alert("Menu_Tree: ERROR - unable to access the product hierarchy file.");
    return;
  }
    
  // 3 input arguments:
  // #1 - non-secure http port number
  // #2 - product hiearchy reference string: e.g. "3/4o" >> 3rd line of Level#1, 4th line of Level#2, line is open
  //                  "5/2/3" >> 5th line of Level#1, 2nd line of Level#2, 3rd line of Level#3, line is closed
  // #3 - oid number of this line (optional, lower levels assumed if not specified) >> 
  //      if non-zero, causes this function to display items in main content area via server when line is clicked
  //================================================================================================================
  
  //Examine the input arguments
  phr_str = gPHR_NONE;    //Default argument values - will generate the top level only of the PH menu tree
  oid = gOID_NONE;
  
  if (firstloadcheck("Menu_Tree"))           //If loading 1st page
  {
    resetPH();                               //  Reset the PH display if 1st page load for this site
  }
  else                                       //Else
  {
    gPH_STATE = ReadCookie(gCOOKIE_PHOPNS);  //  Read the current PH display state
  }                                          //End if
  
  if (Menu_Tree.arguments.length > 0) {              
    click_flag = true;
    ns_port = Menu_Tree.arguments[0];
    if (Menu_Tree.arguments.length > 1) {              //  if Blue Bar was clicked then
      phr_str = Menu_Tree.arguments[1];
      //alert("Menu_Tree: Inputs #1,#2 - ns_port=" + ns_port +", phr_str = " + phr_str);
      if (Menu_Tree.arguments.length > 2) {
        if (!isNaN(Menu_Tree.arguments[2])) {          //    if oid is a valid number
          if (Menu_Tree.arguments[2] > 0) {            //      if oid is greater than zero
            oid = Menu_Tree.arguments[2];              //        Define the oid
          }                                            //      end if
          //alert("Menu_Tree: Input #3 - oid = " + oid);
        }                                              //    end if
      }                                                //  end if
    }
    close_flag = UpdatePHstate(phr_str, oid);        //  Update the product hierarchy display state
  }
  else                                               //Else (Blue Bar not clicked - other page update)
  {
    //**alert("Menu_Tree: no inputs; gPH_STATE = " + gPH_STATE);
  }                                                  //End if
  
  if ( (oid != gOID_NONE) && (close_flag != true) )    //If opening an oid line then
  {
    MenuTreeItems(ns_port, oid);                       //  Update Center Content area for this oid value
  }
  else                                                 //Else (non-oid line clicked)
  {
    GrowMenuTree(ns_port, xmldoc);                     //  Display PH in the Blue Bar area
  }                                                    //End if

  return;

}  //**End of function Menu_Tree

function GrowMenuTree(ns_port, xmldoc)
{
// GrowMenuTree inputs:  
//                       xmldoc    - XML document containing the product hierarchy above the item level
//                       ns_port   - non-secure port number

  var lnum;                   //Level number
  var root;                   //XML file's root node
  var lev1;                   //Level #1 node below the root node
  var num;                    //Node number for looping
  var nod;                    //XML node object
  var new_phs;                //Newest product hierarchy string to have been opened
  
  //alert("GrowMenuTree: Start.");
  root = xmldoc.documentElement;
  if (root == null)
  {
    alert("RewriteMenuTree: XML file's root element is null.");
  }
  
  lnum = 1;  //Initialize level number (zero is first)
  //alert("GrowMenuTree: before GetPHLevel function call.");
  lev1 = GetPHLevel(root.childNodes, lnum);  //Get the "Lev1" node from the XML file
  if (lev1 === false)
  {
    alert("GrowMenuTree: Unable to access level#1 of the product hierarchy.");
    return;
  }
  
  var menu_div = document.getElementById(gID_MENU);
  var rcnt;  //removal count
  //alert("GrowMenuTree: MenuTree childNodes.length=" + menu_div.childNodes.length);
  rcnt = 0;
  gLAST_PHS = GetPHLast();
  
  for (num=menu_div.childNodes.length-1; num >= 0; num--)
  {
    if (num >= menu_div.childNodes.length) continue;
    nod = menu_div.childNodes[num];
    if (nod == null) break;
    switch (nod.nodeType)
    {
      //case 3:  // 3=text node, 8=comment node
      case 8: break;
              //alert("GrowMenuTree: node# " + (num+1).toString() + " of " + menu_div.childNodes.length +
              //", nodeName=" + nod.nodeName + ", nodeValue=" + GetNodeValue(nod) );
              
      default: rcnt++;  // 1=element node - main type of node to be removed
        //alert("GrowMenuTree: removing node# " + (num+1).toString() + ", type=" + nod.nodeType);
        menu_div.removeChild(nod);
    }
  }
  
  //alert("GrowMenuTree: removed node count = " + rcnt);
  pri_phs = "";  //At top of the product hierarchy, so no prior level references
  
  //Define a level on the PH menu tree
  MenuTreeLevel(lev1.childNodes, lnum, menu_div, pri_phs, ns_port); 
  
}  //function GrowMenuTree - end

function MenuTreeLevel(nodes, lnum, menu_div, pri_phs, ns_port)
{
  //==============================================================================================================
  // Inputs:
  //            nodes       - PH XML nodes corresponding to this level
  //            lnum        - level number of the current level
  //            menu_div    - menu tree division object (thing that lines append to for display)
  //            pri_phs     - prior level's product hierarchy reference string
  //            ns_port     - non-secure port number
  //==============================================================================================================
  var nn;                     //Node number
  var onenn;                  //Node number for one tag
  var snum;                   //Sequence number for line being appended to the Menu Tree
  var sstr;                   //Search string to find in the PH state string
  var sloc;                   //Location of search string in the PH state string
  var ltag;                   //Level tag name
  var name;                   //Name value for a line on this level
  var oid;                    //Object ID for a line on this level
  var drill_flag;             //Drill down to the next level flag
  var dmsg;                   //Drill down message
  var pcls_text;              //Class text for the menu tree paragraph being appended in the MenuTree division
  var ptag_text;              //Text for the paragraph tag to be appended to the MenuTree division
  var phr_str;                //Text for the aryPH argument value in the Menu_Tree function call
  var the_phs;                //Product hierarchy reference string for the current line
  var psym;                   //Paragraph symbol prefix for text of paragraph line on displayed menu tree
  var new_open_flag;          //Flag to indicate an open line on the displayed Menu Tree
  var one_flag;               //Flag indicates that only one item is on a lower level branch of the PH tree
  
  ltag = gTAG_LEV + (lnum+1).toString();            //Level tag for the next level down: "Lev#"
  
  //if (lnum == 1)
  //{
  //  alert("MenuTreeLevel: @Start - lnum=" + lnum + ", nodes.length=" + nodes.length + ", pri_phs=" + pri_phs + ", ph_state=" + gPH_STATE);
  //}
  
  if (nodes == null)
  {
    alert("MenuTreeLevel: nodes input is Null.");
    return;
  }
  if (nodes.length <= 0)
  {
    //alert("MenuTreeLevel: nodes.length = " + nodes.length);
    return;
  }
  
  if (lnum > 5) return false;  //Drill down safety stop (prevents excessive recursion)
    
  snum = 0;       //Initialize the line sequence number
              
  for(nn=0; nn < nodes.length; nn++)                  //Level line sequence loop - start
  {
    //if (lnum > 1) {
    //  alert("MenuTreeLevel: Lev" + lnum + ", node#" + nn + ", tagName = " + nodes[nn].tagName + ", nodes.length=" + nodes.length);
    //}
    
    one_flag = false;
    
    if (nodes[nn].tagName == gTAG_NAM)               //  If Name tag node
    {
      snum++;                                        //    Increment sequence number
      name = GetNodeValue(nodes[nn]);                //    Get the Name value
      oid = gOID_NONE;
      drill_flag = false;
      if (nodes[nn+1].tagName == gTAG_OID)           //    If next node has an OID tag
      {
        oid = GetNodeValue(nodes[nn+1]);             //      Define the OID value
        if (oid == "") oid = gOID_NONE;
        nn++;                                        //      Advance to the next node
        if (nn+1 < nodes.length)
        {
          onenn = 0;
          if (nodes[nn+1].tagName == gTAG_ONE)       //        If following node has an one tag
          {
            onenn = nn+1;
            one_flag = true;
            //alert("MenuTreeLevel: one tag at Lev=" + lnum +", node#=" + onenn + "\n");
          }                                          //        End if
        }
      }                                              //    End if
 
      //alert("MenuTreeLevel: Lev" + lnum + ", Seq#" + snum + ", Name=|" + name + "|, oid=|" + oid + "|");
      gMsg += "Lev" + lnum + ", Seq#" + snum + ", Name=|" + name + "|, oid=|" + oid + "|\n";
      
      var para = document.createElement("p");
      pcls_text = "LL" + lnum;  //class=<text> for the paragraph element being appended to MenuTree division
      
      new_open_flag = false;
      //Define the PH node reference string from which the drill down is to occur
      if (lnum == 1)
      {
        the_phs = snum.toString();
      }
      else
      {
        the_phs = pri_phs + gPHR_DLIM + snum;
      }
      
      sstr = gPHR_DLIM2+the_phs;
      //**2008-01-02**if (oid != gOID_NONE)
      //**2008-01-02**{
      //**2008-01-02**  sstr = sstr + gPHR_OPENOID;
      //**2008-01-02**}
      sstr = sstr + gPHR_DLIM2;
      
      sloc = -1;
      sloc = gPH_STATE.indexOf(sstr);

      if (sloc >= 0)
      {
        //alert("MenuTreeLevel: sloc=" + sloc + ", sstr=" + sstr + ", PH state=" + gPH_STATE);
        new_open_flag = true;
        if (oid == gOID_NONE)  //Only drill down if there is no object id (oid) assigned with this name tag
        {
          drill_flag = true;
        }
        //alert("MenuTreeLevel: sstr=" + sstr + ", New drill_flag=" + drill_flag + ", PH state=" + gPH_STATE);
      }

      phr_str = the_phs;
      //alert("MenuTreeLevel: phr_str (old) = [" + phr_str + "], the_phs (new) = [" + the_phs + "]");
      
      para.phr_str = phr_str;
      para.oid = oid;
      para.onclick=function(){ Menu_Tree( ns_port, this.phr_str, this.oid ); }  //Define Menu_Tree as the onclick function
      
      if (oid == gOID_NONE)
      {
        psym = "+&nbsp;";
        if ( new_open_flag )
        {
          psym = "-&nbsp;&nbsp;";
        }
      }
      else
      {
        psym = ">&nbsp;";                        //Closed "oid" line prefix - 2007-08-22
      }
            
      para.className = pcls_text;              //Set class attribute for this paragraph - this works!
//2011-07-11 *** para.innerHTML = psym + name;            //Define the display text for a PH display line
      para.innerHTML = name;            //Define the display text for a PH display line, 2011-07-11
      
      try
      {
        //Add a line to the menu division for this entry in the Product Hierarchy
        menu_div.appendChild(para);
      }
      catch(err)
      {
        alert("MenuTreeLine: appendChild error=|" + err.description + "|.");
      }

      continue;                                      //    Resume looping (need Lev tag for drill down)
    }                                                //  End if (if name tag)
    
    if (!drill_flag)
    {
      //alert("Drill down check msg = |" + dmsg + "|");
      continue;  //Coninue looping without drilling down to the next level.
    }
    
    //*******alert("MenuTreeLevel: drilling down to the next level.");
    //Drill down 1 level deeper into the PH tree (recursive call to this function)
    
    MenuTreeLevel(nodes[nn].childNodes, lnum+1, menu_div, the_phs, ns_port);

  }                                                   //Level line sequnce loop - end
  
  //alert("MenuTreeLevel: @Exit - lnum=" + lnum + ", #Name nodes=" + snum);
    
}  //MenuTreeLevel function - end

function MenuTreeItems(ns_port, oid)     //Display Items in Center Content Area per selection from the Menu Tree
{
  var href_new;           //New href string
  var host;               //Url host string
  var this_port;          //Port# portion of current host string
  
  host = location.hostname;
  this_port = "";

  http_str = "http:";               //Default http protocol string
  if (location.port.length > 0)
  {
    this_port = ":" + ns_port;      //Define the non-secure port string
    //**1499**http_str = location.protocol;   //  Should be set on the test web sites
  }
  
  href_new = http_str + "//" + host + this_port + "/" + gMENU_OID_FILE + "?oid=" + oid;
  //alert("MenuTreeItems: href_new = |" + href_new + "|, ns_port=" + ns_port);  //*** TEMP Alert for testing
  
  location.href = href_new;
  
  return;
  
}  //MenuTreeItems function - end

function GetNodeValue(node)
{  //Return the node value of the specified node - this determination is browser specific
  var nv;          //node value
  
  nv = "";         //assume an empty string as the default node value
  
  if (node.nodeValue != null)
  {
    nv = node.nodeValue;					//for IE browsers
  }
  else
  {
    if (node.firstChild.nodeValue != null)
    {
      nv = node.firstChild.nodeValue;		//for non-IE browsers
    }
  }
  return nv;
}  //GetNodeValue

function GetPHLevel(nodes, lnum)
{                                          //Returns the specified level from the Product Hierarchy XML file
  var ltag;       //Level tag (Lev#)
  var nn;         //Node#
  
  ltag = gTAG_LEV + lnum.toString();
  if (nodes.length <= 0) return false;
  
  for (nn=0; nn < nodes.length; nn++)
  {
    if (nodes[nn].nodeName == ltag)
    {
      return nodes[nn];
    }
  }
  
  return false;
  
}  //GetPHLevel

function GetSysInfo()
{  //Get System Info: results are put into global variables
  var msg;
  var sVer = "";
  var appVer;
  var agent;
  var osType;
  var s1;
  var s2;
  
  msg = "GetSysInfo:\n\n";
  msg += "  navigator.appCodeName=|" + navigator.appCodeName + "|\n";
  msg += "  navigator.appName=|" + navigator.appName + "|\n";
  msg += "  navigator.appVersion=|" + navigator.appVersion + "|\n";
  msg += "  navigator.userAgent=|" + navigator.userAgent + "|\n";
  msg += "  navigator.platform=|" + navigator.platform + "|\n";
  
  appVer = navigator.appVersion;
  agent = navigator.userAgent;
  gBrowserName = navigator.appName;
  gBrowserVersion = -1;
  
  osType = navigator.platform;
  if (osType.indexOf("Mac") >= 0)
  {
    gMac_flag = true;
  }
  msg += "  gMac_flag=" + gMac_flag + "\n";
  
  if (navigator.appName == "Microsoft Internet Explorer")
  {
    gBrowserFullName = gBrowserName;
    gIE_flag = true;
    //**alert("Using IE browser.");
    s1 = appVer.indexOf("MSIE")+5;
    s2 = appVer.indexOf(";", s1);
    sVer = appVer.substring(s1,s2);
    msg += "  IE version=|" + sVer + "|; len=" + sVer.length + "\n";
    if (parseFloat(sVer) != NaN)
    {
      gBrowserVersion = parseFloat(sVer);
      gBrowserFullName += " v" + sVer;
    }
    msg += "  IE version=|" + sVer + "|; len=" + sVer.length + "; fVer=" + gBrowserVersion + "\n";
  }
  else if (navigator.appName == "Netscape")
  {
    s1 = agent.indexOf("Firefox");
    s2 = agent.indexOf("Safari");
    if (s1 > 0)  //If a Firefox variant of the Netscape browser
    {
      gBrowserName = "Firefox";
      gBrowserFullName = gBrowserName;
      gFF_flag = true;
      //**alert("Using Firefox browser.");
      sVer = agent.substring(s1+8);
      if (parseFloat(sVer) != NaN)
      {
        gBrowserVersion = parseFloat(sVer);
        gBrowserFullName += " v" + sVer;
      }
    }
    else if (s2 > 0)
    {
      gBrowserName = "Safari";
      gBrowserFullName = gBrowserName;
      gSF_flag = true;
      //**alert("Using Safari browser.");
      sVer = agent.substring(s2+7);
      if (parseFloat(sVer) != NaN)
      {
        gBrowserVersion = parseFloat(sVer);
        gBrowserFullName += " v" + sVer;
      }
    }
    else         //If a unsupported variant of the Netscape browser
    {
      gBrowserFullName = gBrowserName;
      if (parseFloat(appVer) != NaN)
      {
        sVer = parseFloat(appVer);
        gBrowserFullName += " v" + sVer;
      }
    }
  }
  
  msg += "  Browser=" + gBrowserName + "; sVer=|" + sVer + "|; len=" + sVer.length + "; fVer=" + gBrowserVersion + "\n";
  msg += "  Full Browser Name = |" + gBrowserFullName + "|\n\n";
  //*******alert(msg);
  
}  //GetSysInfo funtion end

function WriteCookie(name, value, mins)  //Write a cookie function (expiration input in minutes)
// Inputs:  name    - cookie name string
//          value   - cookie value string
//          mins    - minutes to expiration integer
{
  var expires = "";
  var cstr = "";
  
  if (mins)
  {
    var date = new Date();
    date.setTime(date.getTime()+(mins*1000*60));  //Add input minutes to current time to get cookie expiration
    expires = "; expires=" + date.toGMTString();
  }
  cstr =  name + "=" + value + expires + "; path=/";
  //alert("WriteCookie: cstr=|" + cstr + "|");
  document.cookie = cstr;
  
}  //WriteCookie function end

function ReadCookie(name)  //Read a cookie function
{
  var re = new RegExp(name+'=([^;]*);?', 'gi');   //Create regex for reading cookies
  var r = re.exec(document.cookie)||[];           //Read specified cookie
  var value = "";
  
  value = unescape(r.length>1?r[1]:null);         //Define cookie's value (or null if undefined)
  //alert("ReadCookie: name=" + name + ", value=|" + value + "|");
  return value;                                   //Return the cookie's value
    
}  //ReadCookie function end

function UpdatePHstate(phr_str, oid)    //Update the Product Hierarchy State - define the open display lines
{
  //Inputs:  
  //                phr_str    - PH ref. string of clicked line in product hierarchy
  //                oid        - Object ID of clicked line (zero if not applicable)
  //
  //
  //Return:
  //                cFlag      - close flag (set true if the PH ref. string is for a line being closed)
  //
  var cFlag;              //Closing the line flag
  var old_value = "";
  var sval = "";          //Search value for PH state cookie value string
  var new_value = "";
  var sloc = -1;          //Initial search location
  var phr_str2            //new PH ref. string to append (w/ oid suffix when oid > 0)
  
  //alert("UpdatePHstate: phr_str= " + phr_str + ", oid=" + oid);
  
  phr_str2 = phr_str;
  //**2008-01-02**if (oid != gOID_NONE)                   //If Object ID defined then
  //**2008-01-02**{
  //**2008-01-02**  phr_str2 = phr_str2 + gPHR_OPENOID;   //  Append Object ID string to Search string
  //**2008-01-02**}                                       //End if
  
  if ((phr_str != null) && (phr_str != gPHR_NONE))
  {
    sval = gPHR_DLIM2 + phr_str2 + gPHR_DLIM2; //Search string = delimiter + PH string
  }
  
  old_value = ReadCookie(gCOOKIE_PHOPNS); //Read cookie to get current PH state
  
  if ((old_value == null) || (old_value == "null")) old_value = "";
  sloc = old_value.indexOf(sval);
  cFlag = false;  //Presume line is being opened

  if (sloc >= 0)            //If PH ref. already defined - means line was open
  {
    cFlag = true;     //Line being closed
    new_value = old_value;
    new_value = new_value.replace(sval,gPHR_DLIM2);                   //Remove this PH ref.
    //alert("UpdatePHstate: after replace #1, new_value=[" + new_value + "]");
    new_value = new_value.replace(gPHR_DLIM2+gPHR_DLIM2,gPHR_DLIM2);  //Clean-up: Remove double delimiter
    //alert("UpdatePHstate: after replace #2, new_value=[" + new_value + "]");
    if (new_value == gPHR_DLIM2) new_value = "";                      //Clean-up: Remove delimiter only
    
    new_value = Close_Lower_Lines(new_value, phr_str);                //Close lines below this closed line
  }
  else                      //Else (PH ref. not defined  - means line was closed)
  {
    if (oid != gOID_NONE)                                            //If OID line being opened
    {
      old_value = Close_OID_Lines(old_value);                        //  Close existing open OID lines
    }                                                                //End if
    
    new_value = old_value + phr_str2 + gPHR_DLIM2;                   //Add this PH ref.
    if (new_value.charAt(0) != gPHR_DLIM2)
    {
      new_value = gPHR_DLIM2 + new_value;                            //Clean-up: Insert leading delimiter
    }
  }
  
  if (oid != gOID_NONE)                                              //If OID line being opened **2008-01-02**
  {
    new_value = old_value;                                           //  Leave unchanged for clicked oid lines
                                                                     //  ...to keep oid lines closed
  }                                                                  //End if

  //vvv TEMP vvv
  var sDo = "opening";
  if (cFlag == true) sDo = "closing";
  //alert("UpdatePHstate: " + sDo + " line at " + phr_str + ", sloc=" + sloc + ", old=" + old_value + ", new=" + new_value);

  gPH_STATE = new_value;                                  //Update global var. to new PH open lines state
  WriteCookie(gCOOKIE_PHOPNS, new_value, gEXPIRE_PHOPNS); //Update cookie      to new PH open lines state
  
  return cFlag;
}  //UpdatePHstate function end

function GetPHLast()    //Get the last PH string appended to the PH State string
{
  var last_str = "";            //Last PH string to return
  var sloc2;                    //Last delimiter location
  var sloc1;                    //Next to last delimiter location
  
  sloc2 = gPH_STATE.lastIndexOf(gPHR_DLIM2);
  if (sloc2 < 2) return last_str;  //No way to have a valid PH string
  
  sloc1 = gPH_STATE.lastIndexOf(gPHR_DLIM2, sloc2-1);
  if (sloc1 < 0) return last_str;  //Next to last delimiter was not found
  
  last_str = gPH_STATE.substring(sloc1+1, sloc2);
  
  return last_str;
}  //GetPHLast function end

function resetPH()  //Clears the Product Hierarchy cookie to reset the Blue Bar display.
{
  gPH_STATE = "";
  WriteCookie(gCOOKIE_PHOPNS, gPH_STATE, gEXPIRE_PHOPNS);
}  //resetPH function end

function pageload()  //Page load event processing
{
  //var cstr;
  //var firstload = false;
  
  //cstr = ReadCookie( gCOOKIE_PLSTATE );
  
  //firstload = firstloadcheck("pageload");

  //alert("pageload: hostname=" + document.location.hostname + ", referrer=" + document.referrer + ", PL cookie=" + cstr);
  //alert("pageload!!: referrer=" + document.referrer + ", PL cookie=" + cstr + ", firstload=" + firstload);

  WriteCookie(gCOOKIE_PLSTATE, gPL_ON, gEXPIRE_PLONSTR); //Long expiration duration
  
  var objCRform = document.getElementById('CRformID');      // vvv REC 1697 VVV
  var icbx;
  if ((objCRform != null) && (objCRform.length > 0))  //If on the CatalogRequest form 
  {
    //***alert('pageload: objCRform.length=' + objCRform.length);   //***TESTING***
    var objCRcbx = document.getElementsByName('CRcbx_group');
    //***alert('pageload: objCRcbx.length=' + objCRcbx.length);
    icbx = 0;
    for(icbx=0; icbx < objCRcbx.length; icbx++)
    {
      if (objCRcbx[icbx].checked)
      {
        //***alert('pageload: checked checkbox for icbx=' + icbx);
        doCRcbxClick(icbx,objCRcbx);
      }
    }
  }                                                         // ^^^ REC 1697 ^^^
  
}  //pageload function end

function pageunload()  //Page load event processing
{
  //var cstr;
  
  //cstr = ReadCookie( gCOOKIE_PLSTATE );

  //alert("pageunload: referrer=" + document.referrer + ", PL cookie=" + cstr);
  
  WriteCookie(gCOOKIE_PLSTATE, gPL_OFF, gEXPIRE_PLOFFSTR);  //Short expiration duration
}  //pageunload function end

function firstloadcheck(callfrom)  //Check if loading page from site for the first time
{
  var cstr;
  var firstload = false;
  
  cstr = ReadCookie( gCOOKIE_PLSTATE );
  
  if ( (isNaN(cstr)) && (!document.referrer) )
  {
    firstload = true;
  }
  //alert("firstloadcheck: called from " + callfrom + ", firstload=" + firstload);
  return firstload;

} // firstloadcheck function end

function Close_OID_Lines(ph_state)  //Remove any oid line references from the PH state string
{
  var ph_new;               //New PH state string (with oid line references removed)
  var nn;                   //Loop counter
  var sloc;                 //Search location
  
  ph_new = ph_state;
  for (nn=1; nn < 5; nn++)                    //Loop for removals - Start
  {
    sloc = 0;
    sloc = ph_new.indexOf(gPHR_OPENOID);
    
    if (sloc < 0) break;                      //  If no oid reference found - exit loop
    
    ph_new = Remove_PH_Line(ph_new, sloc);    //  Remove specified PH line
  }                                           //Loop for removals - End
  
  //alert("Close_OID_Lines: PH old=" + ph_state + ", PH new=" + ph_new);
  
  return ph_new;   //Return the PH state string with oid references removed
   
} //Close_OID_Lines function end

function Close_Lower_Lines(ph_state, phr_str)    //Close lines below this closed line
//  Inputs:
//              ph_state         - Product Hierarchy state string, like "|5|5-1|6|5-1-2oo|"
//              phr_str          - PH line reference string, like "5-1"
//  Return:
//              ph_new           - PH state string with specified line removed
//                                 (for the above inputs, ph_new="|5|5-1|6|")
{
  var ph_new;               //New PH state string (with lower line references removed)
  var nn;                   //Loop counter
  var sloc;                 //Search location
  var fstr;                 //Find string
  
  ph_new = ph_state;
  
  if ( (ph_state.length < 2) || (phr_str.length < 1) )
  {
    return ph_state;  //Early return of same PH state
  }
  
  // The counter limit is for avoiding infinite loops.  2007-12-11
  for (nn=1; nn < 200; nn++)                  //Loop for removals - Start
  {
    sloc = 0;
    fstr = gPHR_DLIM2 + phr_str + gPHR_DLIM;  //  Define find string = "|<str>-"
    
    sloc = ph_new.indexOf(fstr);
    
    if (sloc < 0) break;                      //  If no lower line reference found - exit loop
    
    ph_new = Remove_PH_Line(ph_new, sloc);    //  Remove specified PH line
  }                                           //Loop for removals - End
  
  //alert("Close_Lower_Lines: str=" + phr_str + ", PH old=" + ph_state + ", PH new=" + ph_new);
  
  return ph_new;   //Return the PH state string with oid references removed

} //Close_Lower_Lines function end

function Remove_PH_Line(ph_state, loc)  //Remove specified PH line
//  Inputs:
//              ph_state         - Product Hierarchy state string, like "|5|5-1|6|5-1-2oo|"
//              loc              - character location                    12345678901234567
//  Return:
//              ph_new           - PH state string with specified line removed
//                                 (if loc=3,4,5 or 6,           return="|5|6|5-1-2oo|")
{
  var ph_new="";                 //New PH state string
  var d1=0;                      //delimiter location at or before "loc"
  var d2=0;                      //delimiter location after        "loc"
  
  d1 = ph_state.lastIndexOf(gPHR_DLIM2, loc);    //Define preceding delimiter location
  d2 = ph_state.indexOf(gPHR_DLIM2, loc+1);      //Define trailing delimiter location
  //alert("Remove_PH_Line: PH=" + ph_state + ", loc= " + loc + ", d1=" + d1 + ", d2=" + d2);
  
  ph_new = ph_state;
  if ( (d1 >= 0) && (d2 > d1) )
  {
    if (d1 == 0)
    {
      ph_new = ph_state.substring(d2);
    }
    else
    {
      ph_new = ph_state.substring(0, d1) + ph_state.substring(d2);
    }
    //alert("Remove_PH_Line: loc=" + loc + ", old=" + ph_state + ", new=" + ph_new);
  }
  
  return ph_new;  //Return the new PH state
  
} //Remove_OID_Line function end

function ResetFormText(form_name)  //Clears form text boxes for forms with onClick=ResetFormText
{
  var fn;          // form element number counter
  var msg="";      // message string
  
  for (fn=0; fn < document.forms[form_name].length; fn++)
  {
    if (document.forms[form_name].elements[fn].type == "text")
    {
      msg += document.forms[form_name].elements[fn].name + "(" + 
             document.forms[form_name].elements[fn].value + ") ";
      document.forms[form_name].elements[fn].defaultvalue = "";
      document.forms[form_name].elements[fn].value = "";        //Clear all text elements
    }
  }
  //alert("ResetFormText: form name=|" + form_name + "|, text names (values)=|" + msg + "|. (v18)");
  
  return true;
} //ResetFormText function end

// REC 1200 updates ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

function ClearFormSelect()
{
  // ClearFormSelect - part of REC 1697
  //
  // clears selected form elements for the specified form selected ID
  //
  // Args:  sFormID     I/  (required)  form ID string
  //        bErr        I/  (required)  boolean to clear error messages in <span class="err"> tags
  //        bTxt        I/  (optional)  boolean to clear text elements
  //        bSlo        I/  (optional)  boolean to clear select-one (drop-downs)
  //        bSlm        I/  (optional)  boolean to clear select-multiple (drop-downs)
  //        bChk        I/  (optional)  boolean to clear checkboxes
  //        bRad        I/  (optional)  boolean to clear radio buttons
  //
  
  var sFormID;      // form ID string (required)
  var bErr=false;   // clear error messages flag (required)
  var bTxt=false;   // clear text flag (optional)
  var bSlo=false;   // clear select-one drop-downs flag (optional)
  var bSlm=false;   // clear select-multiple drops downs flag (optional)
  var bChk=false;   // clear checkboxes flag (optional)
  var bRad=false;   // clear radio buttons flag (optional)
  
  var objForm;      // form object
  var i;            // loop counter
  var i2;           // loop counter #2
  var sMsg;         // debug message
  
  sMsg = "ClearFormSelect inputs: ";
  
  for ( i=0; i < arguments.length ; i++) {
    switch (i) {
      case 0:   sFormID = arguments[i];         // get the Form ID
                sMsg += "sFormID=" + sFormID;
                break;
                
      case 1:   bErr = arguments[i];            // get the clear error messages flag
                if (bErr) {sMsg += " bErr=true";}
                break;
                
      case 2:   bTxt = arguments[i];            // get the clear text flag
                if (bTxt) {sMsg += " bTxt=true";}
                break;
                
      case 3:   bSlo = arguments[i];            // get the clear single drop-downs flag
                if (bSlo) {sMsg += " bSlo=true";}
                break;
                
      case 4:   bSlm = arguments[i];            // get the clear multiple drops-downs flag
                if (bSlm) {sMsg += " bSlm=true";}
                break;
                
      case 5:   bChk = arguments[i];            // get the clear checkboxes flag
                if (bChk) {sMsg += " bChk=true";}
                break;
                
      case 6:   bRad = arguments[i];            // get the clear radio buttons flag
                if (bRad) {sMsg += " bRad=true";}
                break;
                
    } // argument switch end
    
  } // for loop through arguments end
  
  //****alert(sMsg);  //debug message display
  
  objForm = document.getElementById(sFormID);
  
  if (!objForm)
  {
    alert("ClearFormSelect: form with an id=" + sFormID + " was not found.");
    return;
  }
    
  for ( i=0; i < objForm.elements.length; i++)
  {
    //alert("ClearFormSelect: objForm.elements[" + i + "].type=" + objForm.elements[i].type);  //***TESTING***
    //alert("ClearFormSelect: objForm.elements[" + i + "].className=" + objForm.elements[i].className);  //***TESTING***
    switch (objForm.elements[i].type)
    {      
      case "text":
      case "textarea":
      case "password":
      //case "hidden":   //included as comment as a potential future option
        if (bTxt)
        {
          objForm.elements[i].value = "";
        }
        break;
        
      case "select-one":
        if (bSlo)
        {
          objForm.elements[i].options[0].selected = true;
        }
        break;
        
      case "select-multiple":
        if (bSlm)
        {
          for ( i2=0; i2 < objForm.elements[i].options.length; i2++)
          {
            objForm.elements[i].options[i2].selected = false;
          }
        }
        break;
        
      case "checkbox":
        if (bChk)
        {
          objForm.elements[i].checked = "";
        }
        break;
        
      case "radio":
        if (bRad)
        {
          objForm.elements[i].checked = "";
        }
        break;
        
    } // switch end of form types
    
  } // for loop end through form elements
  
  var objSpans = document.getElementsByTagName("span");
  for ( i=0; i < objSpans.length; i++)
  {
      if (objSpans[i].className == 'err')
      {
        //****alert("ClearFormSelect: objSpans[" + i + "].className=" + objSpans[i].className + ", gIE_flag=" + gIE_flag);  //***TESTING***
        if (bErr)
        {
          if (gIE_flag)
          {
            objSpans[i].style.cssText = 'display:none;';
          }
          else
          {
            objSpans[i].setAttribute('style', 'display:none');
          }
        }
      }
  }
  
}  // ClearFormSelect function end

function doCRcbxClick(cb_num, cb_group)     // REC 1697
{
  // process checkbox clicks in the CatalogRequest form
  //
  // Args:  cb_num     I/   checkbox value for the checkbox clicked
  //        cb_group   I/   checkbox group object

  var i;                 //loop counter
  var n;                 //checkbox number (top = zero)
  var cb_len;            //length of checkbox group
  var sChkText;          //check type text
  var bAll3Chkd;         //flag indicating all 3 lower check boxes are checked
  var bSomeChkd;         //flag indicating 1 or more check boxes are checked
  var objDivCRlo;        //DIV object w/ id="divCRlo"

  cb_len = cb_group.length;

  n = Number(cb_num);
  //alert("doCheckboxClick: cb_num=" + cb_num);   //**TEMP**

  if (cb_group[n].checked)         //If checkbox is checked
  {
    sChkText = "checked";
    if (n == 0)
    {
      for (i=1; i < cb_len; i++)
      {
        cb_group[i].checked = true;
      }
    }
    //alert("Checkbox checked.");   //**TEMP**
  }
  else                             //Else checkbox is unchecked
  {
    sChkText = "unchecked";
    if (n == 0)
    {
      for (i=1; i < cb_len; i++)
      {
        cb_group[i].checked = false;
      }
    }
    //alert("Checkbox unchecked.");  //**TEMP**
  }
  
  bAll3Chkd = true;
  bSomeChkd = false;
  for (i=1; i < cb_len; i++)
  {
    if (cb_group[i].checked == true)
    {
      bSomeChkd = true;
    }
    else
    {
      bAll3Chkd = false;
    }
  }
  
  if (bAll3Chkd == true)
  {
    //Check top checkbox when the lower 3 checkboxes are checked
    cb_group[0].checked = true;
  }
  else
  {
    //Uncheck top checkbox when the lower 3 checkboxes are not all checked
    cb_group[0].checked = false;
  }
  
  if ( document.getElementById('divCRloff') )
  {
    //Div class of the initial CR form
    objDivCRlo = document.getElementById('divCRloff');
  }
  else
  {
    //Div class of CR form with error(s)
    objDivCRlo = document.getElementById('divCRlon');
  }
  
  if (bSomeChkd == true)
  {
    objDivCRlo.style.display = "inline";
  }
  else
  {
    objDivCRlo.style.display = "none";
  }

  //alert("* * * Checkbox #" + cb_num + " of " + cb_len + " was " + sChkText + ". * * *");   //**TEMP**

}  //doCRcbxClick function end

function doUNScbxClick(cb_num, cb_group)     // REC 1861
{
  // process checkbox clicks in the Unsubscribe form
  //
  // Args:  cb_num     I/   checkbox value for the checkbox clicked
  //        cb_group   I/   checkbox group object

  var i;                 //loop counter
  var n;                 //checkbox number (top = zero)
  var cb_len;            //length of checkbox group
  var sChkText;          //check type text
  var bAllChkd;          //flag indicating all lower check boxes are checked
  var bSomeChkd;         //flag indicating 1 or more check boxes are checked

  cb_len = cb_group.length;

  n = Number(cb_num);

  //alert("GOT HERE Checkbox.");  //**TEMP**

  if (cb_group[n].checked)         //If checkbox is checked
  {
    sChkText = "checked";
    if (n == 0)
    {
      for (i=1; i < cb_len; i++)
      {
        cb_group[i].checked = true;
      }
    }
    //alert("Checkbox checked.");   //**TEMP**
  }
  else                             //Else checkbox is unchecked
  {
    sChkText = "unchecked";
    if (n == 0)
    {
      for (i=1; i < cb_len; i++)
      {
        cb_group[i].checked = false;
      }
    }
    //alert("Checkbox unchecked.");  //**TEMP**
  }
  
  bAllChkd = true;
  bSomeChkd = false;
  for (i=1; i < cb_len; i++)
  {
    if (cb_group[i].checked == true)
    {
      bSomeChkd = true;
    }
    else
    {
      bAllChkd = false;
    }
  }
  
  if (bAllChkd == true)
  {
    //Check top checkbox when all lower checkboxes are checked
    cb_group[0].checked = true;
  }
  else
  {
    //Uncheck top checkbox when the lower checkboxes are not all checked
    cb_group[0].checked = false;
  }
  
}  //doUNScbxClick function end

function doMAICATcbxClick(sCatSel)     // REC 1861
{
  // process checkbox clicks in the Unsubscribe form
  //
  // Args:  sCatSel    I/   selected catalog selection delimited string
  //

  var i;                 //loop counter
  var objCatCbx;         //Catalog checkboxes object
  var objAddrDiv;        //DIV for address inputs object
  var bHideAddrInputs;   //Hide the address inputs flag
  
  //2010-09-28***objCatCbx = document.MyAcctForm.catalog_types;    //Define the catalog checkboxes object
  objCatCbx = document.getElementsByName('catalog_types');  //Define the catalog checkboxes object
  //alert("doMAICATcbxClick: objCatCbx.length=|" + String(objCatCbx.length) + "|.");

  bHideAddrInputs = true;                          //Presume address inputs are to be hidden
  
  for (i = 0; i < objCatCbx.length; i++)                //Checkboxes loop start
  {
    if (objCatCbx[i].checked)                           //  If checkbox is checked
    {
      //***alert("doMAI: Catalog Checkbox #" + String(i+1) + " was Checked.");
      //***alert("Value of checked checkbox = |" + objCatCbx[i].value + "|.");
      if (sCatSel.indexOf(objCatCbx[i].value) < 0)      //    If not previously checked
      {
        bHideAddrInputs = false;                        //      Set hide flag off
        break;                                          //      Exit this loop
      }                                                 //    End if
    }
    else                                                //  Else (if checkbox is unchecked)
    {
      //***alert("doMAI: Catalog Checkbox #" + String(i+1) + " was UN-Checked.");
      if (sCatSel.indexOf(objCatCbx[i].value) >= 0)     //    If previously checked
      {
        bHideAddrInputs = false;                        //      Set hide flag off
        break;                                          //      Exit this loop
      }                                                 //    End if
    }                                                   //  End if
  }                                                     //Check boxes loop end
  
  objAddrDiv = document.getElementById("AcctAddr");
  
  if (bHideAddrInputs)
  {
    objAddrDiv.className = "Be_Hidden";
  }
  else
  {
    objAddrDiv.className = "Be_Seen";
  }
  
  //***alert("doMAICATcbxClick: sCatSel=|" + sCatSel + "|, objCatCbx.length=" + String(objCatCbx.length) + ".");
  //***alert("doMAICATcbxClick: objCatCbx[0-3].value=|" + objCatCbx[0].value + "|"
  //***  + objCatCbx[1].value + "|"+ objCatCbx[2].value + "|"+ objCatCbx[3].value + "|.");

} //doMAICATcbxClick function end

function NextOP()     // REC 1709
{
  // prep for Online Payments page after login (from "Online Payment dropdown link)
  //
  // Define cookie to go to the next page of Online Payments
  WriteCookie(gCOOKIE_NEXTPAGE, "Online_Payment", gEXPIRE_NEXTPAGE);
}

function NextOH()     // REC 1709
{
  // prep for Orders page after login (from "Order History" dropdown link)
  //
  // Define cookie to go to the next page of Order History
// ===INTERIM FIX===WriteCookie(gCOOKIE_NEXTPAGE, "account", gEXPIRE_NEXTPAGE);
  WriteCookie(gCOOKIE_NEXTPAGE, "orders_history", gEXPIRE_NEXTPAGE);
}

 function SetDD(bOn, iMax, sID, bAry)
 // SetDD & PrcDD are used to hide pulldown input elements below dropdowns for IE6.
 {
  //SetDD - sets the
   var iIDnum;                   //integer value from the ID string
   var pattern = /^dd[1-5]$/;    //dropdown ID string must be "dd1", "dd2", "dd3", "dd4" or "dd5"
  
   if (!pattern.test(sID))
   {
     return;
   }
  
   iIDnum = parseInt(sID.substring(2));  //Convert the # in the ID string to an integer
  
   //==alert("SetDD: sID=" + sID + ", sID#=" + iIDnum.toString() + ", bOn=" + bOn.toString());
  
   if (bOn != bAry[iIDnum])
   {
     //==alert("Dropdown with ID of " + sID + " changes array value to " + bOn.toString() + ".");
    
    //Sets dropdown boolean array entry to specified value per the dropdown's ID string.
     bAry[iIDnum] = bOn;
     PrcDD(iIDnum, bAry, iMax)  //Process this dropdown status change
   }

 } // SetDD function end

 function PrcDD(iChgdOne, bAry, iMax)
 {
   var iNum;       //Offset for the array of active dropdown flags
   var iDiv;       //DIV counter
   var iDivMax=3;  //DIV counter maximum (IE6 dropdown/pulldown issues only occur for 1st 3 dropdowns)
   var sDivId;     //DIV ID string containing the pulldown input
   var objDiv;     //DIV DOM object to examine and possibly updated
   var sDivTitle;  //DIV's title text
   var sDDnums;    //String of applicable dropdown DIV's from title
   var sDisplay;   //Display style string
   var sDivIdPrfx="DivHide"; //ID string prefix
   var sTitlePrfx="DD";      //Title string prefix
  
   //==alert("PrcDD: gIE_flag = " + gIE_flag.toString() + ", gBrowserVersion=|" + gBrowserVersion +"|.");
   if ( (!gIE_flag) || (parseInt(gBrowserVersion) != 6))
   {
     return;  //NOT an IE6 browser
   }
   //==alert("PrcDD: This is an IE6 browser!");
    
   for(iDiv=1; iDiv<=iDivMax; iDiv++)   //DIV loop - Start
   {
     sDivId = sDivIdPrfx + iDiv.toString();
     //==alert("PrcDD: sDivId=|" + sDivId + "|.");
     objDiv = document.getElementById(sDivId);
     if (objDiv != null)
     {
       sDivTitle = objDiv.getAttribute('title');
       //==alert("PrcDD: sDivTitle=|" + sDivTitle + "|.");
       if (sDivTitle == "")
       {
         continue;
       }
       sDDnums = sDivTitle.substring(sTitlePrfx.length);
       //==alert("PrcDD: sDDnums=|" + sDDnums + "|.");
      
       for(iNum=1; iNum<=iMax; iNum++)  //  Dropdown loop - Start
       {
         if (sDDnums.indexOf(iNum.toString()) >= 0)
         {
           //==alert("PrcDD: bAry[" + iNum.toString() + "] = " + bAry[iNum].toString() + ".");
           sDisplay = "block";
           if (bAry[iNum])
           {
             sDisplay = "none";
           }
           document.getElementById(sDivId).style.display = sDisplay;
           //==alert("element with id=|" + sDivId + "| now has style.display=|" + sDisplay + "|.");
         }
       }                                //  Dropdown loop - End
     }
        
   }                                    //DIV loop - End

} // PrcPD function end

// 2011-06 Updates vvv

function ABCtoggle (sID)
// toggle the display of the passed DOM object - 1709
{
  var objEle = document.getElementById(sID);
  if (objEle == null) return;
  //===alert("ABCtoggle: sID = |" + sID + "|.");
  
  if (objEle.style.display == "none") 
  {
    objEle.style.display = "";
  }
  else 
  {
    objEle.style.display = "none";
  }
} // ABCtoggle function - end

function QOblur(sID)
//Process blur (focus off) event on a item number input textbox on the Quick Order Entry form
//Input sID is the id value of the input textbox.
//The corresponding item description <span> id has a formation of "QOdsc<num>", where <num> is the trailing number from sID.
{
    //alert("ID = " + sID);

    var objInput = document.getElementById(sID);

    var sIDnum = sID.substring(5);
    var sSpanId = "QOdsc" + sIDnum;
    var objSpan = document.getElementById(sSpanId);
    var sItem;
    var sItemDsc;
    var bDisableButton;     //2011-07-25
    var iLoop;              //2011-07-25
    var iInvalidCount;      //2011-07-25
    var sSpanId;            //2011-07-25
    var eleDscSpan;         //2011-07-25

    //==-=sItemDsc = "initial javascript item description";
    sItemDsc = "";
    objSpan.innerHTML = sItemDsc;

    if (objInput == null) return;
    if (objSpan == null) return;

    sItem = objInput.value;

    //2011-07-11===if (sItem.length < 4) {
    //2011-08-02===if (sItem.length < 1) {  //2011-07-11
    //2011-08-02===    return sItemDsc;     //Item# input is too short
    //2011-08-02===}

    //2011-08-02===sItemDsc = ajax_get("AjaxGetItem.asp", sItem);
    //2011-08-02===objSpan.innerHTML = sItemDsc;
    if (sItem.length > 0)
    {
        sItemDsc = ajax_get("AjaxGetItem.asp", sItem);
        objSpan.innerHTML = sItemDsc;
    }
    
    bDisableButton = false;                     //2011-07-25 vvv
    
    iInvalidCount = 0;
    for (iLoop=1; iLoop <= gQUICK_INPUTS; iLoop++)
    {
        sSpanId = "QOdsc" + iLoop;
        eleDscSpan = document.getElementById(sSpanId);
        
        sItemDsc = eleDscSpan.innerHTML;
        
        if ( (sItemDsc.toLowerCase()).indexOf("invalid") >= 0 )
        {
            iInvalidCount++;    //Increment invalid item count
            document.getElementById(sSpanId).setAttribute("class","err");
        }
        else
        {
            document.getElementById(sSpanId).setAttribute("class","");
        }
    }
    //==alert("QOblur: iInvalidCount = " + iInvalidCount);
    
    if (iInvalidCount > 0)
    {
        document.getElementById("QOAddBtn").disabled=true;
    }
    else
    {
        document.getElementById("QOAddBtn").disabled=false;
    }                                           //2011-07-25 ^^^

} //QOblur function - end

function QOload()
//Process page load of the Quick Order Entry page
{
    var iLoop;
    var thisID;
    var thisInput;
    
    //==alert("QOload function called!");
    
    for (iLoop=1; iLoop <= gQUICK_INPUTS; iLoop++)
    {
        thisID = "QOitm" + iLoop;
        if (iLoop == 1)
        {
            thisInput = document.getElementById(thisID);
            thisInput.focus();
        }
        QOblur(thisID); //Validate pre-loaded item numbers
    }
    //==alert("QOload: last ID = |" + thisID + "|");
   
    
} //QOload function - end

function ajax_get(sAjaxPage, sIn)
//Function that returns the string response via an AJAX request to the sAjaxPage on the server with the sIn input string.
{
    var ajaxReq = new Object();
    var sOut;
    var iLoop;
    var fNum;

    gAjaxOutStr = "";
    sOut = "no_output from ajax_get for sIn=|" + sIn + "|.";

    ajaxReq = GetXmlHttpObject();    //AJAX request object

    if (ajaxReq === false) {
        sOut = "AJAX request setup error";
        return sOut;
    }

    try {
        ajaxReq.open("GET", sAjaxPage + "?input=" + sIn, false);    //IMPORTANT! - 3rd parameter is false for synchronous processing
        ajaxReq.onreadystatechange = AjaxResponse;
        ajaxReq.send(null);
    }
    catch (e) {
        alert("ajaxReq error!");
        //===sOut = "AJAX request open/send error";
    }

    //===alert("ajax_get: after ajaxReq object processing, gAjaxOutStr=|" + gAjaxOutStr + "|.");
    sOut = ajaxReq.responseText;
    if (gAjaxOutStr != "") {
        sOut = gAjaxOutStr;
    }
    return sOut;
    ajaxReq = Nothing;

    function AjaxResponse() {
    //Function processes the AJAX response
        if (ajaxReq.readyState == 4) {                  //If received state is complete 
            //(0=unititialized; 1=loading; 2=loaded; 3=interactive; 4=complete)
            if (ajaxReq.status == 200) {                //  If status is OK
                gAjaxOutStr = ajaxReq.responseText;
                //===alert("ajax_get: successful get! - responseText=|" + gAjaxOutStr + "|.");
            }
        }
        return true;
    } //AjaxResponse function - end

} //ajax_get function - end

// 2011-06 Updates ^^^


//  End of jsfunctions.js -->
