// Get the value of a cookie
function getCookie(cookieName)
{
	var results = document.cookie.match( '(^|;) ?' + cookieName + '=([^;]*)(;|$)' );
	if (results)
	{
		return(unescape(results[2]));
	}
	return "";
}

// Set a cookie.
function setCookie(cookieName, cookieValue, expirationTimeInMinutes)
{
	var expires = null;
	if (expirationTimeInMinutes)
	{
		var expirationDate = new Date();
		expirationDate.setTime(expirationDate.getTime()+ (expirationTimeInMinutes*60*1000));
		expires = ";expires=" + expirationDate.toGMTString();
	}
	document.cookie = cookieName + "=" + escape(cookieValue)+((expires==null) ? "" : expires);
}

function disableCmdButton(buttonName)
{
	var button = document.getElementById(buttonName);
	if (button != null)
	{
		button.disabled = true;
	}
}
function enableCmdButton(buttonName)
{
	var button = document.getElementById(buttonName);
	if (button != null)
	{
		button.disabled = false;
	}
}

// The following four functions allow the top banner to be expanded or collapsed.
// Initially the banner state is 'expanded'.  If any window has 'collapsed' the
// top banner, it will apply to all windows until it is 'expanded'.
 
// Check to see what the current state is and hide or display 
// the top banner as appropriate.
function setBannerState() 
{
	// Get the cookie that stores the state of the banner
	var temp = getCookie('WFDSSBannerState');
 	// If it is set to 'expanded', display the banner 
	if (temp == "" || temp == 'expanded') 
	{ 
		displayBanner();
	}
	// It must be set to 'collapsed', hide the banner
	else 
	{ 
		hideBanner();
	}
}
// Display the top banner, adjust positions of left- and right-hand columns,
// and save the state of banner
function displayBanner()
{
	document.getElementById('divBanner').style.display = 'block';
	document.getElementById('collapseBannerIcon').style.display = 'inline'; // Display the collapse icon
	document.getElementById('expandBannerIcon').style.display = 'none'; // Hide the expand icon 									

	if (document.getElementById('divContentThreeColumnRightSideBar'))
	{
		document.getElementById('divContentThreeColumnRightSideBar').style.top='78px';
	}
	if (document.getElementById('divContentTwoColumnRightSideBar'))
	{
		document.getElementById('divContentTwoColumnRightSideBar').style.top='78px';
	}
	setCookie('WFDSSBannerState', 'expanded');
}
// Hide the top banner, adjust positions of left- and right-hand columns, 
// and save the state of the banner
function hideBanner()
{
	document.getElementById('divBanner').style.display = 'none';
	document.getElementById('collapseBannerIcon').style.display = 'none'; // Hide the collapse icon
	document.getElementById('expandBannerIcon').style.display = 'inline'; // Display the expand icon

	setCookie('WFDSSBannerState', 'collapsed');
}
// Display or hide the top banner.
function toggleBanner(thisObj, thisEvent)
{
	var bannerVisible = document.getElementById('divBanner').style.display;
	if (bannerVisible == 'none')
	{
		displayBanner();
	}
	else
	{
		hideBanner();
	}
}

// The following 4 functions allow the left column to be expanded or collapsed.
// Initially the left column is 'expanded'.  If any window has 'collapsed' the 
// left column, it will apply to all windows until it is 'expanded'.

// Check to see if a cookie has been set (by function "toggleLeftColumn"). 
// If so, hide or display the left column as appropriate.
function setLeftColumnState()
{
	// If this page does not use either two or three column layout, 
	// then hide the icon on the left side of the tab bar
	if ( !(document.getElementById('divContentThreeColumnLeftColumn')) && !(document.getElementById('divContentLeftColumn')) )
	{  
		document.getElementById('collapseLeftColumnIcon').style.display='none';
		document.getElementById('expandLeftColumnIcon').style.display='none';
	}
	else // This page uses either two or three column layout
	{
		var temp = getCookie('WFDSSLeftColumnState');
		if (temp == "" | temp == 'expanded') 
		{ 
			displayLeftColumn();
		}
		else 
		{
			hideLeftColumn();
		}
	}
}
// Display the left column, adjust the positions of the left- and right-hand columns, 
// and set a cookie to store the state of the left column.
function displayLeftColumn()
{
	document.getElementById('collapseLeftColumnIcon').style.display='inline'; // Display the collapse icon
	document.getElementById('expandLeftColumnIcon').style.display='none'; // Hide the expand icon
	
	if (document.getElementById('divContentLeftColumn'))
	{
		document.getElementById('divContentLeftColumn').style.display='block';
		document.getElementById('divContentRightColumn').style.marginLeft='13em';
	}
	
	if (document.getElementById('divContentThreeColumnLeftColumn'))
	{
		document.getElementById('divContentThreeColumnLeftColumn').style.display='block';
		document.getElementById('ddivContentThreeColumnRightMain').style.marginLeft='13em';
	}
	// Set a cookie so when page reloads, we can remember the left hand column state
	setCookie('WFDSSLeftColumnState','expanded');
	
}
// Hide the left column, adjust the positions of the left- and right-hand columns, 
// and set a cookie to store the state of the column.
function hideLeftColumn()
{
	document.getElementById('collapseLeftColumnIcon').style.display='none'; // Hide the collapse icon
	document.getElementById('expandLeftColumnIcon').style.display='inline'; // Display the expand icon
	
	if (document.getElementById('divContentLeftColumn'))
	{
		document.getElementById('divContentLeftColumn').style.display='none';   	// Hide the left column
		document.getElementById('divContentRightColumn').style.marginLeft='0';     // Move main column to left of page
	}
	if (document.getElementById('divContentThreeColumnLeftColumn'))
	{
		document.getElementById('divContentThreeColumnLeftColumn').style.display='none';   	// Hide the left column
		document.getElementById('divContentThreeColumnRightMain').style.marginLeft='0';     // Move main column to left of page
	}
	// Set a cookie so when page reloads, we can remember the left hand column state
	setCookie('WFDSSLeftColumnState','collapsed');
}
// Display or hide the left column.
function toggleLeftColumn()
{
	// If the page uses 2-column layout
	if (document.getElementById('divContentLeftColumn'))
	{
		// If the column is hidden, display it. Otherwise, hide it.
		if (document.getElementById('divContentLeftColumn').style.display=='none')
		{
			displayLeftColumn();																																		// then show it.
		}
		else
		{																																									// If the column is visible,
			hideLeftColumn();																																				// then hide it.																													
		}
	}
	// If the page uses 3-column layout
	if (document.getElementById('divContentThreeColumnLeftColumn'))
	{
		// If the column is hidden, display it. Otherwise, hide it.
		if (document.getElementById('divContentThreeColumnLeftColumn').style.display=='none')
		{
			displayLeftColumn();																																		// then show it.
		}
		else
		{																																									// If the column is visible,
			hideLeftColumn();																																				// then hide it.																													
		}
	}
}

