
var timerRemainingMinutes = 0;
var timerSecondCounter = 1;
var dynamicVariables_Dictionary = new Object();

//	startSessionTimer - sets the initial timer values and begins the timer repetition process
//	args:
//		none
//
//	return value: none
//
//	Program Change Log	
//	Date		Change								Programmer
//	07/28/2009	fixed function totalCells to round	Jim Hamilton
//				on add.	
//
function startSessionTimer()
{
	timerRemainingMinutes = thisSessionLength;
	updateSessionTimer();
}

//	updateSessionTimer - counts down the site's session timer
//	args:
//		none
//
//	return value: none
//
function updateSessionTimer()
{
	var showRemainingMinutes = "";
	var showSecondCounter = "";
	if(timerSecondCounter == 0)
	{
		timerRemainingMinutes--;
		timerSecondCounter = 59;
	} else {
		timerSecondCounter--;
	}
	if(timerRemainingMinutes < 10)
	{
		showRemainingMinutes = "0" + timerRemainingMinutes;
	} else {
		showRemainingMinutes = timerRemainingMinutes;
	}
	if(timerSecondCounter < 10)
	{
		showSecondCounter = "0" + timerSecondCounter;
	} else {
		showSecondCounter = timerSecondCounter;
	}
	
	document.getElementById("SessionTimerMinutesRemaining").innerHTML = showRemainingMinutes + ":" + showSecondCounter;
	if(timerRemainingMinutes == 0 && timerSecondCounter == 0)
	{
		document.getElementById("SessionTimerMinutesRemaining").style["color"] = "red";
	} else {
		setTimeout("updateSessionTimer()",1000);
	}
}

//	resetSessionTimer - puts the session timer back to the original 30 minute value
//	args:
//		none
//
//	return value: none
//
function resetSessionTimer()
{
	timerRemainingMinutes = 30;
	timerSecondCounter = 0;
}

// cross-browser function to change the inner content
// of an element
function changeInnerHTML(doc, divId, html){
	var element = doc.getElementById(divId);
	if (element != null)
	{
		var tagname = element.tagName.toLowerCase();
		//alert('tag: ' + tagname);
		// If it's a SPAN
		if (tagname == 'span' || tagname == 'div' || tagname == 'a')
		{
			element.childNodes.item(0).nodeValue = html;
		} else if (tagname == 'input' && element.type == 'text')
		{
			element.value = html;
		} else
		{
			alert('unsupported tag: ' + tagname);
		}
	} else
	{
		alert('element with id ' + divId + ' does not exist');
	}
}

// cross-browser function to get the internal value
// of an element
function getInnerValue(id) {
	var elem = document.getElementById(id);
	if (elem != null)
	{
		return elem.childNodes.item(0).nodeValue;
	}	else
	{
		return '';
	}
}

//	instructionsToggle - flip a display element and optionally a link too
//	args:
//		instructionsId - the ID attribute of the element to show/hide
//		linkId - the ID attribute of the linking element
//		toggleText - additional text to add after "hide" or "show"
//		forceOption - either "show" or "hide" or null
//		toggleLinkShowText - text to show on link when option is "hide" (e.g. "show")
//		toggleLinkHideText - text to show on link when option is "show" (e.g. "hide")
//
//	return value: none
//
function instructionsToggle(instructionsId, linkId, toggleText, forceOption, toggleLinkShowText, toggleLinkHideText) {
	if (toggleText == null) toggleText = "";
	var initialValue = document.getElementById(instructionsId).style.display;
	var selectOption;
	var addShowText = "";
	var addHideText = "";
	
	if (initialValue == "none")
	{
		selectOption = "show";
	} else {
		selectOption = "hide";
	}
	//forceOption causes override
	if (forceOption == "show")
	{
		selectOption = "show";
	}
	if (forceOption == "hide")
	{
		selectOption = "hide";
	}
	var newLinkText = reverseOption(selectOption);
	if(toggleText != null)
	{
		newLinkText = newLinkText + toggleText;
	}
	if(toggleLinkShowText != null || toggleLinkHideText != null)
	{
		newLinkText = "";
		addShowText = toggleLinkShowText;
		addHideText = toggleLinkHideText;
	}
	if (selectOption == "show")
	{
		document.getElementById(instructionsId).style.display="block";
		if(document.getElementById(linkId))
		{
			changeInnerHTML(document, linkId, newLinkText + addHideText);
		}
	} else {
		document.getElementById(instructionsId).style.display="none";
		if(document.getElementById(linkId))
		{
			changeInnerHTML(document, linkId, newLinkText + addShowText);
		}
	}
	return false;
}

function reverseOption(forceOption)
{
	var returnValue = "";
	if(forceOption == "show") {
		returnValue = "hide";
	}
	if(forceOption == "hide") {
		returnValue = "show";
	}
	return returnValue;
}

function inlineToggle(elementId, forceOption) {
	var initialValue = document.getElementById(elementId).style.display;
	var selectOption;
	if (initialValue == "none")
	{	
		selectOption = "show";
	} else {
		selectOption = "hide";
	}
	//forceOption causes override
	if (forceOption == "show")
	{	
		selectOption = "show";
	}
	if (forceOption == "hide") {
		selectOption = "hide";
	}
	
	if (selectOption == "show") {
		document.getElementById(elementId).style.display="inline";
	} else {
		document.getElementById(elementId).style.display="none";
	}
}

function checkboxToggle(instructionsId) {
	if ((document.getElementById(instructionsId).style.display=="none")  )
               {document.getElementById(instructionsId).style.display="block";}
	else
	{ document.getElementById(instructionsId).style.display="none" ;  }
}

function checkboxToggleWithVerify(instructionsId, checkboxElement) {
	if (checkboxElement.checked==true )
               {document.getElementById(instructionsId).style.display="block";}
	else
	{ document.getElementById(instructionsId).style.display="none" ;  }
}

function checkboxTest(instructionID, linkID) {

	if ((document.getElementById(linkID).checked="true")  )
        {	document.getElementById(instructionsId).style.display="block";	}
	else
	{      document.getElementById(instructionsId).style.display="none" ;      }
}

function Start(page, xDimension, yDimension, windowName) {
if(windowName==null)
{
	windowName="SecPage";
}
newExternalPage = window.open(page,windowName,"location=yes,resizable=yes,top=0,left=0,height=" + yDimension + ",width=" + xDimension + ",toolbar=yes,menubar=yes,scrollbars=yes,status=yes");
newExternalPage.focus();
}

//Advanced Email Check credit-
//By JavaScript Kit (http://www.javascriptkit.com)
//Over 200+ free scripts here!

function validateEmailAddress(idField){
	var testresults;
	var emailValue=document.getElementById(idField).value;
	var emailFilter=/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
	if (emailFilter.test(emailValue)) {
		testresults=true;
	}else{
		alert('Please input a valid email address');
		document.getElementById(idField).focus();
		testresults=false;
	}
	return (testresults);
}

//	addDropDownValue - takes a value from a dropdown box and adds it to a textarea
//	args:
//		idDropDown - the dropdown
//		idTextArea - the textarea
//
//	return value: none
//
function addDropDownValue(idDropDown, idTextArea)
{
	if(document.getElementById(idDropDown) && document.getElementById(idTextArea))
	{
		if(document.getElementById(idTextArea).value != "")
		{
			document.getElementById(idTextArea).value += "\n";
		}
		document.getElementById(idTextArea).value += document.getElementById(idDropDown).value;
	} else {
		alert("problem: " + idDropDown + " or " + idTextArea + " not found in javascript function addDropDownValue()");
	}
		 
}

//	formatClean - takes commas and other junk out of a string and returns it
//	args:
//		stringInput - string value containing number, zero or more commas
//
//	return value: stripped string
//
function formatClean(num)
{
	var sVal='';
	var nVal = num.length;
	var sChar='';
	var minus='-';
	
	//iterate through each character in the string, allowing only numbers and the period character into the result
	for(i=0;i<nVal;i++)
	{
		sChar = num.charAt(i);
		nChar = sChar.charCodeAt(0);
		//if((nChar==48){}
		if ((nChar >=48) && (nChar <=57))  { sVal += num.charAt(i);   }
		if (sChar=='.') {sVal += sChar;	}
	}
	var newsVal=sVal;
	if(Number(sVal)!=0)
	{
		for(i=0;i<sVal.length;i++)
		{
			sChar = sVal.charAt(i);
			nChar = sChar.charCodeAt(0);
			if(nChar!=48)
			{
				break;
			}
			else{
				newsVal=sVal.substring(i+1,sVal.length);
			}
		}
		sVal=newsVal;
	}
	
	//deal with empty string (bad input)
	if(sVal==''){sVal='0';}
	//add leading zero
	if(sVal.indexOf('.')==0) {sVal = '0' + sVal;}
	//deal with minus character
	if(num.indexOf(minus)==0) {sVal = minus + sVal;}
	//alert("result of formatClean function: " + sVal);
	return sVal;
}

//	cleanNumber - uses formatClean, then returns as a number instead of a string
//	args:
//		stringInput - string value containing number
//
//	return value: numeric representation for use in calculations
//
function cleanNumber(stringInput)
{
	return(Number(formatClean(stringInput)));
}

//	formatNumber - puts proper commas into numeric data
//	args:
//		num - guess
//		numFixedPrecision - how many digits to also display
//
//	return value: formatted string representation of number
//
function formatNumber(num, numFixedPrecision)
{
	var sVal='';
	var minus='-';
	var CommaDelimiter=',';
	var intVersion = 0;
	var numVersion = 0;
	var stringNum;
	
	intVersion = Math.abs(parseInt(num));
	if (numFixedPrecision == null) {
		numVersion = Math.abs(Number(num));
	} else {
		numVersion = Math.abs(Number(num)).toFixed(numFixedPrecision);
	}
	stringNum = new String(numVersion);
	
	var samount = new String(intVersion);
	for (var i = 0; i < Math.floor((samount.length-(1+i))/3); i++)
	{
		samount = samount.substring(0,samount.length-(4*i+3)) + CommaDelimiter + samount.substring(samount.length-(4*i+3));
	}
	if(stringNum.indexOf('.') > 0)
	{
		samount = samount + stringNum.substring(stringNum.indexOf('.'));
	}
	if(Number(num) < 0)
	{
		samount = minus + samount;
	}
	return(samount);
}

//	autoCleanInput - uses formatNumber and cleanNumber to prettify input in a text box
//	args:
//		inputElement - element with a value that can be cleaned
//		numFixedPrecision - optional number of digits after decimal point to show
//
//	return value: none
//
function autoCleanInput(inputElement, numFixedPrecision)
{
	if(numFixedPrecision==null) numFixedPrecision=0;
	var intermediateValue = inputElement.value;
	inputElement.value = formatNumber(cleanNumber(intermediateValue), numFixedPrecision);
	return;
}


