/*
sccsid = '@(#) 1.46 wt/wtp/htdocs/scripts/jsgenlib_3.js, wtcode, jtime71 9/7/05 16:18:52'

## 
## (C) COPYRIGHT Journyx, Inc 1997-2005
## All Rights Reserved
## Licensed Materials - Property of Journyx, Inc.
## 

ALL DEVELOPERS READ!!

If you need to reference or include this file, you must use the wtdoc.jsfiles
variable. As documented in defect 10392, there have been problems in the past
with browsers caching js files, so we need to change the name of this file 
before *each* public release. 

This means you need to change the file name in CMVC using File -Rename and 
you need to change the file name in wtdoc.jsfiles before this file is released 
in any maintenance release / patch, or in a general product release.
*/


// Returns true if item is either undefined or null
// WARNING: Uses nested ? operators which is (slightly) faster
function bad(item) {
  return item == undefined ? true : item == null ? true : false;
}

// Ultimate Client-Side JavaScript Client Sniffer
// (C) Netscape Communications 1998.  Permission granted to reuse and distribute.
function Is ()
{   
    // convert all characters to lowercase to simplify testing
    var agt = navigator.userAgent.toLowerCase()

    // *** BROWSER VERSION ***
    this.major = parseInt(navigator.appVersion)
    this.minor = parseFloat(navigator.appVersion)

    this.nav  = ((agt.indexOf('mozilla')!=-1) && ((agt.indexOf('spoofer')==-1)
                && (agt.indexOf('compatible') == -1)))
    this.nav2 = (this.nav && (this.major == 2))
    this.nav3 = (this.nav && (this.major == 3))
    this.nav4 = (this.nav && (this.major == 4))
    this.navonly      = (this.nav && (agt.indexOf(";nav") != -1))

    this.ie   = (agt.indexOf("msie") != -1)
    this.ie3  = (this.ie && (this.major == 2))
    this.ie4  = (this.ie && (this.major == 4))
    this.ie5  = (this.ie && (this.major == 5))	
    this.ie6  = (this.ie && (this.major == 5))	


    this.opera = (agt.indexOf("opera") != -1)

    // *** JAVASCRIPT VERSION CHECK ***
    // Useful to workaround Nav3 bug in which Nav3
    // loads <SCRIPT LANGUAGE="JavaScript1.2">.
    if (this.nav2 || this.ie3) this.js = 1.0
    else if (this.nav3 || this.opera) this.js = 1.1
    else if (this.nav4 || this.ie4) this.js = 1.2

    // NOTE: In the future, update this code when newer versions of JS
    // are released. For now, we try to provide some upward compatibility
    // so that future versions of Nav and IE will show they are at
    // *least* JS 1.2 capable. Always check for JS version compatibility
    // with > or >=.
    else if ((this.nav && (this.minor > 4.05)) || (this.ie && (this.major > 4)))
         this.js = 1.2
    else this.js = 0.0 // HACK: always check for JS version with > or >=

    // *** PLATFORM ***
    this.win   = ( (agt.indexOf("win")!=-1) || (agt.indexOf("16bit")!=-1) )
    // NOTE: On Opera 3.0, the userAgent string includes "Windows 95/NT4" on all
    //        Win32, so you can't distinguish between Win95 and WinNT.

    this.win95 = ((agt.indexOf("win95")!=-1) || (agt.indexOf("windows 95")!=-1))

    // is this a 16 bit compiled version?
    this.win16 = ((agt.indexOf("win16")!=-1)
               || (agt.indexOf("16bit")!=-1) || (agt.indexOf("windows 3.1")!=-1)
               || (agt.indexOf("windows 16-bit")!=-1) )

    this.win31 = (agt.indexOf("windows 3.1")!=-1) || (agt.indexOf("win16")!=-1) ||
                 (agt.indexOf("windows 16-bit")!=-1)

    // NOTE: Reliable detection of Win98 may not be possible. It appears that:
    //       - On Nav 4.x and before you'll get plain "Windows" in userAgent.
    //       - On Mercury client, the 32-bit version will return "Win98", but
    //         the 16-bit version running on Win98 will still return "Win95".
    this.win98 = ((agt.indexOf("win98")!=-1)||(agt.indexOf("windows 98")!=-1))
    this.winnt = ((agt.indexOf("winnt")!=-1)||(agt.indexOf("windows nt")!=-1))
    this.win32 = this.win95 || this.winnt || this.win98 ||
                 ((this.major >= 4) && (navigator.platform == "Win32")) ||
                 (agt.indexOf("win32")!=-1) || (agt.indexOf("32bit")!=-1)

    this.os2   = (agt.indexOf("os/2")!=-1)
                 || (navigator.appVersion.indexOf("OS/2")!=-1)
                 || (agt.indexOf("ibm-webexplorer")!=-1)


    this.mac    = (agt.indexOf("mac")!=-1)

    this.mac68k = this.mac && ((agt.indexOf("68k")!=-1) ||
                               (agt.indexOf("68000")!=-1))

    this.macppc = this.mac && ((agt.indexOf("ppc")!=-1) ||
                               (agt.indexOf("powerpc")!=-1))

    this.sun   = (agt.indexOf("sunos")!=-1)
    this.sun4  = (agt.indexOf("sunos 4")!=-1)
    this.sun5  = (agt.indexOf("sunos 5")!=-1)
    this.suni86= this.sun && (agt.indexOf("i86")!=-1)
    this.irix  = (agt.indexOf("irix") !=-1)    // SGI
    this.irix5 = (agt.indexOf("irix 5") !=-1)
    this.irix6 = ((agt.indexOf("irix 6") !=-1) || (agt.indexOf("irix6") !=-1))
    this.hpux  = (agt.indexOf("hp-ux")!=-1)
    this.hpux9 = this.hpux && (agt.indexOf("09.")!=-1)
    this.hpux10= this.hpux && (agt.indexOf("10.")!=-1)
    this.aix   = (agt.indexOf("aix")  !=-1)      // IBM

    this.aix1  = (agt.indexOf("aix 1")  !=-1)
    this.aix2  = (agt.indexOf("aix 2")  !=-1)
    this.aix3  = (agt.indexOf("aix 3")  !=-1)
    this.aix4  = (agt.indexOf("aix 4")  !=-1)

    this.linux = (agt.indexOf("inux")!=-1)

    this.sco   = (agt.indexOf("sco")!=-1) || (agt.indexOf("unix_sv")!=-1)
    this.unixware = (agt.indexOf("unix_system_v")!=-1)
    this.mpras    = (agt.indexOf("ncr")!=-1)
    this.reliant  = (agt.indexOf("reliantunix")!=-1)
    this.dec   = (agt.indexOf("dec")!=-1) || (agt.indexOf("osf1")!=-1)
           || (agt.indexOf("dec_alpha")!=-1) || (agt.indexOf("alphaserver")!=-1)
           || (agt.indexOf("ultrix")!=-1) || (agt.indexOf("alphastation")!=-1)
    this.sinix = (agt.indexOf("sinix")!=-1)
    this.freebsd = (agt.indexOf("freebsd")!=-1)
    this.bsd = (agt.indexOf("bsd")!=-1)

    this.unix  = (agt.indexOf("x11")!=-1) || this.sun || this.irix || this.hpux ||
                 this.sco ||this.unixware || this.mpras || this.reliant ||
                 this.dec || this.sinix || this.aix || this.linux || this.freebsd

    this.vms   = (agt.indexOf("vax")!=-1) || (agt.indexOf("openvms")!=-1)
}

var is = new Is()
var ctotals = new Array();

function validchars(strg,chars)
{
  for (i = 0; i < strg.length; i++)
  {
     	if (chars.indexOf(strg.charAt(i)) == -1)
        {
            return 0;
        }
  }
  return 1;
}


function atmostonething(strg,achar)
{
 	
  numfound = 0;
  for (i = 0; i < strg.length; i++)
  {      
	if (strg.charAt(i)  == achar)
        {
           numfound = numfound + 1;
        }
    if (numfound > 1)
    {
       return 0;
    }
  }
  return 1;
}


function validatenumeric(fobj)
{
  if ((validchars(fobj.value,'0123456789.') != 0)  && (atmostonething(fobj.value,'.') != 0))
  {
     return 1;
  }
  else
  {
     alert('A numeric value is required for this field.  You entered "' +fobj.value+'".')
     fobj.value = fobj.startvalue;
  }  
}

function validateinteger(fobj)
{
  if (validchars(fobj.value,'0123456789') != 0)
  {
    return 1;
  }
  else
  {
     alert('An integer value is required for this field.  You entered "' +fobj.value+'".')
     fobj.value = fobj.startvalue;
  }  
}


// given an id of a form object will 
// make it hidden if visible or visibile if hidden
function toggleDisplay(id) {

  if (getIdProperty(id,"display") == "none") {
	setIdProperty(id,"display","");
  }
  else {
	setIdProperty(id,"display","none");
  }

  try {
    // fixes issues in Firefox with initially-hidden areas
	// harmless everywhere else 
	fncAdjustPrimaryContentHeight(); 
  } catch(e) {}  // ignore errors

}

