/* /library/javascript/global.js -	
  
   DATE     AUTHOR  CHANGE
   13/11/02	MvO			Created
   28/01/03	MvO			Added functions to allow dynamic clearing and adding of items in a dropdown/combo.
   31/01/03	MvO			ftnCheckNumeric was in twice.  Removed the kludgy version.
   04/02/03	GJB			Added subCheckboxManipulate and made subCheckboxClick a simple wrapper round it.
   03/03/03	MvO			Changed subCheckboxManipulate() to eval ocjs when changing exclusive checkboxes.
   03/03/03	MvO			Changed subCheckboxClick() to handle exclusive groups of checkboxes.
   08/04/03	MvO			Added validation functions to check if only SQL Server Full-text words were entered.
   08/04/03	MvO			Added ftnCheckMoney function.
   09/04/03	MvO			parseInt() bug: changed all parseInt() calls to have radix of 10,
   14/05/03	GSB			Added people picker fucntions  subPeoplePickerSelectedRows, subPeoplePickerCheckSelected,
										subPeoplePickerShowHide, subPeoplePickerTickAll
										Added function subGridSelectedRows for grid xslt template  
   15/05/03	GSB			Added subUploadBox - extenion of subMsgBox that provied and upload dialog
										Added subUploadBoxValidate - validates file & valid extensions from subUploadBox
										Added subConfirmBox - custom confirmation dialog sub
   30/04/03 DC      Changed subCheckboxManipulate and subCheckboxClick so they expects the ID of the hidden input field,
                    not the name of the image related to it. Why? cos I want it that way!
   03/05/03 DC      Added subCheckboxState - to enable or disable a checkbox
   03/05/03 DC      Added ftnGetCheckboxes - to return an array containing a subset of the checkboxes on the page
   19/06/03 DC      altered ftnManipulatechecbox to use disabled gif if checkbox is disabled regrdless of state.
   30/06/03	GJB			Fixed ftnCheckNumeric so it doesn't return true for empty strings
   07/07/03	GSB			Changed subUploadBoxValidate to subValidateFileExts and alter it to be used as a genral purpose file
										extention validation sub
	 17/07/03	Hemang  Added functions for  Calendar/ date picker box , Copied from launch planning 		
	 29/07/03	CHB			**OO** - Indicated change for Online ordering		
	 08/08/03	DLL		  Changed mouseover colour for combo boxes to the correct one.
	 18/08/03	DLL		  Changed ftnGetObject so that it works when id is not set on Mac's.  Also subHelp now displays no help yet
							      text when there is no help available, but subHelp has been called
	 16/09/03 DC      Copied to Retail Operations. Changed so that gImgPath is used throughout.
	 03/10/03 DC      Moved ftnGetMsgBoxHTML into another brand.js in brand subdirectory
	                  because it contains display logic.
	 21/11/03 GSB     Fixed bug in ftnCheckNumeric
   26/02/04 GJB     Modified function that opens combo dropdowns so that they scroll into view if rendered 
                    outside visible area.
	31/03/2004	MvO	Changed subMsgBox() to use window.alert()
  17/06/04  AgMcC  Altered subClearCombo and subAddComboItems, added subAddComboItem and subDeleteFromCombo to allow
  more versatility
  13/04/05  AgMcC  Fixed bug in date picker code
*/


// CONVERSION FUNCTIONS --------------------------------------------------------------------------------------

function ftnStringToDate(strString) {
/*Purpose	:	Returns a variant of type Date from a string in ISO date format, i.e. yyyy-mm-dd
	Effects	:	None.
	Inputs	:	strString - String - the date string to convert.
	Returns	:	Variant of type Date or Null
	Comments:	WILL error if string is not in ISO date format. Use ftnCheckDate to validate 1st.
*/
	var intYear, intMonth, intDay;

	if(!ftnCheckDate(strString)) { //alert("ftnStringToDate() - strString parameter is invalid."); 
	return false; }

	if(strString.length <= 0) {
		return null;
	} else {
		intYear = parseInt(strString.substr(0,4),10);
		intMonth = parseInt(strString.substr(5,2),10);
		intDay = parseInt(strString.substr(8,2),10);
		return new Date(intYear, intMonth, intDay);
    }
}

function ftnDateToString(dteDate)
{
/*
	Purpose	:	Returns a string in ISO format of a date.
	Effects	:	None.
	Inputs	:	dteDate - Date - the date to convert.
	Returns	:	String - the date formatted as an ISO date.
	Comments:	None.
*/
	var strYear, strMonth, strDay;

	if(isNaN(Date.parse(dteDate))) { //alert("ftnDateToString() - dteDate parameter is invalid."); 
	return false; }

	strYear = dteDate.getFullYear().toString();
	strMonth = dteDate.getMonth().toString();
	strDay = dteDate.getDate().toString();
	
	if(strMonth.length == 1) { strMonth = "0" + strMonth; }
	if(strDay.length == 1) { strDay = "0" + strDay; }
	
	return strYear + "-" + strMonth + "-" + strDay;    
}

// MESSAGE BOX FUNCTIONS -----------------------------------------------------------------------

function ftnGetCenter() {
	var intClientHeight = document.body.clientHeight;
	var intClientWidth = document.body.clientWidth;
	var intDocTop = document.body.scrollTop;
	var intDocLeft = document.body.scrollLeft;
	var objLoc = new Object();
	objLoc.x = intDocLeft + intClientWidth/2;
	objLoc.y = intDocTop + intClientHeight/2;
	return objLoc;
}

function subMsgBoxClose()
{
if (!blnMac){
	divMain.innerHTML = "";
	}
	divMain.style.visibility = "hidden";
	divHide.style.display = "none";
	if(strFocusOnClose != null && strFocusOnClose.length > 0) { ftnGetObject(strFocusOnClose).focus();}
}

function subSortResize()
{
	var imgHide = divHide.all.tags("IMG")(0);
	var objLoc = ftnGetCenter();

	divHide.style.height = document.body.scrollHeight;
	imgHide.height = document.body.scrollHeight;
	divMain.style.top = objLoc.y - divMain.clientHeight/2;
}

function subMsgBox(strTitle, strBody, strObject, blnHideClose, blnHelp) {
/*Purpose	:	Displays a message box on the client.
	Effects	:	None.
	Inputs	:	strTitle - String - the message box title.
				strBody - String - the body of the message box.
				strObject - String - ID of the HTML object/element to set the focus to.
				blnHideClose - Boolean - to display the close button or not.
				blnHelp - Boolean - if true then renders the message box wider to display context-sensitive help info.
	Returns	:	None.
	Comments:	None.
*/

	//alert(strTitle.toUpperCase() + "\n\n" + strBody);
	alert(strBody);
}