// totalCells - add an array of named form cells and innerHTML cells and place in total column innerHTML
// args:
//  textboxArray - holds id values of all textbox cells to be totaled
//  spanArray - holds id values of span elements to be totaled
//  idResult - id value for span/textbox result element
//  numFixedPrecision - number of digits of precision after decimal point (optional)
//
// return value: result number put into idresult, which may be either a form field or a text box
//
function totalCells(textboxArray, spanArray, idResult, numFixedPrecision) {
	var intRunningTotal = 0;
	var strFormattedTotal = '';
	var decAfterRoundTotal = 0.00;

	//alert(intRunningTotal);
	
	//first add the text box array values
	if(textboxArray.length > 0) {
		for(var i=0; i < textboxArray.length; i++) {
			//alert(document.getElementById(textboxArray[i]).value);
			if(document.getElementById(textboxArray[i])){
				intRunningTotal += Number(formatClean(document.getElementById(textboxArray[i]).value));
				decAfterRoundTotal = roundNumber(intRunningTotal, 2);

				//change element value to include formatting
				if (numFixedPrecision == null) {
					document.getElementById(textboxArray[i]).value = formatNumber(formatClean(document.getElementById(textboxArray[i]).value));
				} else {
					document.getElementById(textboxArray[i]).value = formatNumber(formatClean(document.getElementById(textboxArray[i]).value), numFixedPrecision);
				}
			}
		}
	}
	
	//second add the span array values
	if(spanArray.length > 0) {
		for(var i=0; i < spanArray.length; i++) {
			if(document.getElementById(spanArray[i])){
				intRunningTotal += Number(formatClean(getInnerValue(spanArray[i])));
				decAfterRoundTotal = roundNumber(intRunningTotal, 2);

				//change element value to include formatting
				if (numFixedPrecision == null) {
					changeInnerHTML(document, spanArray[i], formatNumber(formatClean(getInnerValue(spanArray[i]), numFixedPrecision)));
				} else {
					changeInnerHTML(document, spanArray[i], formatNumber(formatClean(getInnerValue(spanArray[i]), numFixedPrecision)));
				}
			}
		}
	}
	
	//format total
	strFormattedTotal = formatNumber(decAfterRoundTotal, numFixedPrecision);
	
	//set value of total element
	if(document.getElementById(idResult))
	{
		changeInnerHTML(document, idResult, strFormattedTotal);
	} else {
		alert("total field " + idResult + " does not exist");
	}
	//alert(intRunningTotal);
	
	return(strFormattedTotal);
}
//	toggleVisibilitySilent - toggles visibility of an element, but does not change the link at all
//	args:
//		idToggleElement - what to switch on or off
//
//	return value: none
//
function toggleVisibilitySilent(idToggleElement)
{
	if(document.getElementById(idToggleElement).style["display"]=="none")
	{
		//show element
		document.getElementById(idToggleElement).style["display"]="block";
		return(true);
	} else {
		//hide element
		document.getElementById(idToggleElement).style["display"]="none";
		return(true);
	}
}
//
// dummy form spans and inputs, used in "spreadsheet" calculations
//
var dummy_form_spans = Array();
var dummy_form_inputs = Array();
var active_cell_color = "#aaffaa";
var inactive_cell_color = "transparent";

// setFollowersForPrinting - recursively propagate "checked" value down element chains
// args:
//  idBase - id of base element: follower elements will have this element plus '_#' or '_X_#'
//  showDialog - boolean to indicate whether to show a warning about possible execution length
//
function setFollowersForPrinting(idBase, showDialog) {
	if(showDialog!=null)
	{
		alert("This function may take some time to complete, please have patience if you have selected a large number of items to select or deselect.");
	}
	if(document.getElementById(idBase).getAttribute('numchildren') > 0) {
	  for(var i=0; i < document.getElementById(idBase).getAttribute('numchildren'); i++) {
	    if(document.getElementById(idBase + "_" + i)) {
	    	document.getElementById(idBase + "_" + i).checked = document.getElementById(idBase).checked;
	    	setFollowersForPrinting(idBase + "_" + i);
	    }
	    if(document.getElementById(idBase + "_X_" + i)) {
	    	document.getElementById(idBase + "_X_" + i).checked = document.getElementById(idBase).checked;
	    	setFollowersForPrinting(idBase + "_X_" + i);
	    }
	  }
	}
}
// checkColumnsForPrinting - ensures that the Question and Data columns are correctly turned on or off
// also calls setFollowersForPrinting to ensure correct propagation
// args:
// 	idQuestion - if unchecked, both must be unchecked
// 	idData - if checked, both must be checked
// 	selectedColumn - either "Question" or "Data"
//
function checkColumnsForPrinting(idQuestion, idData, selectedColumn) {
	if(selectedColumn=="Question") {
		if(document.getElementById(idQuestion).checked==false) {
			document.getElementById(idData).checked=false;
			setFollowersForPrinting(idData);
		}
	} else {
		if(document.getElementById(idData).checked==true) {
			document.getElementById(idQuestion).checked=true;
			setFollowersForPrinting(idQuestion);
		}
	}
}


