function boundaryInit(){
	hardBoundaryInit();
	softBoundaryInit();
	sumFieldInit();
	updatingFieldsInit();
	createUpdatingEvents();
} //End initBoundaries

function chkboxControl(e){
/*
	I need to know if a checkbox is checked or unchecked.
	But unchecked boxes are not sent with the http request.
	This is unsatisfactory.
	
	The formBuilder places a hidden element right after each checkbox.
	This hidden element, which is always sent with the http request, contains the 'real' value of the checkbox.
	Thus, I have to keep the hidden input and the checkbox in synch.
	
	All checkboxes call this function when onClick is fired.
	If the box is now checked, the value of the hidden function is changed to true.
	If the box is now unchecked, the value is changed to false.
	
	Additionally, the function checks to see if any form elements were locked when the box was checked & then unlocks those elements.
	It also checks to see if any elements were unlocked or unrequired when the box was checked and locks/requires them when the box is unchecked.
*/

	//the checkbox element name always ends with _chk. Strip that out so we can refer to the hidden element.
	var hiddenName = e.slice(0,-4);

	if (document.getElementById(e).checked == true) {
		document.getElementById(hiddenName).value = "true";
	} else {
		document.getElementById(hiddenName).value = "false";
		
		var y = document.getElementById(e).attributes.getNamedItem('onclick').value;
				
		var aAttr = y.split(";");
				
		for(h=0; h < aAttr.length; h++) {
			if (aAttr[h].slice(0,8) == "formLock") {
				var x = aAttr[h];

				RE = /formLock\('/;
				sRep = x.replace(RE,"");
							
				RE = /'\)/;
				sRep = sRep.replace(RE,"");
				formUnlock(sRep);
			} else if (aAttr[h].slice(0,11) == "formRequire") {
				var y = aAttr[h];

				var RE = /formRequire\('/;
				sRep = y.replace(RE,"");
										
				RE = /'\)/;
				sRep = sRep.replace(RE,"");
				formUnrequire(sRep);
			} else if (aAttr[h].slice(0,10) == "formUnlock") {
				var y = aAttr[h];

				var RE = /formUnlock\('/;
				sRep = y.replace(RE,"");
										
				RE = /'\)/;
				sRep = sRep.replace(RE,"");
				formLock(sRep);
			} else if (aAttr[h].slice(0,13) == "formUnrequire") {
				var y = aAttr[h];

				var RE = /formUnrequire\('/;
				sRep = y.replace(RE,"");
										
				RE = /'\)/;
				sRep = sRep.replace(RE,"");
				formRequire(sRep);
			}
		}
	}
} //End checkboxControl

function createUpdatingEvents() {
	for (var index = 0; index < updatingFieldsArray.length; ++index) {
	  var field_to_update = updatingFieldsArray[index];
		var element_to_update = document.getElementById(field_to_update);
		if (element_to_update != null) {
			element_to_update.onchange = sumFieldUpdate;
		}
	}
} //End createUpdatingEvents()


// check date JavaScript function
// if date is valid then function returns true, otherwise returns false
function isDate(txtDate){
  var objDate;  // date object initialized from the txtDate string
  var mSeconds; // milliseconds from txtDate

	// date length should be 10 characters - no more, no less
  // if (txtDate.length != 10) return false;

	// extract day, month and year from the txtDate string
	// expected format is mm/dd/yyyy
	// subtraction will cast variables to integer implicitly
	dateRegex = /([0-9]+)\/([0-9]+)\/([0-9]+)/;
	if (dateRegex.test(txtDate)) {
		resultArray = dateRegex.exec(txtDate);
		var day   = resultArray[2]  - 0;
  	var month = resultArray[1]  - 1; // because months in JS start with 0
  	var year  = resultArray[3] - 0;
	} else {
		return false;
	}

	// third and sixth character should be /
	// if (txtDate.substring(2,3) != '/') return false;
	// if (txtDate.substring(5,6) != '/') return false;

  // test year range
  if (year < 999 || year > 3000) return false;

  // convert txtDate to the milliseconds
  mSeconds = (new Date(year, month, day)).getTime();

  // set the date object from milliseconds
  objDate = new Date();
  objDate.setTime(mSeconds);

  // if there exists difference then date isn't valid
  if (objDate.getFullYear() != year)  return false;
  if (objDate.getMonth()    != month) return false;
  if (objDate.getDate()     != day)   return false;

	// otherwise return true
  return true;
}


function dateCheck(dDate, sFormat){
	switch (sFormat.toLowerCase()) {
		case "jscsv":
			var boundaryDateRegEx = /[0-9]+,[0-9]+,[0-9]+/
			if (boundaryDateRegEx.test(dDate)){
				return true;
			} else {
				return false;
			}	
		break;
		case "input":
			var inputDateRegEx = /[0-9]+\/[0-9]+\/[0-9]+/
			if ((inputDateRegEx.test(dDate)) && isDate(dDate)) {
				return true;
			} else {
				return false;
			}
		break;
		case "js":
			if (dDate instanceof Date) {
				return true;
			} else {
				return false;
			}
		break;
	}
} //End dateCheck

function dateFormat(dDate, initFormat, outputFormat){
	var initDate
	var outputDate
	
	switch (initFormat.toLowerCase()) {
		case "jscsv":
			var aInitDate = new Array(0);
			aInitDate = dDate.split(",");
			initDate = new Date(aInitDate[0],aInitDate[1],aInitDate[2],0,0,0,0);		
		break;

		case "input":
			var aInitDate = new Array(0);
			aInitDate = dDate.split("/");
			initDate = new Date(aInitDate[2],aInitDate[0]-1,aInitDate[1],0,0,0,0);
		break

		case "js":
			initDate = new Date(dDate);
		break;
	}
	
	switch (outputFormat.toLowerCase()) {
		case "js":
			outputDate = initDate;
		break;
		case "mmddyyyy":
			outputDate = initDate.toDateString();
		break;
	}
	
	return outputDate;
} //End dateFormat


function formBoundsToValues(sBoundary,sType) {
	var searchString = sBoundary;
	var resultString = sBoundary;
	var localBoundRE = /\$(.+?)\$/g;
	
	if (localBoundRE.test(searchString)) {
		var a = searchString.match(localBoundRE);
		for(var j=0;j<a.length;j++){
//			window.alert(a[j]);
			formId = a[j].substr(1,a[j].length - 2);
//			window.alert(formId);
			formValue = document.getElementById(formId).value;
			
			if (sType == "numeric") {
				formValue = Math.round(parseFloat(formValue));	
			} else if (sType == "currency") {
				formValue = parseFloat(formValue);
			}


			resultString = searchString.replace(a[j],formValue);
//			window.alert(resultString);
			searchString = resultString;		
		}
	}
	return resultString;
} // End formBoundsToValues

function formLock(formItems) {
//	window.alert('formLock');
	var itemArray = formItems.split(",");

	for(var i=0;i < itemArray.length;i++){
	
		var thisElement = document.getElementById(itemArray[i]);
					
		/*handle SELECT boxes. Set the selected option to invalidddl and disable the other option elements. */
		if (thisElement.tagName == 'SELECT') {
			for(var j=0; j < thisElement.options.length; j++) {
				if (thisElement.options[j].tagName == 'OPTION') {
					if (thisElement.options[j].value == "invalidddl"){
						thisElement.options[j].selected = true;
					} else {
						thisElement.options[j].selected = false;
						thisElement.options[j].disabled = true;
					}
				}
			}
			thisElement.value = 'invalidddl';
			thisElement.style.display = "none";

			if (thisElement.parentNode.className == 'formTitle'){
				thisElement.parentNode.style.display = "none";
			}
		/*handle checkboxes.*/
		} else if(thisElement.type == 'hidden') {
			/*first set the value of the hidden input, which is what's really sent to the db, to false.*/
			thisElement.value = false;

			/*Then manipulate the visible checkboxes*/
			var chkBoxName = itemArray[i] + "_chk";
			var chk = document.getElementById(chkBoxName);
			chk.checked = false;
			chk.value = "";
			chk.style.display = "none";
			
			/*Search for dependents & send them to formLock()*/
			if (chk.attributes.getNamedItem('onclick')){
				var y = chk.attributes.getNamedItem('onclick').value;
				var aAttr = y.split(";");
											
				for(h=0; h < aAttr.length; h++) {
				//window.alert(aAttr[h].slice(0,11));
	
					if (aAttr[h].slice(0,10) == "formUnlock") {
						var e = aAttr[h];
													
						var RE = /formUnlock\('/;
						sRep = e.replace(RE,"");
																				
						RE = /'\)/;
						sRep = sRep.replace(RE,"");
						
						if(sRep.length > 0){
							formLock(sRep);
						}
					}
				}
			}

			if (thisElement.parentNode.className == 'formTitle'){
				thisElement.parentNode.style.display = "none";
			}
		/* handle radio buttons. */
		} else if(thisElement.id.slice(0,5) == "radio") {
			thisElement.style.display = "none";
			var radioName = thisElement.id + "_0";
			var z = document.getElementById(radioName)
			if (z.value != 'nullradio'){
				//window.alert("Setting defValue of " + radioName + " to " + z.value);
				z.setAttribute('defValue', z.value);
				z.value = 'nullradio';
				z.checked = true;
			}
			
			for (g=0; g < thisElement.childNodes.length; g++) {
//window.alert("children of:\n" + thisElement.childNodes[g].tagName);
				if (thisElement.childNodes[g].tagName == 'INPUT') {
					if (thisElement.childNodes[g].attributes.getNamedItem('onclick')){
						var y = thisElement.childNodes[g].attributes.getNamedItem('onclick').value;
						var aAttr = y.split(";");
										
						for(h=0; h < aAttr.length; h++) {
						//window.alert(aAttr[h].slice(0,11));

							if (aAttr[h].slice(0,10) == "formUnlock") {
								var e = aAttr[h];
													
								var RE = /formUnlock\('/;
								sRep = e.replace(RE,"");
																			
								RE = /'\)/;
								sRep = sRep.replace(RE,"");
											
								if(sRep.length > 0){
									formLock(sRep);
								}
							}
						}
					}
				}
			}

			if (thisElement.parentNode.className == 'formTitle'){
				thisElement.parentNode.style.display = "none";
			}
			
			if (document.getElementById(thisElement.id + "_title")){
				var f = document.getElementById(thisElement.id + "_title")
				f.style.display = "none";
			}
		} else {
//window.alert("undef:\n" + thisElement.type);
//window.alert(thisElement.parentNode.className);
			thisElement.value = "";
			thisElement.style.display = "none";
			if (thisElement.parentNode.className == 'formTitle'){
				thisElement.parentNode.style.display = "none";
			} else if (thisElement.parentNode.htmlFor == thisElement.id) {
				thisElement.parentNode.style.display = "none";
			} else if (document.getElementById(thisElement.id + "_title")){
				var f = document.getElementById(thisElement.id + "_title")
				f.style.display = "none";
			}
		}
	}
} //End formLock
					

function formRequire(formItems){
//	window.alert('formRequire');
	var itemArray = formItems.split(",");

	if (requiredArray.length > 0){
		for(var i=0; i < itemArray.length; i++){
			var alreadyListed = false;
			for(var j=0; j < requiredArray.length; j++){
				if (itemArray[i] == requiredArray[j]){
					alreadyListed = true;
				}
			}
			if (alreadyListed == false){
				requiredArray.push(itemArray[i]);
/*				document.getElementById(itemArray[i]).style.backgroundcolor = '#ff9999';*/
				//window.alert(itemArray[i]);
			}
		}
	} else {
		for(var k=0; k < itemArray.length; k++){
			requiredArray.push(itemArray[k]);
		}
	}

/*	window.alert("formRequire");
	for(var l=0; l < requiredArray.length; l++){
		window.alert("requiredArray[" + l + "] : " + requiredArray[l]);
	}
*/
} //End formRequire

function formUnlock(formItems) {
//	window.alert('formUnlock');
	var itemString = new String(formItems);	
	var itemArray = itemString.split(",");
				
	for(var i=0;i < itemArray.length;i++){
		var thisElement = document.getElementById(itemArray[i]);
		/*handle dropdowns*/
		if (thisElement.tagName == 'SELECT') {
			thisElement.style.display = "block";
			for(var j=0; j < thisElement.options.length; j++) {
				if (thisElement.options[j].tagName == 'OPTION') {
					if (thisElement.options[j].defaultSelected == true){
						thisElement.options[j].selected = true;
						thisElement.value = thisElement.options[j].value;
						thisElement.options[j].disabled = false;
					} else {
						thisElement.options[j].selected = false;
						thisElement.options[j].disabled = false;
					}
				}
			}

			if (thisElement.parentNode.className == 'formTitle'){
				thisElement.parentNode.style.display = "block";
			}
		/*handle checkboxes.*/
		} else if(thisElement.type == 'hidden') {
			/*Then manipulate the visible checkboxes*/
			var chkBoxName = itemArray[i] + "_chk";
			var chkBox = document.getElementById(chkBoxName);
			chkBox.style.display = "inline";
			chkBox.checked = chkBox.defaultChecked;
			
			if (thisElement.parentNode.className == 'formTitle'){
				thisElement.parentNode.style.display = "block";
			}
		/* handle radio buttons. */
		} else if(thisElement.id.slice(0,5) == "radio") {
			var radioName = thisElement.id + "_0";
			var y = document.getElementById(radioName)
			//window.alert("setting radio " + radioName + " to " + y.getAttribute('defValue'));
			if(y.getAttribute('defValue') != null){
				y.value = y.getAttribute('defValue');
			}

			for(var j=0; j < thisElement.childNodes.length; j++) {
				if (thisElement.childNodes[j].tagName == 'INPUT') {
					thisElement.childNodes[j].checked = thisElement.childNodes[j].defaultChecked;
				}
			}
			thisElement.style.display = "block";

			if (thisElement.parentNode.className == 'formTitle'){
				thisElement.parentNode.style.display = "block";
			}
			
			if (document.getElementById(thisElement.id + "_title")){
				var f = document.getElementById(thisElement.id + "_title")
				f.style.display = "block";
			}
		/*handle other input types*/
		} else {
			thisElement.readOnly = false;
			thisElement.style.display = "inline";
			
			if (thisElement.defaultValue.length > 0) {
				thisElement.value = thisElement.defaultValue;
			}
			
			if (thisElement.parentNode.className == 'formTitle'){
				thisElement.parentNode.style.display = "block";
			} else if (thisElement.parentNode.htmlFor == thisElement.id) {
				thisElement.parentNode.style.display = "block";
			} else if (document.getElementById(thisElement.id + "_title")){
				var f = document.getElementById(thisElement.id + "_title")
				f.style.display = "block";
			}
		}
	}
} //End formUnlock

function formUnrequire(formItems){
//window.alert('formUnrequire');
	var itemArray = formItems.split(",");

/*
	for(var l=0; l < itemArray.length; l++){
		window.alert("formUnrequire[" + l + "] : " + itemArray[l]);
	}
*/

	if (requiredArray.length > 0){
		for(var i=0; i < itemArray.length; i++){
			var alreadyListed = false;
			var dataLocation = 0;
			
			//check the passed field name against the required array.
			//If it is the required array, mark its position
			for(var j=0; j < requiredArray.length; j++){
				if (itemArray[i] == requiredArray[j]){
					alreadyListed = true;
					dataLocation = j;
				}
			}
			
			//If it exists in the required array. Remove it.
			if (alreadyListed == true){
				if (document.getElementById(requiredArray[dataLocation]).type == 'hidden') {
					var chkBoxName = requiredArray[dataLocation] + "_chk";
					document.getElementById(chkBoxName).parentNode.style.backgroundColor = "#ffffff";
				} else {
					document.getElementById(requiredArray[dataLocation]).style.backgroundColor  = "#ffffff";
				}
				requiredArray.splice(dataLocation, 1);
			}
			
			/*search for dependents & unrequire them as well*/
			var thisElement = document.getElementById(itemArray[i]);

			/*handle checkboxes.*/
			if(thisElement.type == 'hidden') {
				var x = document.getElementById(thisElement.id + "_chk");
//window.alert("checkbox\n" + x.id);
				if (x.attributes.getNamedItem('onclick')){
					var y = x.attributes.getNamedItem('onclick').value;
//window.alert("onclick" + y);
					var aAttr = y.split(";");
											
					for(h=0; h < aAttr.length; h++) {
					//window.alert(aAttr[h].slice(0,11));
		
						if (aAttr[h].slice(0,11) == "formRequire") {
							var e = aAttr[h];
														
							var RE = /formRequire\('/;
							sRep = e.replace(RE,"");
																					
							RE = /'\)/;
							sRep = sRep.replace(RE,"");
							
							if(sRep.length > 0){
								formUnrequire(sRep);
							}
						}
					}
				}
			/* handle radio buttons. */
			} else if(thisElement.id.slice(0,5) == "radio") {
				for (g=0; g < thisElement.childNodes.length; g++) {
					if (thisElement.childNodes[g].tagName == 'INPUT') {
						if (thisElement.childNodes[g].attributes.getNamedItem('onclick')){
							var y = thisElement.childNodes[g].attributes.getNamedItem('onclick').value;
							var aAttr = y.split(";");
											
							for(h=0; h < aAttr.length; h++) {
							//window.alert(aAttr[h].slice(0,11));
	
								if (aAttr[h].slice(0,11) == "formRequire") {
									var e = aAttr[h];
														
									var RE = /formRequire\('/;
									sRep = e.replace(RE,"");
																					
									RE = /'\)/;
									sRep = sRep.replace(RE,"");
													
									if(sRep.length > 0){
										formUnrequire(sRep);
									}
								}
							}
						}
					}
				}
			}
		}
	}
/*
	window.alert("formUnrequire");
	for(var l=0; l < requiredArray.length; l++){
		window.alert("requiredArray[" + l + "] : " + requiredArray[l]);
	}
*/
} //End formUnrequire

function formValidation(){
	sumFieldUpdate();
		
	if (frontEndRequireCheck()) {
		var formPass = true;
	} else {
		var formPass = false;
	}
	
	if (formPass == true && frontEndBoundaryCheck() ) {
		var formPass = true;
	} else {
		var formPass = false;
	}

	if (formPass == true && frontEndSoftBoundaryCheck() ) {
		var formPass = true;
	} else {
		var formPass = false;
	}

	return formPass;
} //End formValidation

function frontEndBoundaryCheck(){
	var submitForm = true;
	var queryString = location.search;
	var RE = /action=review/;

	//test to see if user is just reviewing data. if so, don't check req'd fields
	if (RE.test(queryString) == false){
		for (var index = 0; index < boundaryArray.length; ++index) {
		  var boundary_details = boundaryArray[index];
			
			var field_id = boundary_details[0];
			var data_type = boundary_details[1];
			var low_bound = boundary_details[2];
			var high_bound = boundary_details[3];
			var label = boundary_details[4];

			elementPass = true;

			var element_to_check = document.getElementById(field_id);
			var element_value = element_to_check.value;
			
			if (element_value.length > 0){
				
				if (low_bound != "null"){
					var tempLowBound = formBoundsToValues(low_bound,data_type);
					var finalLowBound = modLocalBoundary(tempLowBound,data_type);
				} else {
					var finalLowBound = low_bound;
				}
				
				if (high_bound != "null"){
					var tempHighBound = formBoundsToValues(high_bound,data_type);
					var finalHighBound = modLocalBoundary(tempHighBound,data_type);
				} else {
					var finalHighBound = high_bound;
				}


				switch(data_type) {
					case "date":
						if (dateCheck(element_value,"input")){
							dInput = dateFormat(element_value, "input", "js");
						} else {
							window.alert	("Error.\n" +
														 label + " contains an invalid date.\n" +
														 "Please enter dates in mm/dd/yyyy format.\n"); 
							elementPass = false;
							break;
						}
		
						if (finalLowBound != "null") {
							boundary = finalLowBound;
							noBound = false;
							
							if (dateCheck(boundary,"jscsv")){
								dBoundary = dateFormat(boundary, "jscsv", "js")
							} else if (dateCheck(boundary,"input")) {
								dBoundary = dateFormat(boundary,"input","js");
							} else if (dateCheck(boundary,"js")) {
								dBoundary = dateFormat(boundary,"js","js");
							} else {
								noBound = true;
							}

							if ((!noBound) && (dInput.getTime() < dBoundary.getTime())) {
								window.alert	("Out Of Bounds\n" + 
																label + "\n" + 
																"Must be on or after " +
																dateFormat(dBoundary, "js", "mmddyyyy"));
								elementPass = false;
							}
						}
						
						if (finalHighBound != "null") {
							boundary = finalHighBound;
							noBound = false
						
							if (dateCheck(boundary,"jscsv")){
								dBoundary = dateFormat(boundary, "jscsv", "js")
							} else if (dateCheck(boundary,"input")) {
								dBoundary = dateFormat(boundary,"input","js");
							} else if (dateCheck(boundary,"js")) {
								dBoundary = dateFormat(boundary,"js","js");
							} else {
								noBound = true;
							}
							
							if ((!noBound) && (dInput.getTime() > dBoundary.getTime())) {
								window.alert	("Out Of Bounds\n" + 
												label + "\n" + 
												"Must be on or before " +
												dateFormat(dBoundary, "js", "mmddyyyy"));
								elementPass = false;
							}
						}
							
					break;
					
					case "escape":
						if (finalLowBound != "null") {
							boundary = finalLowBound;
							
							if (element_value < boundary) {
								window.alert	("Out Of Bounds\n" +
												label + "\n" +
												"Entry too short.\n" +
												"Must be " + boundary + " characters long or longer.");
								elementPass = false;
							}
						}
						
						if (finalHighBound != "null") {
							boundary = finalHighBound;
	
							if (element_value > boundary) {
								window.alert	("Out Of Bounds\n" +
												label + "\n" +
												"Entry too Long.\n" +
												"Must be " + boundary + " characters long or shorter.");
								elementPass = false;
							}
						}
		
					break;
					
					case "numeric":
					case "currency":
						element_value = element_value.replace(/[^0-9.]/,"");

						if (isNaN(element_value)){
							window.alert(label + " is not a number");
							elementPass = false;
							break;
						}

						if (finalLowBound != "null") {
							boundary = finalLowBound;
	
							if (parseFloat(element_value) < parseFloat(boundary)) {
								window.alert	("Out Of Bounds\n" +
												label + "\n" +
												"Entry too small.\n" +
												"Must be " + boundary + " or larger.");
								elementPass = false;
							}
						}
						
						if (finalHighBound != "null") {
							boundary = finalHighBound;
	
							if (parseFloat(element_value) > parseFloat(boundary)) {
								window.alert	("Out Of Bounds\n" +
												label + "\n" +
												"Entry too big.\n" +
												"Must be " + boundary + " or smaller.");
								elementPass = false;
							}
						}
					break;
				}
			}
			
			if (elementPass) {
				element_to_check.style.backgroundColor = "#ffffff";
			} else {
				submitForm = false;
				element_to_check.style.backgroundColor = "#ff9999";
			}
		}
	}
	
	if (submitForm == false){
		//window.alert('Boundaries Exceeded');
		return false;
	} else {
		return true;
	}
} //End frontEndBoundaryCheck


function frontEndSoftBoundaryCheck(){
	var submitForm = true;
	var queryString = location.search;
	var RE = /action=review/;

	//test to see if user is just reviewing data. if so, don't check req'd fields
	if (RE.test(queryString) == false){
		for (var index = 0; index < softBoundaryArray.length; ++index) {
		  var boundary_details = softBoundaryArray[index];
					
			var field_id = boundary_details[0];
			var data_type = boundary_details[1];
			var low_bound = boundary_details[2];
			var high_bound = boundary_details[3];
			var label = boundary_details[4];

			elementPass = true;
			bConfirm = true;

			var element_to_check = document.getElementById(field_id);
			var element_value = element_to_check.value;
			
			if (element_value > 0){
				
				if (low_bound != "null"){
					var tempLowBound = formBoundsToValues(low_bound,data_type);
					var finalLowBound = modLocalBoundary(tempLowBound,data_type);
				} else {
					var finalLowBound = low_bound;
				}
				
				if (high_bound != "null"){
					var tempHighBound = formBoundsToValues(high_bound,data_type);
					var finalHighBound = modLocalBoundary(tempHighBound,data_type);
				} else {
					var finalHighBound = high_bound;
				}

				switch(data_type) {
					case "date":
						if (dateCheck(element_value,"input")){
							dInput = dateFormat(element_value, "input", "js");
						} else {
							window.alert	("Error. Bad date\n" + 
											label + "\n"); 
							elementPass = false;
							break;
						}
		
						if (finalLowBound != "null") {
							boundary = finalLowBound;
							
							if (dateCheck(boundary,"jscsv")){
								dBoundary = dateFormat(boundary, "jscsv", "js")
							} else if (dateCheck(boundary,"input")) {
								dBoundary = dateFormat(boundary,"input","js");
							} else if (dateCheck(boundary,"js")) {
								dBoundary = dateFormat(boundary,"js","js");
							} else {
								window.alert	("Error.\n" +
												"Can't find lower boundary for:\n" + 
												label);
								elementPass = false;
							}
	
							if (dInput.getTime() < dBoundary.getTime()) {
								bConfirm = 		window.confirm	("Your entry of " + 
												dInput.toDateString() + " for\n" + 
												label + "\n" + 
												"is earlier than the date we expect,  " +
												dateFormat(dBoundary, "js", "mmddyyyy") + ".\n\n" +
												"Are you sure this entry is correct?");
								if (!bConfirm) {
									elementPass = false;
								}
							}
						}
						
						if (finalHighBound != "null") {
							boundary = finalHighBound;
						
							if (dateCheck(boundary,"jscsv")){
								dBoundary = dateFormat(boundary, "jscsv", "js")
							} else if (dateCheck(boundary,"input")) {
								dBoundary = dateFormat(boundary,"input","js");
							} else if (dateCheck(boundary,"js")) {
								dBoundary = dateFormat(boundary,"js","js");
							} else {
								window.alert	("Error.\n" +
												"Can't find upper boundary for:\n" + 
												label);
								elementPass = false;
							}
	
							if (dInput.getTime() > dBoundary.getTime()) {
								bConfirm = 		window.confirm	("Your entry of " + 
												dInput.toDateString() + " for\n" + 
												label + "\n" + 
												"is later than the date we expect,  " +
												dateFormat(dBoundary, "js", "mmddyyyy") + ".\n\n" +
												"Are you sure this entry is correct?");
								if (!bConfirm) {
									elementPass = false;
								}
							}
						}
							
					break;
					
					case "escape":
						if (finalLowBound != "null") {
							boundary = finalLowBound;
							
							if (element_value < boundary) {
								bConfirm = 		window.confirm	("Your entry of " + 
												element_value + " for\n" + 
												label + "\n" + 
												"is shorter than the length we expect,  " +
												boundary + ".\n\n" +
												"Are you sure this entry is correct?");
								if (!bConfirm) {
									elementPass = false;
								}
							}
						}
						
						if (finalHighBound != "null") {
							boundary = finalHighBound;
	
							if (element_value > boundary) {
								bConfirm = 		window.confirm	("Your entry of " + 
												element_value + " for\n" + 
												label + "\n" + 
												"is longer than the length we expect,  " +
												boundary + ".\n\n" +
												"Are you sure this entry is correct?");
								if (!bConfirm) {
									elementPass = false;
								}
							}
						}
		
					break;
					
					case "numeric":
					case "currency":
						element_value = element_value.replace(/[^0-9.]/,"");

						if (isNaN(element_value)){
							window.alert(label + " is not a number");
							elementPass = false;
							break;
						}

						if (finalLowBound != "null") {
							boundary = finalLowBound;
	
							if (parseFloat(element_value) < parseFloat(boundary)) {
								bConfirm = 		window.confirm	("Your entry of " + 
												element_value + " for\n" + 
												label + "\n" + 
												"is smaller than the value we expect,  " +
												boundary + ".\n\n" +
												"Are you sure this entry is correct?");
								if (!bConfirm) {
									elementPass = false;
								}
							} 
						}
						
						if (finalHighBound != "null") {
							boundary = finalHighBound;
	
							if (parseFloat(element_value) > parseFloat(boundary)) {
								bConfirm = 		window.confirm	("Your entry of " + 
												element_value + " for\n" + 
												label + "\n" + 
												"is larger than the value we expect,  " +
												boundary + ".\n\n" +
												"Are you sure this entry is correct?");
								if (!bConfirm) {
									elementPass = false;
								}
							}
						}
					break;
				}
			}
			
			if (bConfirm) {
				element_to_check.style.backgroundColor = "#ffffff";
			} else {
				element_to_check.style.backgroundColor = "#ff9999";
			}
			
			if (!elementPass) {
				submitForm = false;
			}
		}
	}
	
	if (submitForm == false){
		//window.alert('Boundaries Exceeded');
		return false;
	} else {
		return true;
	}
} //End frontEndSoftBoundaryCheck

function frontEndRequireCheck(){
	var queryString = location.search;
	var RE = /action=review/;

	//test to see if user is just reviewing data. if so, don't check req'd fields
	if (RE.test(queryString) == false){
		for(var i=0; i <  requiredArray.length; i++){
			
			var thisElement = document.getElementById(requiredArray[i]);
			var requiredCheck = false;

			//window.alert(requiredArray[i]);
			//window.alert(requiredArray[i] + " : " + thisElement.id);
			//window.alert(requiredArray[i] + " : " + thisElement.tagName + " : " + thisElement.type);
			
			/*handle SELECT boxes.  If value is not invalidddl, then an option has been selected.*/
			if (thisElement.tagName == 'SELECT') {
				if (thisElement.value != 'invalidddl'){
					requiredCheck = true;
				}
			/*handle hidden variables and checkboxes.
				If field has a value, then pass.
				If a checkbox is true, then pass.
			*/
			} else if(thisElement.type == 'hidden') {
				if(document.getElementById(thisElement.id +  "_chk")) {
					//window.alert(thisElement.id + " : " + thisElement.value.toLowerCase());
					if (thisElement.value.toLowerCase() == "true") {
						requiredCheck = true;
					}
				} else {
					//window.alert(thisElement.value.length);
					if (thisElement.value.length > 0){
						requiredCheck = true;
					}
				}
			/* handle radio buttons. If one of the children of the radio node is checked, then pass*/		
			} else if(thisElement.id.slice(0,5) == "radio") {
				var radioGroup = thisElement.title;
				//window.alert('radio group : ' + radioGroup);
				k = document.getElementById("coreForm");
				for(var z=0; z < k.length; z++){
					if (k.elements[z].name == radioGroup) {
						//window.alert("matched : " + k.elements[z].name + "Value: " + k.elements[z].value + " Checked? " + k.elements[z].checked);
						if (k.elements[z].checked){
							if (k.elements[z].value != 'nullradio') {
								//window.alert(k.elements[z].name + " : passed with " + k.elements[z].value);
								requiredCheck = true;
							}
						}
					}
				}
			} else if(thisElement.type == 'text') {
				if (thisElement.value.length > 0){
					requiredCheck = true;
				}
			} else if(thisElement.type == 'textarea') {
				if (thisElement.value.length > 0) {
					requiredCheck = true;
				}
			}
			
			//window.alert(requiredArray[i] + " : " + requiredCheck);
			
			if(requiredCheck == false){
				/**/
				//window.alert(thisElement.tagName);
				var submitForm = false;
				if (thisElement.type == 'hidden') {
					if(document.getElementById(thisElement.id +  "_chk")) {
						var chkBoxName = requiredArray[i] + "_chk";
						document.getElementById(chkBoxName).parentNode.style.backgroundColor = "#ff9999";
						document.getElementById(chkBoxName).focus();
					}
				} else if(thisElement.tagName == 'P') {
					thisElement.style.backgroundColor = "#ff9999";
				} else {
					thisElement.style.backgroundColor = "#ff9999";
					thisElement.focus;
				}
			} else {
				//window.alert(thisElement.name);
				if (thisElement.type == 'hidden') {
					var chkBoxName = requiredArray[i] + "_chk";
					if (document.getElementById(chkBoxName)) {
						document.getElementById(chkBoxName).parentNode.style.backgroundColor = "#ffffff";
					}
				} else {
					thisElement.style.backgroundColor = "#ffffff";
				}
			}
		}
	} else {
		// review action always submits the form.
		submitForm = true;
	}


	if (submitForm == false){
		window.alert('Please fill in missing fields.');
		return false;
	} else {
		return true;
	}
} //End frontEndRequireCheck

function modLocalBoundary(sBoundToMod,sCType){
	var modRE = /\((.+)\)/
	
	if (modRE.test(sBoundToMod)){
		var	aMod = sBoundToMod.match(modRE);
		var sModCommand = aMod[1];
		
		var sBoundToMod = sBoundToMod.replace(modRE,"");
	} else {
		var sModCommand = "";
	}

	switch(sCType){
		case "date":
			if (dateCheck(sBoundToMod,"jscsv")){
				var dBoundary = dateFormat(sBoundToMod,"jscsv","js");
			} else if (dateCheck(sBoundToMod,"input")) {
				var dBoundary = dateFormat(sBoundToMod,"input","js");
			}
			
			if (dBoundary != null) {
				var sBoundMod = "dBoundary.getDate() " + sModCommand;
				var modifedBoundary = dBoundary.setDate(eval(sBoundMod));
//	Adding dates returns a string of milliseconds. Reformat back to a date.
				var dBnd = new Date;
				dBnd.setTime(modifedBoundary);			
				var finalBoundary = dBnd;
			} else {
				finalBoundary = sBoundToMod;
			}
		break;
		
		case "escape":
			var sBoundMod = "parseInt(sBoundToMod)" + sModCommand;
			var finalBoundary = eval(sBoundMod);	
		break;
		
		case "numeric":
		case "currency":
			var temp = eval(sBoundToMod);
			var sBoundMod = "parseFloat(temp)" + sModCommand;
			var finalBoundary = eval(sBoundMod);
		break;
	}
	
	return finalBoundary;
} //End modLocalBoundary

function runLockForm() {
/*
	Cycles through all children of all forms on the page & looks for 
		-P elements (which, thanks to the form builder, always wrap Radio and Checkboxes)
		-INPUT children of P elements are checked to see if they are a) checked and b) call a fucntion when OnClick is fired.
	The onClick function calls are taken and the arguments of formLock are put into an array.
	After cycling through all Forms, the array of formLock arguments is passed to formLock.
	Thus, all form elements that should be hidden are hidden when the page loads.
*/		
	var finalLockArray = new Array();
	var finalRequireArray = new Array();

	var fromLockString;
		
	for (f=0; f < document.forms.length; f++){
		var t = document.forms[f];
			
		for (i=0; i < t.childNodes.length; i++){
			if (t.childNodes[i].tagName == 'P'){
				var n = t.childNodes[i];
				for (g=0; g < n.childNodes.length; g++) {
					if (n.childNodes[g].tagName == "INPUT"){
						//window.alert(n.childNodes[g].name);
						if(n.childNodes[g].attributes.getNamedItem('onclick')){
							if(n.childNodes[g].checked == true){
								//window.alert(n.childNodes[g].name);
								var y = n.childNodes[g].attributes.getNamedItem('onclick').value;
								var aAttr = y.split(";");
										
								for(h=0; h < aAttr.length; h++) {
									//window.alert(aAttr[h].slice(0,11));

									if (aAttr[h].slice(0,8) == "formLock") {
										var e = aAttr[h];
												
										var RE = /formLock\('/;
										sRep = e.replace(RE,"");
																			
										RE = /'\)/;
										sRep = sRep.replace(RE,"");
											
										var tempLockarray = sRep.split(",");
											
										for (var k=0;k < tempLockarray.length; k++) {
											finalLockArray.push(tempLockarray[k]);
										}
									} else if (aAttr[h].slice(0,11) == "formRequire") {
										var l = aAttr[h];
												
										var RE = /formRequire\('/;
										sRep = l.replace(RE,"");
																
										RE = /'\)/;
										sRep = sRep.replace(RE,"");
											
										var tempReqArray = sRep.split(",");
											
										for (var m=0;m < tempReqArray.length; m++) {
											finalRequireArray.push(tempReqArray[m]);
										}
									}
								}
							} else {
								//window.alert(n.childNodes[g].name);
								var y = n.childNodes[g].attributes.getNamedItem('onclick').value;
								var aAttr = y.split(";");
										
								for(h=0; h < aAttr.length; h++) {
									//window.alert(aAttr[h].slice(0,11));

									if (aAttr[h].slice(0,10) == "formUnlock") {
										var e = aAttr[h];
												
										var RE = /formUnlock\('/;
										sRep = e.replace(RE,"");
																			
										RE = /'\)/;
										sRep = sRep.replace(RE,"");
											
										var tempLockarray = sRep.split(",");
											
										for (var k=0;k < tempLockarray.length; k++) {
											finalLockArray.push(tempLockarray[k]);
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}

	formLockString = finalLockArray.join(",");
	formRequireString = finalRequireArray.join(",");
	//window.alert(formLockString);
	//window.alert(formRequireString);
	
	if (formLockString.length > 0) {
		formLock(formLockString);
	}

	if (formRequireString.length > 0) {
		formRequire(formRequireString);
	}
} //End runLockForm

function runUnlockForm() {
	var finalUnlockArray = new Array();
	var finalUnrequireArray = new Array();

	var fromUnlockString;
		
	for (f=0; f < document.forms.length; f++){
		var t = document.forms[f];
			
		for (i=0; i < t.childNodes.length; i++){
			if (t.childNodes[i].tagName == 'P'){
				var n = t.childNodes[i];
				for (g=0; g < n.childNodes.length; g++) {
					if (n.childNodes[g].tagName == "INPUT"){
						//window.alert(n.childNodes[g].name);
						if(n.childNodes[g].attributes.getNamedItem('onclick')){
							if(n.childNodes[g].checked == true){
								//window.alert(n.childNodes[g].name);
								var y = n.childNodes[g].attributes.getNamedItem('onclick').value;
								var aAttr = y.split(";");
										
								for(h=0; h < aAttr.length; h++) {
									//window.alert(aAttr[h].slice(0,11));

									if (aAttr[h].slice(0,10) == "formUnlock") {
										var e = aAttr[h];
												
										var RE = /formUnlock\('/;
										sRep = e.replace(RE,"");
																			
										RE = /'\)/;
										sRep = sRep.replace(RE,"");
											
										var tempUnlockarray = sRep.split(",");
											
										for (var k=0;k < tempUnlockarray.length; k++) {
											finalUnlockArray.push(tempUnlockarray[k]);
										}
									} else if (aAttr[h].slice(0,13) == "formUnrequire") {
										var l = aAttr[h];
												
										var RE = /formUnrequire\('/;
										sRep = l.replace(RE,"");
																
										RE = /'\)/;
										sRep = sRep.replace(RE,"");
											
										var tempUnreqArray = sRep.split(",");
											
										for (var m=0;m < tempUnreqArray.length; m++) {
											finalUnrequireArray.push(tempUnreqArray[m]);
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}

	formUnlockString = finalUnlockArray.join(",");
	formUnrequireString = finalUnrequireArray.join(",");
/*
	window.alert(formUnlockString);
	window.alert(formUnrequireString);
*/

	if (formUnlockString.length > 0) {
		formUnlock(formUnlockString);
	}

	if (formUnrequireString.length > 0) {
		formUnrequire(formUnrequireString);
	}
} //End runUnlockForm

function sumFieldUpdate() {
	for (var index = 0; index < sumFieldArray.length; ++index) {
		field_to_update = sumFieldArray[index][0];

		var element_to_update = document.getElementById(field_to_update);

		var sCompareType = sumFieldArray[index][1];
		var sRawCalc = sumFieldArray[index][2];
		var sMessage = sumFieldArray[index][3];
		
		//window.alert(sRawCalc);

		var sTempCalc = formBoundsToValues(sRawCalc,sCompareType);

		//window.alert(sTempCalc);

		var sFinalCalc = modLocalBoundary(sTempCalc,sCompareType);
		
		//window.alert(sFinalCalc);

		if (isNaN(sFinalCalc)) {
			element_to_update.value = "-"
		} else {
			element_to_update.value = sFinalCalc;
		}
	}
} //End sumFieldUpdate

function updateTooltip(sTooltipId) {
	var x = document.getElementById(sTooltipId);
	var RE = /\*(.+)\*/;
	
/*
	for (i=0; i < x.childNodes.length; i++){
		var y = x.childNodes[i];
		window.alert(y.nodeType + " : " + (y.nodeValue != null));
		if (y.nodeType == 3 && RE.exec(y.nodeValue) != null) {
			x.replaceChild(document.createTextNode("booga!"), y);
			window.alert("replacing");
		}
	}
*/
}