function getStyleBySelector( selector )
{
    if (!is.nav)
    {
        return null;
    }
    var sheetList = document.styleSheets;
    var ruleList;
    var i, j;
    /* look through stylesheets in reverse order that
       they appear in the document */
    for (i=sheetList.length-1; i >= 0; i--)
    {
        ruleList = sheetList[i].cssRules;
        for (j=0; j<ruleList.length; j++)
        {
            if (ruleList[j].type == CSSRule.STYLE_RULE &&
                ruleList[j].selectorText == selector)
            {
                return ruleList[j].style;
            }   
        }
    }
    return null;
}
function setIdProperty( id, property, value )
{
    
    if (is.nav4)
    {
        document[id][property] = value;
    }

    else if (is.nav)
    {
        var styleObject = document.getElementById( id );
        if (styleObject != null)
        {
            styleObject = styleObject.style;
            styleObject[ property ] = value;
        }
    }	    
    else if (is.ie)
    {
         document.all[id].style[property] = value;
    }
}
function getIdProperty( id, property )
{ 
   if (is.nav4)
   {
       return document[id][property];
   }
   else if (is.nav)
   {
       var styleObject = document.getElementById( id );
       if (styleObject != null)
       {
          styleObject = styleObject.style;
          if (styleObject[property])
          {
                return styleObject[ property ];
          }
       }
       styleObject = getStyleBySelector( "#" + id );
       return (styleObject != null) ?
            styleObject[property] :
            null;
   }
   else
   {
      return document.all[id].style[property];
   }
}




// method for forwarding to a new page 
// via javascript
function changePage(newLoc)
{
  document.location.href = newLoc;
}



//  checks for doublclicking of form buttons
// if a button is click once all others 
// are disabled
var ap = 0;
function isok(frm) {
  if (ap == 0) {
    ap = 1;
    return 1;
  }
  else {
    alert('The form has been submitted, please wait until it has completed before pressing any more buttons.');
    return 0;
  }
}

// This returns true/false whereas isok itself always returns 1/0
function chkisok(frm) {
  if (isok(frm)) {
	return true;
  }
  return false;
}


// limits the number of characters allowed in a textarea
function MaxText(formObj,maxChars)
{
   var result = true;
   if (formObj.value.length >= maxChars)
   {
     if (window.event) window.event.returnValue = false;
     result = false;
   }
   if (formObj.value.length > maxChars) formObj.value = formObj.value.substring(0,maxChars);	
   return result;
}






// Capture keydowns and keypresses 
// on the grid entry form.  
// Designed to capture TABS and ENTER
// and handle correctly
function entsub(efield,e)
{
  var keycode;
  if (window.event)
  {
    keycode = window.event.keyCode;
  }
  else
  {
    if (e)
    {
      keycode = e.which;
    }
    else
    {
      return true;
    }
  }

  if (keycode == 94534)
  {
  var fieldname = efield.name; 

  var rownum = '';
  var colnum = '';
  var k = 0;
  
  if (fieldname.charAt(0) == 'r')
  {
     k = k + 1;
     while (fieldname.charAt(k) != 'c')
     {
       rownum = rownum + fieldname.charAt(k)
       k = k + 1
       if (k > 10)
       {
         return true;
       } 
     }
     k = k + 1;
     while (k < fieldname.length)
     {
       colnum = colnum + fieldname.charAt(k);
       k= k + 1;
     }
  }

  rownum = rownum-0;
  colnum = colnum-0;

  var newfield = 'r' + (rownum+1) + 'c' + colnum;

  if (eval("efield.form." + newfield))
  {
      eval("efield.form." + newfield).focus();
      return false;
  }
  else
  {
    newfield = 'r0c' + (colnum+1);
    if (eval("efield.form." + newfield))
    {
       eval("efield.form." + newfield).focus();
       return false;
    }
  }
  }
  
  if (keycode == 13)
  {
    if (isok(efield.form))
       {
         thingshavechanged=0;
         donotaskatall = 1;
         efield.form.submit();
         return false;
       }
  }
  else
  {
    return true;
  }
}







////////////////////////////////////////////////
////////////////////////////////////////////////
////////////////////////////////////////////////




// makes sure the totals for each day are either 0 or 100%
function isValid(this_form, numcols, startcol) 
{
   var colTotal;
   for (j = startcol; j < numcols+startcol;j++) 
   {
      colTotal = eval("this_form.ctotal"+j+".value");
      colTotal = parseFloat(colTotal.substring(0,colTotal.length-1));	  
      if (colTotal != 0 && colTotal != 100) 
      {
	 return 0;
      }
    }
    return 1;
}





// return somestring, with all but the items 
// in the string bag removed
function filterstringwithbag(somestring,somebag)
{
  var formatted = "";
  var i = 0;
  var c = "";	 	

  for (i = 0; i < somestring.length; i++)
  {
    c = somestring.charAt(i);
    if (somebag.indexOf(c) != -1)
    {formatted += c;}
  }
  return formatted;
}

function timeofdaytominutes(timeofday)
{
  
  var ampmtype = 'am';		
  
  if (timeofday.indexOf("a") != -1)
  {
    ampmtype = 'am';
  }

  if (timeofday.indexOf("p") != -1)	  
  {
    ampmtype = 'pm';
  }
  
         		

  timeofday = filterstringwithbag(timeofday,'0123456789:');
  var h = Number(timeofday.substring(0,timeofday.indexOf(":")));
  var m = Number(timeofday.substring(timeofday.indexOf(":")+1,timeofday.length+1));
  
 
  if (ampmtype == 'am')
  {
    if (h == 12)
    {h = 0;}		  
  }
  else
  {
    if (h != 12)
    {h = h + 12;}			
  }
  return h*60+m;		
}
	
	
function minutestotimeofday(minutes)
{
   // special case for midnight
   if (minutes == 1440)
   {
     var hours = '12';
     var minutes = '00';		 
     var ampm = 'am';
   }
   else
   {	  

     var hoursminutes = minutestohoursminutes(minutes);
     var hours   = Number(hoursminutes.substring(0,hoursminutes.indexOf(":")));
     var minutes = Number(hoursminutes.substring(hoursminutes.indexOf(":")+1,hoursminutes.length+1)); 	   
     var ampm = 'pm';	
   
     if (hours < 12)
     {
       ampm = 'am'
       if (hours == 0)
       {
          hours = 12;
       }
     }   
     else
     {		
       if (hours != 12)			
       {
         hours = hours - 12;
       }
     }

     if (minutes < 10)
     {
       minutes = '0' + minutes;
     }
   }

   return hours + ':' + minutes + ' ' + ampm		

}

function minutestohoursminutes(numminutes)
{
  return minutes_to_hhmm(numminutes);
}	

function sortAsNumber(a,b)
{
  var la = Number(a);
  var lb = Number(b);
  return ((la<lb) ? -1 : ((la > lb) ? 1 : 0));
}

function calctime()
{                          
    var etbox = window.document.persist_form.elapsedtime;
    
    var timeampm = etbox.value.split(' ');
    var ctime    = timeampm[0]
    var ampm     = timeampm[1]
	
    var currenttime   = ctime.split(':');
    var currenthour   = currenttime[0]-0;
    var currentminute = currenttime[1]-0;
    var currentsecond = currenttime[2]-0;

    currentsecond = currentsecond + 1;
    if (currentsecond > 59)
    {
	  currentsecond = 0;
	  currentminute = currentminute + 1;
	  if (currentminute > 59)
	  {
	      currentminute = 0;
	      currenthour = currenthour + 1;     
              if (currenthour == 12)
              {
                  if (ampm == 'am')
                  {
                      ampm = 'pm';
                  }
                  else
                  {
                     if (ampm == 'pm')
                     {
                       ampm = 'am';
                     }
                  }
              }
              else
              {
                  if (currenthour == 13)
                  {
                     currenthour = 1;
                  }
               }
	  }
    }
			
    if (currentsecond < 10)
    {
	  currentsecond = '0' + currentsecond;
    }
			
    if (currentminute < 10)
    {
	  currentminute = '0' + currentminute;
    }		
    etbox.value = currenthour + ':' + currentminute + ':' + currentsecond + ' ' + ampm; 
    setTimeout("calctime()",1000);
}


function totalTimecolumn(listoftimes)
{
  if (listoftimes.length == 0)
  {
   return '0:00';
  }

  // given a list of times in am/pm form
  // calculate the total hours for the day
  var i;
  var total = 0.0;
  var outtime = 0;
  var intime = 0;

  for (i=0;i<listoftimes.length;i=i+2)
  {
     // an unmatched pair
     // should not be used
     if (i+1 < listoftimes.length)
     {
        outtime = timeofdaytominutes(listoftimes[i+1])
        intime  = timeofdaytominutes(listoftimes[i])
        
        // midnight punch 
	if (outtime == 0)
        {
          outtime = 1440;
        }
	total = total + (outtime-intime)
     }
  }
  return minutestohoursminutes(total)	
}