function subConfirmBox(strTitle, strBody, varAction)
{
/*Purpose	:	displays a confirmation dialog to the user, if "no" pressed the dialog closes, if "yes" pressed
						then action in varAction is taken e.g 'javascript:myfrom.submit();' or '/asp/dosomethingscript.asp'.
	Effects	:	None.
	Inputs	:	strTitle -	title of confirmation box
						strBody -		text of confirmation box
						varAction -	Action to be take if yes button clicked e.g 'javascript:myfrom.submit();' or '/asp/dosomethingscript.asp'.
	Returns	:	None.
	Comments:	Requires the subMsgBox function
*/
	strBodyHTML =  '<table width="100%" border="0" cellspacing="0" cellpadding="0">';
	strBodyHTML += '	<tr>';
	strBodyHTML += '		<td><p>' + strBody + '</p></td>';
	strBodyHTML += '	</tr>';
	strBodyHTML += '	<tr><td height="13"></td></tr>';
	strBodyHTML += '	<tr>';
	strBodyHTML += '		<td align="right" valign="bottom">';
	strBodyHTML += '			<a href="javascript:subMsgBoxClose();"><img src="'+gImgPath+'generic/button_no.gif" border="0" /></a>';
	strBodyHTML += '			<img src="/images/clear.gif" height="1" width="7" />';
	strBodyHTML += '			<a href="' + varAction + '"><img src="'+gImgPath+'generic/button_yes.gif" border="0" /></a>';
	strBodyHTML += '		</td>';
	strBodyHTML += '	</tr>';
	strBodyHTML += '</table>';
	subMsgBox(strTitle,strBodyHTML,'',true,false);
}

function ftnConfirmBox(strTitle, strBody)
{
/*Purpose	:	displays a confirmation dialog to the user. (similar to built-in confirm())
	Effects	:	None.
	Inputs	:	strTitle -	title of confirmation box
						strBody -		text of confirmation box						
	Returns	:	Boolean - depending on users selection.
	Comments:	Requires the subMsgBox function
*/
	strBodyHTML =  '<table width="100%" border="0" cellspacing="0" cellpadding="0">';
	strBodyHTML += '	<tr>';
	strBodyHTML += '		<td><p>' + strBody + '</p></td>';
	strBodyHTML += '	</tr>';
	strBodyHTML += '	<tr><td height="13"></td></tr>';
	strBodyHTML += '	<tr>';
	strBodyHTML += '		<td align="right" valign="bottom">';
	strBodyHTML += '			<a href="javascript:return false;"><img src="'+gImgPath+'generic/button_no.gif" border="0" /></a>';
	strBodyHTML += '			<img src="/images/clear.gif" height="1" width="7" />';
	strBodyHTML += '			<a href="javascript:return true;"><img src="'+gImgPath+'generic/button_yes.gif" border="0" /></a>';
	strBodyHTML += '		</td>';
	strBodyHTML += '	</tr>';
	strBodyHTML += '</table>';
	return(subMsgBox(strTitle,strBodyHTML,'',true,false));
}


function subUploadBox(strTitle, strBody, strFormURL, varFileType, strExts, blnExts)
{
/*Purpose	:	Displays a custom upload dialog on the client.
	Effects	:	None.
	Inputs	:	strTitle -								title of message box
						strBody -									text of message box
						strFormURL -							URL of the script that will process the form with the uploaded file
						varFileType (optional) -	file type if needed e.g for My Area Hard Drive Files it is the 
																			type of document (UserDocTypeID) uploaded.
						strExts (optional) -			a comma seperated list of file extentions e.g "mp3,wav,jpg"
																			must be used in conjuction with blnExts
																			This var is passed to subUploadBoxValidate when form is submited
						blnExts (optional) -			determines whether or not to allow or dis-allow file types 
																			listed in strExts to be uploaded
																			must be used in conjuction with strExts
																			This var is passed to subUploadBoxValidate when form is submited
																			true = allow only file extentions listed in strExts to be uploaded
																			false = dis-allow any file extentions listed in strExts to be uploaded
	Returns	:	None.
	Comments:	Requires the subMsgBox function
*/
  var strBodyHTML='';
  strBodyHTML += '<form action="' + strFormURL + '" enctype="multipart/form-data" method="post" id="uploadform" name="uploadform"';
  strBodyHTML += 'onSubmit="subValidateFileExts(&quot;file&quot;,&quot;&quot;,' + blnExts + ',&quot;' + strExts + '&quot;,true);">';
  strBodyHTML += '	<input type="hidden" name="filetype" value="' + varFileType + '" />';
  strBodyHTML += '	<table width="100%" border="0" cellpadding="0" cellspacing="0">';
  strBodyHTML += '		<tr>';
  strBodyHTML += '			<td>' + strBody + '</td>';
  strBodyHTML += '		</tr>';
  strBodyHTML += '		<tr><td height="7"></td></tr>';
  strBodyHTML += '		<tr>';
  strBodyHTML += '			<td width="100%" align="left">';
  strBodyHTML += '				<input type="file" name="file" id="file" class="txt" style="width:100%"/>';
  strBodyHTML += '			</td>';
  strBodyHTML += '		</tr>';
	strBodyHTML += '		<tr><td height="10"></td></tr>';
	strBodyHTML += '		<tr>';
	strBodyHTML += '			<td>';
  strBodyHTML += '				<table width="100%" border="0" cellpadding="0" cellspacing="0">';
  strBodyHTML += '					<tr>';
  strBodyHTML += '						<td align="right"><input type="image" src="'+gImgPath+'generic/button_upload.gif" /></td>';
  strBodyHTML += '					</tr>';
	strBodyHTML += '				</table>';
	strBodyHTML += '			</td>';
	strBodyHTML += '		</tr>';
	strBodyHTML += '	</table>';
	strBodyHTML += '</form>';
  
  subMsgBox(strTitle,strBodyHTML,'',true,false);
}

// IMAGE FUNCTIONS ------------------------------------------------------------------
function subPreloadImage(strImageVar, strImageSrc) {
/*Purpose	:	Used to an preload image.
	Effects	:	None
	Inputs	:	strImageVar - String - id of the image tag
				strImageSrc - String - URL of the image
	Returns	:	None
*/
	if (document.images) {
		eval(strImageVar + ' = new Image()');
		eval(strImageVar + '.src = "' + strImageSrc + '"');
	}
}


// OTHER GLOBAL FUNCTION ---------------------------------------------------------------------
function subDoHelp(){
/*Purpose	:	Opens dialog window containing module-level help (/main/core/help.asp)
	Effects	:	As above
	Inputs	:	None.
	Returns	:	None.
*/
	var vRetVal = window.showModalDialog(strVRoot+'/main/core/help.asp',"","dialogHeight: 307px; dialogWidth: 530px; center: Yes; help: No; resizable: Yes; status: No;");
}

function subInitCheckboxes() {
/*Purpose	:	Finds all checkboxes and makes sure the state of the image matches the state
	    			of the hidden checkbox
	Effects	:	None.
	Inputs	:	None.
	Returns	:	None.
*/
	var objInputTags = document.getElementsByTagName("INPUT");
	var objInput;
	var i;

	// loop through INPUT TYPE=HIDDEN collection
	for(i=0; i<objInputTags.length; i++) {
		objInput = objInputTags[i];
		if(objInput.type=="hidden") {
			if(objInput.ischeckbox=="1") {
				if (objInput.disabled) {
					ftnGetObject('image' + objInput.id).src = (objInput.value=="1") ? gImgPath+"utils/tick_disabled.gif" : gImgPath+"utils/notick_disabled.gif";
				} else {
					ftnGetObject('image' + objInput.id).src = (objInput.value=="1") ? gImgPath+"utils/tick.gif" : gImgPath+"utils/notick.gif";
				}
			}
		}
	}
}

