// STANDARD/Share/CustomForm.js
// Client-side functions used in Quick and Custom Search pages

// IMPORTANT NOTE:
//
// If you want this interface to save hidden form values, then
// you must send the second parameter to SaveForm and third
// parameter to SetForm as a boolean value of true so they
// will save and set the hidden form fields. The default behavior
// is to IGNORE hidden form fields.

//-------------------------------------------------------------------
//
// SaveForm()
//
// This function iterates through the given form saving all of the
// form values in an encoded string.
//
//   oForm   --  The form to save
//   bHidden --  Flag value for whether to save hidden form fields
//   Returns --  An encoded string suitable for sending to the server side routines
//               which save the form data.
//
function SaveForm(oForm, bHidden, bEmpty) {
  var szTmp = new String(), 
      sz2 = new String(),
      aRadios = new Array(),
      i, j, idx,
      bSeen = false;

	// Go through each of the form elements and save the values.
	for (i = 0; i < oForm.elements.length; i++) {
		// Now interrogate the contents of the form element.
		if ( (oForm.elements[i].type == "hidden" ) &&
		     (bHidden == true)                     && 
		     (oForm.elements[i].name == "totalform"))  {
			continue; // Don't save our own value.
		}
		if (( bHidden == true ) &&
		    ( oForm.elements[i].type == "hidden" ))  {
		  if (oForm.elements[i].value != "" || (oForm.elements[i].value == "" && bEmpty == true)) {
		    if (szTmp.length > 0) szTmp += "@@";
		    szTmp += EscapeAt(oForm.elements[i].name) + "="; 
		    sz2 = oForm.elements[i].value;
		    if (sz2>'') {
				 	sz2 = new String(sz2.replace(/"/g,"'"));
		    } else {
					sz2 = new String('');
		    }
		    szTmp += EscapeAt(sz2);
		  }
		} else if ( oForm.elements[i].type == "text" ) {
		  if (oForm.elements[i].value != "" || (oForm.elements[i].value == "" && bEmpty == true)) {
				if (szTmp.length > 0) szTmp += "@@";
				szTmp += EscapeAt(oForm.elements[i].name) + "=";
				sz2 = oForm.elements[i].value;
				if (sz2>'') {
					sz2 = new String(sz2.replace(/"/g,"'"));
				} else {
					sz2 = new String('');
				}
				szTmp += EscapeAt(sz2);
			}
		} else if ( oForm.elements[i].type == "textarea" ) {
			if (oForm.elements[i].value != "" || (oForm.elements[i].value == "" && bEmpty == true)) {
				if (szTmp.length > 0) szTmp += "@@";
				szTmp += EscapeAt(oForm.elements[i].name) + "=";
				sz2 = oForm.elements[i].value;
				if (sz2>'') {
					sz2 = new String(sz2.replace(/"/g,"'"));
				} else {
					sz2 = new String('');
				}
			szTmp += EscapeAt(sz2);
			}
		} else if ( oForm.elements[i].type == "checkbox" ) {
			if (szTmp.length > 0) szTmp += "@@";
			szTmp += EscapeAt(oForm.elements[i].name) + "=";
			if (oForm.elements[i].checked == true) {
			  szTmp += "checked";
			} else {
			  szTmp += "unchecked";
			}
		} else if ( oForm.elements[i].type == "radio" ) {
			bSeen = false;
			// First check and see if we have seen this radio button already.
			for (idx = 0; idx < aRadios.length; idx++) {
				if (aRadios[idx] == oForm.elements[i].name) bSeen = true;
			}
			if (bSeen == false) {
			  aRadios[aRadios.length] = oForm.elements[i].name;  // save this name
			  if (szTmp.length > 0) szTmp += "@@";
			  szTmp += EscapeAt(oForm.elements[i].name) + "=";
			  var oRadio = eval("oForm." + oForm.elements[i].name);

			  for (j = 0; j < oRadio.length; j++) {
			    if (oRadio[j].checked == true) {
						szTmp += EscapeAt(oRadio[j].value);
						break;
					}
			  }
			}
		} else if ( oForm.elements[i].type == "select-one" ) {
			var oSelect = eval("oForm." + oForm.elements[i].name);
			if (oSelect.selectedIndex > -1) {
				if (szTmp.length > 0) szTmp += "@@";
				szTmp += EscapeAt(oForm.elements[i].name) + "=";
				szTmp += EscapeAt(oSelect.options[ oSelect.selectedIndex ].value);
			}
		} else if ( oForm.elements[i].type == "select-multiple" ) {
			var oSelect = eval("oForm." + oForm.elements[i].name);
			for (j = 0; j < oSelect.length; j++) {
			  if (oSelect.options[j].selected == true) {
					if (szTmp.length > 0) szTmp += "@@";
					szTmp += EscapeAt(oForm.elements[i].name) + "=" + 
					         EscapeAt(oSelect.options[j].value);
				}
			}
		}
	}		// End for each form element

  if (szTmp.length > 0) szTmp += "@@";
  return szTmp;
}

//-------------------------------------------------------------------
//
// Global values used for manipulating the form data values.
//
var aNames = new Array(),
    aValues = new Array();

//
// ParseFormData
//
// Take the encoded string and parse into component values.
//
//   szData  --  The encoded data values.
//
function ParseFormData(szData) {
	var szTmp = new String();
	var i, j, idx;

	szData = new String(szData);
	aNames = new Array();
	aValues = new Array();

	// First break up the data string and save the values.
	idx = 0;
	i = 0;
	while (i < szData.length) {
		l = szData.indexOf("@@", i);  // find index of first component.
		if (l == -1) {
			i = szData.length;
			continue;
		}

		// Parse out the name-value pair.
		szTmp = szData.substring(i, l);
		// Advance the pointer
		i = l + 2; // Allow for the @@

		// Remove any escape sequences we added.
		szTmp = UnEscapeAt(szTmp);
		// Now we must break up the substring
		e = szTmp.indexOf("=");
		aNames[idx] = szTmp.substring(0, e);
		aValues[idx] = szTmp.substring((e+1), szTmp.length);
		idx++;
	}
}

//
// SetForm
//
// This function takes an encoded form data string and a pointer to
// a form to set.
//
//   oForm   --  Pointer to the form.
//   szData  --  The encoded data values.
//   bHidden --  Flag value for whether to set hidden fields
//   Returns --  Nothing.
//
function SetForm(oForm, szData, bHidden, bClearVal) {
	var szTmp = new String();
	var i, j, idx;
	
	// Make sure we have some data
	if ((typeof(szData) == "undefined") || (szData.length < 1)) return;
	ParseFormData(szData);
	
	var txtTmp = new String();
	// Now we must iterate through the form elements and match names.
	for (i = 0; i < oForm.elements.length; i++) {
		// Now interrogate the contents of the form element.
		if (( bHidden == true )&&
		    ( oForm.elements[i].type == "hidden")) {
			oForm.elements[i].value = GetVal(oForm.elements[i].name);
		} else if ( oForm.elements[i].type == "text" ) {
			txtTmp = GetVal(oForm.elements[i].name);
			if (bClearVal == true) {
				if (txtTmp != "") {
					oForm.elements[i].value = txtTmp;
				}
			}	else {
				oForm.elements[i].value = GetVal(oForm.elements[i].name);
			}
					
		} else if ( oForm.elements[i].type == "textarea" ) {
			txtTmp = GetVal(oForm.elements[i].name);
			if (bClearVal == true) {
				if (txtTmp != "") {
					oForm.elements[i].value = txtTmp;
				}
			} else {
			  oForm.elements[i].value = GetVal(oForm.elements[i].name);
			}
		} else if ( oForm.elements[i].type == "checkbox" ) {
		  if (GetVal(oForm.elements[i].name) == "checked") {
				oForm.elements[i].checked = true;
		  } else {
		    oForm.elements[i].checked = false;
		  }
		} else if ( oForm.elements[i].type == "radio" ) {
			szTmp = GetVal(oForm.elements[i].name);
			szTmp = szTmp.toLowerCase();
			if (oForm.elements[i].value.toLowerCase() == szTmp) {
				oForm.elements[i].checked = true;
			} else {
			  oForm.elements[i].checked = false;
			}
		} else if ( oForm.elements[i].type == "select-one" ) {
		  var oSelect = eval("oForm." + oForm.elements[i].name);
		  szTmp = GetVal(oForm.elements[i].name);
		  szTmp = szTmp.toLowerCase();
		  for (j = 0; j < oSelect.length; j++) {
		    if (oSelect.options[j].value.toLowerCase() == szTmp) {               
					oSelect.options[j].selected = true;
		    } else {
		      oSelect.options[j].selected = false;
		    }
		  }
		} else if ( oForm.elements[i].type == "select-multiple" ) {
		  var oSelect = eval("oForm." + oForm.elements[i].name);
		  szTmp = GetValMul(oForm.elements[i].name);
		  for (j = 0; j < oSelect.length; j++) {
		    // First turn off any that are selected.
		    oSelect.options[j].selected = false;
		    if (CheckArray(oSelect.options[j].value.toLowerCase(), szTmp) == true) {
					oSelect.options[j].selected = true;
				} else {
					oSelect.options[j].selected = false;
				}
		  }
		}   
	}		// End for each form element
	   
  return;
}

//-------------------------------------------------------------------
//
//  The following functions are the same in both CustomForm.js and
//  CustomForm.inc. Any changes made to one file should be reflected
//  in the other file.
//
//-------------------------------------------------------------------
//
// EscapeAt
//
// This function escapes any @ symbols in the data so they will not
// interfere with the @@ delimiter sequence.
//
//   szString --  Input string to encode
//   Returns  --  Encoded string (@ symbols escaped)
//
function EscapeAt(szString) {
	var i;
	var szTmp = new String();

	for (i = 0; i < szString.length; i++) {
		if (szString.charAt(i) == "@") {
			//szTmp += "\\@ ";
			szTmp += "~@~";
		} else {
			szTmp += szString.charAt(i);
		}
	}
	return szTmp;
}

//-------------------------------------------------------------------
//
// UnEscapeAt
//
// This function removes any escape sequences added to the @ symbol.
//
//   szString --  Input string to unencode
//   Returns  --  Unencoded string (@ symbols unescaped)
//
function UnEscapeAt(szString) {
	var i;
	var szTmp = new String();

	i = 0;
	while (i < szString.length) {
		if ( (szString.charAt(i) == '~')  && 
				(szString.charAt(i+1) == "@") && 
				(szString.charAt(i+2) == '~')    ) {      
			szTmp += "@";
			i += 3;
		} else {
			szTmp += szString.charAt(i);
			i++;
		}
	}
	return szTmp;
}

//-------------------------------------------------------------------
//
// GetVal
//
// Return a single value field given the fieldname.
//
//   szFieldName  --  The fieldname value to retrieve.
//   Returns      --  The value or empty string if not found.
//
function GetVal(szFieldName) {
	var idx;
	for (idx = 0; idx < aNames.length; idx++) {
		if (aNames[idx].toLowerCase() == szFieldName.toLowerCase()) {
			return new String(aValues[idx]);
		}
	}
	return "";
}

//-------------------------------------------------------------------
//
// GetValMul
//
// Return a multi-value field given the field name. An array of
// string values is returned.
//
//   szFieldName  --  The fieldname value to retrieve.
//   Returns      --  An array of strings with the multiple values.
//
function GetValMul(szFieldName) {
	var idx, i;
	var aTmp = new Array();

	i = 0;
	for (idx = 0; idx < aNames.length; idx++) {
	  if (aNames[idx].toLowerCase() == szFieldName.toLowerCase()) {
			aTmp[i] = new String(aValues[idx]);
			i++;
	  }
	}

	if (i == 0) { // No values found, put one empty value in first
	  aTmp[0] = new String("");
	}
	return aTmp;
}

//-------------------------------------------------------------------
//
// CheckArray
//
// This function is used server-side as a shortcut function to compare the
// stored values with what is present on the form. Using this function, you
// can set the initial values on a multi-select listbox by passing it the
// previously retrieved form values array and the value to check it against.
//
//   szVal    --  The string to match against.
//   aTmp     --  The array to match with.
//   Returns  --  true if a match is found. false otherwise.
//
function CheckArray(szVal, aTmp) {
	var i;

	for (i = 0; i < aTmp.length; i++) {
		if (szVal == aTmp[i].toLowerCase()) return true;
	}
	return false;
}
//-------------------------------------------------------------------
//  END functions that are the same in both CustomForm.js and
//  CustomForm.inc
//-------------------------------------------------------------------

//-------------------------------------------------------------------
//
// ClearForm()
//
// This function iterates through the given form clearing all values.
// If it finds a label of "No Value Selected" in a multi-select
// listbox, it will reset the value to nothing. This resets multi
// values which have been overloaded into the first selection.
//
//   oForm   --  The form to save
//   Returns --  Nothing.
//
function ClearForm(oForm) {

	// Go through each of the form elements and save the values.
	for (i = 0; i < oForm.elements.length; i++) {
		// Now interrogate the contents of the form element.
		if (( oForm.elements[i].type == "text" ) || 
				( oForm.elements[i].value == "hidden")) {
			oForm.elements[i].value = '';
		} else if ( oForm.elements[i].type == "textarea" ) {
		  oForm.elements[i].value = '';
		} else if ( oForm.elements[i].type == "checkbox" ) {
		  oForm.elements[i].checked = false;
		} else if ( oForm.elements[i].type == "radio" ) {
		  var oRadio = eval("oForm." + oForm.elements[i].name);
			for (j = 0; j < oRadio.length; j++) {
				oRadio[j].checked = false;
			}
		} else if (( oForm.elements[i].type == "select-one" ) ||
					( oForm.elements[i].type == "select-multiple" )) {
		  var oSelect = eval("oForm." + oForm.elements[i].name);
		  for (j = 0; j < oSelect.length; j++) {
		    oSelect.options[j].selected = false;
		    if (oSelect.options[j].text == 'No Value Selected') {
		      oSelect.options[j].value = '';
		    }
		  }
		}
	}		// End for each form element

	return;
}


//-------------------------------------------------------------------
//
// JFormGet
//
// This function combines several smaller functions into a single wrapper,
// and assumes we are using JFormPut to save the form values.
// This is the "get" that should be done to retrieve the form data.
// This assumes that the FormName provided is the first form on the page.
//
function JFormGet (FormName, bHidden, parentReference) {
	if (typeof(parentReference) == "undefined") {
		var parentReference = "";
	} else {
		parentReference += ".";
	}

	// Get Form values from UtilityFrame; if FormName is not in UtilityFrame, no values are retrieved
  if (bHidden == true) {
    eval("SetForm(document.forms[0], " + parentReference + "parent.UtilityFrame." + FormName + ", true);");
  } else {
    eval("SetForm(document.forms[0], " + parentReference + "parent.UtilityFrame." + FormName + ", false);");
  }
}


//-------------------------------------------------------------------
//
// JFormPut
//
// This function combines several smaller functions into a single wrapper,
// and assumes we are using JFormGet to retrieve the form values.
// This is the "put" that should be done to save the form data.
// This assumes that the FormName provided is the first form on the page.
//
function JFormPut (FormName, bHidden, frameReference, parentReference) {
  if (typeof(frameReference)=='undefined') {
  	var frameReference="";
  } else if (frameReference!='') {
	  frameReference += '.';
  }
  
  if (typeof(parentReference)=='undefined') {
  	var parentReference="";
  } else {
	  parentReference += '.';
  }

	// Save form values to the UtilityFrame; creates variable in UtilityFrame, if it doesn't already exist
  if (bHidden == true) {
    eval(parentReference + "parent.UtilityFrame." + FormName + " = SaveForm(eval(frameReference + 'document.forms[0]'), true);");
  } else {
    eval(parentReference + "parent.UtilityFrame." + FormName + " = SaveForm(eval(frameReference + 'document.forms[0]'), false);");
  }

  // Not sure what this does ~ pbs ~ 2005-05-05
  var sParms = "user=" + eval(parentReference + 'parent.UtilityFrame.szUIDMember');
      sParms += "&form=" + FormName;		
      sParms += "&type=user";
  eval('sParms += "&data=" + escape(' + parentReference + 'parent.UtilityFrame.' + FormName + ')');
}


function SizeForm(oForm) {
	var
	  i,
	  len = 0;
	      
	// Go through each of the form elements and get the length
	for (i = 0; i < oForm.elements.length; i++) {
	  // Generic for the name of the field
	  if ((oForm.elements[i].type == "select-one") ||(oForm.elements[i].type == "select-multiple")) {
	    for (j = 0; j < oForm.elements[i].options.length; j++) {
	      if (oForm.elements[i].options[j].selected == true) {
	        len += oForm.elements[i].options[j].value.length +
	               oForm.elements[i].name.length + 1;
	      }
	    }
	  } else {
	    if (oForm.elements[i].value==null) {
	 	    len += oForm.elements[i].name.length  +1;
	    } else {
	 	    len += oForm.elements[i].name.length + oForm.elements[i].value.length +1;
	    } 
	  }
	}		// End for each form element
	return(len);
}

function CheckAndSubmit(fname) {
	if ((SizeForm(fname)+fname.action.length) > 1024) {
		fname.method = "post";
		fname.enctype="application/x-www-form-urlencoded";
	} else {
		fname.method = "get";
		fname.enctype="application/x-www-form-urlencoded";
	}
	fname.submit();
}

function FormIsEmpty(oForm) {
	var bIsEmpty = true,
		oItem = null,
		sType = "",
		sValue = "";
		
	for(var i = 0; i < oForm.length; i++) {
		oItem = oForm.item(i);
		sType = oItem.type.toLowerCase();
		sValue = oItem.value;
		
		if ((sType == "text" || sType == "textarea" || sType == "select-one" || sType == "select-multiple") && sValue != "") {
			bIsEmpty = false;
		} else if (sType == "checkbox" && oItem.checked == true) {
			bIsEmpty = false;
		}
	}
	return(bIsEmpty);
}

// Added function for caching Custom Search criteria client-side ~ VI 54643 ~ pbs ~ 2005-05-05
//============================================================================================
//	This function clears the Custom Search cached form values in UtilityFrame: Srh[PropType]Custom,
//	if it exists.
//		Arguments
//			sPropType = PropType (there is a separate variable for each Prop Type)
//		Returns
//			None
//			If it exists, sets parent.UtilityFrame.Srh[PropType]Custom = ""
//============================================================================================
function fClearCSCacheValues (sPropType) {    
	var sUtlFrameVarName = new String ("");
	var sPropType        = new String (sPropType).toLowerCase();
	
	// Utility Frame variable name is case-sensitive - PropType must be in form Xxx
  sPropType = sPropType.substr(0,1).toUpperCase() + sPropType.substr(1,sPropType.length);
	
  // Get Utility Frame variable name
	sUtlFrameVarName = "Srh" + sPropType + "Custom";

  // Clear all cached Custom Search values
	if ( (typeof (eval ("parent.UtilityFrame." + sUtlFrameVarName)) != "undefined") 
	    && ( eval ("parent.UtilityFrame." + sUtlFrameVarName) != "undefined") ) 
	{
		eval ("parent.UtilityFrame." + sUtlFrameVarName + "= ''");
	}
}


// Added function to correct client-side information when SearchName changes ~ VI 70025 ~ pbs ~ 2006-02-18
//============================================================================================
//	This function corrects the client-side custom search criteria, in the following cases:
//	  1) User changes the SearchName of an existing search on CusSrh.asp page
//	  2) User changes the SearchName of an existing search in the textbox on CustEdit.asp page
//	  3) User changes the SearchName by selecting another search from the CustomSearchList on CustEdit.asp page
//
//  The calling page determines that there is a new search before calling this function
//  
//  	Arguments
//	    sPropType       - Property Type
//      sExistingID     - SearchID when page is first loaded
//      sExistingName   - SearchName when page is first loaded
//      sNewID          - SearchID for new search
//      sNewName        - SearchName for new search
//     
//		Returns
//			None
//			In parent.UtilityFrame.Srh[PropType]Custom variable,
//			    replaces sExistingID, sExistingName with sNewID, sNewName
//============================================================================================
function fFixClientSideCriteria (sPropType, sExistingID, sExistingName, sNewID, sNewName) {
  var sExistingSearchID   = new String (sExistingID);
  var sExistingSearchName = new String (sExistingName);
  var sNewSearchID        = new String (sNewID);
  var sNewSearchName      = new String (sNewName);
  var sPropType           = new String (sPropType).toLowerCase();
  
	// Utility Frame variable name is case-sensitive - PropType must be in form Xxx
  sPropType = sPropType.substr(0,1).toUpperCase() + sPropType.substr(1,sPropType.length);
  var sUtlFrameVarName = "Srh" + sPropType + "Custom";

  // Regular expressions for necessary replacements
  var reSearchID    = new RegExp("@@SearchID=.*?@@", "ig");
  var reID          = new RegExp("@@ID=.*?@@", "ig");
  var reSearchName  = new RegExp("@@SearchName=.*?@@", "ig");

  var sCriteria     = new String (eval("parent.UtilityFrame." + sUtlFrameVarName));

  sCriteria = sCriteria.replace (reSearchID, "@@SearchID=" + sNewSearchID + "@@");
  sCriteria = sCriteria.replace (reID, "@@ID=" + sNewSearchID + "@@");
  sCriteria = sCriteria.replace (reSearchName, "@@SearchName=" + sNewSearchName + "@@");

  // Save new SearchID, Search Name to Utility Frame ~ VI 70025
  if ((typeof(parent.UtilityFrame.SearchName) != "undefined") 
      && (typeof(parent.UtilityFrame.SearchID) != "undefined"))
  {    // May not be defined coming from QS or first time called
    parent.UtilityFrame.SearchName = sNewSearchName;
    parent.UtilityFrame.SearchID = sNewSearchID;
    
  }
	eval ("parent.UtilityFrame." + sUtlFrameVarName + " = sCriteria;");
}