function resortcolumn(theform,columnnum)
{
   var timestosort = []; 
   var i;
   var j = 0;
   var tempin  = 0;	
   var tempout = 0;	
   var lastval = -1;		   

   for (i=0;(eval("theform.IN" + columnnum + "XXX" + i) || eval("theform.OUT" + columnnum + "XXX" + i));i++)
   {
     if (eval("theform.IN" + columnnum + "XXX" + i + ".value"))
     {
          tempin = timeofdaytominutes(eval("theform.IN" + columnnum + "XXX" + i + ".value"))
	  
          if (tempin <= lastval)
	  {
               if (tempin < 720)
	       {
                  tempin += 720;
               }
          }	
	  lastval = tempin;
	  timestosort[j] = tempin;   
          j = j + 1;
     }
     
     if (eval("theform.OUT" + columnnum + "XXX" + i + ".value"))
     {

          // it is possible that an OUT punch could be midnight
          // so treat 12:00am in an out punch as midnight

          tempout = timeofdaytominutes(eval("theform.OUT" + columnnum + "XXX" + i + ".value"))
	  
		
	  if (tempout == 0)
          {
              tempout += 1440;
          }
          else
          {

            if (tempout <= lastval)
	    {
               if (tempout < 720)
	       {
                  tempout += 720;
               }
            }	
          }

	  lastval = tempout;
          timestosort[j] = tempout 
	  j = j + 1;

     }	
   }
   
   timestosort.sort(sortAsNumber);	
   var numtosort = timestosort.length;	

   j = 0;		
   for (i=0;(eval("theform.IN" + columnnum + "XXX" + i) || eval("theform.OUT" + columnnum + "XXX" + i));i++)
   {
     inbox = eval("theform.IN" + columnnum + "XXX" + i)
     outbox = eval("theform.OUT" + columnnum + "XXX" + i) 	   

     if (j < numtosort)
     {
	inbox.value = minutestotimeofday(timestosort[j]);
        j = j + 1;
     }
     else 
     {
        inbox.value = "";
     }

     if (j < numtosort)
     {
	outbox.value = minutestotimeofday(timestosort[j])
        j = j + 1;
     }
     else 
     {
        outbox.value = "";
     }				
   }
}



function hoursminutestominutes(hoursminutes)
{
   var h = Number(hoursminutes.substring(0,hoursminutes.indexOf(":")));
   var m = Number(hoursminutes.substring(hoursminutes.indexOf(":")+1,hoursminutes.length+1));
   return h*60+m	
}	

function subtracthours(firsttime,secondtime)
{
  return minutestohoursminutes(hoursminutestominutes(firsttime)-hoursminutestominutes(secondtime))
}


function timetotals(theform,columnnum)
{

   
   // first we need to make sure that all the entries for
   // this column are ordered correctly
   resortcolumn(theform,columnnum)	
		
   // this method build an array to pass to totaltimecolumn
   var times = [];   	
   var j = 0;	
   var i = 0;	   
   var totalcolumn = eval("theform.TOTAL"+columnnum);
   if (!(totalcolumn))
   {
      return
   } 
   
   var differencetotalcolumn = eval("theform.DTOTAL"+columnnum);	
   var ptotime =  eval("theform.ctotal"+columnnum+".PTO");
   var img = eval("theform.IMGTOTAL" + columnnum);


   for (i=0;(eval("theform.IN" + columnnum + "XXX" + i) || eval("theform.OUT" + columnnum + "XXX" + i));i++)
   {
     if (eval("theform.IN" + columnnum + "XXX" + i + ".value"))
     {
       if (eval("theform.OUT" + columnnum + "XXX" + i + ".value"))
       {
          times[j] = eval("theform.IN" + columnnum + "XXX" + i + ".value");
 	  times[j+1] = eval("theform.OUT" + columnnum + "XXX" + i + ".value");
	  j = j + 2;
        }
      }
    }	
   
   
   totalcolumn.value = totalTimecolumn(times);
   

   if (ptotime)
   {
        var ctotalhrs = eval("theform.ctotal"+columnnum+".value");
        var adjustedhrs = subtracthours(ctotalhrs,ptotime);
	differencetotalcolumn.value = subtracthours(totalcolumn.value,adjustedhrs);
   }
   else
   {
	differencetotalcolumn.value = subtracthours(totalcolumn.value,eval("theform.ctotal"+columnnum+".value"));	
   }

   
   if (differencetotalcolumn.value == '0:00')
   {
      img.style.visibility = 'hidden';
   }
   else
   {
      img.style.visibility = 'visible';
   }
			
}
	  



// format a string as dec or hh:mm form
function formatTime(timestring,fmat)
{	 
  var rawtimestring = timestring;

  if (fmat == "timeofday")
  {
    var bag = "0123456789:ampAMP";
    var neg = "";
  }	
  else
  {
    var bag = "O1234567890:.";
    if (timestring.charAt(0) == "-") 
    {
       var neg = "-";
    }
    else
    {
       var neg = "";
    }
  }

  var formatted = filterstringwithbag(timestring,bag)
  if (formatted == ""){return "";}
 
  if (fmat == 'timeofday')
  {
     formatted = formatted.toUpperCase();
     var ampmtype = ""

     // identify if they have included am or pm    
     // and remove it 	
     if (formatted.indexOf("A") != -1)
     {
          ampmtype = "am";
     }
     else
     {
        if (formatted.indexOf('P') != -1)
        {
          ampmtype = "pm";
        }
	else
        {
          ampmtype = "military";
        }
     }

     formatted = filterstringwithbag(formatted,'0123456789:')

     // we have hours and minutes to consider
     if (formatted.indexOf(":") != -1)
     {
       var h = Number(formatted.substring(0,formatted.indexOf(":")));
       var m = Number(formatted.substring(formatted.indexOf(":")+1,formatted.length+1));	
       if ((formatted.indexOf(":")-formatted.length) == -2)
       {
           m *= 10;
       } 

     }
     else
     {	
       var h = Number(formatted);
       var m = 0;		
     }				

     // now we have an hour and a minute and we know if it is 
     // AM or PM or Military time
         
     if (m > 60)
     {		 
	alert('Error: "' + rawtimestring +'" is not a valid time of day.');
	return ""; 
     }
     
     if ((ampmtype == "am") || (ampmtype == "pm"))
     {
        if (h > 12)
	{
 	   alert('Error: "' + rawtimestring +'" is not a valid time of day.');
	   return "";     
	}
     }
     else
     {
        if (h > 23)
        {
          alert('Error: "' + rawtimestring +'" is not a valid time of day.');
	  return "";     
	}
     }			
     
     if (m < 10) {m = '0' + m;}
	
     if (ampmtype == 'military')
     {
	if (h > 12)
	{
		h = h - 12;
		ampmtype = 'pm';
	}
	else
	{	
	     if (h == 12)
	     {
		ampmtype = 'pm';
	     }
	     else
	     {
		if (h == 0)
		{
		    h = 12;
		}	
                ampmtype = 'am';
	     }
	}
     }	
     // assuming they got this far, everything should be kosher
     return h + ':' + m + ' ' + ampmtype;				
  }	


  if (formatted.indexOf(":") != -1)
  {

     if (fmat == 'hhmm')
     { 	

        pos = formatted.indexOf(":");
        if ((formatted.indexOf(":",pos+1) == -1) && (formatted.indexOf(".") == -1))
        {
          return neg + formatted;
        }
        alert("time value '" + timestring + "' is not valid.");
        return "";
     }
     else
     {
	   h = to_hour(formatted);
	   m = to_minute(formatted);
	
	   retv = format_dec(h+(m/60.0)) 	
           return neg + retv
		
      }
  }
  if (formatted.indexOf(".") != -1)
  {
     if (fmat == 'hhmm')
     {
        var n = Math.round((Number(formatted)*60));
        var hours   = Math.round((n/60)-.5);
        var minutes = n%60;
        if ((hours == "NaN") || (minutes == "NaN"))
        {
           alert("time value '" + timestring + "' is not valid.");
	   return "";
        }
        if (minutes < 10)
        {
           return (neg + hours + ":0" + minutes)
        }
        return (neg + hours + ":" + minutes)
     }
     else
     {
       formatted = format_dec(formatted)	
       return (neg + formatted)
     }
  }
  else
  {
     if (fmat == 'hhmm')
     {	
        return (neg + formatted + ":00")
     }
     else
     {
       if (fmat == 'percent')
	{
           return (neg + formatted)
	}
	else
	{	
       	   return  (neg + formatted + ".00")
	}
     }	
  }
}




function formatMe(this_object,fmat)
{
  this_object.value = formatTime(this_object.value,fmat)
}