function subCheckboxKeypress(strID) 
{
if (event.keyCode==32) subCheckboxClick(strID);  
}

function subCheckboxClick(strID) {
/*Purpose	:	Generic click event handler for checkboxes generated from the "checkbox" 
				global XSLT template. This function is called when you click on such a 
				checkbox.
	Effects	:	Works out whether the checkbox needs to be selected or deselected then 
				delegates to subCheckboxManipulate(), setting the ocjs (onClick) attribute
				for execution if present.
	Inputs	:	strID - String - the id of the checkbox image.
	Returns	:	None.
*/
	var objImage = ftnGetObject('image'+strID);
	var objHidden = ftnGetObject(strID);

  if (objHidden.disabled==false)
    if (objHidden.value == "1")                     		  // Tick or Un-tick the checkbox
		  subCheckboxManipulate(strID,false,true);
	  else
		  subCheckboxManipulate(strID,true,true);
	
	var intExclusiveGroupNumber = objImage.exclusivegroupnumber;
	// if the group the checkbox belongs to is exclusive from any other groups then clear the ticks from the other groups
	if (intExclusiveGroupNumber != 0) {
		// loop through all checkboxes and clear those not in the group of the ticked checkbox
		var objImages = document.images;
		for(i=0; i<objImages.length; i++) {
			var objImageExc = objImages[i];
			//**OO** Changed to match LR -- if(objImageExc.exclusivegroupnumber != intExclusiveGroupNumber && objImageExc.exclusivegroupnumber != 0) {
			if(objImageExc.exclusivegroupnumber != intExclusiveGroupNumber && objImageExc.exclusivegroupnumber != 0 && objImageExc.exclusivegroupnumber != undefined) {	
				objHiddenExc = ftnGetObject(objImageExc.fieldid);
				if(objHiddenExc.value == "1") {
					objImageExc.src = "'+gImgPath+'utils/notick.gif";
					objHiddenExc.value = "0";
					eval(objImageExc.ocjs);
				}
			}
		}
	}
}

function subCheckboxState(strID,blnDisabled,blnExecOnClick){
/*Purpose	:	Enables or disables checkboxes generated from the "checkbox" global XSLT template.
	Effects	:	Changes the image and sets the associated hidden field according to the state specified.
            Executes the Javascript code in the checkbox image "ocjs" attribute if requested.
	Inputs	:	strID - String - the id of the checkbox image.
            blnDisabled - boolean - desired state of checkbox.
            blnExecOnClick - boolean - if true, executes the checkboxs ocjs (onClick) event.
	Returns	:	None.
*/
	var objImage = ftnGetObject('image'+strID);
	var objHidden = ftnGetObject(strID);

	//set property on the input type=hidden and the image
	objHidden.disabled=blnDisabled;
  objImage.src=(blnDisabled) ? gImgPath+"utils/tick_disabled.gif" : (objHidden.value=="1") ? gImgPath+"utils/tick.gif" : gImgPath+"utils/notick.gif";
  
}

function ftnGetCheckboxes(intSearchType) {
/*Purpose	:	Return an array containing a subset of (or all the) checkboxes on the current page
	Effects	:	None, really. Makes coding a bit easier.
	Inputs	:	intSearchType, one of the following values:
            0 : return all checkboxes          \
            1 : return all ticked checkboxes   |- including disabled checkboxes
            2 : return all unticked checkboxes /
            4 : return all checkboxes          \
            5 : return all ticked checkboxes   |- excluding disabled checkboxes
            6 : return all unticked checkboxes /
	Returns	:	An array continaing the "input type=hidden"'s which contain each checkboxes value.
*/
  var blnChecked = ((intSearchType==1)||(intSearchType==5)||(intSearchType==4)||(intSearchType==0));
  var blnUnChecked = ((intSearchType==2)||(intSearchType==6)||(intSearchType==4)||(intSearchType==0));
  var aCheckboxs = new Array();
	var objInputs = document.body.getElementsByTagName("INPUT");
	var blnAdd;
	
  if (objInputs!=null)
    for (i=0; i<objInputs.length; i++)
		  if (objInputs[i].type=='hidden')
        if (ftnGetObject('image'+objInputs[i].id))
          {
          blnAdd=false;
          if ((intSearchType<4) || (!(objInputs[i].disabled)))
            blnAdd = (objInputs[i].value=='1') ? blnChecked : blnUnChecked;
          if (blnAdd) aCheckboxs[aCheckboxs.length]=objInputs[i];
          }
  return aCheckboxs;
  }
  
function subCheckboxManipulate(strID,blnChecked,blnExecOnClick) {
/*Purpose	:	Generic click event handler for checkboxes generated from the "checkbox" global XSLT template.
	Effects	:	Changes the image and sets the associated hidden field according to the state specified.
				    Executes the Javascript code in the checkbox image "ocjs" attribute if requested.
	Inputs	:	strID - String - the id of the checkbox image.
				    blnChecked - boolean - desired state of checkbox.
				    blnExecOnClick - boolean - if true, executes the checkboxs ocjs (onClick) event.
	Returns	:	None.
*/
	var objImage = ftnGetObject('image'+strID);
	var objHidden = ftnGetObject(strID);
	var objImageExc;
	var objHiddenExc;
	var state = objHidden.value;
	
	if (blnChecked == false)
	  {
		objHidden.value = "0";
		objImage.src = (objHidden.disabled) ? gImgPath+"utils/tick_disabled.gif" : gImgPath+"utils/notick.gif";
	  }
	else
	  {
		objHidden.value = "1";
		objImage.src = (objHidden.disabled) ? gImgPath+"utils/tick_disabled.gif" : gImgPath+"utils/tick.gif";
	  }
		
	// if checkbox group selection is exclusive then reset rest of the group
	if(objImage.exc == 1) {
		var objImages = document.images;
		for(i=0; i<objImages.length; i++) {
			objImageExc = objImages[i];
			if(objImageExc.groupid == objImage.groupid) {
				objHiddenExc = ftnGetObject(objImageExc.fieldid);
				if(objImageExc.id != objImage.id && objHiddenExc.value == "1") {
					objImageExc.src = gImgPath+"utils/notick.gif";
					objHiddenExc.value = "0";
					eval(objImageExc.ocjs);
				}
			}
		}
	}
	if(blnExecOnClick == true && objImage.ocjs != '') eval(objImage.ocjs);
}