/*
 * Returns the number of checkboxes/radio buttons checked in the specified form
 */
function numChecked(form, elementId)
{
	var checkedCount = 0;

	if (form != null)
	{
		var numElements = form.elements.length;
		var element;
		var index;
		for (var i = 0; i < numElements; i++)
		{
			element = form.elements[i];
			if ((element.type == "checkbox") || (element.type == "radio"))
			{
				index = element.name.lastIndexOf(":");
				if ((element.name.substr(index + 1) == elementId) && (element.checked))
				{
					++checkedCount;
				}
			}
		}
	}
	return checkedCount;
}

/*
 * The following variable (radioMap) and four functions allow 'single select'
 * Data Tables using a radio button for each row in the table.  The key for the
 * radioMap is the id of the radio button on the table without the prepended
 * unique identifcation tags.
 *
 * To use the onRadioButtonClicked method, you should first call setRadioSelection
 * when you initialize your page to set the original selection value of the map
 * used to maintain selection values.
 */

var radioMap = new Array()
function initRadioSelection(form, radioId, selectionValue)
{
	var selectedElement = null;

	if (form != null)
	{
		var numElements = form.elements.length;
		var element;
		for (var i = 0; i < numElements; i++)
		{
			element = form.elements[i];
			if (element.type == "radio")
			{
				radioIdIndex = element.name.lastIndexOf(":");
				if (element.name.substr(radioIdIndex + 1) == radioId)
				{
					element.checked = (element.value == selectionValue);
					if (element.checked == true)
					{
						selectedElement = element;
					}
				}
			}
		}
	}
	if (selectedElement != null)
	{
		setRadioSelection(radioId, selectionValue);
	}
	else
	{
		setRadioSelection(radioId, null);
	}
	return selectedElement;
}
function setRadioSelection(radioId, selectionValue)
{
	radioMap[radioId] = selectionValue;
}
function getRadioSelection(radioId)
{
	return radioMap[radioId];
}
function onRadioButtonClicked(thisObj, thisEvent) 
{
	if (thisObj.type == "radio")
	{
		var radioIdIndex = thisObj.name.lastIndexOf(":");
		var radioId = thisObj.name.substr(radioIdIndex + 1);
		var prevSelection = getRadioSelection(radioId);

		if (thisObj.value != prevSelection)
		{	// A new radio button was selected
			thisObj.checked = true;
	
			if (prevSelection != null)
			{
				var thisForm = thisObj.form;
				var numElements = thisForm.elements.length;
				var element;
				for (var i = 0; i < numElements; i++)
				{
					element = thisForm.elements[i];
					if (element.type == "radio")
					{
						radioIdIndex = element.name.lastIndexOf(":");
						if (element.name.substr(radioIdIndex + 1) == radioId)
						{
							if (element.value == prevSelection)
							{
								element.checked = false;
								break;
							}
						}
					}
				}
			}
			setRadioSelection(radioId, thisObj.value);
		}
	}
}
/*
 * The following variable (checkboxMap) and four functions allow 'single select'
 * Data Tables using a checkbox for each row in the table.  The key for the
 * checkboxMap is the id of the checkbox on the table without the prepended
 * unique identifcation tags.
 *
 * To use the onCheckboxButtonClicked method, you should first call setCheckboxSelection
 * when you initialize your page to set the original selection value of the map
 * used to maintain selection values.
 */