// do totals for an entry screen
//
function totals(this_form) {

  var startcol = colstart;    
  var fmat = regstype;    
  var toth = 0;
  var totm = 0;
  var rowtotalh = 0;
  var rowtotalm = 0;
  var columntotalh = 0;
  var columntotalm = 0;

  var rowcol, rxcx_widget;
  var ctotal_widget, rtotal_widget, gtotal_widget;
  var totalcolumn_widget, difftotalcolumn_widget;
  var ptotime;
  

  // do column totals
  for (var j = startcol; ; j++) {
	rowcol = "r0c" + j;
	rxcx_widget = this_form[rowcol];
	if (!rxcx_widget) {
	  break;
	}

	if (fmat == "hhmm") {
	  columntotalh = 0;
	  columntotalm = 0;
	  columnptom = 0; 

	  // rows move fastest
	  for (var i = 0; ; i++) {
		rowcol = "r" + i + "c" + j;
		rxcx_widget = this_form[rowcol];
		if (!rxcx_widget) {
		  break;
		}
		var h = to_hour(rxcx_widget.value);
		var m = to_minute(rxcx_widget.value);
		columntotalm += m + (h * 60);
		// if we haven't already done this with rows...
		totm += m + (h * 60);

		if (dd2PTO.length != 0) {
		  var setaspto = 0;
		  var dd2x_widget = this_form["dd2_" + i];
		  var rowpaytype = dd2x_widget.value;
		  for (var k = 0; k < dd2PTO.length; k++) {
			if (rowpaytype == dd2PTO[k]) {
			  columnptom += m + (h * 60);
			  rxcx_widget.style.color = "#ff00ff";
			  setaspto = 1;
			  break;
			}
		  }
		  if (setaspto == 0) {
			rxcx_widget.style.color = "#000000";
		  }
		}
	  }

	  ctotal_widget = this_form["ctotal" + j];
	  if (ctotal_widget) {
		ctotal_widget.value = minutes_to_hhmm(columntotalm);
		ctotal_widget.PTO = minutes_to_hhmm(columnptom);
	  }

	  totalcolumn_widget = this_form["TOTAL" + j];
	  difftotalcolumn_widget = this_form["DTOTAL" + j];
	  ptotime = this_form["ctotal" + j].PTO;
	  if (totalcolumn_widget) {
		if (ptotime) {
		  if (ctotal_widget) {
			ctotalhrs = ctotal_widget.value;
			adjustedhrs = subtracthours(ctotalhrs, ptotime)
			  difftotalcolumn_widget.value = subtracthours(totalcolumn_widget.value, adjustedhrs);
		  }
		}
		else {
		  if (ctotal_widget) {
			difftotalcolumn_widget.value = subtracthours(totalcolumn_widget.value, ctotal_widget.value);
		  }
		}
		img = this_form["IMGTOTAL" + j];
		img.style.visibility = (difftotalcolumn_widget.value == '0:00') ? "hidden" : "visible";
	  }
	}
	else {
	  columntotalh = 0.0;
	  for (var i = 0; ; i++) {
		rowcol = "r" + i + "c" + j;
		rxcx_widget = this_form[rowcol];
		if (!rxcx_widget) {
		  break;
		}
		var h = Number(rxcx_widget.value);
		columntotalh += h;
		toth += h;
	  }

	  ctotal_widget = this_form["ctotal" + j];
	  if (ctotal_widget) {
		if (fmat == "percent") {
		  ctotal_widget.value = format_percent(columntotalh) + "%";
		}
		else {
		  ctotal_widget.value = format_dec(columntotalh) + "";
		}
	  }
	}
  }

  if (fmat == "percent") {
	scalar = (toth) ? (1.0 / toth * 100) : 0.0;
  }
  
  // do row totals
  for (var i = 0; ; i++) {
	rowcol = "r" + i + "c" + startcol;
	var rxcx_widget = this_form[rowcol];
	if (!rxcx_widget) {
	  break;
	}

	if (fmat == "hhmm") {
	  rowtotalh = 0;
	  rowtotalm = 0;
	  for (var j = startcol; ; j++) {
		rowcol = "r" + i + "c" + j;
		rxcx_widget = this_form[rowcol];
		if (!rxcx_widget) {
		  break;
		}
		var h = to_hour(rxcx_widget.value);
		var m = to_minute(rxcx_widget.value);
		rowtotalm += m + (60 * h);
	  }
	  rtotal_widget = this_form["rtotal" + i];
	  if (rtotal_widget) {
		rtotal_widget.value = minutes_to_hhmm(rowtotalm);
	  }
	}
	else {
	  rowtotalh = 0.0;
	  for (var j = startcol; ; j++) {
		rowcol = "r" + i + "c" + j;
		rxcx_widget = this_form[rowcol];
		if (!rxcx_widget) {
		  break;
		}
		var h = Number(rxcx_widget.value);
		rowtotalh += h;             
	  }
	  rtotal_widget = this_form["rtotal" + i];
	  if (rtotal_widget) {
		if (fmat == "percent") {
		  rtotal_widget.value = (Math.round(format_percent(rowtotalh) * scalar * 100) / 100) + "%";
		}
		else {
		  rtotal_widget.value = format_dec(rowtotalh);
		}
	  }
	}
  }
  
  // do grand totals
  gtotal_widget = this_form.grandtotal;
  if (gtotal_widget) {
	if (fmat == "hhmm") {
	  gtotal_widget.value = minutes_to_hhmm(totm);
	}
	else if (fmat == "dec") {
	  gtotal_widget.value = format_dec(toth);
	}
	// else do nothing
  }
}



function format_percent(somenumber)
{
        // same as format_dec, but leaves off 
	// unnecessary .00 
	somenumber *= 100;
	somenumber = Math.round(somenumber);
	somenumber /= 100;
	somenumber = '' + somenumber
	if ((somenumber == "NaN"))
        {
           return "";
        }

	if (somenumber.indexOf('.') != -1)
	{
	  idx  = somenumber.indexOf('.'); 	
	  leng = somenumber.length;
	  if ((leng - idx) < 3)
	  {
	    return somenumber + '0';
	  }
	}
	return somenumber
}


// format for dec
function format_dec(somenumber)
{
	somenumber *= 100;
	somenumber = Math.round(somenumber);
	somenumber /= 100;
	somenumber = '' + somenumber
	if ((somenumber == "NaN"))
        {
           return "";
        }

	if (somenumber.indexOf('.') != -1)
	{
	  idx  = somenumber.indexOf('.'); 	
	  leng = somenumber.length;
	  if ((leng - idx) < 3)
	  {
	    return somenumber + '0';
	  }
	}
	else
	{
	  return somenumber + '.00';
	}
	return somenumber
}
 
// snag the hour
function to_hour(hhmm)
{

  if (((hhmm.indexOf("-") == 0) && (hhmm.indexOf(":") == 1)) || (hhmm.indexOf(":") == 0)) {
	return 0;
  }

  if (hhmm.indexOf(":") != -1)
  {
    return Number(hhmm.substring(0,hhmm.indexOf(":")));
  }
  return 0;
}

// snag the minute
function to_minute(hhmm)
{
  if (hhmm.indexOf(":") != -1)
  {
	if (hhmm.indexOf("-") != -1) {
	  return -(Number(hhmm.slice(hhmm.indexOf(":")+1)));
	}
	else {
	  return Number(hhmm.slice(hhmm.indexOf(":")+1));
	}	  
  }
  return 0;
} 

// convert # of minutes to a hh:mm string
function minutes_to_hhmm(m)
{
  var neg = "";
  var hours;
  var minutes = m;
  var minuteString = "";

  if (m < 0) {
	minutes = -minutes;
	neg = "-";
  }

  if (minutes > 59) {
	hours = Math.round((minutes/60)-.5);
  }
  else {
	hours = 0;
  }
  minutes %= 60;
  minutes = Math.round(minutes);

  if (minutes < 10) {
	minuteString = "0" + minutes;
  }
  else {
	minuteString = minutes;
  }

  return neg + hours + ":" + minuteString;
}

	
disabletree = 'no'
///////////////////////////////////////////////////////////////

function isin(itm,lst)
{
 for (loopZ = 0; loopZ < lst.length;loopZ++)
  {
  	if (lst[loopZ] == itm)
	{
	   return 1;
	}
  }
  return 0;
} 
	

function ismultiselected(the_select)
{
   var numselected = 0;
   for (var loop=0; loop < the_select.options.length; loop++)
   {
      if (the_select.options[loop].selected == true)
      {
           numselected += 1;
           if (numselected > 1){return 1;}
      }
   }
   return 0;	
}







function expandtoproject(sbox,projectid)
{        
     var currprojectid = projectid;

     // find and expand all parents
     while (2>1)
     {

        currprojectid = getparent(currprojectid);

        if (currprojectid == 'noparent')
	{
	   return;
        }
	expanded[expanded.length] = currprojectid
     }
}	
			
function getparent(projectid)
{
   ndx = viableProject(projectid);
   var loopWX = 0;	  
   var i = 0;

   for (loopWX = 0; loopWX < projectids.length; loopWX++)
   {
     alist = eval('window.X'+loopWX+'chlds');  
     if (alist)
     {	
       for (i = 0; i < alist.length;i++)
       {
        if (ndx == alist[i])
        {
           return projectids[loopWX];
        }
      }
    }
  }
  // no parent
  return 'noparent'
}