function subGridRowClick(strGridId, intGroupId) {
/*Purpose	:	Generic click event handler for table rows generated by using the "grid" global XSLT template.
	Effects	:	Changes the image and sets the associated hidden field.  Executes the Javascript code in the 
				grid table "ocjs" attribute.
	Inputs	:	strGridId - String - the id of the grid table.
				intGroupId - Integer - the group id the row belongs to.
	Returns	:	None.
*/
	var objTable = ftnGetObject(strGridId);
	var objRows = objTable.getElementsByTagName("TR");
	if(objRows != null) {
		for(i=0; i<objRows.length; i++) {
			if(objRows[i].rowid == intGroupId) {
				if (objRows[i].hasdata) {
					objRows[i].selected = (objRows[i].selected == "1") ? 0 : 1;
					objRows[i].getElementsByTagName("IMG")[1].src = (objRows[i].selected == "1") ? objRows[i].activeicon : objRows[i].idleicon;
					objRows[i].getElementsByTagName("INPUT")[0].value = objRows[i].selected;
				}
			}
		}
	}
	if(objTable.ocjs) { eval(objTable.ocjs); }
}


function subGridSelectedRows(strGridId) {
/*Purpose	:	Builds an array of IDs of selected table rows of the "grid" global XSLT template.
	Effects	:	None
	Inputs	:	strGridId - String - the id of the grid table.
	Returns	:	Array of IDs of selectted rows.
*/
  var arrIDs = new Array();
  var objGridID = ftnGetObject(strGridId);
	var objRows = objGridID.getElementsByTagName("TR");
  if (objRows!=null)
  {
    for (i=0; i<objRows.length; i++)
    {
      if (objRows[i].selected=='1')
      {
        arrIDs[arrIDs.length]=objRows[i].rowid;
      }
    }
  }
  return arrIDs;
}

// DROPDOWN/COMBO FUNCTIONS (create using "combo" global XSLT template)-------------------------------------

// MOUSE event handlers for dropdown/combos
function subMouseIn(objCell) {
  if (window.objHilightedCell) subMouseOut(window.objHilightedCell);
  objCell.style.color = "#666666";
  objCell.style.cursor = "hand";
  window.objHilightedCell=objCell;  
  }
function subMouseOut(objCell) {objCell.style.color = ""; objCell.style.cursor = "default";}

function subDropdownClick(objCell)
{
/*
	Purpose	:	Click event handler for custom dropdowns created using the "combo" global XSLT template (type = 2).
	Effects	:	Changes the sets the associated hidden field.  Executes the Javascript code in the 
				    combo "ocjs" attribute.
	Inputs	:	objCell - Object - the TD tag firing the event.
	Returns	:	None.
*/
  var strCbo = ftnGetParentCombo(objCell);
	var strHeadName = "combohead" + strCbo;
	var objTop = ftnGetObject(strHeadName);
	objTop.getElementsByTagName("SPAN")[0].innerText = objCell.innerText;
	subOpenCloseCombo(strCbo);
	ftnGetObject(strCbo).value = objCell.extid;
	if(ftnGetObject(strCbo).ocjs != "") eval(ftnGetObject(strCbo).ocjs);
}

function ftnGetCurrentTD(varCombo)
{	
/*
	Purpose	:	Returns the current TD in the currently open combobox
	Effects	:	None
	Inputs	:	varCombo - if string, the base name of the combo who's current TD you want
	                     if object, the DIV object which is the dropdown who's current TD you want
	Returns	:	see above
*/
var objDIV;
if (typeof(varCombo)=="object")
  objDIV=varCombo;
else
  objDIV=ftnGetObject("combo" + varCombo);
var objTDs = objDIV.getElementsByTagName("TD");
var strStart = ftnGetObject("combohead" + ftnGetParentCombo(objDIV)).innerText;

var i;
if(objTDs != null) 
	for(i=0; i<objTDs.length; i++)
	  if (strStart==objTDs[i].innerText) 
	    return objTDs[i];
}

function subComboKeyDownHandler()
{
if (event.keyCode==9)
  {
  subOpenCloseCombo(ftnGetParentCombo(window.objOpenCombo), true);
  }

if ((event.keyCode==38) || (event.keyCode==40) || (event.keyCode==33) || (event.keyCode==34))
  {
  if (event.altKey)
    {
    if (event.keyCode==40)
      {
      var strCombo = ftnGetParentCombo(window.objOpenCombo);
      if (window.objOpenCombo.style.display=="inline")
        subShowHideCombo(strCombo, true);
      else
        subShowHideCombo(strCombo, false);
      }
    }
  else
    {
    var intMove = ((event.keyCode==38) || (event.keyCode==40)) ? 1 : 8;
    var blnUp = ((event.keyCode==38) || (event.keyCode==33));
    var objCurrentTD = ftnGetCurrentTD(window.objOpenCombo);
    
    //find & choose next TD
	  var objNextTR = null;
	  if (objCurrentTD)
	    {
	    var objTR = objCurrentTD.parentElement;
      objNextTR = objTR;
 	    for(i=0; i<intMove; i++)
 	      {
 	      objNextTR = (blnUp) ? objNextTR.previousSibling : objNextTR.nextSibling;
 	      if (!objNextTR) break;
 	      }
      subMouseOut(objCurrentTD);
	    }
    if (!objNextTR)
      {
      var objTDs = window.objOpenCombo.getElementsByTagName("TD");
      objNextTR = (blnUp) ? objTDs[objTDs.length-1].parentElement : objTDs[0].parentElement;
      }
    subKeyChoose(objNextTR.firstChild);
    }
  event.cancelBubble=true
  return false;
  }
}

function subComboKeyUpHandler()
{
if ((event.keyCode==38) || (event.keyCode==40) || (event.keyCode==33) || (event.keyCode==34))
  {
  event.cancelBubble=true
  //alert(event.keyCode);
  return false;
  }
}

function subComboKeypressHandler()
{
/*
	Purpose	:	Processes alpha keystrokes for focused combos
	Effects	:	Chooses the next entry in the list which begins with the pressed key's letter
	Inputs	:	None.
	Returns	:	None.
*/
var objTDs = window.objOpenCombo.getElementsByTagName("TD");
var strKey = String.fromCharCode(event.keyCode).toUpperCase();
var strStart = window.objOpenComboHead.innerText;
var blnHitStart = false;
var obj1stTD = null;
var blnFound = false;

if ((event.keyCode==13) || (event.keyCode==27))
  {
  //they pressed enter or escape
  var strBaseName=ftnGetParentCombo(window.objOpenCombo);
  subShowHideCombo(strBaseName, true);
  if (event.keyCode==13)
    {
    objHidden = ftnGetObject(strBaseName);
		if ((window.objOpenCombo.blnFireJS) && (objHidden.ocjs != "")) eval(objHidden.ocjs);
		window.objOpenCombo.blnFireJS = false;
		}
  }
else
  {
  if(objTDs != null) 
	  for(i=0; i<objTDs.length; i++)
	    {
	    if (objTDs[i].innerText.substring(0,1).toUpperCase()==strKey)
	      if (blnHitStart)
	        {
		      subKeyChoose(objTDs[i]);
		      blnFound=true;
		      break;
		      }
		    else 
		      {
		      subMouseOut(objTDs[i]);
		      if (!obj1stTD) obj1stTD=objTDs[i];
		      }
	    if (strStart <= objTDs[i].innerText) blnHitStart = true;
	    subMouseOut(objTDs[i]);
	    }
	    if ((!blnFound) && (obj1stTD)) subKeyChoose(obj1stTD);
	}
event.cancelBubble=true
return false;
}