var checkboxMap = new Array()
function initCheckboxSelection(form, checkboxId, selectionValue)
{
	var selectedElement = null;

	if (form != null)
	{
		var numElements = form.elements.length;
		var element;
		for (var i = 0; i < numElements; i++)
		{
			element = form.elements[i];
			if (element.type == "checkbox")
			{
				checkboxIdIndex = element.name.lastIndexOf(":");
				if (element.name.substr(checkboxIdIndex + 1) == checkboxId)
				{
					element.checked = (getCheckboxValue(element) == selectionValue);
					if (element.checked == true)
					{
						selectedElement = element;
					}
				}
			}
		}
	}
	if (selectedElement != null)
	{
		setCheckboxSelection(checkboxId, selectionValue);
	}
	else
	{
		setCheckboxSelection(checkboxId, null);
	}
	return selectedElement;
}
function setCheckboxSelection(checkboxId, selectionValue)
{
	checkboxMap[checkboxId] = selectionValue;
}
function getCheckboxSelection(checkboxId)
{
	return checkboxMap[checkboxId];
}
function getCheckboxValue(checkboxElement)
{
	var checkboxValue = document.getElementById(checkboxElement.id + "Value");
	if (checkboxValue != null)
	{
		return checkboxValue.value;
	}
	return null;
}
function onCheckboxClicked(thisObj, thisEvent) 
{
	if (thisObj.type == "checkbox")
	{
		var checkboxIdIndex = thisObj.name.lastIndexOf(":");
		var checkboxId = thisObj.name.substr(checkboxIdIndex + 1);
		var prevSelection = getCheckboxSelection(checkboxId);
		var thisValue = getCheckboxValue(thisObj);

		if (thisValue != prevSelection)
		{	// A new checkbox was selected
			thisObj.checked = true;
	
			if (prevSelection != null)
			{
				var thisForm = thisObj.form;
				var numElements = thisForm.elements.length;
				var element;
				for (var i = 0; i < numElements; i++)
				{
					element = thisForm.elements[i];
					if (element.type == "checkbox")
					{
						checkboxIdIndex = element.name.lastIndexOf(":");
						if (element.name.substr(checkboxIdIndex + 1) == checkboxId)
						{
							if (getCheckboxValue(element) == prevSelection)
							{
								element.checked = false;
								break;
							}
						}
					}
				}
			}
			setCheckboxSelection(checkboxId, thisValue);
		}
		else
		{	// The item is being deselected
			setCheckboxSelection(checkboxId, null);
		}
	}
}

/*
 * Returns the number of elements in the checkbox list on the specified form
 */
function getCheckboxListSize(form, checkboxId)
{
	var count = 0;

	if (form != null)
	{
		var numElements = form.elements.length;
		var element;
		var index;
		for (var i = 0; i < numElements; i++)
		{
			element = form.elements[i];
			if (element.type == "checkbox")
			{
				index = element.name.lastIndexOf(":");
				if (element.name.substr(index + 1) == checkboxId)
				{
					++count;
				}
			}
		}
	}
	return count;
}
/*
 * The following function returns the root (everything up to and including the 
 * colon) of the hidden field names associated with a 'single select' data table.
 */
function initDataTableSingleSelect(form, fieldName, selectionValue)
{
	var selectedRoot = null;

	if (form != null)
	{
		var numElements = form.elements.length;
		var element;
		for (var i = 0; i < numElements; i++)
		{
			element = form.elements[i];
			if ((element.type == "hidden") && (element.value == selectionValue))
			{
				var lastColon = element.name.lastIndexOf(":" + fieldName);
				if (lastColon > 0)
				{
					selectedRoot = element.name.substr(0, lastColon + 1) + fieldName;
					break;
				}
			}
		}
	}
	return selectedRoot;
}

/*
 * removes non-numeric values - returning only the numeric portion
 * @return a numeric variable
 */
function removeNonNumerics(s) {
  return includeFilter(s, "0123456789");
}

/*
 * Strips all characters from the input string that are not in the given filter
 */
function includeFilter(input, filter)
{
  var output = "";
  for (i=0; i < input.length; i++) {
     x = input.charAt(i);
     if (filter.indexOf(x,0) != -1) {
       output += x;
     }
  }
  return output;
}

/*
 * Strips all characters from the input string that are in the given filter
 */
function stripFilter(input, stripCharacters)
{
  var output = "";
  for (i=0; i < input.length; i++) {
     x = input.charAt(i);
     if (stripCharacters.indexOf(x,0) == -1) {
       output += x;
     }
  }
  return output;
}

function verifyPercentage(percentageField, minValue, maxValue)
{
	var errorMessage = "";
	if (percentageField != null)
	{
		var value = stripFilter(percentageField.value, " ");
		var tempValue = includeFilter(value, "0123456789.,%");
		if (tempValue != value)
		{
			errorMessage = percentageField.value + " contains invalid characters for a percentage";
		}
		else
		{
			value = includeFilter(value, "0123456789.");
			if (value.length > 0)
			{
				var percent = new Number(value);
				if ((percent < minValue) || (percent > maxValue))
				{
					errorMessage = "Please enter a percentage between " + minValue + " and " + maxValue;
				}
				else
				{
					percent = Math.round(percent * 100) / 100;
					value = new String(percent);
					var maxStr = new String(maxValue);
					if (value.length > maxStr.length)
					{
						value = value.substr(0, maxStr.length);
					}
					percentageField.value = value + "%";
				}
			}
			else
			{
				percentageField.value = "0.0%";
			}
		}		 
	}
	return errorMessage;
}