function multidrilldown(the_select, loading, rootProjName)
{
 
  if (the_select.selectedIndex == -1)
  {
    if (loading == 1)
    {
      the_select.selectedIndex = 0;	
    }
    else
    {	
      return;
    }
  }	
  else
  {
    // if they are using navigator 4
    // we are in single click mode by default
    if (is.nav4)
    {
	if (ismultiselected(the_select) == 1) { return }
    }	 		
  }

  var remslcted = the_select.selectedIndex
  // are we expanding something?
  var currentselected = the_select.options[the_select.selectedIndex].value;
  var currentindex    = viableProject(currentselected);
  var currentpn       = projectpnames[currentindex];


  if (currentpn.charAt(0) == '+')
  {
	if (isin(the_select.options[the_select.selectedIndex].value,expanded) != 0)
	{
	   // we are collapsing
	   var tempexpanded = [];
	   for (var loopA=0;loopA < expanded.length;loopA++)
	   {
		if (expanded[loopA] != the_select.options[the_select.selectedIndex].value)  		   
		{
		   tempexpanded[tempexpanded.length] = expanded[loopA];
                }
           }
	   expanded = tempexpanded;
	}
	else
	{		
	  // we are expanding
	  expanded[expanded.length] = the_select.options[the_select.selectedIndex].value
	}

  }
	


  newndx  = viableProject(rootProjName);

  idxs = eval('window.X'+newndx+'chlds');
	
  the_select.length = 1;
  the_select.options[0].text  = projectpnames[newndx]
  the_select.options[0].value = rootProjName;
	
  if (is.nav)
  {
     buffer = '...';	
  }
  else
  {
     buffer = '   ';	
  }

  setMultiProjectOptionText(the_select,idxs,buffer);  	
  the_select.selectedIndex = remslcted 
  	

}



  
function setMultiProjectOptionText(the_select,idxs,buffer)
{ 

 if (is.nav)
 {
 var mybuffer    = buffer + '...'	
 }	
 else
 {
 var mybuffer    = buffer + '   '	
 }

 var loopstart   = the_select.length;
 var grewhowmuch = 0; 	
 var needstogrow = idxs.length;
 var loop        = loopstart-1;	

 while (1 == 1)
 {
    
    loop              += 1;
    grewhowmuch       += 1	

    if (grewhowmuch > needstogrow)
    {	
	return grewhowmuch
    }

    the_select.length += 1;	

    var newpname = projectpnames[idxs[loop-loopstart]]
    if (newpname.charAt(0) == '+')
    {	
      	
      if (isin(projectids[idxs[loop-loopstart]],expanded) == 1)
      {        
	 newpname = ' -' + newpname.substring(1,newpname.length); 

	 the_select.options[the_select.length-1].text  =   mybuffer+newpname;
         the_select.options[the_select.length-1].value =   projectids[idxs[loop-loopstart]];

         var newndx  = viableProject(projectids[idxs[loop-loopstart]]);
         var newidxs = eval('window.X'+newndx+'chlds');
         var numfilledin = setMultiProjectOptionText(the_select,newidxs,mybuffer);
	 grewhowmuch += numfilledin;
	 needstogrow += numfilledin;	
      }
      else
      {
	 the_select.options[the_select.length-1].text  =   mybuffer+newpname;
         the_select.options[the_select.length-1].value =   projectids[idxs[loop-loopstart]];
      } 

    }
    else
    {
      the_select.options[the_select.length-1].text  =   mybuffer + '  '+newpname;
      the_select.options[the_select.length-1].value =   projectids[idxs[loop-loopstart]];	
    } 
  }

}

    


function drilldown(the_select, loading)
{
 
  var undefinedx = eval('the_select.thisbrowsersideaofundefined');

  if (disabletree == 'yes')
  {
    return
  }	

  if (the_select.selectedIndex == -1)
  {
    if (loading == 1)
    {
      the_select.selectedIndex = 0;	
    }
    else
    {	
      return;
    }
  }	
  slcted     = the_select.options[the_select.selectedIndex].value;
  currentpn  = the_select.options[the_select.selectedIndex].text;

  if (slcted == '*Any*')
  {
    return;
  }	

  ndx = viableProject(slcted);  
  if ((currentpn.charAt(0) == '-') || loading)
  {
   newslcted = hisparent(slcted,ndx,undefinedx);
   ndx = viableProject(newslcted);
  }
  else
  {
   newslcted = slcted;
   slcted = -1;
  }
  selectedpn = '- ' + projectpnames[ndx].substring(1,projectpnames[ndx].length);
  indxs = eval('window.X'+ndx+'chlds');
  if (indxs == undefinedx)
  {
      return;
  }		
  setProjectOptionText(newslcted,selectedpn,the_select,indxs,slcted);  
}


function hisparent(slcted,ndx,undefinedx)
{
  for (loop = 0; loop < projectids.length;loop++)
  {
    alist = eval('window.X'+loop+'chlds');  
    if (alist != undefinedx)
    {	
      for (i = 0; i < alist.length;i++)
      {
        if (ndx == alist[i])
        {
           return projectids[loop];
        }
      }
    }
  }
  return slcted
}


// get all the parents starting from the top
// recursive and returns number of parents returned

	


  
function setProjectOptionText(top,toppname,the_select,idxs,slcted)
{  
 // leaf, nothing to do
 if (idxs.length == 0) return;
 

  if (projectwildcards == 'yes')
  {
    the_select.options[0].text  = '*Any*';
    the_select.options[0].value = '*Any*';		 
    the_select.options[1].text  = toppname;	
    the_select.options[1].value = top;
    loopstart = 2;
  }
  else
  {
    var iter = 0;
    var currtoppname = toppname;
    var currtop      = top;
    the_select.length = 0;	
    pnamelist = []	
    idlist    = []
    while (2>1)
    {
       pnamelist[iter]  = currtoppname;
       idlist[iter]  = currtop;
       
       oldcurrtop = currtop;
       currtop =  getparent(oldcurrtop);
       
       if (oldcurrtop == currtop)
       {
        break;
       } 
       currtoppname = projectpnames[viableProject(currtop)];
       iter += 1;
    }
    loopstart = iter;
   }
  
 the_select.length = idlist.length - 1;
 
 idlist.reverse()
 pnamelist.reverse()

 
 
 spacer = ''
 for (i = 1; i < idlist.length; i ++)
 {
   the_select.options[i-1].text = spacer + pnamelist[i];     	
   the_select.options[i-1].value = idlist[i];
   spacer = spacer + '. . ';
 }
 //spacer = spacer + '. . ';

 // reset our length
 the_select.length = idxs.length+loopstart;	

 for (loop=loopstart; loop < idxs.length+loopstart; loop++)
 {

     the_select.options[loop].text =   spacer + projectpnames[idxs[loop-loopstart]];
     the_select.options[loop].value = projectids[idxs[loop-loopstart]]
 
   if ((slcted != -1) && (slcted != -2))
   {
      if (the_select.options[loop].value == slcted)
      {
         the_select.selectedIndex = loop;
         slcted = -2;
      }
   }
 }     

		
	while (loop < the_select.length) 
 	{	
     		the_select.options[loop].text  = '';
     		the_select.options[loop].value  = '';
     		loop++;
 	}   
 	if (slcted != -2)
 	{
     		the_select.selectedIndex = loopstart-1;  
 	}
}
	

	    
function reSelectIfNone(the_select)
{

 if (the_select.selectedIndex == -1)
 {
   the_select.selectedIndex = 0;
   return	
 }	

 if (the_select.options[the_select.selectedIndex].value == '')
 {
   the_select.selectedIndex = 0;
   return	 
 }

}

function viableProject(projid)
{
 i = 0;
 while(i <= projectids.length)
 {
   if (projid == projectids[i])
   {
      return i;
   }
   i++;
  }
 return -1;
}

function viableCode(code) {
  i = 0;
  while (i <= masterlist.length) {
	if (code == masterlist[i]) {
	  return i+1;
	}
	i++;
  }
  return -1;
}




function copyoptions(src_slct,dest_slct)
{
	dest_slct.length = src_slct.length;
	for (itr=0;itr < src_slct.length;itr++)
	{
	   dest_slct.options[itr].value = src_slct.options[itr].value;
	   dest_slct.options[itr].text = src_slct.options[itr].text;
	}
}


// for dtl on a few admin screens
function getdotted(slct)
{
	slct.length = dotlistpn.length + 1;
	for (i=0;i < dotlistpn.length;i++)
	{
		slct.options[i].text   = dotlistpn[i];
                slct.options[i].value  = dotlistid[i];
	}
     disabletree = 'yes';
}

function getcollapse(slct)
{
   disabletree = 'no';	
   drilldown(slct,1);	 
}


function appendselected(opt1,opt2,treeon)
{
    slist = getallselected(opt1,treeon);
    			
    clength = opt2.length;	
    for (var Loopi=0; Loopi < slist.length; Loopi++)
    {
	
      var addit = 1;	
      for (var Loopj=0; Loopj < clength; Loopj++)
      {
        if (slist[Loopi].value == opt2[Loopj].value)
	{
	   addit = 0;
	}
       }
       if (addit == 1)
       {
         opt2.length = opt2.length+1;
         opt2.options[opt2.length-1].value = slist[Loopi].value;
	 opt2.options[opt2.length-1].text  = slist[Loopi].text;
       }	    
     }
}

