/*
sccsid = '@(#) 1.53 wt/wtp/htdocs/scripts/jsgenlib_7.js, wtcode, jtimedev 10/11/07 13:54:58'

## 
## (C) COPYRIGHT Journyx, Inc 1997-2007
## 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, 10);
  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 = [];

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;
	  }
	}
  }
  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)
{
  var hours, ampm, hoursminutes;

  // special case for midnight
  if (minutes == 1440) {
	hours = '12';
	minutes = '00';		 
    ampm = 'am';
  }
  else {	  
	
	hoursminutes = minutestohoursminutes(minutes);
	hours   = Number(hoursminutes.substring(0,hoursminutes.indexOf(":")));
	minutes = Number(hoursminutes.substring(hoursminutes.indexOf(":")+1,hoursminutes.length+1)); 	   
	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;
  var bag, neg;
  var h,m;
  var ampmtype = "";

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

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

	// 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) {
	  h = Number(formatted.substring(0,formatted.indexOf(":")));
	  m = Number(formatted.substring(formatted.indexOf(":")+1,formatted.length+1));	
	  if ((formatted.indexOf(":")-formatted.length) == -2) {
		m *= 10;
	  } 
	  
	} else {	
	  h = Number(formatted);
	  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)-0.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;

  var j, i, k; // loop counters
  var h, m; // hours, minutes

  // do column totals
  for (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 (i = 0; ; i++) {
		rowcol = "r" + i + "c" + j;
		rxcx_widget = this_form[rowcol];
		if (!rxcx_widget) {
		  break;
		}
		h = to_hour(rxcx_widget.value);
		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 (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 (i = 0; ; i++) {
		rowcol = "r" + i + "c" + j;
		rxcx_widget = this_form[rowcol];
		if (!rxcx_widget) {
		  break;
		}
		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 (i = 0; ; i++) {
	rowcol = "r" + i + "c" + startcol;
	rxcx_widget = this_form[rowcol];
	if (!rxcx_widget) {
	  break;
	}

	if (fmat == "hhmm") {
	  rowtotalh = 0;
	  rowtotalm = 0;
	  for (j = startcol; ; j++) {
		rowcol = "r" + i + "c" + j;
		rxcx_widget = this_form[rowcol];
		if (!rxcx_widget) {
		  break;
		}
		h = to_hour(rxcx_widget.value);
		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 (j = startcol; ; j++) {
		rowcol = "r" + i + "c" + j;
		rxcx_widget = this_form[rowcol];
		if (!rxcx_widget) {
		  break;
		}
		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)-0.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) { 

  var mybuffer;
  if (is.nav) {
	mybuffer    = buffer + '...';
  }	
  else {
	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;
  }
}


/*
 * repopulateSelect - populates a select list from a list of Options
 * used to dynamically populate lists
 *
 * sourceList should be an array of Options, which can be copied
 * directly to the select object.
 *
 * selectId is a string containing the id of the target select
 * list to be populated.
 * 
 * originally created for 13183, in wtrptlist.py
 *
 */


function repopulateSelect(sourceList, selectId) {
  selectObject = document.getElementById(selectId);
  selectObject.options.length = sourceList.length;

  for (var i=0; i<sourceList.length; i++) {
	selectObject.options[i] = new Option(sourceList[i].text, sourceList[i].value);
  }
}


// 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 = [];
  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 = [];
  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);
	var idxs;
	var selectedvalue;

	if (ndx != -1) {	  
	  idxs = window['X'+ndx];
	}
	else {
	  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') {
		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) {

		  // DIN 13479 - the following was commented out because it
		  // was causing problems with the DIN 13418 change.
		  // Essentially in 13418 we made jtgui call selectbyvalue()
		  // even when dropdown threshold is in effect for this
		  // column.  (In order to have the correct default Task/code
		  // selected after project deps. were applied.)  That caused
		  // a problem with cases where there's no dependencies
		  // defined for the default project. It skipped over the code
		  // that turns a text-box (threshold enabled) into a regular
		  // dropdown - presumably for reasons of efficiency.  Since
		  // this code was skipped, selectbyvalue() got errors because
		  // it assumed the presence of a dropdown, not a text box.

		  //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);
			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;
  }	

  var i; // 
  txt = striptreechars(txt);	
  if (slbox.appended) {  
	i = slbox.length;
  }
  else {		
	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) {
		  // do we need a 'pass' type statement here?
		}
		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)
 */

  var strExp;

  if (exp == "") {
	exp = "never";
  }
  if (typeof(exp) == 'string') {
	if (exp == 'never') { 
	  strExp = "Thu, 7 Dec 2113 01:00:00 UTC";
	}
	else if (exp == 'exp' || exp == 'now') { 
	  strExp = "Fri, 13 Apr 1970 01:00:00 UTC";
	}
	else {
	  if (Date.parse(exp)) {
		strExp = exp;
	  }
	  else {
		exp = exp*1;
		if (isNaN(exp)) {
		  strExp = (new Date((new Date()).getTime() + 840*3600000)).toGMTString();
		}
		else {
		  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;
	  return "11.0"
	}
      
	catch(e) {
	  try  {
		var owc = new ActiveXObject("owc10.PivotTable.10");
		//return owc.MajorVersion + "." + owc.MinorVersion;
		return "11.0"
	  }
	  catch(e) {
		try  {
		  var owc = new ActiveXObject("owc.PivotTable.9");
		  //return owc.MajorVersion + "." + owc.MinorVersion;    
		  return "11.0"
		}
		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;
  var i,j; // loop counters

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

	option = source.options[i];
    if (!option.selected) {
      continue;
    }
	
	var alreadySelected = 0;
	for (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 (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 = [];
  var valueArray = [];
  var OriginSelectArray = [];

  var destTextArray = [];
  var destValueArray = [];
  var destOriginSelectArray = [];

  var i; // loop counter
  var this_opt;
	      
  // loop through and keep track of the stuff we want to keep.
  for (i=0;i<selectList.length;i++){
	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 (i=0;i< selectList.length;i++){
	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.
  var the_dest;
  
  for (i=0;i< destTextArray.length;i++){

	if (!destinationObject) {
	  saved_DestinationObject = destOriginSelectArray[i];
	  if (!bad(saved_DestinationObject)) {
		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 {
	  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 = [];
  var index;

  // 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 (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 (index=selectList.length-1;index >-1;index--) {
      if (selectList.options[index].selected) {               
	    temparray[temparray.length] = index;
      }
    }
  }

  for (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 (i=0;i< temparray.length;i++){
    selectList.options[temparray[i]].selected=false;
  }
		  
  // loop through and make the moved options selected again
  for (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; 
  }
}