function subKeyChoose(objTD, blnDontSetJS)
{
	var strCbo = ftnGetParentCombo(objTD);
	var objTR = objTD.parentElement;
	var objNewTR;
	ftnGetObject(strCbo).value = objTD.extid;
  subMouseIn(objTD);
	window.objOpenComboHead.getElementsByTagName('SPAN')[0].innerText=objTD.innerText;
  if (!blnDontSetJS) window.objOpenCombo.blnFireJS = true;
  //scroll into view the current TD, plus 4 (ask DC why)
 	if (window.objOpenCombo.style.display == "inline") {
 	  for(i=0; i<4; i++) {
 	    objNewTR = objTR.nextSibling;
 	    if (!objNewTR) break;
 	    else objTR = objNewTR;
 	    }
    if(objTR)
	  {
		// determine if we need to scroll the whole combo into view
	    var objCombo = ftnGetObject("comboplaceholder" + strCbo);
		var intComboTop = ftnGetObjLoc(objCombo).top;
		var intComboHeight = objCombo.clientHeight;
		var objComboDIV = ftnGetObject("combo" + strCbo);
		var intComboDIVHeight = parseInt(objComboDIV.style.height.substr(0, objComboDIV.style.height.length - 2), 10);
		var intComboDIVScrollTop = objComboDIV.scrollTop;
		var intComboDIVClientHeight = objComboDIV.clientHeight;
		var intTopDocClientHeight = window.top.document.body.clientHeight;
		var intCombinedTop = 0;
		var intCombinedScrollTop = document.body.scrollTop;
		var objTemp = window.frameElement;
		
		while(objTemp != null)
		{
			intCombinedTop += ftnGetObjLoc(objTemp).top;
			intCombinedScrollTop += objTemp.document.body.scrollTop;
			objTemp = objTemp.frameElement;
		}
		
		var intCombinedComboBottom = intCombinedTop + intComboTop + intComboHeight + intComboDIVHeight - intCombinedScrollTop;
		if(intCombinedComboBottom > intTopDocClientHeight)
		{
			objTR.scrollIntoView(false);
		} 
		else
		{
			// mini scroll to get the combo item into view within the DIV
			var intComboItemBottom = ftnGetObjLoc(objTR).top + objTR.style.height;
			var intNumberOfClicks = Math.ceil((intComboItemBottom - intComboDIVClientHeight - intComboDIVScrollTop) / 12) + 1;
			if(intNumberOfClicks > 0)
			{
				for(i=0;i<intNumberOfClicks;i++)
					objComboDIV.doScroll("scrollbarDown");
			}
			else
			{
				for(i=0;i<Math.abs(intNumberOfClicks);i++)
					objComboDIV.doScroll("scrollbarUp");
			}
		}
	  }
    }
}

function subFocusBlurCombo(strBaseName, blnFocus)
{
/*
	Purpose	:	Sets "focus" to a combo, either as a result of being "tabbed" onto, or clicked on.
	Effects	:	Captures (or releases) the windows keypress/up/dowm events, sets (or un-sets) OpenCombo and OpenComboHead
	Inputs	:	strBaseName - String the base name of the combo.
	          blnFocus - true=got focus, false=lost focus
	Returns	:	None.
*/
if (blnFocus)
  {
	window.objOpenCombo = ftnGetObject("combo" + strBaseName);
	window.objOpenComboHead = ftnGetObject("combohead" + strBaseName);
	document.body.onkeypress = subComboKeypressHandler;
	document.body.onkeydown = subComboKeyDownHandler;
	document.body.onkeyup = subComboKeyUpHandler;
  }
else
  {
  //alert(window.event.srcElement.id);
  document.body.onkeypress = null;
	document.body.onkeydown = null;
	document.body.onkeyup = null;
  window.objOpenCombo.style.display="none";
  window.objOpenCombo = null;
  window.objOpenComboHead = null;
	}
}

function subShowHideCombo(strBaseName, blnHide)
{
	var strName = "combo" + strBaseName;
  var objDIV = ftnGetObject(strName);
  
  if (!blnHide)
    {
    objDIV.filters[0].apply();
    objDIV.style.display = "inline";
    objDIV.filters[0].play();
    var objCurrentTD = ftnGetCurrentTD(strBaseName);
    if (objCurrentTD) subKeyChoose(objCurrentTD, true);
    
    // This checks dropdowns current location - if it appears outside the visible area, it is scrolled into view
    if((document.body.clientHeight + document.body.scrollTop) < (parseInt(objDIV.style.top) + objDIV.scrollHeight)) {
      // Check the dropdown contents exist, to avoid runtime errors
      if (objDIV.children[0]) {
        //objDIV.children[0].scrollIntoView(false);
      }
    }
   }
  else
    objDIV.style.display = "none";
}

	
function subOpenCloseCombo(strBaseName, blnForceClose)
{	
/*
	Purpose	:	Click event handler for custom dropdowns created using the "combo" global XSLT template.
	Effects	:	Displays/hides the dropdown as appropriate.
	Inputs	:	strBaseName - String the base name of the combo.
	Returns	:	None.
*/
	var strName = "combo" + strBaseName;
	var strHeadName = "combohead" + strBaseName;
	var objDIV = ftnGetObject(strName);
	var objTop = ftnGetObject(strHeadName);
	var objHidden;
	
	if ((objDIV.style.display == "none") && (!blnForceClose)) {
		// opening combo
		subFocusBlurCombo(strBaseName, true);
		ftnGetObject("comboanchor" + strBaseName).blur();
		subShowHideCombo(strBaseName, false);
	} else {
		// closing combo
		subFocusBlurCombo(strBaseName, false);
		subShowHideCombo(strBaseName, true);
    objHidden = ftnGetObject(strBaseName);
		if ((objDIV.blnFireJS) && (objHidden.ocjs != "")) eval(objHidden.ocjs);
		objDIV.blnFireJS = false;		
	}
	
}

function subCloseAnyOpenCombo()
{
/*
	Purpose	:	Closes all open combos that were created using the "combo" global XSLT template.
	Effects	:	Hides the dropdown as appropriate.
	Inputs	:	None.
	Returns	:	None.
*/
	var strThis = ftnGetParentCombo(window.event.srcElement);

  if (window.objOpenCombo)
    {
  	var strThis = ftnGetParentCombo(window.event.srcElement);
  	var strFound = ftnGetParentCombo(window.objOpenCombo);
		if(strFound != strThis)
			{
 		  subShowHideCombo(strFound, true);
		  subFocusBlurCombo(strFound, false);
    	}
    else
      {
    	var objDIVs = document.getElementsByTagName("DIV");
	    if(objDIVs != null) {
		    for(i=0; i<objDIVs.length; i++) {
			    if(objDIVs[i].iscombo) {
			      strFound=ftnGetParentCombo(objDIVs[i]);
				    if(strFound != strThis)
				      if (objDIVs[i].style.display != "none") 
				      {
 		          subShowHideCombo(strFound, true);
		          subFocusBlurCombo(strFound, false);
    				  }
    		  }
			  }
		  }
    }
	}
}