function removeselected(opt)
{
   var unselect = getallnotselected(opt);
   for (var i=0;i < unselect.length;i++)
   {
     opt.options[i].value = unselect[i].value;
     opt.options[i].text  = unselect[i].text;
   }
   opt.length = unselect.length;
}	  


function selectall(opt)
{
// select everything in a multselect
for (var i =0;i < opt.length;i++)
{
  opt[i].selected = 1;
 }
}	

function removeall(opt)
{
 selectall(opt);
 removeselected(opt);
}



function formatprojectname(projectname)
{
  // strip leading + if necessary	
  if (projectname.charAt(0) == '+')
  {
    return projectname.substring(1,projectname.length);
  }
  return projectname;
}

function getallnotselected(opt)
{
   // this function returns all the select items in a multi select
   var unselected = new Array();
   var index = 0;
   for (var intLoop=0; intLoop < opt.length; intLoop++) 
   {
    if (!(opt[intLoop].selected)) 
     {
      index = unselected.length;
      unselected[index] = new Object;
      unselected[index].value = opt[intLoop].value;
      unselected[index].text = opt[intLoop].text;
     }
   }
   return unselected;
}

function getallselected(opt,treeon) 
{
   // this function returns all the select items in a multi select
   var selected = new Array();
   var index = 0;
   for (var intLoop=0; intLoop < opt.length; intLoop++) 
   {
    if (opt[intLoop].selected) 
    {
      index = selected.length;
      selected[index] = new Object;
      selected[index].value = opt[intLoop].value;
      if (treeon == 1)
      {		
         var pnameindex = viableProject(opt[intLoop].value)
         var newpname = formatprojectname(projectpnames[pnameindex]);
         selected[index].text  = newpname;
      }
      else
      {
         selected[index].text = opt[intLoop].text;
      }
      
    }
   }
   return selected;
}

 

function autopopulate(the_form,projid,row,tablenumber) {

  // every browser has a different way of representing this..  (TODO: probably should use bad() instead, or just take out the eval)
  //var undefinedx = eval('the_form.thisbrowsersideaofundefined');
  var undefinedx = the_form.thisbrowsersideaofundefined;

  for (loopY = 0; loopY < objectclasses.length; loopY++) {	
	var lookupstr = 'X'+projid+'X'+objectclasses[loopY];
	var ndx = viableCode(lookupstr);

	if (ndx != -1) {	  
	  var idxs = window['X'+ndx];
	}
	else {
	  var idxs = [];
	}

	var the_select_prefix_name = 'T'+objectclasses[loopY]+'t'+tablenumber;	
	var the_select_prefix = window[the_select_prefix_name];

	var the_select_name = the_select_prefix + row;
	var the_select  = the_form[the_select_name];

	var ids_list_n = 'dd'+(loopY+1)+'_list';
	var ids_list = window[ids_list_n];

	var names_list_n = 'dd'+(loopY+1)+'_list_PN';
	var names_list = window[names_list_n];

	var kill_popup_link = null;
	
	if (the_select.options != undefinedx) {
	  if (the_select.type != 'hidden') {
		var selectedvalue = the_select.options[the_select.selectedIndex].value;

		// setOptionText(eval('dd'+(loopY+1)+'_list'),eval('dd'+(loopY+1)+'_list_PN'),the_select,idxs);
		setOptionText(ids_list,names_list,the_select,idxs);

		if (selectbyvalue(the_select,selectedvalue) == 'itemnotfound') {
		  the_select.selectedIndex = -1;	 
		  the_select.selectedIndex = 0;	 
		}

		kill_popup_link = the_select;
	  }
	}	
	else {
	  if (the_select.value != undefinedx) {
		var the_input_name = the_select_prefix + row + 'INPUT';
		var the_input = the_form[the_input_name];

		if (the_input != undefinedx) {
		  if (idxs.length == 0) {
			continue;
		  }	
		  currentvalue = the_select.value;

		  for (loopx=0; loopx < idxs.length; loopx++) {
			if (ids_list[idxs[loopx]] == currentvalue) {
			  // we have to set the value of the display input
			  // to be the prettyname
			  the_input.value = names_list[idxs[loopx]];
			  continue; 
			}
		  }

		  if (the_input.type != "text") {
			the_select.value = ids_list[idxs[0]];
			the_input.value  = names_list[idxs[0]];
		  }
		  else {

			// This is a text input -- that means it was a "popup search" thingie
			// replace it with a real dropdown.

			// delete "the_select" after saving its name.
			var saved_select_name = the_select.name;
			the_select.parentNode.removeChild(the_select);

			// make "the_input" a select dropdown
			var new_input = document.createElement("SELECT");
			new_input.name = saved_select_name;
			new_input.id = saved_select_name;
			new_input.isProjDepCreated = 1; // used in generalUI.js fncCheckProjDepsPopupSearch
			new_input.onChange = 'thingshavechanged=1;'; // needed for 

			// populate the new list
			setOptionText(ids_list,names_list,new_input,idxs);
			var selectedvalue = the_input.value;

			// make the appropriate selection
			if (selectbyvalue(new_input,selectedvalue) == 'itemnotfound') {
			  new_input.selectedIndex = -1;	 
			  new_input.selectedIndex = 0;	 
			}
			
			// remove the old one and plug the new one in
			var inputParent = the_input.parentNode;

			kill_popup_link = new_input;

			inputParent.removeChild(the_input);
			inputParent.appendChild(new_input);

		  }
		}	
	  }
	}

	if (kill_popup_link) {
	  // Delete the icon/link for popup search -- popup searches
	  // aren't currently aware of dependencies to limit the
	  // search.  So, we disable search.

	  inputParent = kill_popup_link.parentNode;

	  // loop over the input's parent until we find an element with clsPopupSearchLink.
	  for (var child_i = 0; child_i < inputParent.childNodes.length; child_i++) {
		ch_node = inputParent.childNodes[child_i];
		if (ch_node.className == 'clsPopupSearchLink') {
		  // window.alert('Removing childNode: ' + ch_node.id + " name: " + ch_node.name);
		  inputParent.removeChild(ch_node);
		  break;
		}
	  }	  
	}
	
  }

  // If we're NOT inside the real jtgui ONLOAD, and inner scrollbars are active,
  // then readjust them since the widths of the dropdowns may have changed.
  if (bad(window['INSIDE_JTGUI_ONLOAD']) && JXDoPositionMainTables) {
	if (!(is.ie)) {
	  //fncPositionMainTables();
	  jtguiOnLoad();
	}
	else {
	  //fncPositionMainTables();
	  // jtguiOnLoad();
	}
  }

}



function newOptionText(ids,pnms, the_select)
{
  var numnew = ids.length;
  the_select.length = numnew;
 	
  for (ii =0;ii<numnew;ii++)
  {
     the_select.options[ii].text  = pnms[ii];
     the_select.options[ii].value = ids[ii];
	 the_select.options[ii].selected = false;
  }
}


function setOptionText(ids, pnms, the_select, idxs) {
  var undefinedx = eval('the_select.yepgiamnoitdede');

  // make sure we are not messing with a hidden element
  if (the_select.options == undefinedx) {
	return;
  }
 
  // possible (in IE) we hit back and the options are now out
  // of range of the current choices
  if (the_select.selectedIndex == -1) {
	the_select.selectedIndex = 0;
  }
  if (the_select.selectedIndex > the_select.length) {
	the_select.selectedIndex = 0;
  }

  // get the current selected value
  //tst1 = the_select.options[the_select.selectedIndex].value;
 
  // set the drop down length	
  if (idxs.length == 0) {
    the_select.length = ids.length;
  }
  else {	
    the_select.length = idxs.length;
  }
 
  var phldr = 0;
  for (loop=0; loop < the_select.options.length; loop++) {
	if ((idxs.length == 0) || ((loop < idxs.length) && (idxs[loop] != -1))) {
	  if (idxs.length != 0) {
		the_select.options[phldr].text = pnms[idxs[loop]];
		the_select.options[phldr].value = ids[idxs[loop]];
	  }
	  else {
		the_select.options[phldr].text  = pnms[loop];
		the_select.options[phldr].value = ids[loop];
	  }
	  phldr = phldr + 1;	
	}
  } 
}




// populate a box with selected values from another box
function populatebyselected(originbox,destbox)
{

   // first get the selected ids and pnames from the origin box
   var ids    = [];		
   var pnames = [];   
   var i;
   var k = 0;	

   for (i = 0; i < originbox.length; i++)
   {
      if (originbox[i].selected)
      {
         ids[k] = originbox[i].value;

	 // we need to strip off all those annoying tree 
	 // characters from the pretty names 
	 var newpname = originbox[i].text;
         var firstchar = newpname.charAt(0);
         while ((firstchar == ' ') || 
                (firstchar == '.') ||  
                (firstchar == '-') ||
	 	(firstchar == '+'))
	{
	   // slice it up	
	   newpname = newpname.substring(1,newpname.length);
	   firstchar = newpname.charAt(0);	
	}

	 pnames[k] = newpname;
         k = k + 1;
      }	    
   }	   
   // ok thats done, now lets populate the destination
   setOptionText(ids, pnames, destbox, []);
}