function validateNonNegativeNumber(fieldName, field)
{
	var errorMessage = "";
	if (field != null)
	{
		var value = stripFilter(field.value, " ");
		var validCharacters = "0123456789."; 
		var tempValue = includeFilter(value, validCharacters);
		if (tempValue != value)
		{
			errorMessage = fieldName + " must be a non-negative number\n";
		}
	}
	return errorMessage;
}	
function verifyNumber(field, fieldName, minValue, maxValue, precision)
{
	var errorMessage = "";
	if (field != null)
	{
		var value = stripFilter(field.value, " ");
		var validCharacters = "0123456789,.-"; 
		var tempValue = includeFilter(value, validCharacters);
		if (tempValue != value)
		{
			errorMessage = fieldName + " contains invalid characters (" +
				field.value + ") for a numeric field\n";
		}
		else if (value.length > 0)
		{
			var numericValue = new Number(value);
			var factor = Math.pow(10, precision);
			numericValue = Math.round(numericValue * factor) / factor;
			if ((numericValue < minValue) || (numericValue > maxValue))
			{
				errorMessage = "Please enter a numeric value between " + minValue + " and " +
					maxValue + " for " + fieldName + "\n";
			}
			else
			{
				field.value = numericValue;
			}
		}		 
	}
	return errorMessage;
}

function validateRequiredField(fieldName, fieldValue)
{
	fieldValue = stripFilter(fieldValue, " ");
	if (fieldValue.length == 0)
	{
		return fieldName + " is a required field.\n";
	}
	return "";
}

function validatePhoneNumber(field, fieldName, required)
{
	var message = "";
	if (field == null)
	{
		message = "A null field was passed for the " + fieldName + "\n";
	}
	else
	{
		var fieldValue = field.value;
		if (required)
		{
			message = validateRequiredField(fieldName, fieldValue);
		}
		if (message.length == 0 && (required || (fieldValue.length > 0)))
		{		
			fieldValue = includeFilter(fieldValue, "0123456789");
			if (fieldValue.length != 10)
			{
				message = "Phone numbers must contain 10 digits - the area code is required.\n";
			}
			else
			{
				fieldValue = fieldValue.substr(0, 3) + "-" + fieldValue.substr(3, 3) +
					"-" + fieldValue.substr(6, 4);
				field.value = fieldValue;
			}
		}
	}

	return message;
}

function validateEmailAddress(field, fieldName, required)
{
	var message = "";
	if (field == null)
	{
		message = "A null field was passed for the " + fieldName + "\n";
	}
	else
	{
		var fieldValue = field.value;
		if (required)
		{
			message = validateRequiredField(fieldName, fieldValue);
		}
		if (message.length == 0 && (required || (fieldValue.length > 0)))
		{		
			var ampFound = fieldValue.indexOf("@");
			var dotFound = fieldValue.indexOf(".");
			if (!(ampFound > 0) || !(dotFound > 0))
			{
				message = "Invalid email address.\n";
			}
			else
			{
				field.value = fieldValue;
			}
		}
	}

	return message;
}

/**
This function should be used as the onunload event handler for all forms.
The purpose of this onunload event handler is to inform the user that a
modified form was exited and the changes were not saved.  This message 
should only be displayed if the user exits the form through a browser
initiated event (back or forward button, refresh, closing the browser,
or entering a new URL).  In these cases, the user will not be able to save
the modifications, but the users want to be notified.

Since the onunload event handler is called every time a page is exited,
an externally defined boolean value (checkForChange) is used to determine
if the form is being exited as the result of an FPA-initiated event.  For
FPA-initiated unloads, the value should be set to false.

Externally defined variables:
	checkForChange - boolean value set to false if the 'formChanged' check
					 was already performed through an FPA-initiated event
	commonFormNotSaved - message to be displayed if the form was changed
	
Externally defined function:
	formChanged() - returns true if a persisted field was modified on the
				    form
**/
var commonFormNotSaved = "The changes made to this form were not saved";
var commonFormNoUpdate = "Please update at least one value before submitting the form";
var commonFormConfirmExit = "You have made changes that have not been saved.\nDo you want to continue?";

function onUnloadCheck()
{
	if ((checkForChange == true) && (formChanged() == true))
	{
		alert(commonFormNotSaved)
	}
}


/**
This function should be associated with FPA form 'Submit' buttons.
The purpose of this function is to provide consistent behavior for
submitting forms.  As such, this function first verifies that the form
has been changed, then validates the contents of the form, and finally
submits the form if the modified form contains valid data.

If the form is submitted, the global checkForChange boolean is set to false
to prevent the 'form unload message' from being displayed.

Externally defined variables:
	checkForChange - boolean value set to false if the form is submitted
	commonFormNoUpdate - message to be displayed if persistent data was not modified
	
Externally defined functions:
	formChanged() - returns true if a persisted field was modified
	checkForm(formName) - returns an empty string if the contents of the form
					are valid, otherwise an error message is returned
**/
function submitForm() 
{
	if (formChanged())	
	{
		// check the input data on the page
		// if there are no error messages an empty string will be returned
		var errorMessage = checkForm()
		
		// if we have an error message display it
		if (errorMessage != "")
		{
			alert(errorMessage)
			return false
		}
		checkForChange = false
		return true
	}
	
	alert(commonFormNoUpdate)
	return false	 
}