function ftnGetParentCombo(objAny)
{
/*
	Purpose	:	Returns the name of the parent combo for the specified object.
	Effects	:	None.
	Inputs	:	objAny - Object - the object to find the parent of.
	Returns	:	String - the id of the partent combo.
*/
	var objDad = objAny;

	while(objDad != null)	{
		if(typeof(objDad.id) != "string") return "";
		if(objDad.id.substring(0,9) == "combohead") return objDad.id.substring(9, objDad.id.length);
		if(objDad.id.substring(0,5) == "combo") return objDad.id.substring(5, objDad.id.length);
		objDad = objDad.parentElement;
	}
	return "";
}

function ftnGetObjLoc(objIn)
{
/*
	Purpose	:	Finds the position of the specified object relative to screen 0, 0.
	Effects	:	None.
	Inputs	:	objIn - Object - the object to find the position of.
	Returns	:	Object - an object containing .left and .top.
*/
	var objOut = new Object();
	objOut.left = objIn.offsetLeft;
	objOut.top = objIn.offsetTop;
	var objNewPos = objIn.offsetParent;
	while(objNewPos != null)
	{
		if (objNewPos.style) if (objNewPos.style.position=='absolute') break; 
		objOut.left += objNewPos.offsetLeft;
		objOut.top += objNewPos.offsetTop;
		objNewPos = objNewPos.offsetParent;
	}
	return objOut;
} 

function subPlaceAllCombos()
{
/*
	Purpose	:	Places all combos to their correct position on screen.
	Effects	:	None.
	Inputs	:	None.
	Returns	:	None.
*/	
	if(!window.combosPlacedAlready) {
		var objDIVs = document.getElementsByTagName("DIV");
		var strName;
		if(objDIVs != null) {
			for(i=0; i<objDIVs.length; i++) {
				if(objDIVs[i].iscombo) {
					strName = ftnGetParentCombo(objDIVs[i]);
					subPlaceCombo(strName);
				}
			}
		}
		window.combosPlacedAlready = true;
	}
}

function subClearCombo(strBaseName, strDefaultText)
{
/*
  Purpose  :  Clears all the contents of a combo.
  Effects  :  The combo itself.
  Inputs  :  strBaseName - String - the base name of the combo.
        strDefaultText - String - the text to display.
  Returns  :  None.
*/
  if(blnMac) {
    var objCombo = ftnGetObject(strBaseName);
    for(intLoop=objCombo.options.length; intLoop>0; intLoop--) {
      objCombo.options.remove(intLoop);
    }
  } 
  else {  
    var objDIV = ftnGetObject("combo" + strBaseName);
    var objTable = ftnGetObject("table" + strBaseName).firstChild;
    var objHead = ftnGetObject("combohead" + strBaseName);
    // clear the selected/typed-in item
    if(objHead.type == "1") {
      objHead.all("combotextbox" + strBaseName).value = strDefaultText;
    } else {
      //objHead.all("combotext").innerText = strDefaultText;
      objHead.all("comboDefaultText").innerText = strDefaultText;
    }
    // loop through and delete all rows
    for(intLoop=objTable.rows.length; intLoop>0; intLoop--) {
      objTable.deleteRow();
    }
    // resize combo
    objDIV.style.height = 0;
    // clear its value
    ftnGetObject(strBaseName).value = "0";
  }
}

function subDeleteFromCombo(strBaseName, intAmount)
{
/*
  Purpose  :  Clears an amount of rows from bottom of a combo
  Effects  :  The combo itself.
  Inputs  :  strBaseName - String - the base name of the combo.
             intAmount - Int - amount to delete
  Returns  :  None.
*/
  if(blnMac) {
    var objCombo = ftnGetObject(strBaseName);
    var endNum = objTable.rows.length-intAmount;
    for(intLoop=objCombo.options.length; intLoop>endNum; intLoop--) {
      objCombo.options.remove(intLoop);
    }
  } 
  else {  
    var objDIV = ftnGetObject("combo" + strBaseName);
    var objTable = ftnGetObject("table" + strBaseName).firstChild;
    var objHead = ftnGetObject("combohead" + strBaseName);

    // loop through and delete all rows
    var endNum = objTable.rows.length-intAmount;
    for(intLoop=objTable.rows.length; intLoop>endNum; intLoop--) {
      objTable.deleteRow();
    }
  }
}

function subAddComboItems(strBaseName, arrValues, arrDescs, strDefaultText)
{  
/*
  Purpose  :  Adds an array of values/descriptions into a combo.
  Effects  :  The combo itself.
  Inputs  :  strBaseName - String - the base name of the combo.
        arrValues - Array - list of values.
        arrDescs - Array - list of descriptions.
        strDefaultText - String - the text to display.
  Returns  :  None.
*/
  if(blnMac) {
    var objOption;
    var objCombo = ftnGetObject(strBaseName);
    for(intLoop=0; intLoop<arrValues.length; intLoop++) {
      objOption = document.createElement("OPTION");
      objOption.value = arrValues[intLoop];
      objOption.text = arrDescs[intLoop];
      objCombo.add(objOption);
    }
  } else {
    var objDIV = ftnGetObject("combo" + strBaseName);
    var objTable = ftnGetObject("table" + strBaseName).firstChild;
    var objHead = ftnGetObject("combohead" + strBaseName);
    // set the default text
    if(objHead.type == "1") {
      objHead.all("combotextbox" + strBaseName).value = strDefaultText;
    } else {
      //objHead.all("combotext").innerText = strDefaultText;
      objHead.all("comboDefaultText").innerText = strDefaultText;
    }
    // loop through and create the items
    var objRow, objCell;
    for(intLoop=0; intLoop<arrValues.length; intLoop++) {
      objRow = document.createElement("TR");
      objCell = document.createElement("TD");
      objCell.className = 'combocell';
      objRow.appendChild(objCell);
      objCell.extid = arrValues[intLoop];
      objCell.onmouseout = _subMouseOut;
      objCell.onmouseover = _subMouseIn;
      if(objHead.type == "1") {
        objCell.onclick = _subComboClick;
      } else {
        objCell.onclick = _subDropdownClick;
      }
      //objCell.innerHTML = arrDescs[intLoop];
      objCell.appendChild(document.createTextNode(arrDescs[intLoop]))
      objTable.appendChild(objRow);
    }
    // resize combo
    //objDIV.style.height = (arrValues.length*15);
  }
}