// select in a select box based on value
function selectbyvalue(slbox,val)
{
  var i = 0;
  for (i = 0;i < slbox.options.length;i++) {
	if (slbox.options[i].value == val) { 
	  slbox.selectedIndex = i;
	  return;
	}
  }
  // if we got here the item was not available
  return 'itemnotfound';
}


// select in a select box based on value
function addextravalue(slbox,val,txt)
{

    if (txt.substring(txt.length-14,txt.length) == '(not loggable)')
    {	
      return;
    }	

    txt = striptreechars(txt);	
    if (slbox.appended)
    {  
      var i = slbox.length;
    }
    else
    {		
      var i = slbox.length + 1;
      slbox.length = i;
      slbox.appended = 1;
    } 
    slbox.options[i-1].value = val;
    slbox.options[i-1].text = txt;	
    slbox.selectedIndex = i-1;
}


function striptreechars(txt)
{
   // first kill leading spaces
   // +/./- in the text
   var newpname = txt;
   var firstchar = newpname.charAt(0);
   while ((firstchar == ' ') || 
          (firstchar == '.') ||  
          (firstchar == '-') ||
	  (firstchar == '+'))
   {
       // slice it up	
       newpname = newpname.substring(1,newpname.length);
       firstchar = newpname.charAt(0);	
   }	
   return newpname;
}


// synch the selected value of two inputs
function sync(sl1,sl2)
{ 
    itm = sl1.options[sl1.selectedIndex].value;
    selectbyvalue(sl2,itm);
}




// XXXXXXXXXXXXXXXXXXXX
var ie=document.all
var dom=document.getElementById
var ns4=document.layers



function initbox(elementname)
{


  if (!dom&&!ie&&!ns4) return;
  crossobj= (dom)?document.getElementById(elementname).style : ie? eval('document.all.'+elementname) : eval('document.'+elementname)
  //crossobj.top=(event.y+document.body.scrollTop-100);
  //crossobj.left=(event.x-20);	
  crossobj.visibility=(dom||ie)? "visible" : "show";
}


// returns index of select radio set, -1 if nothing selected
function getRadio(fradio)
{
if (fradio[0]){for (var i=0;i<fradio.length;i++) {if (fradio[i].checked) {return i}}}
else {if (fradio.checked) { return 0;}}
return -1;
}


function togglecheckboxes(cbox)
{
  var waschecked = 0;
  var initdone = 0;
  var checkval = true
  for(var i=0;i < cbox.length;i++)
  {
    if (cbox[i].type == 'checkbox')
    {		
      if (initdone == 0) {
	initdone = 1;
        if (cbox[i].checked == true) 
	{
	  checkval = false
        }
      }
      cbox[i].checked = checkval
    }
   }
}

function checkall(cbox,cstat) 
{
  var waschecked = 0;
  for(var i=0;i < cbox.length;i++)
  {
    if (cbox[i].type == 'checkbox')
    {		
      waschecked = cbox[i].checked;
      cbox[i].checked=cstat
      if (cbox[i].checked)
      { 
       if (waschecked)
       {
       }
       else
       {
         inccheck();
       }
      }
      else
      {
       if (waschecked)
       {
         deccheck();
       }
      }
    }
 }
}	


function areanychecked(cbox) 
{
  // If there is a single checkbox then no indexing
  if (cbox.checked == true) {
	return true;
  }
  //Else there would be an array of check boxes
  for(var i=0;i < cbox.length;i++)
  {
    if (cbox[i].type == 'checkbox')
    {		
      if (cbox[i].checked == true){
	return true;
      }
    }
  }
  return false;
}


//// some code for remembering scrollbar locations between loads

var db = (document.body) ? 1 : 0; 
var scroll = (window.scrollTo) ? 1 : 0; 


function setCookie (name, value, exp, path, domain, secure) {
 /*
    INPUT
      name (string) - name of the cookie
      value (string) - value of the cookie
      exp (string) - default is "never"
                     if "never" it sets exp to "Thu, 7 Dec 2113 01:00:00 UTC"
                     if "exp" it sets exp to "Fri, 13 Apr 1970 01:00:00 UTC"
                     if int (ie "5", "20", "60000") it translates to int hours from now
                     if valid GMT date then it uses that as exp
                     else it defaults to 840 hours (5 weeks)
      path (string)
 */
 if(exp == "") {
   exp = "never";
 }
 if (typeof(exp) == 'string') {
   if (exp == 'never') { 
     var strExp = "Thu, 7 Dec 2113 01:00:00 UTC";
   }
   else if (exp == 'exp' || exp == 'now') { 
     var strExp = "Fri, 13 Apr 1970 01:00:00 UTC";
   }
   else {
     if (Date.parse(exp)) {
      var strExp = exp;
     }
     else {
       exp = exp*1;
       if (isNaN(exp)) {
        var strExp = (new Date((new Date()).getTime() + 840*3600000)).toGMTString();
       }
       else {
        var strExp = (new Date((new Date()).getTime() + exp*3600000)).toGMTString();
       }
     }
   }
 }
 document.cookie = name + '=' + escape(value) + ((strExp)?(';expires=' + strExp):'') + ((path)?';path=' + path:'')  + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "");
}


function readCookie(name) {
 var strCookies = document.cookie;
 
 // find beginning of cookie value in document.cookie
 var prefix = name + "=";
 var begin = strCookies.indexOf("; " + prefix);
 if (begin == -1) {
   begin = strCookies.indexOf(prefix);
   if (begin != 0) return null;
 }
 else begin += 2;
 
 // find end of cookie value
 var end = document.cookie.indexOf(";", begin);
 if (end == -1) end = strCookies.length;
 
 // return cookie value
 return unescape(strCookies.substring(begin + prefix.length, end));
}

function killCookie(name, path) {
 setCookie (name, null, 'now', path);
}



function killAllCookies(path) {
 var strCookies = document.cookie;
 
 var astrCookies = document.cookie.split(";");
 
 for(var i=0;i<=astrCookies.length-1;i++) {
   var astrCookie = astrCookies[i].split("=");
   var strCookieName = astrCookie[0];
   if (i>0) {
     if (strCookieName.indexOf(" ") == 0) {
       // remove leading space
       strCookieName = strCookieName.substring(1,strCookieName.length)
     }
   }
   killCookie(strCookieName, path);
 }
 alert('All cookies deleted for path ' + path);
}



function listCookies(path) {
 var strCookies = document.cookie;
 var astrCookies = document.cookie.split(";");
 var strOutput = "";
 if (strCookies != null && strCookies.length > 0) {
   for(var i=0;i<=astrCookies.length-1;i++) {
     var astrCookie = astrCookies[i].split("=");
     var strCookieName = astrCookie[0];
     var strCookieValue = astrCookie[1];
     if (i>0) {
       if (strCookieName.indexOf(" ") == 0) {
         // remove leading space
         strCookieName = strCookieName.substring(1,strCookieName.length)
       }
     }
     strOutput = strOutput + "\n   " + strCookieName + ": " + strCookieValue;
   }
 }
 if (strOutput.length < 5) {
   strOutput = " { no cookies for path " + path + " } ";
 }
 else {
   strOutput = "cookies for path " + path + strOutput;
 }
 alert(strOutput);
}


function saveScroll(pagename) 
{ 
 if (!scroll) return; 
 var now = new Date(); 
 now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); 
 var x = (db) ? document.body.scrollLeft : pageXOffset; 
 var y = (db) ? document.body.scrollTop : pageYOffset; 
 setCookie(pagename+"xy", x + "_" + y, now); 
} 


function loadScroll(pagename) 
{ 
 if (!scroll) 
 {
  return;
 } 
 var xy = readCookie(pagename+"xy"); 
 if (!xy) 
 {
   return;
 } 

 var ar = xy.split("_"); 
 if (ar.length == 2) 
 {
   scrollTo(parseInt(ar[0]), parseInt(ar[1])); 
 }
} 



disablelist = [];
// disables fobj (some formobject)
// and sets enableall to run in 9 seconds
function disablethis(fobj)
{
  disablelist[disablelist.length] = fobj;
  fobj.disabled = true;
  setTimeout("enableall()",9000);
}

//
// take the list of disables objects and 
// enables them
function enableall()
{
 var i = 0;
 for (i=0;i < disablelist.length;i++)
 {
  if (disablelist[i])
  {
     disablelist[i].disabled = false;
  }
 }
 disablelist = [];
}