/**
This function should be associated with FPA form 'Cancel' buttons.
The purpose of this function is to determine whether the form has been
changed before exiting the form.  If the form has changed, the user is
prompted to determine whether they want to continue to exit.  If the form
has not been changed, the form is exited without displaying any message.

If the form is exited, the global checkForChange boolean is set to false
to prevent the 'form unload message' from being displayed.

Externally defined variables:
	checkForChange - boolean value set to false if the form is exited
	commonFormConfirmExit - message to be displayed to confirm exit
	
Externally defined function:
	formChanged() - returns true if a persisted field was modified on the
				    form
**/
function cancelForm() 
{
	if (formChanged() == true)	
	{
		if (confirm(commonFormConfirmExit) == true)
		{
			// Set check flag to false to suppress onunload message
			checkForChange = false;
		}
		else
		{
			return false;
		}
	}
	return true;
}

function onMenuItemClicked()
{
	if (checkForChange == true)
	{
		if (formChanged() == true)
		{
			if (confirm(commonFormConfirmExit) == false)
			{
				return false;
			}
		}
		checkForChange = false;
	}
	return true;
}

function suppressEnter(thisObj, thisEvent) 
{
	var evt = (thisEvent) ? thisEvent : event;
	var charCode = (evt.charCode) ? evt.charCode :
		((evt.which) ? evt.which : evt.keyCode);
	if (charCode == 13)
	{
		return false;
	}
	return true;
}

function convertNumberToDollars(number)
{
	var dollars = "";
	var numDigits = 0;
	number = number.toFixed(0);
	if (number >= 0)
	{
		dollars = (number % 10) + dollars;
		number = Math.floor(number / 10);
		++numDigits;
		while (number > 0)
		{
			if (numDigits % 3 == 0)
			{
				dollars = "," + dollars;
			}
			dollars =  (number % 10) + dollars;
			number = Math.floor(number / 10);
			++numDigits;
		}
		dollars = "$" + dollars;
	}
	return dollars;
}

// This function returns an Arrray containing the labels for all selected 
// options in a multiple-select listbox.
function getSelectedOptionsText(selectObj)
{
	var selectedOptions = new Array();
	if (selectObj.type == "select-multiple")
	{
		var index = 0;
		for (var i = 0; i < selectObj.length; i++)
		{
			if (selectObj.options[i].selected)
			{
				selectedOptions[index] = selectObj.options[i].text;
				index++;
			}
		}
	}
	return selectedOptions;
}

// This function clears all selected options in a multiple-select listbox.
function clearSelectedOptions(selectObj)
{
	if (selectObj.type == "select-multiple")
	{
		for (var i = 0; i < selectObj.length; i++)
		{
			if (selectObj.options[i].selected)
			{
				selectObj.options[i].selected = false;
			}
		}
	}
}

// This function validates that the time input field contains hours and minutes
// in the format HH:MM or HHMM where HH is 0-23 and MM is 0-59.
function validateTimeField(fieldName, timeObj)
{
	var errorMessage = "";
	if (timeObj != null)
	{
		var timeValue = stripFilter(timeObj.value, " ");
		var tempValue = includeFilter(timeValue, "0123456789");
		switch (tempValue.length)
		{
			case 0:
				break;
			case 1:
			case 2:
				timeValue = tempValue + ":00";
				break;
			case 3:
				timeValue = tempValue.substr(0, 1) + ":" + tempValue.substr(1);
				break;
			case 4:
				timeValue = tempValue.substr(0, 2) + ":" + tempValue.substr(2);
				break;
			default:
				errorMessage = "Invalid time entered - time must be entered as HH, HHMM, or HH:MM where HH is 0-23 and MM is 0-59\n";
				break;
		}
		timeObj.value = timeValue;
		if ((tempValue.length > 0) && (tempValue.length < 5))
		{
			var found = timeValue.indexOf(":");
			var hours = timeValue.substring(0, found);
			var numericHours = new Number(hours);
			if ((numericHours < 0) || (numericHours > 23))
			{
				errorMessage = fieldName + " contains an invalid hour. Please enter an hour between 0 and 23\n";
			}
			var minutes = timeValue.substring(found+1);
			var numericMinutes = new Number(minutes);
			if ((numericMinutes < 0) || (numericMinutes > 59))
			{
				errorMessage = fieldName + " contains an invalid minutes value. Please enter a value between 0 and 59\n";
			}
		}
	}
	return errorMessage;
}

// This function validates year, month, and day are entered if it is required.
// It also validates that year, month, and day values are all entered if any one
// is entered, and the values represent a valid date.
function validateDateFields(fieldName, yearObj, monthObj, dayObj, required)
{
	var year = yearObj.options[yearObj.selectedIndex].value;
	var month = monthObj.options[monthObj.selectedIndex].value;
	var day = dayObj.options[dayObj.selectedIndex].value;

	if (required == true)
	{
		if (year == 0 || month == 0 || day == 0)
		{
			return fieldName + " is a required field.\n";
		}
	}
	else
	{
		if (year == 0 && month == 0 && day == 0)
		{
			return "";
		}
	}

	var maxDays = 31;
	if (month == 2)
	{
		if (isLeapYear(year) == true)
		{
			maxDays = 29;
		}
		else
		{
			maxDays = 28;
		}
	}
	if (month == 4 || month == 6 || month == 9 || month == 11)
	{
		maxDays = 30;
	}
	if (day > maxDays)
	{
		return fieldName + " has an incorrect day value for the month specified.\n";
	}	
	return "";
}