function subAddComboItem(strBaseName, value, desc)
{  
/*
  Purpose  :  Adds a single value to a combo.
  Effects  :  The combo itself.
  Inputs  :  strBaseName - String - the base name of the combo.
        value - value returned if selected.
        desc - decription (display text).
  Returns  :  None.
*/
  if(blnMac) {
    <!-- completely untested -->
    var objOption;
    var objCombo = ftnGetObject(strBaseName);
    objOption = document.createElement("OPTION");
    objOption.value = value;
    objOption.text = desc;
    objCombo.add(objOption);
  } else {
    var objDIV = ftnGetObject("combo" + strBaseName);
    var objTable = ftnGetObject("table" + strBaseName).firstChild;
    var objHead = ftnGetObject("combohead" + strBaseName);
    var objRow, objCell;
    objRow = document.createElement("TR");
    objCell = document.createElement("TD");
    objCell.className = 'combocell';
    objRow.appendChild(objCell);
    objCell.extid = value;
    objCell.onmouseout = _subMouseOut;
    objCell.onmouseover = _subMouseIn;
    if(objHead.type == "1") {
      objCell.onclick = _subComboClick;
    } else {
      objCell.onclick = _subDropdownClick;
    }
    //objCell.innerHTML = desc;
    objCell.appendChild(document.createTextNode(desc))

    objTable.appendChild(objRow);
  }
}
/* Psuedo-functions used to assign to the event handlers for new combo items */
function _subMouseOut() { subMouseOut(window.event.srcElement) }
function _subMouseIn() { subMouseIn(window.event.srcElement) }
function _subComboClick() { subComboClick(window.event.srcElement) }
function _subDropdownClick() { subDropdownClick(window.event.srcElement) }

// EVENT HANDLERS ====================================================================================

function subDoWindowOnload()
{
/*
	Purpose	:	Window onLoad event handler.
	Effects	:	None.
	Inputs	:	None.
	Returns	:	None.
*/
	if(strOnLoadScript.length > 0) { eval(strOnLoadScript); }
	subInitCheckboxes();
}

// bind event handlers
window.onload = subDoWindowOnload;


/*
Date Picker box, next to date field is used to have graphical popup date box from where user can select
date,  month, year instead of typing in date. All functions below starting with ftnDatePicker
are for the same, code picked up from LaunchPlanning
*/

/*Date picker functions/code start here */

var intDatePickerValue = 0;
var dtDatePickerDate = new Date;
var dtDatePickerMonths = new Array();
var dtDatePickerDataField;
var dtDatePickerDataFieldName = '';
dtDatePickerMonths[0] ="January";
dtDatePickerMonths[1] ="February";
dtDatePickerMonths[2] ="March";
dtDatePickerMonths[3] ="April";
dtDatePickerMonths[4] ="May";
dtDatePickerMonths[5] ="June";
dtDatePickerMonths[6] ="July";
dtDatePickerMonths[7] ="August";
dtDatePickerMonths[8] ="September";
dtDatePickerMonths[9] ="October";
dtDatePickerMonths[10] ="November";
dtDatePickerMonths[11] ="December";
dtDatePickerMonths[12] ="January";
var intMonthIncrementSpeed = 75;


function ftnDatePickerShow()
{
  /*
    Extra check for invalid date validating. If user enters an invalid date and 
    clicks the calendar, this will ensure that an alert will pop up notifying the 
    user to enter the correct format date.
    It will also check for yyyy-mm-dd being entered into the field and converting
    it to todays date.
  */	  
  var objDatePickerDataField = document.getElementById(dtDatePickerDataFieldName);
  
  if(objDatePickerDataField.value.length > 0) {
	if(objDatePickerDataField.value.toUpperCase() == 'YYYY-MM-DD')  // If date is invalid set to today
    {
      var dteDate,
      dteDate = new Date();   
      var dteMonth = (dteDate.getMonth() + 1);
      var dteDay = dteDate.getDate();
      
      if(dteMonth.toString().length < 2) {
	    dteMonth = "0" + dteMonth;
      }
      else {
	    dteMonth;
      }
      
      if(dteDay.toString().length < 2) {
	    dteDay = "0" + dteDay;
      }
      else {
	    dteDay;
      }
      
      objDatePickerDataField.value = dteDate.getYear() + "-";
      objDatePickerDataField.value += dteMonth + "-";
      objDatePickerDataField.value += dteDay;
    }
    
    if(!ftnCheckDate(objDatePickerDataField.value)) {
	  subMsgBox('Date Invalid','You must enter a valid date (yyyy-mm-dd) in the field.');
	  //alert('You must enter a valid date (yyyy-mm-dd) in the field.');
	  return false;
    }
  }
  
  dtDatePickerDataField.blur();
  dtDatePickerDate = ftnDatePickerGetDateFromField();
  ftnDatePickerUpdateCalendar();
  objdatepicker = document.getElementById('ctrl_datePicker').style;
  var objdatePickerIconLocation = ftnGetObjLoc(document.getElementById('ico_' + dtDatePickerDataFieldName));

  intNewTop = objdatePickerIconLocation.top ;
  intNewLeft = objdatePickerIconLocation.left ;
  intDatepickerHeight = 130;
  intDatepickerWidth = 155;

  var oDocument = document.getElementsByTagName('body');
  if (intDatepickerHeight + event.clientY - event.offsetY  > oDocument[0].clientHeight )
  {
    intNewTop = objdatePickerIconLocation.top  - (intDatepickerHeight + event.clientY - event.offsetY  - oDocument[0].clientHeight) ;
  }

//  if (intNewTop < 0 )
//  {
//    intNewTop = objdatePickerIconLocation.top  - (intNewTop)  ;
//  }
  if (intDatepickerWidth + event.clientX - event.offsetX  > oDocument[0].clientWidth )
  {
    intNewLeft = objdatePickerIconLocation.left - (intDatepickerWidth + event.clientX - event.offsetX  - oDocument[0].clientWidth) ;
  }

  objdatepicker.pixelTop=(intNewTop); // the calendar button has a 2px bottom margin
  objdatepicker.pixelLeft=(intNewLeft);
  objdatepicker.visibility='visible';
  objdatepicker.display='block';
}

function ftnDatePickerIncrementMonth(direction)
{
  var dtToday = new Date;
  
  if (((direction == -1)) || (direction == 1)) //(dtToday <= dtDatePickerDate) &&
  {
   dtDatePickerDate.setDate(1);
   dtDatePickerDate.setMonth(dtDatePickerDate.getMonth() + direction);
   ftnDatePickerUpdateCalendar();
   intDatePickerValue=setTimeout('ftnDatePickerIncrementMonth(' + direction + ')',intMonthIncrementSpeed);
  }
}

function ftnDatePickerCellClick()
{
  var objCell = event.srcElement;
  ctrl_datepicker.style.visibility="hidden";

  var arrDateParts;

  arrDateParts = objCell.datevalue.split('/');

  dtDatePickerDataField.value=arrDateParts[2] + '-' + arrDateParts[1] + '-' + arrDateParts[0];
  dtDatePickerDataField.focus();
}

function ftnDatePickerCellMouseOut()
{
  var objCell = event.srcElement;
  objCell.style.color="#333333";
  objCell.style.backgroundColor="#ffffff";
}

function ftnDatePickerCellMouseOver()
{
  var objCell = event.srcElement;
  objCell.style.color="#ffffff";
  objCell.style.backgroundColor="#FF7800";
}