//
// returns the highest version of Office Web Components that the client supports
// 0 is returned if OWC is not installed
// this will need to be updated to try check for newer versions of OWC when they are released
//
function getOWCversion()
{
 var agt = navigator.userAgent.toLowerCase();
 this.major = parseInt(navigator.appVersion);
 this.ie   = (agt.indexOf("msie") != -1);

 if (this.ie) {
  try  {
   var owc = new ActiveXObject("owc11.PivotTable.11");
   return owc.MajorVersion + "." + owc.MinorVersion;
  }
      
  catch(e) {
   try  {
    var owc = new ActiveXObject("owc10.PivotTable.10");
    return owc.MajorVersion + "." + owc.MinorVersion;
   }
   catch(e) {
    try  {
     var owc = new ActiveXObject("owc.PivotTable.9");
     return owc.MajorVersion + "." + owc.MinorVersion;    
    }
    catch(e) {
     return 0;
    }
   }
  }
 }
 return 0;
}


function addFields(source,destination, removeFieldsFromSource){
  // option is an option object
  // destination is a Select list object
  // if the option value and text is already in destination
  // we don't add it again
  //
  // NOTE - we might have to add a paramater that skips checking the target list for the existence of the value
  //        That check could be really slow if the target list is large.

  // removeFieldsFromSource can be set to delete the moved items from
  // the original source list.  This isn't the default because the
  // default for removeFields() is *not* to put them back in the
  // source list.

  var option;
  for (var i=0;i<source.length;i++) {

	option = source.options[i];
    if (!option.selected) {
      continue;
    }
	
	var alreadySelected = 0
    for (var j=0;j<destination.length;j++){
      if ((destination.options[j].text == option.text) && (destination.options[j].value == option.value)) {
		alreadySelected = 1
      }
    }

	if (alreadySelected == 1) {
		continue;
	}

    // if we're here, the option isn't in the destination list already, so we should add it
    var index = destination.selectedIndex;			
	  if (index == -1){
        index = destination.length;
	  }
	  destination.length = destination.length + 1;

		  
    // move all of the selected items down 1 
    for (var j=destination.length-1; j > index; j--) {
      destination.options[j].text = destination.options[j-1].text;
  	  destination.options[j].value = destination.options[j-1].value;
  	  destination.options[j].selected = destination.options[j-1].selected;
    }
		  

	var dest_opt = destination.options[index];

	dest_opt.text = option.text;
	dest_opt.value = option.value;		    
	dest_opt.selected = false;
	dest_opt.JX_Origin_Select = source;  // remember where we came from so we can put it back in removeFields below

  }

  // We've copied over the selected fields, now remove the selected
  // fields from the source object because they have been moved to the
  // destination.

  if (removeFieldsFromSource) {
    removeFields(source,0);
  }

  return true;
}


function removeFields(selectList,removeAll, destinationObject) {
  // selectList is the select object we're removing from
  // if removeAll is set, everything gets cleared out of the selectList
  // destinationObject is the optional place to stick the deleted option(s) 
  //  (presumably the 'available' input)

  // The only problem with adding them back to the destinationObject is that
  // they'll show up in the "wrong" order if they were previously sorted, since
  // the items are added back to the end of the destinationObject.
		  		  
  if ((removeAll == 0) && (selectList.selectedItem == -1)) {
    return;
  }	

  var newLength = 0;
  var textArray = new Array();
  var valueArray = new Array();
  var OriginSelectArray = new Array();

  var destTextArray = new Array();
  var destValueArray = new Array();
  var destOriginSelectArray = new Array();
	      
  // loop through and keep track of the stuff we want to keep.
  for (var i=0;i<selectList.length;i++){
	var this_opt = selectList.options[i];
    if ((removeAll == 0) && (this_opt.selected == false)) {
      textArray[textArray.length] = this_opt.text;
      valueArray[valueArray.length] = this_opt.value;
	  OriginSelectArray[OriginSelectArray.length] = this_opt.JX_Origin_Select;  // could be null/undef
      this_opt.text = "";
      this_opt.value = "";
      this_opt.JX_Origin_Select = null;
    } 
	else {
      destTextArray[destTextArray.length] = this_opt.text;
      destValueArray[destValueArray.length] = this_opt.value;      
	  
	  var origin_select = this_opt.JX_Origin_Select;
	  // warning - could be putting a null/undef in there - need to keep arrays the same length.
	  destOriginSelectArray[destOriginSelectArray.length] = origin_select;
	}
  }
		  
  // now put all the options we didn't delete back in the list
  selectList.length = textArray.length;
  for (var i=0;i< selectList.length;i++){
	var this_opt = selectList.options[i];
	this_opt.text = textArray[i];
	this_opt.value = valueArray[i];
	this_opt.JX_Origin_Select = OriginSelectArray[i];
	this_opt.selected = false;
  }

  // now put all the deleted options into the destination Select
  // object, if we were given one.

  for (var i=0;i< destTextArray.length;i++){

	if (!destinationObject) {
	  saved_DestinationObject = destOriginSelectArray[i];
	  if (!bad(saved_DestinationObject)) {
		var the_dest = saved_DestinationObject;
	  }
	  else {		
		// we weren't given a destination object, and we couldn't find
		// one stashed from the addFields function above, so there's
		// not much we can do here.
		continue;  
	  }
	}
	else {
	  var the_dest = destinationObject;
	}

	var starting_point = the_dest.length;
	the_dest.length = starting_point + 1;

	var the_dest_opt = the_dest.options[starting_point];

    the_dest_opt.text = destTextArray[i];
    the_dest_opt.value = destValueArray[i];
	the_dest_opt.selected = false;
  }

  return true;
}

function moveOptions(selectList, dir){
  // selectList is a select object		  
  // dir is the direction we want to move it (-1 moves it towards index 0, 1 moves it towards the end of the list)

  var i = selectList.selectedIndex;
  if (i == -1){return;}

  if ( (selectList.options[0].selected) && dir == -1){
    return;
  }

  if ( (selectList.options[selectList.length-1].selected) && (dir == 1)) {
    return ;
  }	
	  
  var temparray = new Array();

  // loop through and get the selected indices
  // if we're moving options up (dir == -1) go from 0 to selectList.length
  if (dir < 0){
    for (var index=i;index < selectList.length;index++) {
      if (selectList.options[index].selected) {               
	    temparray[temparray.length] = index;
      }
    }
  }

  // if we're moving options down (dir ==1) go from selectList.length to 0
  else {
    for (var index=selectList.length-1;index >-1;index--) {
      if (selectList.options[index].selected) {               
	    temparray[temparray.length] = index;
      }
    }
  }


  for (var i=0;i<temparray.length;i++){
    index = temparray[i];
    var temptext = selectList.options[index + dir].text;
    var tempvalue = selectList.options[index + dir].value;
			  
    selectList.options[index + dir].text = selectList.options[index].text;
    selectList.options[index + dir].value = selectList.options[index].value;
		  
    selectList.options[index].text = temptext;
    selectList.options[index].value = tempvalue;
  }	

  // de-select everything
  for (var i=0;i< temparray.length;i++){
    selectList.options[temparray[i]].selected=false;
  }
		  
  // loop through and make the moved options selected again
  for (var i=0;i < temparray.length;i++){				     
    selectList.options[temparray[i] + dir].selected = true;			 
  }		
}

function toggleArrow(id) {
  imgSrc = id.src;
  
  if (id.src.indexOf("right") > -1){
    id.src = imgSrc.replace("right","down");
  }
  else {
    id.src = imgSrc.replace("down","right");    
  }
}  


var ScrollPos = 0; // Initial Index of position in MyScrollText
var NormalText; // Text of the button before mouseover
var MyObject;// Object to be manipulated
var MyScrollText; // Text to be scrolled on object
var MyInterval; // ID for Interval
var Spaces = ""; // Spaces for paddin
// Usage SetScroll(true|false,this,[Text
// to be Scrolled])




function StartScroll(TObject)
{
if (is.ie)
{
  objectname = TObject.name;	
  if (TObject.value.length <= TObject.size)
  {
    TObject.noscroll = 1;
    return;
  }
  TObject.noscroll = 0;
	
  ScrollPosition = 0;
  ScrollDirection  = 'forward';	
  ScrollerText     = TObject.value;
  ScrollerInterval = window.setInterval('ScrollText();',100);
  Scroller         = TObject;
}

}

function StopScroll(TObject)
{

if (is.ie)
  {
    if (TObject.noscroll)
    {
      return;
    }
    
    window.clearInterval(ScrollerInterval);
    ScrollPosition = 0;
    TObject.value = ScrollerText;	
  }
}

function ScrollText()
{
    Scroller.value = ScrollerText.substr(ScrollPosition,ScrollerText.length);

    if (ScrollDirection == 'forward')
    {
     if (ScrollPosition >= (ScrollerText.length - Scroller.size))
     {ScrollDirection = 'backward';}
     else {ScrollPosition++;}
    }

    else
    {
     if (ScrollPosition < 1)
     {ScrollDirection = 'forward';}
     else {ScrollPosition--;}
    }
}

function closeIfPopup() {
  if (window.opener) {
    // window.opener.location = 'wte.pyc'
    window.close();
    return false;
  } else { return true; }
}