// This function returns true if the year is a leap year.
function isLeapYear(year)
{
	// A year is a leap year if it is divisible by 4 but not by 100. 
	// If a year is divisible by 4 and by 100, it is not a leap year unless it is also 
	// divisible by 400.
	if (year % 4 == 0)
	{
		if (year % 100 == 0)
		{
			return (year % 400 == 0);
      	} 
      	else 
      	{
			return true;
     	}
	}
	else 
	{
		return false;
	}
}

// This function validates that the first date is prior to the second date.
function validateDateOrder(dateName1, year1, month1, day1, dateName2, year2, month2, day2)
{
	var errorMessage = "";
	var date1 = new Date(year1, month1 - 1, day1);
	var date2 = new Date(year2, month2 - 1, day2);
	if (date1 > date2)
	{
		errorMessage = dateName1 + " must be prior to " + dateName2 + "\n";
	}
	return errorMessage;
}
/**
This function is used to trap the Enter key and prevent it from resulting
in erroneous window or dialog behavior.  To use this function, the window 
or dialog must add an onkeypress="trapEnter(thisObj, thisEvent)" to the 
BODY tag so that key presses go to this function.

Externally defined variable:
	defaultButton - the name of the default button to execute.  It is 
					initialized to "", but a window can override it.
**/
var defaultButton = "";
function trapEnter(thisObj, thisEvent) 
{
	var evt = (thisEvent) ? thisEvent : event;
	var charCode = (evt.charCode) ? evt.charCode :
		((evt.which) ? evt.which : evt.keyCode);
	var element = (thisEvent) ? thisEvent.srcElement : event.target;

	// If Enter was pressed
	if (charCode == 13)
	{
		// If focus is on a button, submit, image, textarea, or unspecified type, allow Enter
		if (element.type == "button" || element.type == "submit" || element.type == "image"
			|| element.type == "textarea" || element.type == "")
		{
			return true;
		}
		// Else if the default button is set, click it
		else if (defaultButton != "")
		{
			document.getElementById(defaultButton).click();
			return false;
		}
		// Don't allow the Enter
		else
		{
			return false;
		}
	}
	// Allow the keystroke
	return true;
}

// This function gets all SELECTED options in the from select object, adds them to
// the to select object, and then removes them from the from select object.
function moveAllSelections(fromObj, toObj) 
{
	if ((fromObj.type != "select-multiple") ||
		(toObj.type != "select-multiple"))
	{
		return false;
	}

	// Get the selections from the from select object
	var selText = new Array();
	var selValue = new Array();
	var selIndex = 0;
	for (var i = 0; i < fromObj.length; i++)
	{
		if (fromObj.options[i].selected)
		{
			selText[selIndex] = fromObj.options[i].text;
			selValue[selIndex] = fromObj.options[i].value;
			selIndex++;
		}
	}

	// If no selections, do nothing
	if (selIndex == 0)
	{
		return false;
	}
	
	// Add the selections to the to select object
	if (toObj.length == 0) // Currently empty, just add the selections
	{
		for (var i = 0; i < selText.length; i++)
		{
		   	var newOpt = new Option(selText[i], selValue[i]);
    		toObj.options[i] = newOpt;
		}
	}
	else // It has entries, merge the new selections in alphabetical order
	{
		// These 2 arrays will contain the merged list of items
		var optText = new Array();
		var optValue = new Array();
		var newCount = 0;
		var selStart = 0;
		
		for	(var i = 0; i < toObj.length; i++)
    	{
      		var currentText = toObj.options[i].text;
      		for (var j = selStart; j < selText.length; j++)
      		{
      			if (selText[j] < currentText)
      			{
      				optText[newCount] = selText[j];
      				optValue[newCount] = selValue[j];
      				newCount++;
      				selStart = j + 1;
      			}
      			else
      			{
					break;
				}
			}
			optText[newCount] = toObj.options[i].text;
			optValue[newCount] = toObj.options[i].value;      			
      		newCount++;	
    	}
    	// Add any remaining selected items
    	for (var k = selStart; k < selText.length; k++)
    	{
			optText[newCount] = selText[k];
			optValue[newCount] = selValue[k];      			
      		newCount++;
    	}
    	// Store all the options in the destination select object    		
    	for	(var n = 0; n < newCount; n++)
    	{
      		var newOpt = new Option(optText[n], optValue[n]);
      		toObj.options[n] = newOpt;
    	}
			
	}
	// Now remove the selected options from the source select object
    for (var p = fromObj.length-1; p >= 0; p--)
    {
		if (fromObj.options[p].selected)
      	{
			fromObj.options[p] = null;
		}
    }
    return false;	
}