function ftnDatePickerGetDateFromField()
{
  var tmpDate = new Date;

  if ((dtDatePickerDataField.value.length == 10) && (dtDatePickerDataField.value.indexOf("-") > 1))
  {
   tmpDate.setDate(1);
   tmpDate.setYear(dtDatePickerDataField.value.substring(0,4));
   tmpDate.setMonth(dtDatePickerDataField.value.substring(5,7) - 1);
   tmpDate.setDate(dtDatePickerDataField.value.substring(8,10));
  }
  return tmpDate;
}
function ftnDatePickerUpdateCalendar()
{

  var intCurrentMonth = dtDatePickerDate.getMonth();
  var intCurrentYear = dtDatePickerDate.getFullYear();
  var tmpDate = new Date

  tmpDate.setDate(1);
  tmpDate.setYear(intCurrentYear);
  tmpDate.setMonth(intCurrentMonth);

  var dtExistingDate = ftnDatePickerGetDateFromField();

  var strOut= '<table border="0" cellpadding="0" cellspacing="1" bgcolor="#CCCCCC" width="155">';
  var strClass
  var intCounter
  var intCell = 0;
  var intLastDate = 0;
  var intCurrentDate = 1;

  var strDateValue;

  strOut = strOut + "<tr>"

  // fill in the leading blank cells
  for (intCounter = 0; intCounter < tmpDate.getDay() ; intCounter ++)
  {
   strOut = strOut + '<td  width="21" class="datepickercell">&nbsp;</td>';
   intCell ++;
  }

  while (intCurrentDate > intLastDate)
  {
   if ((intCell%7 == 0) & ( intCell > 0))
   {
    strOut = strOut + "</tr><tr>";
   }
   if (intCurrentDate < 10)
   {
    strDateValue = "0" + intCurrentDate;
   }
   else
   {
    strDateValue = intCurrentDate;
   }

   if (intCurrentMonth < 9)
   {
    strDateValue = strDateValue + "/" + "0" + (intCurrentMonth + 1);
   }
   else
   {
    strDateValue = strDateValue + "/" + (intCurrentMonth + 1);
   }

   strDateValue = strDateValue + "/" + intCurrentYear
   if (dtExistingDate.toString() == tmpDate.toString())
   {
    strClass = "datepickercurrent";
   }
   else
   {
    strClass = "datepickercell";
   }

   strOut = strOut + '<td  width="21" class="' + strClass + '" align="center" datevalue="' + strDateValue + '" onClick="ftnDatePickerCellClick();" onMouseOver="ftnDatePickerCellMouseOver();" onMouseOut="ftnDatePickerCellMouseOut();">' + intCurrentDate + '</td>';
   intCell ++;
   intLastDate = intCurrentDate;
   tmpDate.setDate(tmpDate.getDate() + 1);

   if ((intCurrentYear & 4 != 0) && ( intCurrentMonth == 1 ) && (intLastDate == 28)) { tmpDate.setDate(1); }
   if ((intCurrentYear & 4 == 0) && ( intCurrentMonth == 1 ) && (intLastDate == 29)) { tmpDate.setDate(1); }

   intCurrentDate = tmpDate.getDate();
  }

  for (intCounter = intCell; intCounter < 42 ; intCounter ++)
  {
   if (intCounter%7 == 0)
   {
    strOut = strOut + "</tr><tr>";
   }
   strOut = strOut + '<td  width="21" class="datepickercell">&nbsp;</td>';
  }

  strOut = strOut + "</tr>"
  strOut = strOut + "</table>"
  document.getElementById('datepicker_dayspanel').innerHTML = strOut;
  document.getElementById('datepicker_monthpanel').innerText = dtDatePickerMonths[dtDatePickerDate.getMonth()] + ' - ' + dtDatePickerDate.getYear();

}

function ftnDatePickerAutoHide()
{
  intDatePickerValue=setTimeout("ctrl_datepicker.style.visibility='hidden'",750);
}

function ftnDatePickerAutoIncrement(direction)
{
  intDatePickerValue=setTimeout("ftnDatePickerIncrementMonth(" + direction + ")",250);
}

function ftnDatePickerCreate()
{
  document.writeln("<div style='z-index:1000;background-color:#ffffff;cursor:hand;position:absolute;width:155;display:none;visibility:hidden' id='ctrl_datepicker' onMouseMove='clearTimeout(intDatePickerValue);' onMouseOut='ftnDatePickerAutoHide();'>");
  document.writeln(" <table border='0' cellpadding='0' cellspacing='1' bgcolor='#444444' width='155'>");
  document.writeln("");
  document.writeln("  <tr>");
  document.writeln("   <th class='datepickertitle' align='center' onMouseUp='clearTimeout(intDatePickerValue);' onClick='ftnDatePickerIncrementMonth(-1);clearTimeout(intDatePickerValue);' onMouseDown='ftnDatePickerAutoIncrement(-1)'>&lt;</th>");
  document.writeln("   <th class='datepickertitle' colspan='5' align='center'><span id='datepicker_monthpanel'>Febuary - 2003</span></th>");
  document.writeln("   <th class='datepickertitle' align='center' onMouseUp='clearTimeout(intDatePickerValue);' onClick='ftnDatePickerIncrementMonth(1);clearTimeout(intDatePickerValue);' onMouseDown='ftnDatePickerAutoIncrement(1)'>&gt;</th>");
  document.writeln("  </tr> ");
  document.writeln("  <tr>");
  document.writeln("   <th class='datepickercell' align='center' width='21'>S</th>");
  document.writeln("   <th class='datepickercell' align='center' width='21'>M</th>");
  document.writeln("   <th class='datepickercell' align='center' width='21'>T</th>");
  document.writeln("   <th class='datepickercell' align='center' width='21'>W</th>");
  document.writeln("   <th class='datepickercell' align='center' width='21'>T</th>");
  document.writeln("   <th class='datepickercell' align='center' width='21'>F</th>");
  document.writeln("   <th class='datepickercell' align='center' width='21'>S</th>");
  document.writeln("  </tr>");
  document.writeln(" </table>");
  document.writeln(" <span id='datepicker_dayspanel'></span>");
  document.writeln(" ");
  document.writeln("</div>");
}

/*Date picker functions/code ends here */

//copied from jagpartners...if page accessed straight from url...bottom frame was not displayed
function ftnCheckFrames()
{
	if (parent.location.href == self.location.href)
	{
		parent.location.href = ftnGetDomain(self.location.href) + '/default.asp?u=' + ftnGetRelativeURL(self.location.href);
	}
}
function ftnGetDomain(strURL)
{
	return strURL.substr(0, strURL.indexOf('/', 8));
}

function ftnGetRelativeURL(strURL) {
	return escape(strURL.substr(strURL.indexOf('/', 8)));
}

function subFullImage(strURL,intX,intY) {
	var intScrY;
	var intScrX;
	try	{
		intScrY = (screen.availHeight)-60;
		intScrX = (screen.availWidth)-40;
	} catch(e) {
		intScrY = 420;
		intScrX = 600;      
	}		      

	if (intY > intScrY) intY=intScrY;
	if (intX > intScrX) intX=intScrX;

	window.open('/library/asp/getImage.asp?url='+strURL.replace('&','%26'),'imagewindow','height='+intY+',width='+intX+',status=no,toolbar=no,menubar=no,location=no,resizable=yes,dependent=yes');
}



function ftnPopUpWindow(strURL, intWidth, intHeight, strOptions)
{
   window.open(strURL, null, "height=" + intHeight + ", width=" + intWidth + "," + strOptions)
}