//	addRowToFormTable - takes a table of form inputs and adds one more row
//	args:
//		idTableBase - base string for table and form elements
//		arrayElementIDs - array of elements to add to a total value
//		arrayName = actual name of the array
//
//	return value: none
//
function addRowToFormTable(idTableBase, arrayElementIDs, arrayName)
{
	var numRows;
	var numColumns;
	var cellIterator;
	var inputIterator;
	var rowIterator;
	var sumColumn;
	
	//ensure that all hidden identifiers for this table exist
	if(document.getElementById("Table_" + idTableBase) && document.getElementById("Hidden_" + idTableBase + "_NumRows") && document.getElementById("Hidden_" + idTableBase + "_NumColumns"))
	{
		//numRows = Number(document.getElementById("Hidden_" + idTableBase + "_NumRows").value);
		numRows = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length;
		//alert("Number of rows: " + numRows);
		numColumns = Number(document.getElementById("Hidden_" + idTableBase + "_NumColumns").value);
		//alert("Column number id: Hidden_" + idTableBase + "_NumColumns");
		//alert("Number of columns: " + numColumns);
		rowIterator = document.createElement("tr");
		
		//which column is the sum?  Default is last
		if(document.getElementById("Hidden_" + idTableBase + "_SumColumn"))
		{
			sumColumn = Number(document.getElementById("Hidden_" + idTableBase + "_SumColumn").value);
		} else {
			sumColumn = numColumns - 1;
		}
		
		//prepare the column elements
		for(var i = 0; i < numColumns; i++)
		{
			cellIterator = document.createElement("td");
			inputIterator = document.createElement("input");
			inputIterator.setAttribute("type", "text");
			inputIterator.setAttribute("id", "Post_" + idTableBase + "_" + numRows + "_" + document.getElementById("Hidden_" + idTableBase + "_Column_" + i).value);
			inputIterator.setAttribute("name", "Post_" + idTableBase + "_" + numRows + "_" + document.getElementById("Hidden_" + idTableBase + "_Column_" + i).value);
			if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_Size"))
			{
				inputIterator.setAttribute("size", Number(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_Size").value));
				if(Number(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_Size").value) < 10)
				{
					//alert("setting style text-align: right on Post_" + idTableBase + "_" + numRows + "_" + document.getElementById("Hidden_" + idTableBase + "_Column_" + i).value);
					inputIterator.setAttribute("style", "text-align:right;");
				}
			} else {
				inputIterator.setAttribute("size", 20);
			}
			if(i == sumColumn)
			{
				if((arrayElementIDs != null) && (arrayName))
				{
				//make sure to add JS totaling function
				inputIterator.setAttribute("onBlur", "totalCells(" + arrayName + ", dummy_form_spans, 'Form_" + idTableBase + "_Total');");
				}
			}
			
			inputIterator.value = "";
			//alert("adding form input Post_" + idTableBase + "_" + numRows + "_" + document.getElementById("Hidden_" + idTableBase + "_Column_" + i));
			cellIterator.appendChild(inputIterator);
			rowIterator.appendChild(cellIterator);
		}
		document.getElementById("Table_" + idTableBase).tBodies[0].appendChild(rowIterator);
		if(document.getElementById("PROGRAM_20052006_P3Q1_testoutput"))
		{
			//special testing function
			document.getElementById("PROGRAM_20052006_P3Q1_testoutput").value=getInnerValue("Table_" + idTableBase);
			document.getElementById("PROGRAM_20052006_P3Q1_testoutput").style["display"]="block";
		}
		
		//increment number of rows
		numRows = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length;
		
		//set hidden number of rows
		document.getElementById("Hidden_" + idTableBase + "_NumRows").value = numRows;
		
		
		//deal with array, we have to push the new element onto it
		if(arrayElementIDs != null)
		{
			//alert("adding element Post_" + idTableBase + "_" + (numRows-1) + "_" + document.getElementById("Hidden_" + idTableBase + "_Column_" + (numColumns - 1)).value + " to array;");
			arrayElementIDs.push("Post_" + idTableBase + "_" + (numRows-1) + "_" + document.getElementById("Hidden_" + idTableBase + "_Column_" + (numColumns - 1)).value);
		}
		
	} else {
		return;
	}
}

//	deleteRowFromFormTable - removes the last row in a table
//	args:
//		idTableBase - base string for table and form elements
//		arrayElementIDs - array of elements to add to a total value
//
//	return value: none
//
function deleteRowFromFormTable(idTableBase, arrayElementIDs)
{
	var numRows, numColumns;
	var lastRow;
	var lastRowNum;
	var numMinRows;
	
	
	//ensure that all hidden identifiers for this table exist
	if(document.getElementById("Table_" + idTableBase) && document.getElementById("Hidden_" + idTableBase + "_NumRows") && document.getElementById("Hidden_" + idTableBase + "_NumColumns"))
	{
		//numRows = Number(document.getElementById("Hidden_" + idTableBase + "_NumRows").value);
		numRows = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length;
		numColumns = Number(document.getElementById("Hidden_" + idTableBase + "_NumColumns").value);
		if(document.getElementById("Hidden_" + idTableBase + "_MinRows"))
		{
			numMinRows = Number(document.getElementById("Hidden_" + idTableBase + "_MinRows").value);
		} else {
			numMinRows = 0;
		}
		if(document.getElementById("Table_" + idTableBase).tBodies[0].rows.length == numMinRows)
		{
			alert("Sorry, no more rows exist to remove.");
			return;
		}
		lastRowNum = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length - 1;
		lastRow = document.getElementById("Table_" + idTableBase).tBodies[0].rows[lastRowNum];
		document.getElementById("Table_" + idTableBase).tBodies[0].removeChild(lastRow);
		
		//decrement number of rows
		numRows = lastRowNum;
		
		//set hidden number of rows
		document.getElementById("Hidden_" + idTableBase + "_NumRows").value = numRows;
		
		//pop last element off array
		if(arrayElementIDs)
		{
			arrayElementIDs.pop();
		}
		
		for(var r = 0; r < numRows; r++)
		{
			//set Link cell
			document.getElementById("Cell_" + idTableBase + "_" + r + "_Link").style["background"] = inactive_cell_color;
			
			//set other cells
			for(var i = 0; i < numColumns; i++)
			{
				document.getElementById("Cell_" + idTableBase + "_" + r + "_" + i).style["background"] = inactive_cell_color;
			}
		}
		
		//if form exists, mess with insides
		if(document.getElementById("Table_" + idTableBase + "_Edit"))
		{
			//hide
			document.getElementById("Table_" + idTableBase + "_Edit").style["display"] = "none";
			
			//make it inactive
			document.getElementById("Table_" + idTableBase + "_Edit").style["background"] = inactive_cell_color;
			
			//hide modify link
			document.getElementById("Button_" + idTableBase + "_UpdateRow").style["display"] = "none";
		}
		
	} else {
		return;
	}
}

//	validateHiddenFormTableInputs - alerts user and stops updates to hidden form tables if validation checks fail
//	args:
//		idTableBase - base string for table and form elements
//
//	return value: true/false depending on validation
//
function validateHiddenFormTableInputs(idTableBase)
{
	var outputValue = true;
	var numColumns;
	//ensure that all hidden identifiers for this table exist
	//alert("starting function validateHiddenFormTableInputs() with idTableBase of " + idTableBase);
	try
	{
		if(document.getElementById("Hidden_" + idTableBase + "_NumColumns"))
		{
			numColumns = Number(document.getElementById("Hidden_" + idTableBase + "_NumColumns").value);
			for(var i = 0; i < numColumns; i++)
			{
				//alert("typeof input with name " + document.getElementById("Hidden_" + idTableBase + "_Column_" + i).value + ":\n\n" + typeof(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value")));
				if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_JSValidateRule"))
				{
					//alert("type of element Hidden_" + idTableBase + "_Column_" + i + "_JSValidateRule is... ");
					//alert(typeof(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_JSValidateRule")));
					//alert("column " + i + " appears to have a validation rule of " + document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_JSValidateRule").value);
					if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_JSValidateRule").value == "Email")
					{
						outputValue = validateEmailAddress("Form_" + idTableBase + "_Column_" + i + "_Value");
					}
					if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_AncillaryValueUtility"))
					{
						if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_AncillaryValueUtility").value == "Email")
						{
							outputValue = validateEmailAddress("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue");
						}
					}
					else if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_JSValidateRule").value == "Date")
					{
						outputValue = validateDateById("Form_" + idTableBase + "_Column_" + i + "_Value", document.getElementById("Hidden_" + idTableBase + "_Column_" + i).value);
					}
					else if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_JSValidateRule").value == "Required")
					{
						outputValue = validateRequiredById("Form_" + idTableBase + "_Column_" + i + "_Value");
					}
					if(outputValue == false)
					{
						//return immediately
						return outputValue;
					}
				}
			}
		}
	}
	catch(err)
	{
		alert("Error was found in function validateHiddenFormTableInputs() for idTableBase of " + idTableBase + "\n\nError message:\n\n" + err.message);
		outputValue = false;
	}
	dynamicVariables_Dictionary[idTableBase + "_FormValidation"] = outputValue;
	return outputValue;
}

//	validateRequiredById - forces the user to enter input in a particular input field
//	args:
//		idValue - full ID of the form input
//
//	return value: true/false depending on validation
//
function validateRequiredById(idValue)
{
	try
	{
		var inputExists = true;
		//alert("running function validateRequiredById on input " + idValue);
		if(document.getElementById(idValue).value == "")
		{
			inputExists = false;
			//alert("You must enter data in this field.");
			alert("You must enter data in this field.\n\n" + idValue);
			document.getElementById(idValue).focus();
		}
	}
	catch(err)
	{
		alert("error in function validateRequiredById() with input " + idValue);
	}
	return inputExists;
}

/**
 * DHTML date validation script for mm/dd/yyyy. Courtesy of SmartWebby.com (http://www.smartwebby.com/dhtml/)
 */


function isInteger(s){
	var i;
    for (i = 0; i < s.length; i++){   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}

function stripCharsInBag(s, bag){
	var i;
    var returnString = "";
    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++){   
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function daysInFebruary (year){
	// February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}
function DaysArray(n) {
	for (var i = 1; i <= n; i++) {
		this[i] = 31;
		if (i==4 || i==6 || i==9 || i==11) {this[i] = 30};
		if (i==2) {this[i] = 29};
   } 
   return this;
}

function isDate(dtStr, strDateName, warnUser){
	// Declaring valid date character, minimum year and maximum year
	var dtCh= "/";
	var minYear=1900;
	var maxYear=2100;
	var daysInMonth = DaysArray(12);
	var pos1=dtStr.indexOf(dtCh);
	var pos2=dtStr.indexOf(dtCh,pos1+1);
	var strDay=dtStr.substring(pos1+1,pos2);
	var strMonth=dtStr.substring(0,pos1);
	//var strDay=dtStr.substring(0,pos1)
	//var strMonth=dtStr.substring(pos1+1,pos2)
	var strYear=dtStr.substring(pos2+1);
	if(warnUser == null)
	{
	    warnUser = true;
	}
	strYr=strYear;
	if (strDay.charAt(0)=="0" && strDay.length>1) strDay=strDay.substring(1);
	if (strMonth.charAt(0)=="0" && strMonth.length>1) strMonth=strMonth.substring(1);
	for (var i = 1; i <= 3; i++) {
		if (strYr.charAt(0)=="0" && strYr.length>1) strYr=strYr.substring(1);
	}
	month=parseInt(strMonth);
	day=parseInt(strDay);
	year=parseInt(strYr);
	if (pos1==-1 || pos2==-1){
		if(warnUser == true) alert("(" + strDateName + ") The date format should be : mm/dd/yyyy");
		return false;
	}
	if (strMonth.length<1 || month<1 || month>12){
		if(warnUser == true) alert("(" + strDateName + ") Please enter a valid month");
		return false;
	}
	if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
		if(warnUser == true) alert("(" + strDateName + ") Please enter a valid day");
		return false;
	}
	if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
		if(warnUser == true) alert("(" + strDateName + ") Please enter a valid 4 digit year between "+minYear+" and "+maxYear);
		return false;
	}
	if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
		if(warnUser == true) alert("(" + strDateName + ") Please enter a valid date");
		return false;
	}
return true;
}

//	validateDateById - tries to validate a string in an input field as proper date data, and focuses on it if validation fails
//	args:
//		idValue - full ID of the form input
//		inputName - a descriptive name for the input
//
//	return value: true/false depending on validation
//
function validateDateById(idValue, inputName)
{
	var dateIsValid = true;
	if(isDate(document.getElementById(idValue).value, inputName) == false)
	{
		dateIsValid = false;
		document.getElementById(idValue).focus();
	}
	return dateIsValid;
}

//	addRowToHiddenFormTable - takes a table of literals with hidden form inputs and adds one more row
//	args:
//		idTableBase - base string for table and form elements
//		arrayElementIDs - array of elements to add to a total value
//		arrayName = actual name of the array
//
//	return value: false
//
function addRowToHiddenFormTable(idTableBase, arrayElementIDs, arrayName)
{
	var numRows, numColumns, sumColumn, thisColumnIndex;
	var cellIterator;
	var inputIterator;
	var rowIterator;
	var textIterator;
	var spanIterator;
	var containerIterator;
	var linkIterator;
	var thisColumnValue, thisColumnDisplayValue, thisColumnName;
	var createDisplayInput = false;
	var triggerRunningTotal = false;
	
	triggerRunningTotal = false;
	try
	{
	    //first step is validation
	    if(validateHiddenFormTableInputs(idTableBase))
	    {
		    //ensure that all hidden identifiers for this table exist
		    if(document.getElementById("Table_" + idTableBase) && document.getElementById("Hidden_" + idTableBase + "_NumRows") && document.getElementById("Hidden_" + idTableBase + "_NumColumns"))
		    {
			    //numRows = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length;
			    numRows = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length;
			    //alert("Number of rows: " + numRows);
			    numColumns = Number(document.getElementById("Hidden_" + idTableBase + "_NumColumns").value);
			    //alert("Column number id: Hidden_" + idTableBase + "_NumColumns");
			    //alert("Number of columns: " + numColumns);
			    rowIterator = document.createElement("tr");
    			
			    //which column is the sum?  Default is last
			    if(document.getElementById("Hidden_" + idTableBase + "_SumColumn"))
			    {
				    sumColumn = Number(document.getElementById("Hidden_" + idTableBase + "_SumColumn").value);
				    //even if there's not a running total column, we want to get the sum
				    triggerRunningTotal = true;
			    } else {
				    sumColumn = numColumns - 1;
			    }
    			
			    //each row has an edit link
			    cellIterator = document.createElement("td");
			    cellIterator.setAttribute("id", "Cell_" + idTableBase + "_" + numRows + "_Link");
			    cellIterator.style["margin-left"] = "5px";
			    cellIterator.style["margin-right"] = "5px";
    			
			    linkIterator = document.createElement("a");
			    linkIterator.id = "Link_" + idTableBase + "_" + numRows + "_Edit";
			    linkIterator.setAttribute("href", "#");
    			
			    if(document.getElementById("Hidden_" + idTableBase + "_JSFireOnEdit"))
				    {
					    attachEventHandlerToElement(linkIterator, "onclick", "editRowInHiddenFormTable('" + idTableBase + "', " + numRows + ");" + document.getElementById("Hidden_" + idTableBase + "_JSFireOnEdit").value);
				    } else {
					    attachEventHandlerToElement(linkIterator, "onclick", "return editRowInHiddenFormTable('" + idTableBase + "', " + numRows + ");");
				    }
			    textIterator = document.createTextNode("edit");
			    linkIterator.appendChild(textIterator);
			    cellIterator.appendChild(linkIterator);
    			
			    //add a hidden editable field
			    inputIterator = document.createElement("input");
			    inputIterator.setAttribute("type", "hidden");
			    inputIterator.setAttribute("id", "Hidden_" + idTableBase + "_" + numRows + "_EditStatus");
			    inputIterator.setAttribute("name", "Hidden_" + idTableBase + "_" + numRows + "_EditStatus");
			    inputIterator.value = "True";
			    cellIterator.appendChild(inputIterator);
    			
			    if(document.getElementById("Hidden_" + idTableBase + "_AllowDelete"))
			    {
				    //add a link to delete
				    textIterator = document.createTextNode(" | ");
				    cellIterator.appendChild(textIterator);
    				
				    linkIterator = document.createElement("a");
				    linkIterator.id = "Link_" + idTableBase + "_" + numRows + "_Delete";
				    linkIterator.setAttribute("href", "#");
				    if(document.getElementById("Hidden_" + idTableBase + "_JSFireOnDelete"))
				    {
					    attachEventHandlerToElement(linkIterator, "onclick", "removeRowFromHiddenFormTable('" + idTableBase + "', " + numRows + ");" + document.getElementById("Hidden_" + idTableBase + "_JSFireOnDelete").value);
				    } else {
					    attachEventHandlerToElement(linkIterator, "onclick", "return removeRowFromHiddenFormTable('" + idTableBase + "', " + numRows + ");");
				    }
				    textIterator = document.createTextNode("del");
				    linkIterator.appendChild(textIterator);
				    cellIterator.appendChild(linkIterator);
    				
			    }
			    if(document.getElementById("Hidden_" + idTableBase + "_PopulateID"))
			    {
				    //add a hidden ID field and populate from table
				    inputIterator = document.createElement("input");
				    inputIterator.setAttribute("type", "hidden");
				    inputIterator.setAttribute("id", "Hidden_" + idTableBase + "_" + numRows + "_ID");
				    inputIterator.setAttribute("name", "Hidden_" + idTableBase + "_" + numRows + "_ID");
				    inputIterator.value = document.getElementById("Form_" + idTableBase + "_ID_Value").value;
				    cellIterator.appendChild(inputIterator);
			    }
    			
			    //add initial cell to row
			    rowIterator.appendChild(cellIterator);
    			
			    //prepare the column elements
			    for(var i = 0; i < numColumns; i++)
			    {
				    thisColumnName = document.getElementById("Hidden_" + idTableBase + "_Column_" + i).value;
				    cellIterator = document.createElement("td");
				    cellIterator.setAttribute("id", "Cell_" + idTableBase + "_" + numRows + "_" + i);
				    inputIterator = document.createElement("input");
				    inputIterator.setAttribute("type", "hidden");
				    inputIterator.setAttribute("id", "Hidden_" + idTableBase + "_" + numRows + "_" + thisColumnName);
				    inputIterator.setAttribute("name", "Hidden_" + idTableBase + "_" + numRows + "_" + thisColumnName);
				    if(thisColumnName=="RunningTotal")
				    {
					    //we will want to do the running total later
					    triggerRunningTotal = true;
				    }
				    //check for existing value
				    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value"))
				    {
					    thisColumnValue = document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value").value;
					    thisColumnDisplayValue = thisColumnValue;
					    //special rules for dropdown
					    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value").options)
					    {
						    thisColumnIndex = document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value").selectedIndex;
						    thisColumnDisplayValue = document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value").options[thisColumnIndex].text;
						    createDisplayInput = true;
					    } else {
						    createDisplayInput = false;
					    }
					    //alert("setting column value for column " + i + " to " + thisColumnValue);
				    } else {
					    thisColumnValue = "";
					    thisColumnDisplayValue = "";
				    }
    				
				    inputIterator.value = thisColumnValue;
				    //add a container into which all the display-related stuff will be inserted
				    //this may wind up as a link or a span depending on hidden inputs
				    if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_AncillaryValueUtility"))
				    {
					    switch(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_AncillaryValueUtility").value)
					    {
					    case "Email":
						    containerIterator = document.createElement("a");
						    containerIterator.setAttribute("id", "Link_" + idTableBase + "_" + numRows + "_"  + thisColumnName);
						    containerIterator.setAttribute("href", "mailto:" + document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue").value);
						    break;
					    case "Mouseover":
					        containerIterator = document.createElement("span");
					        containerIterator.setAttribute("id", "Span_" + idTableBase + "_" + numRows + "_"  + thisColumnName + "_Mouseover");
					        containerIterator.setAttribute("title", document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue").value);
					        break;
					    case "MouseoverLink":
					        containerIterator = document.createElement("a");
						    containerIterator.setAttribute("id", "Link_" + idTableBase + "_" + numRows + "_"  + thisColumnName);
						    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue2").value.indexOf("[MoveStoredFile=True]")>-1)
						    {
						        containerIterator.setAttribute("href", "#");
						    } else {
						        containerIterator.setAttribute("href", document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue2").value);
						    }
						    containerIterator.setAttribute("title", document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue").value);
						    break;
					    case "MouseoverEmail":
					        containerIterator = document.createElement("a");
						    containerIterator.setAttribute("id", "Link_" + idTableBase + "_" + numRows + "_"  + thisColumnName);
						    containerIterator.setAttribute("href", "mailto:" + document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue2").value);
						    containerIterator.setAttribute("title", document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue").value);
						    break;
					    default:
						    containerIterator = document.createElement("span");
					    }
				    } else {
					    containerIterator = document.createElement("span");
				    }
    				
				    //add the text to the cell before adding the input
				    //we will use a span because that gives us element control later
				    spanIterator = document.createElement("span");
				    spanIterator.setAttribute("id", "Span_" + idTableBase + "_" + numRows + "_"  + thisColumnName);
				    //alert("setting id of span to Span_" + idTableBase + "_" + numRows + "_"  + thisColumnName + ": actual value is " + spanIterator.getAttribute("id"));
				    textIterator = document.createTextNode(thisColumnDisplayValue);
				    spanIterator.appendChild(textIterator);
				    containerIterator.appendChild(spanIterator);
    				
				    //alert("adding form input Post_" + idTableBase + "_" + numRows + "_" + document.getElementById("Hidden_" + idTableBase + "_Column_" + i));
				    cellIterator.appendChild(inputIterator);
    				
				    if(createDisplayInput == true)
				    {
					    //also create a hidden display input
					    inputIterator = document.createElement("input");
					    inputIterator.setAttribute("type", "hidden");
					    inputIterator.setAttribute("id", "Hidden_" + idTableBase + "_" + numRows + "_" + thisColumnName + "_Display");
					    inputIterator.setAttribute("name", "Hidden_" + idTableBase + "_" + numRows + "_" + thisColumnName + "_Display");
					    inputIterator.value = thisColumnDisplayValue;
					    cellIterator.appendChild(inputIterator);
				    }
				    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue"))
				    {
					    //create hidden ancillary input
					    inputIterator = document.createElement("input");
					    inputIterator.setAttribute("type", "hidden");
					    inputIterator.setAttribute("id", "Hidden_" + idTableBase + "_" + numRows + "_" + thisColumnName + "_Ancillary");
					    inputIterator.setAttribute("name", "Hidden_" + idTableBase + "_" + numRows + "_" + thisColumnName + "_Ancillary");
					    inputIterator.value = document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue").value;
					    cellIterator.appendChild(inputIterator);
					    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue2"))
					    {
					        //secondary ancillary hidden input
					        inputIterator = document.createElement("input");
					        inputIterator.setAttribute("type", "hidden");
					        inputIterator.setAttribute("id", "Hidden_" + idTableBase + "_" + numRows + "_" + thisColumnName + "_Ancillary2");
					        inputIterator.setAttribute("name", "Hidden_" + idTableBase + "_" + numRows + "_" + thisColumnName + "_Ancillary2");
					        inputIterator.value = document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue2").value;
					        cellIterator.appendChild(inputIterator);					    
					    }
				    }
    				
				    cellIterator.appendChild(containerIterator);
    				
				    rowIterator.appendChild(cellIterator);
			    }
			    document.getElementById("Table_" + idTableBase).tBodies[0].appendChild(rowIterator);
    			
			    //increment number of rows
			    numRows = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length;
    			
			    //set hidden number of rows
			    document.getElementById("Hidden_" + idTableBase + "_NumRows").value = numRows;
			    //alert("setting number of rows to " + document.getElementById("Hidden_" + idTableBase + "_NumRows").value);
    			
			    //deal with array, we have to push the new element onto it
			    if(arrayElementIDs != null)
			    {
				    //alert("adding element Post_" + idTableBase + "_" + (numRows-1) + "_" + document.getElementById("Hidden_" + idTableBase + "_Column_" + (numColumns - 1)).value + " to array;");
				    arrayElementIDs.push("Hidden_" + idTableBase + "_" + (numRows-1) + "_" + document.getElementById("Hidden_" + idTableBase + "_Column_" + (numColumns - 1)).value);
			    }
			    if(triggerRunningTotal == true)
			    {
				    //trigger running total function, uses id base
					    calculateRunningTotal(idTableBase);
			    }
    			
			    //deal with colors; none should be selected and the form should also be inactive
			    for(var r = 0; r < numRows; r++)
			    {
				    //set Link cell
				    document.getElementById("Cell_" + idTableBase + "_" + r + "_Link").style["background"] = inactive_cell_color;
    				
				    //set other cells
				    for(var i = 0; i < numColumns; i++)
				    {
					    document.getElementById("Cell_" + idTableBase + "_" + r + "_" + i).style["background"] = inactive_cell_color;
				    }
			    }
    			
			    //ensure that the form is set to match the row color
			    document.getElementById("Table_" + idTableBase + "_Edit").style["background"] = inactive_cell_color;
    			
			    //set current row hidden value
			    document.getElementById("Hidden_" + idTableBase + "_CurrentRow").value = "";
    			
			    //hide the update link
			    document.getElementById("Button_" + idTableBase + "_AddRow").style["display"] = "none";
    			
			    //hide the form
			    document.getElementById("Table_" + idTableBase + "_Edit").style["display"] = "none";
		    } else {
			    alert("some of the objects were not found!");
		    }
	    }
    } catch(err) {
        alert("error in function addRowToHiddenFormTable(): " + err.message);
    }
	return false;
}


//	editRowInHiddenFormTable - uses a row in a hidden form table to populate a set of form fields
//	args:
//		idTableBase - base string for table and form elements
//		currentRow - 0-based indexer of what row to edit
//
//	return value: false
//
function editRowInHiddenFormTable(idTableBase, currentRow)
{
	var numColumns, numRows;
	var thisColumnName, thisColumnValue, thisRowColor;
	
	try
	{
	    //ensure that all hidden identifiers for this table exist
	    if(document.getElementById("Table_" + idTableBase) && document.getElementById("Hidden_" + idTableBase + "_NumRows") && document.getElementById("Hidden_" + idTableBase + "_NumColumns"))
	    {
		    numRows = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length;
		    numColumns = Number(document.getElementById("Hidden_" + idTableBase + "_NumColumns").value);
    		
		    //iterate through each column
		    for(var i = 0; i < numColumns; i++)
		    {
			    //get column name
			    thisColumnName = document.getElementById("Hidden_" + idTableBase + "_Column_" + i).value;
    			
			    //get column value
			    thisColumnValue = document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_" + thisColumnName).value;
    			
			    //assign to form input
			    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value"))
			    {
				    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value").value = thisColumnValue;
			    }
			    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue"))
			    {
				    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue").value = document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_" + thisColumnName + "_Ancillary").value;
				    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue2"))
				    {
				        document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue2").value = document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_" + thisColumnName + "_Ancillary2").value;
				    }
			    }
			    if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_SpecialEditDistribution"))
			    {
				    if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_SpecialEditDistribution").value=="Phone")
				    {
					    //phone values split into four inputs based on string manipulation
					    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value_1").value = thisColumnValue.substring(1, 4);
					    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value_2").value = thisColumnValue.substring(6, 9);
					    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value_3").value = thisColumnValue.substring(10, 14);
					    if(thisColumnValue.length > 15) {
						    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value_4").value = thisColumnValue.substring(16);
					    }
				    }
			    }
		    }
    		
		    //mark this row with a different color and reset the others to inactive
		    for(var r = 0; r < numRows; r++)
		    {
			    if(r == currentRow)
			    {
				    //set to active
				    thisRowColor = active_cell_color;
			    } else {
				    //set to inactive
				    thisRowColor = inactive_cell_color;
			    }
			    //alert("set row " + r + " color to " + thisRowColor);
    			
			    //set Link cell
			    document.getElementById("Cell_" + idTableBase + "_" + r + "_Link").style["background"] = thisRowColor;
    			
			    //alert("background set to: " + document.getElementById("Cell_" + idTableBase + "_" + r + "_Link").style["background"]);
    			
			    //set other cells
			    for(var i = 0; i < numColumns; i++)
			    {
				    if(document.getElementById("Cell_" + idTableBase + "_" + r + "_" + i))
				    {
					    document.getElementById("Cell_" + idTableBase + "_" + r + "_" + i).style["background"] = thisRowColor;
				    } else {
					    alert("Could not find Cell_" + idTableBase + "_" + r + "_" + i + " in function editRowInHiddenFormTable().  Please alert system administrators of a Javascript problem.");
				    }
			    }
		    }
    		
		    //make the editing table visible
		    document.getElementById("Table_" + idTableBase + "_Edit").style["display"] = "block";
    		
		    //ensure that the form is set to match the row color
		    document.getElementById("Table_" + idTableBase + "_Edit").style["background"] = active_cell_color;
    		
		    //focus on the edit form
		    document.getElementById("Table_" + idTableBase + "_Edit").focus();
    		
		    //ensure that the modify link shows up
		    document.getElementById("Button_" + idTableBase + "_UpdateRow").style["display"] = "inline";
    		
		    //ensure that the add link dosen't
		    document.getElementById("Button_" + idTableBase + "_AddRow").style["display"] = "none";
    		
		    //set current row hidden value
		    document.getElementById("Hidden_" + idTableBase + "_CurrentRow").value = currentRow;
    		
	    } else {
    		
	    }
    } catch(err) {
        alert("error in function editRowInHiddenFormTable(): " + err.message);
    }
	return false;
}

//	updateRowInHiddenFormTable - populates hidden and displayed data in a table row based on form inputs
//	args:
//		idTableBase - base string for table and form elements
//
//	return value: false
//
function updateRowInHiddenFormTable(idTableBase)
{
	var numColumns, numRows, currentRow, thisColumnIndex;
	var thisColumnName, thisColumnValue, thisColumnDisplayValue, thisRowColor;
	//alert("DEBUG: beginning function updateRowInHiddenFormTable()");
	try
	{
	    //first step is validation
	    if(validateHiddenFormTableInputs(idTableBase))
	    {
		    //ensure that all hidden identifiers for this table exist
		    if(document.getElementById("Table_" + idTableBase) && document.getElementById("Hidden_" + idTableBase + "_NumRows") && document.getElementById("Hidden_" + idTableBase + "_NumColumns"))
		    {
			    numRows = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length;
			    numColumns = Number(document.getElementById("Hidden_" + idTableBase + "_NumColumns").value);
			    currentRow = Number(document.getElementById("Hidden_" + idTableBase + "_CurrentRow").value);
    			
			    //iterate through each column
			    for(var i = 0; i < numColumns; i++)
			    {
				    //alert("DEBUG: processing column " + i + ", name " + document.getElementById("Hidden_" + idTableBase + "_Column_" + i).value);
				    if(document.getElementById("Hidden_" + idTableBase + "_ID_Value"))
				    {
					    //set hidden ID field value
					    //get column value
					    thisColumnValue = document.getElementById("Form_" + idTableBase + "_ID_Value").value;
    					
					    //assign to hidden input
					    document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_ID").value = thisColumnValue;
				    }
				    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value"))
				    {
					    //get column name
					    thisColumnName = document.getElementById("Hidden_" + idTableBase + "_Column_" + i).value;
    					
					    //get column value
					    thisColumnValue = document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value").value;
					    thisColumnDisplayValue = thisColumnValue;
    					
					    //special case, dropdown has a display that is different
					    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value").options)
					    {
						    thisColumnIndex = document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value").selectedIndex;
						    thisColumnDisplayValue = document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value").options[thisColumnIndex].text;
						    //update display input value
						    document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_" + thisColumnName + "_Display").value = thisColumnDisplayValue;
					    }
    					
					    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue"))
					    {
						    //update display input value
						    document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_" + thisColumnName + "_Ancillary").value = document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue").value;
						    switch(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_AncillaryValueUtility").value)
						    {
						    case "Email":
							    //change link href
							    document.getElementById("Link_" + idTableBase + "_" + currentRow + "_" + thisColumnName).setAttribute("href", "mailto:" + document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_" + thisColumnName + "_Ancillary").value);
							    break;
					        case "Mouseover":
					            //change title
					            document.getElementById("Span_" + idTableBase + "_" + currentRow + "_" + thisColumnName + "_Mouseover").setAttribute("title", document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue").value);
					            break;
						    case "MouseoverLink":
							    //change link href and title
							    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue2").value.indexOf("[MoveStoredFile=True]")>-1)
							    {
							        document.getElementById("Link_" + idTableBase + "_" + currentRow + "_" + thisColumnName).setAttribute("href", "#");
							    } else {
							        document.getElementById("Link_" + idTableBase + "_" + currentRow + "_" + thisColumnName).setAttribute("href", document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_" + thisColumnName + "_Ancillary2").value);
							    }
							    document.getElementById("Link_" + idTableBase + "_" + currentRow + "_" + thisColumnName).setAttribute("title", document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue").value);
							    //change secondary ancillary value
							    document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_" + thisColumnName + "_Ancillary2").value = document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue2").value;
							    break;
					        case "MouseoverEmail":
							    //change link href and title
							    document.getElementById("Link_" + idTableBase + "_" + currentRow + "_" + thisColumnName).setAttribute("href", "mailto:" + document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_" + thisColumnName + "_Ancillary2").value);
							    document.getElementById("Link_" + idTableBase + "_" + currentRow + "_" + thisColumnName).setAttribute("title", document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue").value);
							    //change secondary ancillary value
							    document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_" + thisColumnName + "_Ancillary2").value = document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue2").value;
							    break;
					        default:
						    }
					    }
					    //alert("DEBUG: value " + thisColumnValue + ", display value " + thisColumnDisplayValue);
    					
					    //assign to hidden input
					    if(document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_" + thisColumnName)) document.getElementById("Hidden_" + idTableBase + "_" + currentRow + "_" + thisColumnName).value = thisColumnValue;
    					
					    //assign to display span
					    if(document.getElementById("Span_" + idTableBase + "_" + currentRow + "_" + thisColumnName).childNodes[0]) document.getElementById("Span_" + idTableBase + "_" + currentRow + "_" + thisColumnName).childNodes[0].nodeValue = thisColumnDisplayValue;
    					
				    }
				    //change cells on selected rows back to normal
				    document.getElementById("Cell_" + idTableBase + "_" + currentRow + "_" + i).style["background"] = inactive_cell_color;
			    }
			    //alert("DEBUG: all updates to cells complete");
			    //change link row cell
			    document.getElementById("Cell_" + idTableBase + "_" + currentRow + "_Link").style["background"] = inactive_cell_color;
    			
			    //do running total
			    calculateRunningTotal(idTableBase);
    			
			    //hide update button
			    document.getElementById("Button_" + idTableBase + "_UpdateRow").style["display"] = "none";
    			
			    //hide editing table
			    document.getElementById("Table_" + idTableBase + "_Edit").style["display"] = "none";
    			
    			
    			
			    return false;
    			
		    } else {
			    return false;
		    }
	    }
	} catch(err) {
        alert("error in function updateRowInHiddenFormTable(): " + err.message + " (current row: " + currentRow + ")");
    }
	return false;
}

//	removeRowFromHiddenFormTable - removes an arbitrary row in a table
//	args:
//		idTableBase - base string for table and form elements
//		removeRowNum - which row to remove?
//		arrayElementIDs - array object containing IDs of elements
//
//	return value: false
//
function removeRowFromHiddenFormTable(idTableBase, removeRowNum, arrayElementIDs)
{
	var numRows, numColumns;
	var removeRow;
	var lastRowNum;
	var numMinRows;
	var cellIterator;
	var linkIterator;
	var inputIterator;
	var spanIterator;
	var thisColumnName;
	//confirmation
	if(!confirm("Are you sure you wish to remove this row of data?  Your changes will not be saved until the Question is saved."))
	{
		return false;
	}
	try
	{
	
	    var appVer = getInternetExplorerVersion();
	    if(appVer >= 7.0)
	    {
	        //alert("Sorry, Internet Explorer 7 has a bug that interferes with the deletion code you are attempting to activate.  In order to delete this row of data, please switch to Opera, Firefox, another non-IE browser or an earlier version of Internet Explorer.  We hope to have this issue resolved soon, when it does this message will go away.");
	        //return false;
	    }
    	
	    //ensure that all hidden identifiers for this table exist
	    if(document.getElementById("Table_" + idTableBase) && document.getElementById("Hidden_" + idTableBase + "_NumRows") && document.getElementById("Hidden_" + idTableBase + "_NumColumns"))
	    {
		    //numRows = Number(document.getElementById("Hidden_" + idTableBase + "_NumRows").value);
		    numRows = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length;
		    numColumns = Number(document.getElementById("Hidden_" + idTableBase + "_NumColumns").value);
		    //alert("start remove process");
		    if(document.getElementById("Hidden_" + idTableBase + "_MinRows"))
		    {
			    numMinRows = Number(document.getElementById("Hidden_" + idTableBase + "_MinRows").value);
		    } else {
			    numMinRows = 0;
		    }
		    if(document.getElementById("Table_" + idTableBase).tBodies[0].rows.length == numMinRows)
		    {
			    alert("Sorry, no more rows exist to remove.");
			    return;
		    }
		    removeRow = document.getElementById("Table_" + idTableBase).tBodies[0].rows[removeRowNum];
		    document.getElementById("Table_" + idTableBase).tBodies[0].removeChild(removeRow);
    		
		    //alert("current numRows value: " + numRows);
    		
		    //decrement the id and other attributes of a bunch of pieces above this row
		    for(var i = removeRowNum + 1; i < numRows; i++)
		    {
			    //link cell and links inside it
			    if(document.getElementById("Cell_" + idTableBase + "_" + i + "_Link"))
			    {
				    cellIterator = document.getElementById("Cell_" + idTableBase + "_" + i + "_Link");
				    cellIterator.id = "Cell_" + idTableBase + "_" + (i - 1) + "_Link";
    				
				    linkIterator = document.getElementById("Link_" + idTableBase + "_" + i + "_Edit");
				    linkIterator.setAttribute("href", "#");
				    attachEventHandlerToElement(linkIterator, "onclick", "return editRowInHiddenFormTable('" + idTableBase + "', " + (i - 1) + ");");
				    linkIterator.id = "Link_" + idTableBase + "_" + (i - 1) + "_Edit";
    				
				    linkIterator = document.getElementById("Link_" + idTableBase + "_" + i + "_Delete");
				    linkIterator.setAttribute("href", "#");
				    if(document.getElementById("Hidden_" + idTableBase + "_JSFireOnDelete"))
				    {
					    attachEventHandlerToElement(linkIterator, "onclick", "return removeRowFromHiddenFormTable('" + idTableBase + "', " + (i - 1) + ");" + document.getElementById("Hidden_" + idTableBase + "_JSFireOnDelete").value);
				    } else {
					    attachEventHandlerToElement(linkIterator, "onclick", "return removeRowFromHiddenFormTable('" + idTableBase + "', " + (i - 1) + ");");
				    }
				    linkIterator.id = "Link_" + idTableBase + "_" + (i - 1) + "_Delete";
    				
			    }
    			
			    //hidden ID input
			    if(document.getElementById("Hidden_" + idTableBase + "_" + i + "_ID"))
			    {
				    replaceHiddenElement("Hidden_" + idTableBase + "_" + i + "_ID", "Hidden_" + idTableBase + "_" + (i - 1) + "_ID");
				    /*inputIterator = document.getElementById("Hidden_" + idTableBase + "_" + i + "_ID");
				    inputIterator.setAttribute("name", "Hidden_" + idTableBase + "_" + (i - 1) + "_ID");
				    inputIterator.id = "Hidden_" + idTableBase + "_" + (i - 1) + "_ID";*/
			    }
    			
    			
    			
			    //go through each of the other cells
			    for(var c=0; c < numColumns; c++)
			    {
				    //alert("trying to find Cell_" + idTableBase + "_" + i + "_" + c);
				    cellIterator = document.getElementById("Cell_" + idTableBase + "_" + i + "_" + c);
				    cellIterator.id = "Cell_" + idTableBase + "_" + (i - 1) + "_" + c;
    				
				    thisColumnName = document.getElementById("Hidden_" + idTableBase + "_Column_" + c).value;
				    replaceHiddenElement("Hidden_" + idTableBase + "_" + i + "_" + thisColumnName, "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName);
				    /*inputIterator = document.getElementById("Hidden_" + idTableBase + "_" + i + "_" + thisColumnName);
				    inputIterator.setAttribute("name", "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName);
				    //alert("setting ID to '" + "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName + "'");
				    //inputIterator.setAttribute("id", "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName);
				    inputIterator.id = "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName;
				    */
				    //display input
			        if(document.getElementById("Hidden_" + idTableBase + "_" + i + "_" + thisColumnName + "_Display"))
			        {
				        replaceHiddenElement("Hidden_" + idTableBase + "_" + i + "_" + thisColumnName + "_Display", "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName + "_Display");
				        /*inputIterator = document.getElementById("Hidden_" + idTableBase + "_" + i + "_" + thisColumnName + "_Display");
				        inputIterator.setAttribute("name", "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName + "_Display");
				        inputIterator.id = "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName + "_Display";
				        //alert("testdisplay");*/
			        }
        			
			        //Ancillary value input
			        if(document.getElementById("Hidden_" + idTableBase + "_" + i + "_" + thisColumnName + "_Ancillary"))
			        {
				        replaceHiddenElement("Hidden_" + idTableBase + "_" + i + "_" + thisColumnName + "_Ancillary", "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName + "_Ancillary");
				        /*inputIterator = document.getElementById("Hidden_" + idTableBase + "_" + i + "_" + thisColumnName + "_Ancillary");
				        inputIterator.setAttribute("name", "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName + "_Ancillary");
				        inputIterator.id = "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName + "_Ancillary";
				        //alert("testancillary");*/
			        }
        			
			        if(document.getElementById("Hidden_" + idTableBase + "_" + i + "_" + thisColumnName + "_Ancillary2"))
			        {
				        replaceHiddenElement("Hidden_" + idTableBase + "_" + i + "_" + thisColumnName + "_Ancillary2", "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName + "_Ancillary2");
				        /*inputIterator = document.getElementById("Hidden_" + idTableBase + "_" + i + "_" + thisColumnName + "_Ancillary2");
				        inputIterator.setAttribute("name", "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName + "_Ancillary2");
				        inputIterator.id = "Hidden_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName + "_Ancillary2";
				        //alert("testancillary2"); */
			        }
    				
				    spanIterator = document.getElementById("Span_" + idTableBase + "_" + i + "_" + thisColumnName);
				    spanIterator.id = "Span_" + idTableBase + "_" + (i - 1) + "_" + thisColumnName;
			    }
		    }
    		
		    //decrement number of rows
		    numRows--;
    		
		    //set hidden number of rows
		    document.getElementById("Hidden_" + idTableBase + "_NumRows").value = numRows;
    		
		    //unset current row specification
		    document.getElementById("Hidden_" + idTableBase + "_CurrentRow").value = "";
    		
		    if(arrayElementIDs)
		    {
			    //pop last element off array
			    arrayElementIDs.pop();
		    }
		    //alert("prepping calculateRunningTotal()");
		    //recalculate running total values
		    calculateRunningTotal(idTableBase);
		    //alert("finish calculateRunningTotal()");
    		
		    //set cell colors to inactive
		    for(var r = 0; r < numRows; r++)
		    {
			    //set Link cell
			    document.getElementById("Cell_" + idTableBase + "_" + r + "_Link").style["background"] = inactive_cell_color;
    			
			    //set other cells
			    for(var i = 0; i < numColumns; i++)
			    {
				    document.getElementById("Cell_" + idTableBase + "_" + r + "_" + i).style["background"] = inactive_cell_color;
			    }
		    }
    		
		    //if edit table exists, mess with insides
		    if(document.getElementById("Table_" + idTableBase + "_Edit"))
		    {
			    //hide
			    document.getElementById("Table_" + idTableBase + "_Edit").style["display"] = "none";
    			
			    //make it inactive
			    document.getElementById("Table_" + idTableBase + "_Edit").style["background"] = inactive_cell_color;
    			
			    //hide modify button
			    document.getElementById("Button_" + idTableBase + "_UpdateRow").style["display"] = "none";
		    }
		    //alert("finish remove function");
		    return false;
	    } else {
		    return false;
	    }
    } catch(err) {
        alert("error in function removeRowFromHiddenFormTable(): " + err.message);
    }
    return false;
}

//	activateHiddenFormTableAdd - turns on the editing table for a hidden form table
//	args:
//		buttonObject - the clicked button, probably passed with "this"
//		idTableBase - base string for table and form elements
//
//	return value: false
//
function activateHiddenFormTableAdd(buttonObject, idTableBase)
{
	try
	{
	    var numRows = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length;
	    var numColumns = Number(document.getElementById("Hidden_" + idTableBase + "_NumColumns").value);
	    var currentRow;
    	
	    //show editor
	    document.getElementById("Table_" + idTableBase + "_Edit").style["display"] = "block";
    	
	    //change editor background color to normal
	    document.getElementById("Table_" + idTableBase + "_Edit").style["background"] = "transparent";
    	
	    //return currently edited row to normal
	    if(numRows > 0 && document.getElementById("Hidden_" + idTableBase + "_CurrentRow").value != "")
	    {
		    currentRow = Number(document.getElementById("Hidden_" + idTableBase + "_CurrentRow").value);
    		
		    //set Link cell
		    document.getElementById("Cell_" + idTableBase + "_" + currentRow + "_Link").style["background"] = inactive_cell_color;
    		
		    //set other cells
		    for(var i = 0; i < numColumns; i++)
		    {
			    document.getElementById("Cell_" + idTableBase + "_" + currentRow + "_" + i).style["background"] = inactive_cell_color;
		    }
	    }
    	
	    //set all values to their defaults: blank, or no change if JSValidateRule is "Readonly"
	    for(var i = 0; i < numColumns; i++)
	    {
		    //ensure inputs are enabled
		    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value").disabled = false;
		    if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_JSValidateRule"))
		    {
			    if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_JSValidateRule").value != "Readonly")
			    {
				    //set to blank
				    //alert("blanking value Form_" + idTableBase + "_Column_" + i + "_Value");
				    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value").value = "";
			    }
		    } else {
			    //set to blank
			    //alert("blanking value Form_" + idTableBase + "_Column_" + i + "_Value");
			    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value").value = "";
		    }
		    if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_SpecialEditDistribution"))
		    {
			    if(document.getElementById("Hidden_" + idTableBase + "_Column_" + i + "_SpecialEditDistribution").value=="Phone")
			    {
				    //phone values split into four inputs, clear all of them
				    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value_1").value = "";
				    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value_2").value = "";
				    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value_3").value = "";
				    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_Value_4").value = "";
			    }
		    }
		    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue"))
		    {
			    //blank ancillary value
			    document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue").value = "";
			    if(document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue2"))
		        {
			        //blank secondary ancillary value
			        document.getElementById("Form_" + idTableBase + "_Column_" + i + "_AncillaryValue2").value = "";
		        }
		    }
	    }
    	
	    //hide the update (edit) button
	    document.getElementById("Button_" + idTableBase + "_UpdateRow").style["display"] = "none";
    	
	    //show the update (add) button
	    document.getElementById("Button_" + idTableBase + "_AddRow").style["display"] = "inline";
    	
    } catch(err) {
        alert("error in function activateHiddenFormTableAdd(): " + err.message);
    }
    return false;
}

//	cancelHiddenFormTableAction - turns off the editing table
//	args:
//		idTableBase - base string for table and form elements
//
//	return value: false
//
function cancelHiddenFormTableAction(idTableBase)
{
	try
	{
	    var numRows = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length;
	    var numColumns = Number(document.getElementById("Hidden_" + idTableBase + "_NumColumns").value);
	    var currentRow;
    	
	    //hide editor
	    document.getElementById("Table_" + idTableBase + "_Edit").style["display"] = "none";
    	
	    //change editor background color to normal
	    document.getElementById("Table_" + idTableBase + "_Edit").style["background"] = "transparent";
    	
	    //return currently edited row to normal
	    if(numRows > 0)
	    {
		    currentRow = Number(document.getElementById("Hidden_" + idTableBase + "_CurrentRow").value);
		    //set Link cell
		    document.getElementById("Cell_" + idTableBase + "_" + currentRow + "_Link").style["background"] = inactive_cell_color;
    		
		    //set other cells
		    for(var i = 0; i < numColumns; i++)
		    {
			    document.getElementById("Cell_" + idTableBase + "_" + currentRow + "_" + i).style["background"] = inactive_cell_color;
		    }
	    }
    	
	    //hide the update (edit) button
	    document.getElementById("Button_" + idTableBase + "_UpdateRow").style["display"] = "none";
    	
	    //hide the update (add) button
	    document.getElementById("Button_" + idTableBase + "_AddRow").style["display"] = "none";
    	
    } catch(err) {
        alert("error in function cancelHiddenFormTableAction(): " + err.message);
    }
	return false;
}

//	calculateRunningTotal - takes a set of hidden form inputs and adds up a set of running totals in span elements
//	args:
//		idTableBase - base string for table and form elements
//
//	return value: none
//
function calculateRunningTotal(idTableBase)
{
	var numRows;
	var sumColumn;
	var sumColumnName;
	var runningTotal;
	var numColumns;
	runningTotal = 0;
	
	try
	{
	    //ensure that all hidden identifiers for this table exist
	    if(document.getElementById("Table_" + idTableBase) && document.getElementById("Hidden_" + idTableBase + "_NumRows") && document.getElementById("Hidden_" + idTableBase + "_NumColumns"))
	    {
		    numRows = document.getElementById("Table_" + idTableBase).tBodies[0].rows.length;
		    numColumns = Number(document.getElementById("Hidden_" + idTableBase + "_NumColumns").value);
		    //which column is the sum?  Default is last
		    if(document.getElementById("Hidden_" + idTableBase + "_SumColumn"))
		    {
			    sumColumn = Number(document.getElementById("Hidden_" + idTableBase + "_SumColumn").value);
		    } else {
			    sumColumn = numColumns - 1;
		    }
		    sumColumnName = document.getElementById("Hidden_" + idTableBase + "_Column_" + sumColumn).value;
		    //alert("sum column: " + sumColumnName + "\nnum rows: " + numRows);
		    for(var i = 0; i < numRows; i++)
		    {
                if(!document.getElementById("Hidden_" + idTableBase + "_" + i + "_" + sumColumnName) )
                {
                    alert("error, element '" + "Hidden_" + idTableBase + "_" + i + "_" + sumColumnName + "' doesn't exist!");
                }
			    runningTotal += Number(formatClean(document.getElementById("Hidden_" + idTableBase + "_" + i + "_" + sumColumnName).value));
			    //alert("running total for row " + i + ": " + runningTotal);
			    if(document.getElementById("Span_" + idTableBase + "_" + i + "_RunningTotal"))
			    {
				    //assign to this row's span
				    document.getElementById("Span_" + idTableBase + "_" + i + "_RunningTotal").childNodes[0].nodeValue = formatNumber(runningTotal);
			    }
    			
			    if(document.getElementById("Hidden_" + idTableBase + "_" + i + "_RunningTotal"))
			    {
				    //also assign to this row's hidden input
				    document.getElementById("Hidden_" + idTableBase + "_" + i + "_RunningTotal").value = formatNumber(runningTotal);
			    }
		    }
		    //assign to the master grand total value in the dynamic variables pool; useful even if there's no running total column
		    dynamicVariables_Dictionary[idTableBase + "_GrandTotal"] = runningTotal;
	    } else {
		    return;
	    }
    } catch(err) {
        alert("error in function calculateRunningTotal(): " + err.message);
    }
}

//	masqueradePostBack - fakes a postback to the server by pretending to submit using an existing asp:Button object
//	args:
//		buttonSneak - the object represented by the calling button, usually passed with "this"
//		idProperButton - the id value of the proper asp:Button object
//		idHiddenValue - optional ID of a hidden form element
//		strHiddenValue - optional string to place as the hidden form element value
//
//	return value: true or false depending on success; don't want the user to see a bad postback
//
function masqueradePostBack(buttonSneak, idProperButton, idHiddenValue, strHiddenValue)
{
	var changeHiddenValue;
	var buttonProper;
	var valueProperButton;
	if(idHiddenValue != null && strHiddenValue != null)
	{
		changeHiddenValue = true;
	} else {
		changeHiddenValue = false;
	}
	if(!document.getElementById(idProperButton))
	{
		alert("sorry, no asp:Button element exists with id " + idProperButton + "; terminating submit.");
		return false;
	}
	//acquire button and current value (text)
	buttonProper = document.getElementById(idProperButton);
	valueProperButton = buttonProper.value;
	
	//erase value and name attributes of proper button
	buttonProper.value="";
	buttonProper.setAttribute("name", "");
	
	//populate name and value attributes of our sneak button
	buttonSneak.setAttribute("name", idProperButton);
	buttonSneak.value = valueProperButton;
	
	if(changeHiddenValue == true)
	{
		//change the value of the hidden input
		document.getElementById(idHiddenValue).value = strHiddenValue;
	}
	return true;
}

//	requireCheckForSave - passes a checkbox that must be checked to enable save buttons, otherwise disables them
//	args:
//		inputElement - element with a value that can be cleaned
//
//	return value: none
//
function requireCheckForSave(inputElement)
{
	if(inputElement.checked==true)
	{
		//enable save
		if(document.getElementById("Button_SaveQuestion_Stay"))
		{
			document.getElementById("Button_SaveQuestion_Stay").disabled=false;
		}
		if(document.getElementById("Button_SaveQuestion_Next"))
		{
			document.getElementById("Button_SaveQuestion_Next").disabled=false;
		}
	} else {
		//disable save
		if(document.getElementById("Button_SaveQuestion_Stay"))
		{
			document.getElementById("Button_SaveQuestion_Stay").disabled=true;
		}
		if(document.getElementById("Button_SaveQuestion_Next"))
		{
			document.getElementById("Button_SaveQuestion_Next").disabled=true;
		}
	}
}

//	validateTextLengths - compares a set of textarea elements with a set of maximum length parameters and alerts the user if one is over
//	args:
//		elementIDs - an array of element ID values to iterate through
//		maxLengths - an array of length values to compare against
//
//	return value: true if validation passes, false otherwise - meant for returns from submit buttons
//
function validateTextLengths(inputElement)
{
	
	//fail if the two arrays don't have the same length value
	if(elementIDs.length != maxSizes.length)
	{
		alert("sorry, there is a problem with the validation code.  Please submit feedback indicating that on this page there is an error in the validateTextLengths function.");
		return false;
	}
	for(var i = 0; i < elementIDs.length; i++)
	{
		if(document.getElementById(elementIDs[i]).value.length > maxSizes[i])
		{
			alert("You may only enter " + maxSizes[i] + " characters in this field.");
			document.getElementById(elementIDs[i]).focus();
			return false;
		}
	}
}


//	synchronizeDropDownsByText - ensures two dropdowns have the same text selected (values might be different)
//	args:
//		masterID - ID of the "master" dropdown object
//		slaveID - ID of the "slave" dropdown object
//
//	return value: true if sync worked
//
function synchronizeDropDownsByText(masterID, slaveID)
{	
	var returnValue = false;
	if(document.getElementById(masterID) && document.getElementById(slaveID))
	{
		var masterElement = document.getElementById(masterID);
		var slaveElement = document.getElementById(slaveID);
		
		for(var i = 0; i < masterElement.length; i++)
		{
			if(masterElement.options[masterElement.selectedIndex].text==slaveElement.options[i].text)
			{
				slaveElement.selectedIndex = i;
				returnValue = true;
			}
		}
		return returnValue;
	} else
	{
		alert("elements not found in function synchronizeDropDownsByText(); please alert a system administrator using the feedback mechanism.");
		return returnValue;
	}
}

//	synchronizeDropDownsByValue - ensures two dropdowns have the same value selected (text might be different)
//	args:
//		masterID - ID of the "master" dropdown object
//		slaveID - ID of the "slave" dropdown object
//
//	return value: true if sync worked
//
function synchronizeDropDownsByValue(masterID, slaveID)
{	
	var returnValue = false;
	if(document.getElementById(masterID) && document.getElementById(slaveID))
	{
		var masterElement = document.getElementById(masterID);
		var slaveElement = document.getElementById(slaveID);
		
		for(var i = 0; i < masterElement.length; i++)
		{
			if(masterElement.options[masterElement.selectedIndex].value==slaveElement.options[i].value)
			{
				slaveElement.selectedIndex = i;
				returnValue = true;
			}
		}
		return returnValue;
	} else
	{
		alert("elements not found in function synchronizeDropDownsByValue(); please alert a system administrator using the feedback mechanism.");
		return returnValue;
	}
}

//	synchronizeDropDownsByIndex - ensures two dropdowns have the same index selected
//	args:
//		masterID - ID of the "master" dropdown object
//		slaveID - ID of the "slave" dropdown object
//
//	return value: true if sync worked
//
function synchronizeDropDownsByIndex(masterID, slaveID)
{	
	var returnValue = false;
	if(document.getElementById(masterID) && document.getElementById(slaveID))
	{
		var masterElement = document.getElementById(masterID);
		var slaveElement = document.getElementById(slaveID);
		
		if(slaveElement.length >= masterElement.selectedIndex)
		{
			slaveElement.selectedIndex = masterElement.selectedIndex;
			returnValue = true;
		} else
		{
			alert("slave element does not possess enough options in function synchronizeDropDownsByIndex(); please alert a system administrator using the feedback mechanism.");
		}
		return returnValue;
	} else
	{
		alert("elements not found in function synchronizeDropDownsByIndex(); please alert a system administrator using the feedback mechanism.");
		return returnValue;
	}
}

//	validateFieldLive - validates length of a field as the user types in it
//	args:
//		textField - textarea field object, probably passed with "this"
//		maxLength - the number of maximum characters
//		updateID - optional ID value of a field to update with the number of remaining characters
//
//	return value: false if over, true otherwise
//
function validateFieldLive(textField, maxLength, updateID)
{	
	var currentLength = 0;
	var updateColor;
	var updateText;
	var returnValue = true;
	currentLength = textField.value.length;
	
	if (currentLength > maxLength){
		alert("You may not enter more than " + maxLength + " characters.");
		textField.value = textField.value.substr(0, textField.value.length + maxLength - currentLength);
		textField.focus();
		updateText = "0";
		updateColor = "red";
		returnValue = false;
	} else {
		updateColor = "green";
		updateText = maxLength - currentLength;
		returnValue = true;
	}
	
	//change value of update field
	if(document.getElementById(updateID))
	{
		document.getElementById(updateID).style["color"] = updateColor;
		changeInnerHTML(document, updateID, updateText);
	}
	
	return returnValue;
}

//	populateDropDownWithArray - takes a 2D array to populate a dropdown list
//	args:
//		dropdownID - ID of the dropdown object to change
//		itemArray - the array, each has 0, 1 text/value
//		selectValue - make the first option found with this value selected
//
//	return value: false if over, true otherwise
//
function populateDropDownWithArray(dropdownID, itemArray, selectValue)
{	
	var dropdownElement = document.getElementById(dropdownID);
	
	//clear by setting length to zero
	dropdownElement.length = 0;
	
	for(var i = 0; i < itemArray.length; i++)
	{
		dropdownElement.options[i] = new Option(itemArray[i][0], itemArray[i][1]);
		if(selectValue != null)
		{	
			if(selectValue == itemArray[i][1])
			{
				dropdownElement.selectedIndex = i;
			}
		}
	}
}

//	attachEventHandlerToElement - hack to allow events like onclick in multiple browsers
//	basically, IE doesn't play with setAttribute() for adding JS handlers on DOM elements
//	args:
//		attachElement - node to attach to
//		eventName - attribute name
//		eventCode - attribute value
//
//	return value: none
//
function attachEventHandlerToElement(attachElement, eventName, eventCode)
{
	if(document.all)
	{
		attachElement[eventName] = new Function(eventCode);
	} else {
		attachElement.setAttribute(eventName, eventCode);
	}
}

//Check if value exists in dropdown or not if so select that index
function selectIfExist(dropdownID, text){
    var dropdownElement = document.getElementById(dropdownID);
    text=text.toUpperCase();
    if (dropdownElement.options){
        
        for(i=0;i<dropdownElement.options.length;i++){
            t=new String(dropdownElement.options[i].text);
            ctext=t.toUpperCase();
            if (ctext.indexOf(text)>=0){
                dropdownElement.selectedIndex=i;
                return true;
            }
        }
        
    }
    return false;
}

//Check - uncheck checboxes based on pattern of id
function resetCB(vRegExpID, value){
    vEleSet=document.getElementsByTagName("input");
    for (i=0;i<vEleSet.length;i++){
        if (vRegExpID.test(vEleSet[i].id)){
            vEleSet[i].checked=value;
        }
    }
}




//AJAX Request 
function GetXmlHttpObject()
{ 
	var objXMLHttp=null
	if (window.XMLHttpRequest){
		objXMLHttp=new XMLHttpRequest()
	}
	else if (window.ActiveXObject){
		objXMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
	}
	return objXMLHttp
} 
	currentFolder=0;
	currentUser=0;
	var xmlHttp;
	var url;
	xmlHttp=GetXmlHttpObject();
var Currcallback='';
function doAJAX(file, method, params, Callbackfunc){
	url=file;
		
    if (typeof(Callbackfunc)!='function') Callbackfunc='';
    Currcallback=Callbackfunc;
    
    methodU=new String(method);
    
    method=methodU.toUpperCase().toString();
	if (method!='GET' && method!='POST')
		return false;
	if (method=='GET'){
		url+='?'+params;
	}
	xmlHttp.open(method,url,true);
	if(method.toString()=='POST'){
		xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	}

	xmlHttp.onreadystatechange=function(){

		if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete"){
		    //alert(xmlHttp.responseText); //show alert to user
		    if (typeof(Currcallback)!='function'){
			    
			    eval(xmlHttp.responseText);
			}else{
			     Currcallback();
			}
			
		}
		
	}
    
	if (method=='POST' && params!='')
		xmlHttp.send(params);
	else
		xmlHttp.send(null);
    
	return false;
}

/**************************************
» Jonas Raoni Soares Silva
» http://www.joninhas.ath.cx
**************************************/

String.prototype.pad = function(l, s, t){
	return s || (s = " "), (l -= this.length) > 0 ? (s = new Array(Math.ceil(l / s.length)
		+ 1).join(s)).substr(0, t = !t ? l : t == 1 ? 0 : Math.ceil(l / 2))
		+ this + s.substr(0, l - t) : this;
};

//	attachEventHandlerToElement - hack to allow events like onclick in multiple browsers
//	basically, IE doesn't play with setAttribute() for adding JS handlers on DOM elements
//	args:
//		attachElement - node to attach to
//		eventName - attribute name
//		eventCode - attribute value
//
//	return value: none
//
function attachEventHandlerToElement(attachElement, eventName, eventCode)
{
	//alert("testing JS function attachEventHandlerToElement");
	if(document.all)
	{
		attachElement[eventName] = new Function(eventCode);
	} else {
		attachElement.setAttribute(eventName, eventCode);
	}
}

// getInternetExplorerVersion - Returns the version of Internet Explorer or a -1 (indicating the use of another browser).
// 
// args:
//
function getInternetExplorerVersion()
{
  var rv = -1; // Return value assumes failure.
  if (navigator.appName == 'Microsoft Internet Explorer')
  {
    var ua = navigator.userAgent;
    var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    if (re.exec(ua) != null)
      rv = parseFloat( RegExp.$1 );
  }
  return rv;
}

//	replaceHiddenElement - hack to mimic changing name attribute of hidden input elements
//	IE7 doesn't do this the easy way
//  will change both the ID and the name of the new element
//	args:
//		idOriginal - node to attach to
//		idNew - new value to use
//
//	return value: none
//
function replaceHiddenElement(idOriginal, idNew)
{
	var originalNode = document.getElementById(idOriginal);
	var parentNode = originalNode.parentNode;
	var originalValue = originalNode.value;
	var newNode = document.createElement("input");
	newNode.setAttribute("type", "hidden");
	newNode.setAttribute("id", idNew);
	newNode.setAttribute("name", idNew);
	newNode.value = originalValue;
	
	//remove old node
	parentNode.removeChild(originalNode);
	
	//add new node
	parentNode.appendChild(newNode);
}

//	daysBetween - calculate the number of days between two JS date variables, which are expressed as the number of milliseconds since an origin date
//	args:
//		date1 - first date
//		date2 - second date
//
//	return value: integer number of days difference
//
function daysBetween(date1, date2) {

    // The number of milliseconds in one day
    var ONE_DAY = 1000 * 60 * 60 * 24

    // Convert both dates to milliseconds
    var date1_ms = date1.getTime()
    var date2_ms = date2.getTime()

    // Calculate the difference in milliseconds
    var difference_ms = Math.abs(date1_ms - date2_ms)
    
    // Convert back to days and return
    return Math.round(difference_ms/ONE_DAY)

}

//	clearChildNodes - uses DOM to get rid of existing child nodes of something
//	args:
//		nodeParent - element passed by some means
//
//	return value: none
//
function clearChildNodes(nodeParent)
{
	while(nodeParent.hasChildNodes()==true)
	{
		nodeParent.removeChild(nodeParent.firstChild);
	}
}

//	roundNumber - round a number to a certain number of digits - more accurate than toFixed()
//	args:
//		rnum - number to round
//      rlength - number of decimal places to round to
//
//	return value: rounded value
//
function roundNumber(rnum, rlength) {
	if (rnum > 8191 && rnum < 10485) {
		//some JS implementations have trouble rounding between these two numbers
		rnum = rnum-5000;
		var newnumber = Math.round(rnum*Math.pow(10,rlength))/Math.pow(10,rlength);
		newnumber = newnumber+5000;
	} else {
		var newnumber = Math.round(rnum*Math.pow(10,rlength))/Math.pow(10,rlength);
	}
	return newnumber;
}

//aspnetFormatDate - formats a Date object the way that .NET would if .ToString() were called
//	args:
//		dateIn - date to format
//      showTime - include the time component or not?
//
//	return value: formatted string (MM/dd/yyyy hh:mm:ss a)
//
function aspnetFormatDate(dateIn, showTime)
{
	var sOut = "";
	try
	{
	    dateIn = new Date(dateIn);
	    sOut += leadingZero(dateIn.getMonth() + 1) + "/";
	    sOut += leadingZero(dateIn.getDate()) + "/";
	    sOut += dateIn.getFullYear();
	    if(showTime == true)
	    {
	        sOut += " ";
	        var numHours;
	        if(dateIn.getHours() >= 12)
	        {
	            numHours = dateIn.getHours() - 12;
	        } else {
	            numHours = dateIn.getHours();
	        }
	        if(numHours == 0)
	        {
	            numHours = 12;
	        }
	        sOut += leadingZero(numHours) + ":";
	        sOut += leadingZero(dateIn.getMinutes()) + ":";
	        sOut += leadingZero(dateIn.getSeconds()) + " ";
	        if(dateIn.getHours() >= 12)
	        {
	            sOut += "PM";
	        } else {
	            sOut += "AM";
	        }
	    }	
    } catch(err) {
        alert("error in function aspnetFormatDate for input " + dateIn + ":" + err.message);
    }
	return sOut;
}

//leadingZero - add a leading zero character for values under 10
//	args:
//		numIn - the number to potentially change
//
//	return value: maybe altered number
//
function leadingZero(numIn)
{
    if(numIn < 10 && numIn >= 0)
    {
        return "0" + numIn;
    } else {
        return numIn;
    }
}

//Team mgmt page functions
function team_mgmt_email(){
    
    if (selectIfExist('Form_NonGroupUsersList',document.getElementById('NU_Email').value)) { 
		if (document.getElementById('Form_NonGroupUsersList').selectedIndex!=0){
			document.getElementById('NU_Email').value='';
    	    alert('Member '+document.getElementById('Form_NonGroupUsersList').options[document.getElementById('Form_NonGroupUsersList').selectedIndex].text+' already exists, please click on their name in the user directory to load their info into the add new user form.');
        	document.getElementById('Form_NonGroupUsersList').selectedIndex=0;
		}
        
    }
}
var userinfo;
function getUserInfo(userID, add_stmt){
    doAJAX('requestUserInfo.aspx','POST','user='+userID+'&addstmt='+add_stmt);
}


function assign_user_data(){   
    document.getElementById('NU_Email').value=userinfo[0];
    document.getElementById('NU_Pass').value=userinfo[1];
    document.getElementById('NU_FirstName').value=userinfo[2];
    document.getElementById('NU_LastName').value=userinfo[3];
}
//Team mgmt functions ends

//aspnetFormatDate - formats a Date object the way that .NET would if .ToString() were called
//	args:
//		dateIn - date to format
//      showTime - include the time component or not?
//
//	return value: formatted string (MM/dd/yyyy hh:mm:ss a)
//
function aspnetFormatDate(dateIn, showTime)
{
	var sOut = "";
	try
	{
	    dateIn = new Date(dateIn);
	    sOut += leadingZero(dateIn.getMonth() + 1) + "/";
	    sOut += leadingZero(dateIn.getDate()) + "/";
	    sOut += dateIn.getFullYear();
	    if(showTime == true)
	    {
	        sOut += " ";
	        var numHours;
	        if(dateIn.getHours() >= 12)
	        {
	            numHours = dateIn.getHours() - 12;
	        } else {
	            numHours = dateIn.getHours();
	        }
	        if(numHours == 0)
	        {
	            numHours = 12;
	        }
	        sOut += leadingZero(numHours) + ":";
	        sOut += leadingZero(dateIn.getMinutes()) + ":";
	        sOut += leadingZero(dateIn.getSeconds()) + " ";
	        if(dateIn.getHours() >= 12)
	        {
	            sOut += "PM";
	        } else {
	            sOut += "AM";
	        }
	    }	
    } catch(err) {
        alert("error in function aspnetFormatDate for input " + dateIn + ":" + err.message);
    }
	return sOut;
}
// End aspnetFormatDate - formats a Date object the way that .NET would if .ToString() were called

//	convertToURL - encodes a string in the URL format
//	args:
//		strInput - string to encode
//
//	return value: URL encoded output
//
function convertToURL(strInput) {
    var result = "";
    var strCopyInput = new String(strInput);

    /*for (i = 0; i < strInput.length; i++)
    {
    if (strInput.charAt(i) == " ")
    {
    result += "+";
    } else {
    result += strInput.charAt(i);
    }
    }*/
    result = strCopyInput.replace(" ", "+");
    return (escape(result));
}

//	convertFromURL - decodes a URL string
//	args:
//		strInput - string to decode
//
//	return value: URL decoded output
//
function convertFromURL(strInput) {
    var result = strInput.replace(/\+/g, " ");

    return (unescape(result));
}