// This function gets all SELECTED options in the from select object and copies them to
// the to select object.
function copyAllSelections(fromObj, toObj) 
{
	if ((fromObj.type != "select-multiple") ||
		(toObj.type != "select-multiple"))
	{
		return false;
	}

	// Get the selections from the from select object
	var selText = new Array();
	var selValue = new Array();
	var selIndex = 0;
	for (var i = 0; i < fromObj.length; i++)
	{
		if (fromObj.options[i].selected)
		{
			selText[selIndex] = fromObj.options[i].text;
			selValue[selIndex] = fromObj.options[i].value;
			selIndex++;
		}
	}

	// If no selections, do nothing
	if (selIndex == 0)
	{
		return false;
	}
	
	// Add the selections to the to select object
	if (toObj.length == 0) // Currently empty, just add the selections
	{
		for (var i = 0; i < selText.length; i++)
		{
		   	var newOpt = new Option(selText[i], selValue[i]);
    		toObj.options[i] = newOpt;
		}
	}
	else // It has entries, merge the new selections in alphabetical order
	{
		// These 2 arrays will contain the merged list of items
		var optText = new Array();
		var optValue = new Array();
		var newCount = 0;
		var selStart = 0;
		
		for	(var i = 0; i < toObj.length; i++)
    	{
      		var currentText = toObj.options[i].text;
      		for (var j = selStart; j < selText.length; j++)
      		{
      			if (selText[j] < currentText)
      			{
      				optText[newCount] = selText[j];
      				optValue[newCount] = selValue[j];
      				newCount++;
      				selStart = j + 1;
      			}
      			else
      			{
					break;
				}
			}
			optText[newCount] = toObj.options[i].text;
			optValue[newCount] = toObj.options[i].value;      			
      		newCount++;	
    	}
    	// Add any remaining selected items
    	for (var k = selStart; k < selText.length; k++)
    	{
			optText[newCount] = selText[k];
			optValue[newCount] = selValue[k];      			
      		newCount++;
    	}
    	// Store all the options in the destination select object    		
    	for	(var n = 0; n < newCount; n++)
    	{
      		var newOpt = new Option(optText[n], optValue[n]);
      		toObj.options[n] = newOpt;
    	}
			
	}
    return false;	
}


// This function gets ALL options in the from select object, adds them to
// the to select object, and then removes them from the from select object.
function moveAllOptions(fromObj, toObj) 
{
	if ((fromObj.type != "select-multiple") ||
		(toObj.type != "select-multiple"))
	{
		return false;
	}

	// Get all options in the from object
	var fromText = new Array();
	var fromValue = new Array();
	var fromIndex = 0;
	for (var i = 0; i < fromObj.length; i++)
	{
		fromText[selIndex] = fromObj.options[i].text;
		fromValue[selIndex] = fromObj.options[i].value;
		fromIndex++;
	}

	// If no options, do nothing
	if (fromIndex == 0)
	{
		return false;
	}
	
	// Add the options to the to select object
	if (toObj.length == 0) // Currently empty, just add the options
	{
		for (var i = 0; i < fromText.length; i++)
		{
		   	var newOpt = new Option(fromText[i], fromValue[i]);
    		toObj.options[i] = newOpt;
		}
	}
	else // It has entries, merge the new options in alphabetical order
	{
		// These 2 arrays will contain the merged list of items
		var optText = new Array();
		var optValue = new Array();
		var newCount = 0;
		var selStart = 0;
		
		for	(var i = 0; i < toObj.length; i++)
    	{
      		var currentText = toObj.options[i].text;
      		for (var j = selStart; j < selText.length; j++)
      		{
      			if (selText[j] < currentText)
      			{
      				optText[newCount] = selText[j];
      				optValue[newCount] = selValue[j];
      				newCount++;
      				selStart = j + 1;
      			}
      			else
      			{
					break;
				}
			}
			optText[newCount] = toObj.options[i].text;
			optValue[newCount] = toObj.options[i].value;      			
      		newCount++;	
    	}
    	// Add any remaining selected items
    	for (var k = selStart; k < selText.length; k++)
    	{
			optText[newCount] = selText[k];
			optValue[newCount] = selValue[k];      			
      		newCount++;
    	}
    	// Store all the options in the to select object    		
    	for	(var n = 0; n < newCount; n++)
    	{
      		var newOpt = new Option(optText[n], optValue[n]);
      		toObj.options[n] = newOpt;
    	}
			
	}
	// Now remove all the options from the from select object
    for (var p = fromObj.length-1; p >= 0; p--)
    {
		fromObj.options[p] = null;
    }
    return false;	
}

// This function parses the comma-separated selection values in the text field,
// locates those selection values in the from select object, and copies those
// options to the to select object.
function loadSelections(textObj, fromObj, toObj)
{
	if (textObj != null)
	{
		var selections = stripFilter(textObj.value, " ");
		if (selections.length > 0)
		{
			// The list of selections is a comma-separated string of values contained
			// in the text field.
			// Create an array from the list and loop through the items
			var selectList = selections.split(",");
			for (var i = 0; i < selectList.length; i++)
			{
				// Loop through the available list box, find the item, and select it
				for (var j = 0; j < fromObj.length; j++)
				{
					var optionValue = fromObj.options[j].value;
					if (optionValue == selectList[i])
					{
						fromObj.options[j].selected = true;
						break;
					}
				}
			}			 
			copyAllSelections(fromObj, toObj);
			fromObj.selectedIndex = -1;
		}
	}
}
// This function finds all the checkboxes on the specified form and
// with the specified name and based on the value for selection,
// it either clicks (true) or unclicks (false) the checkbox.
function selectAllCheckboxes(formName, groupName, selection)
{
	var form = document.forms[formName];	
	var numElements = form.elements.length;
	var element;
	for (var i = 0; i < numElements; i++)
	{
		element = form.elements[i];
		if (element.type == "checkbox")
		{
			nameIndex = element.name.lastIndexOf(":");
			if (element.name.substr(nameIndex + 1) == groupName)
			{
				if (selection == true)
				{
					if (element.checked == false)
					{
						element.click();
					}
				}
				else
				{
					if (element.checked == true)
					{
						element.click();
					}					
				}
					
			}
		}
	}
}
// This function finds the radio button group with the specified name on
// the specified form and selects the radio button in the group with a 
// value of 0.
function clearRadioGroup(formName, name)
{
	var form = document.forms[formName];	
	var numElements = form.elements.length;
	var element;
	for (var i = 0; i < numElements; i++)
	{
		element = form.elements[i];
		if (element.type == "radio")
		{
			radioNameIndex = element.name.lastIndexOf(":");
			// Select the first one
			if (element.name.substr(radioNameIndex + 1) == name)
			{
				if (element.value == 0)
				{
					element.checked = true;
					break;
				}
			}
		}
	}
}

// Returns the number of elements in the radio list on the specified form
function getRadioListSize(form, radioId)
{
	var count = 0;
	if (form != null)
	{
		var numElements = form.elements.length;
		var element;
		var index;
		for (var i = 0; i < numElements; i++)
		{
			element = form.elements[i];
			if (element.type == "radio")
			{
				index = element.name.lastIndexOf(":");
				if (element.name.substr(index + 1) == radioId)
				{
					++count;
				}
			}
		}
	}
	return count;
}
// Display or hide the collapsible section.
// thisObj is the image object that was clicked.
function displayHideSection(thisObj, openClose) 
{
	var imgObj = new Object();
	imgObj.elNode = thisObj;
	
    // Search for the div containing the image object
	while(imgObj.elNode.parentNode.tagName != "DIV" && imgObj.elNode.parentNode.tagName != "BODY")
	{
		imgObj.elNode = imgObj.elNode.parentNode;
	}
	
	// Get the image's parent node (the DIV)
	var divObj = imgObj.elNode.parentNode;

	// Check to see if there is a div container within the image's DIV parent.
	// If it doesn't exist, we will create one to hold the elements.
	var resObj;
	var containerExists = false;
	for(i = 0; i < divObj.childNodes.length; i++) 
	{
		if (divObj.childNodes[i].tagName == "DIV" && divObj.childNodes[i].id.substring(0,20) == "divContainerSection_")
		{
			containerExists = true;
			resObj = divObj.childNodes[i];
            break;
		}
	}
	
	// If the parent of the image and parent of the elements in the section 
	// are not the same, put the section elements in a DIV.
	if (containerExists == false)
	{
		resObj = document.getElementById(putElementsInDiv(thisObj));
	}

	// Find the image objects for displaying and hiding the section
	var spanObj = new Object();
	spanObj = thisObj.parentNode;
	var hideObj = new Object();
	var displayObj = new Object();
	for(i = 0; i < spanObj.childNodes.length; i++) 
	{
		if (spanObj.childNodes[i].tagName == 'IMG')
		{
			var objId = spanObj.childNodes[i].id;
			if (objId.indexOf("hide") != -1)
			{
				hideObj = spanObj.childNodes[i];
			}
			if (objId.indexOf("display") != -1)
			{
				displayObj = spanObj.childNodes[i];
			}
		}
	}
		
	// Display or hide the section
	if((openClose == "open") || ((openClose != "close") && (resObj.style.display)) == "none")
	{
		resObj.style.display = 'block';
		if (hideObj)
		{
			hideObj.style.display = 'inline';
		}
		if (displayObj)
		{
			displayObj.style.display = 'none';
		}
	} 
	else 
	{
		resObj.style.display = 'none';
		if (hideObj)
		{
			hideObj.style.display = 'none';
		}
		if (displayObj)
		{
			displayObj.style.display = 'inline';
		}
	}

}
// Put the child elements of the object passed in into a div.
// This function is used by displayHideSection()
function putElementsInDiv(obj) 
{
	// Create a div container
	var parentDiv = document.createElement("div");
	// set the id
	var idsuffix = obj.id; // JFK 20060606
	if (!idsuffix) 
	{ 
		closeablePortletDivSeq++;
		idsuffix = closeablePortletDivSeq;
	} // JFK 20060606
	
	parentDiv.id = "divContainerSection_" + idsuffix; // JFK 20060606 (idsuffix was obj.id)

	// Loop through all the child nodes and start adding elements to the DIV	
	// after finding the span with the buttons
	var spanFound = false;
	for (i = 0; i < obj.childNodes.length; i++) 
	{
		//alert(obj.id + "\\" + obj.childNodes[i].tagName + "//" + obj.childNodes[i].id);		
		// if we've found the first span (the one containing the buttons), continue
		if (spanFound == false && obj.childNodes[i].tagName == "SPAN") 
		{
			// go through all remaining objects from the bottom up
			for (j = obj.childNodes.length-1; j > i; j--)
			{
				//alert(obj.id + "//" + obj.childNodes[j].tagName + "//" + obj.childNodes[j].id);		
				// add the first node
				if (parentDiv.childNodes.length == 0)
				{
					parentDiv.appendChild(obj.childNodes[j]);	
				} 
				else 
				{
					// insert remaining nodes before the first one
					parentDiv.insertBefore(obj.childNodes[j],parentDiv.childNodes[0]);	
				}
			}
			// done
			break;
		}		
	}

	// add this div
	obj.appendChild(parentDiv);	
	
    return parentDiv.id;
}

