// Version 4.0  released 3/13/2006
// Version 4.0  Last Modified 11/2/2006
// Version 4.0  Last Modified 4/13/2007
// Added more getAttribute notation is validate this form

// 4/13/2007
// CancelEvent was added

//3/13/2006
// In general this library is backwardly compatible with all previous versions, but has been cross browser tested 
// particularly in the use of getAttribute in the form validation piece.
// Also a library prefs object was added.  so far the only property is version and debugFlg

// SetRecAction and DeleteThisRecord have been removed.

// Version 3.1 Released 8/25/2005 //
// version 3.1 last modified 12/9/2005
// added GetItemFromNvArray()
// added IntegerCompare()

// NOTE .... before deploying this into your project check to makes sure you don't have
//           name space conflicts with the two new fuctions.

// Version 3.1 Released 8/25/2005 //
// Change History //
// 12/6/2005 dk fixed problems with IsDate functions, solving bug with dates entered with .'s
// 12/9/2005 dk added additional logic to IsDate the function myDate.split("/").length must = 3

// Version 3.0  Released 6/7/2004
// version 3.0 last modified 9/29/2004 
// Change History //
// 9/29/2004 dk fixed an error in GetFileInfo()

// Version 2.0  LastModified 05/20/2004
// Change History //
// V2.0
// 07/11/2003  Added:
//   GetFieldValue(f), GetFieldSelectedName(f),  GetFieldInfo(f, returnType)
//   function SetFieldValue(f, selectedValue), UpdateSelectOptions(frmControl,nvOptionsArray,selectedValue)

// 03/03/2004 DK Edited GetFieldInfo, correcting a problem with a loop counter <=lenght, changed to < length
// this change would affect GetFieldValue() when getting the value of a set of radio buttons where no option is selected.
// Additional results from GetFieldInfo() now correctly handles radio, checkbox and multiselect controls
// 05/14/2004 GetFieldInfo() significantly enhances, bug fixes
// 05/14/2004 Added these functions
// ConvertDateStringToFourDigitYear(dateString), DateCompare(dateFrom,dateTo,compareType)
// GetFileInfo(url,infoType), GetIDStrFromCheckboxes(controlName), SetCheckboxes(controlName,State)

var PrefsFormsLib = new LibraryPrefs();

function LibraryPrefs(){
  this.DebugFlg=false; // provided only for debug purpose 
  this.Version="4.0"
  /*5/15/07 sb added the below prefs for additional form validation*/
  this.CharacterFilter=1; /*values 0 = off, 1 - normal , additional values as necessary*/
  this.MaxEmailLength=75;  //this integer should be the same as the max length of the email field in the database .
  this.ReplaceChars= new Array("\"","'", ";",":","'",".","/","-"); /*NV pair of characters to replace*/
  this.StripChars= new Array("%","\x1B","\\","<",">","{","}");  /*list of characters to remove*/
}


function SetRecAction_OLD (idFld,action){
// alert("idfld: " + idFld)
//'<FunctionNotes>
//'  <Name>SetRecAction</Name>
//'  <Gets>
//  idFld is the name of the record id field ex Project_ID0; 
//  action is one of three key words Insert Update Delete</Gets>
//'  <Returns>nothing, but this changes the value of the RecAction field</Returns>
//'  <Author>kelleyd</Author>
//'  <DateModified>3/1/2002</DateModified>
//'  <Notes>
 // idFld is the name of the record id field ex Project_ID0
 // action is one of three key words Insert Update Delete
 // RecAction is a form field that contains a comma delimited list of fldname and actions, ex Project_ID0,Update,Project_ID1,Delete...
 // get the comma delimited list from the hidden field
//' </Notes>
//'</FunctionNotes>

  var rActionStr = theForm.RecAction.value;
 // if the RecAction field is empty add the current values
  if (rActionStr.indexOf(",") == -1){//string is probably empty
    theForm.RecAction.value= idFld + "," + action
    return ;
  }//end if
 // by this point we know there is something in the field, build an array from the string
  var rActionArray = rActionStr.split(",");  var len = rActionArray.length;  var k=0;
  while (k < len){//k is a counter, len is the length of the array
    if (idFld == rActionArray[k]) {//if table name and record number match
      rActionArray[k+1] = action;
      theForm.RecAction.value=rActionArray.join();// converts the array to a string
      return ;
    } //end if
   k = k + 2// increment counter
  }//end while
 // if you made it this far, the item was not found
  theForm.RecAction.value=rActionArray.join()+","+ idFld + "," + action
  return ;
}//end function

function DeleteThisRecord_OLD(idFld,fldNameList,indx){
//'<FunctionNotes>
//'  <Name>DeleteThisRecord</Name>
//'  <Gets>
// idFld - Record index field name Rec_ID, 
//  fldNameList - a comma delimited list of form element names, and 
//  indx - a record value, integer, 0-n </Gets>
//'  <Returns>n/a</Returns>
//'  <Author>kelleyd</Author>
//'  <DateModified>3/1/2002</DateModified>
//'  <Notes>This is used to delete child records on a form, the form is assumed to be called theForm. The function clears the values in each of the fields in fldNameList and adds idFld#,Delete to the RecAction form element</Notes>
//'</FunctionNotes>
  var fldNameArray=fldNameList.split(",")
  for (i=0;i<fldNameArray.length;i++){
    eval("theForm." + fldNameArray[i] + indx).value=""
  }//end for
  SetRecAction(idFld+indx,"Delete")//this updates the RecAction field element
}

function IsDate(dStr,displayErrors){
//'<FunctionNotes>
//'  <Name>IsDate</Name>
//'  <Gets>dStr a string value in m/dd/yy or yyyy format, 
//         displayError optional, default = true, control how errors are handled, when set to true, the user sees and error from this function, if false, the function shows no error alerts.</Gets>
//'  <Returns>True/False</Returns>
//'  <Author>kelleyd</Author>
//'  <DateModified>3/1/2002</DateModified>
//'  <Notes> verification of string value to be a valid date</Notes>
//'  <History>dk 8/8/03 corrected bug that appears in validating dates where users specified a month with more than 31 days.</History>
//'</FunctionNotes>
  if (displayErrors == null) displayErrors = true;
	var ErrStr = "", monthNameArray = new Array("","January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")
//tests to make sure the entered value is a valid date.  Returns True or false
	 dArray = new Array(3);
	 var result = 0,m,d,y;
 // pattern matching with regular expressions
 // this bit forces a user's date entry to split on dashes rather than
 // slashes so that either can be used in the form element value.
	 // finds a forward slash anywhere in the string
	 var pattern = /\//g;
	 // replacement string is a dash
	 var replacement = "-"
	 // finds and replaces all instances of pattern with replacement.  does nothing if no match is found
	 var dStr = dStr.replace(pattern,replacement);
	 //if (newDStr) { dStr = newDStr; }
	 dArray = dStr.split("-");
	 for (var i = 0; i < dArray.length; i++){
	   if (!IsInteger(dArray[i])) return false;
     if (dArray.length!=3 ) return false;
	 }
	 //so far all the values are numeric
	 //now test to see it this is a valid date
	m = dArray[0]; // parse date into variables
    d = dArray[1];
    y = parseInt(dArray[2]);
    if(y<100) {y = 2000 + y;}
  if (m<1 || m>12) ErrStr = ErrStr + "Month "+ m +" is out of range!\n";
   if (d<0 || d>31) ErrStr = ErrStr + "Day "+ d +" is out of range!\n";
  if ((m==4 || m==6 || m==9 || m==11) && d==31) {
  	ErrStr = ErrStr + "The month of " + monthNameArray[m] + " doesn't have 31 days!\n"
  }
  if (m == 2) { // check for february 29th
  	var isleap = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0));
  	  if (d>29 || (d==29 && !isleap)) {
    	ErrStr = ErrStr + "February '" + y + " doesn't have " + d + " days!\n";
  	  }
  }
			
  if (ErrStr == "")  return true;
  if (ErrStr !="" && displayErrors == true)  alert(ErrStr); 
  return false;
}	// end function		

function GetDateObject(dateStr){
  dArray = new Array(3);
  var returnDate, m, d, y, errFlg = false;
  var pattern = /\//g;
  var replacement = "-";
  var dStr = dateStr.replace(pattern,replacement);// finds and replaces all instances of pattern with replacement.  does nothing if no match is found
  dArray = dStr.split("-");
  for (var i = 0; i < dArray.length; i++){
    if (!IsNumeric(dArray[i])) errFlg=true;
  }
  if (dArray.length == 3 && errFlg !=true) { // this checks for array items before trying to parse them
    y = parseInt(dArray[2]);
    if( y < 100)  y = y + 2000;
    m = parseInt(dArray[0]) - 1
    d = parseInt(dArray[1])
    returnDate = new Date (y,m,d);
   }// end if
  return returnDate;
}

function FixThisDate(frmElement){
//'<FunctionNotes>
//'  <Name>FixThisDate</Name>
//'  <Gets>a object reference to a form elment</Gets>
//'  <Returns>sets the form element to a valid date formated as mm-dd-yyyy</Returns>
//'  <Author>kelleyd</Author>
//'  <DateModified>3/27/2002</DateModified>
//'  <Notes>use this function to be more tollerant of data entry error the user may make with date fields.</Notes>
//'</FunctionNotes>
  var dArray //= new Array(2);
  var dStr = frmElement.value; var pattern = /\//g;
  dStr =dStr.replace(pattern,"-");
  dArray = dStr.split("-");
  var currentDate = new Date()
  if (dArray.length == 2) dArray[2] = currentDate.getYear()
  if (dArray.length == 3 && dArray[2] =="") dArray[2]=currentDate.getYear()
  if (dArray.length == 3) {	// this checks for array items before trying to parse them
     if(dArray[2]=="" || dArray[2]==null) dArray[2] = currentDate.getYear()
     if(dArray[2].length == 2 ) dArray[2] = "20" + dArray[2];
     frmElement.value = dArray[0] + "-" + dArray[1] + "-" + dArray[2]
  }// end if
}// end function


function IsNumeric(n){
//<FunctionNotes>
//  <Name>IsNumeric</Name>
//  <Gets>N/A</Gets>
//  <Returns>True or false</Returns>
//  <Author>kelleyd</Author>
//  <DateModified>3/15/2002</DateModified>
//  <Notes>Verifies whether or not a given value is numeric</Notes>
//</FunctionNotes>
//tests for 0-9 all numeric values.  returns true or false
	  var str = "0123456789.-";
	  for (var i = 0; i < n.length; i++){
	    if (str.indexOf(n.substring(i,i + 1)) == -1) return false;
	  }
	  return true;
}

function ValidateThisField(frmElement,displayErrors){
//<FunctionNotes>
//  <Name>ValidateThisField</Name>
//  <Gets>an object that is a reference to a form element and an optional element that controls how the function processes errors.</Gets>
//  <Returns>True or false, plus may display a text alert in displayErrors is null or true</Returns>
//  <Author>kelleyd</Author>
//  <DateModified>3/15/2002</DateModified>
//  <Notes>This is a generic validation function to be used on a standard asp form.  
//   the function can be called by an onBlur event linked to the form element and is also called from the 
//   ValidateThisForm function.  The function displays individual error messages through a js alert box when displayErrors 
//   is null or true.  if displayErrors is false, the function returns an error string.  The function looks for the following form element properties (min,max,datatype,required)  values: for these properties are min & max: integer or date, datatype: string,date,integer required: true or false.  Note. datatype must be specified for all options except required
//   ** modified 6/02 by KRS -- added the frmElementDisplay option for redisplaying form element names that are heretofor ambiguous
//	</Notes>
//</FunctionNotes>
  if (displayErrors==null) displayErrors = true;
  var errStr=""
  // exit function if this isn't a supported control type.
  if (frmElement.type != "text" && frmElement.type != "textarea" ) return true;
  
  if (Has_Attribute(frmElement, "datatype")){// executes only if the frmElement includes the property datatype
    if (frmElement.getAttribute("datatype").toLowerCase() == "integer"){
      if (frmElement.value !=null && frmElement.value !=""){// test for data type
        if (!IsNumeric(frmElement.value)){ errStr +=  "\n .. the value entered is not a valid numeric value."};
        if (Has_Attribute(frmElement, "min") ) {
           if (parseFloat(frmElement.getAttribute("min")) > parseFloat(frmElement.value)){ 
             errStr +=  "\n .. the value entered is less than the minimum value allowed " + frmElement.getAttribute("min")
           }
        }
        if (Has_Attribute(frmElement, "max")) {
           if (parseFloat(frmElement.getAttribute("max")) < parseFloat(frmElement.value)){
              errStr += "\n .. the value entered is greater than the maximum value allowed " +  frmElement.getAttribute("max")
           }
        }
      }// end test for data type
    }// end if, item was an integer
    
    
    if (frmElement.getAttribute("datatype").toLowerCase() == "date"){
      if (frmElement.value !=null && frmElement.value !=""){// test for data type
        if (IsDate(frmElement.value,false) == false){ errStr = errStr + "\n .. the value entered is not a valid date."};
        if (Has_Attribute(frmElement, "min")) {
          if (GetDateObject(frmElement.getAttribute("min")) > GetDateObject(frmElement.value)) {
             errStr = errStr + "\n .. the value entered occurs before the minimum date allowed (" + frmElement.getAttribute("min") + ")"
           }
        }
        if (Has_Attribute(frmElement, "max")) {
            if (GetDateObject(frmElement.getAttribute("max")) < GetDateObject(frmElement.value)){
               errStr = errStr + "\n .. the value entered occurs after maximum date allowed (" + frmElement.getAttribute("max") + ")"
            }
        }
      }// end test this data type
    }// end if, item was a date
    
    if (frmElement.getAttribute("datatype").toLowerCase() == "text"){// test text fields for maxlength  
      if(Has_Attribute(frmElement, "maxlength")){ 
        if(parseFloat(frmElement.getAttribute("maxlength")) < parseFloat(frmElement.value.length)) {
          errStr = errStr + "\n .. the value entered is too long for the field."
        }
      }// end test for max length
    }//end test for text datatype
    
    /*5/15/07 sb added additional form validation for email, zip, phone, and ssn*/
    if(frmElement.value!=""){
      if(frmElement.getAttribute("datatype").toLowerCase()=="ssn"){
        if(!IsSSN(frmElement.value)){errStr += "\n .. the social security number you entered is invalid.";}
      }
      
      if(frmElement.getAttribute("datatype").toLowerCase()=="zip"){
        if(!IsZip(frmElement.value)){errStr += "\n .. the zip code you entered is invalid.";}
      }
      
      if(frmElement.getAttribute("datatype").toLowerCase()=="phone"){
        if(!IsPhone(frmElement.value)){errStr += "\n .. the " + frmElement.name + " you entered is invalid.";}
      }
      
      if(frmElement.getAttribute("datatype").toLowerCase()=="email"){
        if(!IsEmail(frmElement.value)){errStr += "\n .. the email address you entered is invalid.";}
      }
    } //end if frmElement.value !=""
    /*5/15/07 end sb validation updates for email, zip, phone, and ssn*/
    
  }//end if, datatype was specified
  
// decide what to return based on error conditions and displayerror flag
  if (errStr == "") {// no errors
     if (displayErrors == true ) return true;
     if (displayErrors == false ) return errStr
  }else{ // some errors were found
    var frmElementDisplay		// see description in ValidateThisForm, displayName. -- 6/02 KRS
     if (Has_Attribute(frmElement,"fieldname") && frmElement.name != frmElement.getAttribute("fieldName")) {
     frmElementDisplay = frmElement.getAttribute("fieldname");
	 } else {
     frmElementDisplay = frmElement.name;
	 }
     if (displayErrors == true ) {
       var errheader= "-----------------------\n" + "     Error!" +  "\n-----------------------\n\n"
       alert(errheader + "Data entered in the field " + frmElementDisplay + " is not valid: " + errStr); return false;
     }else { // end case where errors were found, and display errors was true
       // don't display errors, just return the error str
       return "\n" + frmElementDisplay + " is not valid:" + errStr + "\n\n";
     }//end if
  }// end if

}// end function

function ValidateThisForm(f){
//<FunctionNotes>
//  <Name>ValidateThisForm</Name>
//  <Gets>a form object</Gets>
//  <Returns>true or false, and displays an alert message</Returns>
//  <Author>kelleyd</Author>
//  <DateModified>1/9/2002</DateModified>
//  <Notes>the function looks for custom form element property tags, recognizing the following:
//  datatype: text, date, integer, 
//   min: date or numeric values only
//   max: same as minValue
//   maxlength: applies only to text values
//   required: boolean True/False 
//	 ** modified 6/02 by KRS - added a displayName option for field names that are ambiguous
//   ** modified 11/2/2006 by DK added getAttribute("required")
//  </Notes>
//</FunctionNotes>
  var j, errorStr = ""
  for (j=0;j<f.length;j++){
    var e = f.elements[j]
	//alert("name: " + e.name + " type: " + e.type);
    if (e.type == "text" || e.type == "textarea"){
      errorStr = errorStr + ValidateThisField(e,false)
    }// end if  

    // check for required values
    if (e.type == "text" || e.type == "textarea" || e.type == "radio" || e.type == "select-one"){
      if(Has_Attribute(e, "required")){  //5/15/07 sb added as additional check for cross-browser support
        if (e.getAttribute("required") != null){
          if (e.getAttribute("required") == 'true' && e.value=="" ) {
  		 var displayName	// displayName is an alternate name for dynamic or generic field names.
  		 			// this is the variable to display when the field name is too vague, e.g. Value8
  					// (when the descriptive name, e.g. ZipCode, should be used instead)
  					// fieldname is passed in the input string -- 6/02 KRS
  		  if ( e.fieldname != null && e.name != e.fieldname) {
  		   displayName = e.fieldname;
  		  } else {
  		   displayName = e.name;
  		  }
  		 errorStr = errorStr + "\n" + displayName + " is a required field.\n";
  		} // end if required and the value is not empty
        }//end if, field has a required tag
      }//end check for required values
    } //end check for has_attribute
  }// end for loop
  if (errorStr != "") {
    alert("The form could not be saved because the following errors were found:\n" + errorStr);
    return false;
  }else{
    return true;
  }
}// end function


function GetFieldValue(f){
//Gets: a obj reference to a form control,
//Returns: the value of the selected option of the form control
//Notes: this function calls the other function which determines the value of the control
	return GetFieldInfo(f, "value")
}
function GetFieldSelectedName(f){
//Gets: a obj reference to a form control,
//Returns: the name of the selected option of the form control
//Notes: this function calls the other function which determines the name of the control
	return GetFieldInfo(f, "name")
}
function GetFieldInfo(f, returnType){
//Gets: a obj reference to a form control, and returnType=[ "name" | "value" ]
//Returns: the current value or name of the selected option of the form control.
//Notes: When returnType=name, returns the name of the form control except for Select //  elements, which return a comma-delimited string of Display Text for selected values. // When returnType=value, returns the current field value for text-oriented controls, //  Checkboxes, Radiobuttons, and Select elements return a comma-delimited list of the 
//  'value' properties for only the currently selected items (Radios return only 1 item). // For text-related controls (text/textarea/password/hidden), this function works the same 
//  as calling referencedObject.value or referencedObject.name
  returnType=returnType.toLowerCase() // make input parameter case insensitive
  var returnVal=""

  if(f){ // make sure the reference exists and is a select element
	//For Radio and Checkbox objects with multiple members
    if(f.type == null){ 
      if(returnType == "name") {returnVal = f[0].name;}//return name of the radio/CB control
      if(returnType == "value") {
        for(j=0;j<f.length;j++) {
          if(f[j].checked == true) {//return values only if checked
			if(returnVal != "") {returnVal = returnVal + ",";}
			returnVal = returnVal + f[j].value; //return value of the element
		  }
		}//end for
      }
    }
	//For Radio and Checkbox objects with single members 
  	else if(f.type == "checkbox" || f.type=="radio") { 
      if(returnType == "name") {returnVal = f.name; }//return name of the radio/CB control
      if(returnType == "value" && f.checked == true) {returnVal = f.value; }//return value only if checked
    } 
	// single and multiple select elements
	else if (f.type== "select-multiple" || f.type=="select-one") { 
      for(j=0;j<f.length;j++){
        if(f[j].selected == true) { // only return selected option elements
          if(returnVal != "") {returnVal = returnVal + ",";}
		  if(returnType == "value") {returnVal = returnVal + f[j].value;}//return value of the element
          if(returnType == "name") {returnVal = returnVal + f[j].text;}//return display text of the element
	    }
	  }// end for
    }
	//For other object types
	else{ 
      if(returnType == "value") returnVal = f.value //return value of the element
      if(returnType == "name") returnVal = f.name //return name of the element
    }// end form element selection if/elseif/else statement
  }
  return returnVal
}// end function


function GetFieldInfo_OLD(f, returnType){
//Gets: a obj reference to a form control, 
//Returns: the value or name of the selected option of the form control.
//Note: when the returnType is "value", this work primarily with Selected Options and Radio control types. When the returnType is "name", this work primarily with Selected Options only (because each radio button of the Radio button group has the same name). For text and textarea control types, this function works the same as calling referencedObject.value or referencedObject.name
  var returnVal="", propertyType
  if(f){ // make sure the reference exists and is a select element
	  if(f.type == null || f.type == "select-one"){ //For Radio and Drop Down object types
	  	if(f.type == null){propertyType = "checked"}
		if(f.type == "select-one"){propertyType = "selected"}
	    for(j=0;j<f.length;j++){
	      if(eval("f[" + j + "]." + propertyType) == true){
		  	if(returnType == "value") returnVal = f[j].value //return value of the element
			if(returnType == "name" && f.type == "select-one") returnVal = f[j].text //return name of the selected option of the dropdown control
			if(returnType == "name" && f.type == null) returnVal = f[j].name //return name of the radio control
			break;}
	    }//end for
	  }
	  //For other object types
	  else{
	  	if(returnType == "value") returnVal = f.value //return value of the element
		if(returnType == "name") returnVal = f.name //return name of the element
	  }// end if
  }
  return returnVal
}// end function


function SetFieldValue(f, selectedValue){
//Gets: a obj reference to a select type form control, value of the option that will be selected 
//Returns: Nothing. Set the control with its value equal to the selectedValue
//Note: this work primarily with Selected Options and Radio control types. For text and textarea control types, this function works the same as calling referencedObject.value = setVale
  var returnVal=""
  if(f){ // make sure the reference exists and is a select element
  	  if(f.type == null || f.type == "select-one"){ //For Radio and Drop Down object types
		  for(j=0;j<f.length;j++){
		    if(f[j].value==selectedValue){
				if(f.type == "select-one"){f.selectedIndex=j;}//For Drop Down object type
				else{f[j].checked = true}//For Radio object type
			}
		  }// end for
	  }
	  //For other object types
	  else{f.value = selectedValue}// end if
  }
}// end function

function UpdateSelectOptions(frmControl,nvOptionsArray,selectedValue){
/* frmControl is the reference to a Select control,
   nvOptionsArray contains a name-value list of options
   selectedValue contains desired Value (not name) that is to be Selected upon completion
   if there is no matching value, the first item will be selected by default */
 if(frmControl && frmControl.options){ // make sure the reference exists and is a select element
   var count=0;
   frmControl.options.length=0;
   for(i=0;i<nvOptionsArray.length;i+=2){
   		isSelected = (nvOptionsArray[i+1] == selectedValue)
      temp=new Option(nvOptionsArray[i],nvOptionsArray[i+1],isSelected,isSelected);
      frmControl [count]=temp;
      count++;
    }
 }
}// End Function

function StringCompare(a,b){
//Gets: two strings to be compared 
//Returns: true or false
  if (a.toLowerCase() == b.toLowerCase()) {return true; }else{return false;}
}

function IsInThisArray(thisValue,someArray){
//Gets: a value string or int and a js array
//Returns: T/F
  var j;
  for(j=0;j<someArray.length;j++){
    if(someArray[j]==thisValue){return true}
  }
  return false;
}

function GetNameFromNVArray(thisValue,nvArray){
//Gets: a value and an nvArray.
//Returns: the name corresponding to the value passed in thisValue
//         comparable to the asp function of the same name.
  var j
  for (j=1;j < nvArray.length;j=j+2){
    if(nvArray[j]==thisValue){return nvArray[j-1];}
  }
  return false;;
}

function DateCompare(fromDate,toDate,compareType){
//Gets: 2 string date values of form mm/dd/yy or mm-dd-yy 
//      and a comparison operator values "Equal | = |  GreaterThan | > | LessThan | < "
//      null values of compareType are assumed to be =
//Returns:T/F
//Note: correctly handles 2 digit years and assumes values are > 2000
 var dTo,dFrom
 if (fromDate != "" && toDate != "") {
   if (IsDate(toDate,false) && IsDate(fromDate,false)) { 
     // confirm years are 4 digit before converting to date type vars.
     dTo = new Date(ConvertDateStringToFourDigitYear(toDate));	
     dFrom = new Date(ConvertDateStringToFourDigitYear(fromDate));} 
 }else{
   return false;
 }
 
 //alert(dTo);alert(dFrom);
 // at this point you know you have two dates, now do your comparisons
 // Equal
 if (compareType.toLowerCase()=="equal" || compareType=="=" || compareType==null){
   if (dFrom==dTo){return true;}else{return false;}
 }
 // GreaterThan  | >
 if (compareType.toLowerCase()=="greaterthan" || compareType==">"){
   if (dFrom>dTo){return true;}else{return false;}
 }
 // LessThan  | <
 if (compareType.toLowerCase()=="lessthan" || compareType=="<"){
   if (dFrom < dTo){return true;}else{return false;}
 }
  if (compareType==">="){ if (dFrom>=dTo){return true;}else{return false;} } 
  if (compareType=="<="){ if (dFrom<=dTo){return true;}else{return false;} }
}

function ConvertDateStringToFourDigitYear(myDateStr){
//Gets: a string of from m/d/yy or mm-dd-yy
//Returns: same date in the form of  4 digit year.
//Note: use this to compensate from what the user input and JS use of 1900 as a base year.
//      you probably don't need to worry about this unless you are doing date comparison of validation
  if(myDateStr!=""){
    // find delimiter
    var delimiter = ""
    if (myDateStr.indexOf("/")>0){delimiter="/"}
    if (myDateStr.indexOf("-")>0){delimiter="-"}
    if (delimiter!=""){
      var mmDDYY=myDateStr.split(delimiter)
      if(mmDDYY.length==3){
        if(mmDDYY[2].length==2){mmDDYY[2]="20" + mmDDYY[2];return mmDDYY.join(delimiter)}
        if(mmDDYY[2].length==4){return myDateStr}
      }// end array had 3 elements
    }// end delimiter was found
  }// end string not empty
}  // end function

function GetFileInfo(thisURL,infoType){
//Gets: a url or path (string) and 
//      infoType (string) Values: Extension or FileType | Name | Drive
//Returns GetFileInfo("myImage.gif","FileType") returns "gif"  OR
//        returns 'myImage.gif' from 'SomePath/myImage.gif' when infoType is FileName
//        returns 'c:' from 'c:\somepath\myImage.gif'
  var p, fileType, fileName, drive
  if (infoType=="Extension" || infoType=="FileType"){
    p = thisURL.lastIndexOf(".")
    if ((thisURL.length - p) == 4 || (thisURL.length - p)==5){
      fileExtention = thisURL.substring(p+1)// gets gif from myFile.gif
      return fileExtention;}
  }// end get extension
  
  if (infoType=="Name" || infoType=="FileName"){
    p = thisURL.lastIndexOf("/")
    if (p==-1){
      if(thisURL.lastIndexOf("\\") > 0){
        p=thisURL.lastIndexOf("\\")}
    }     //
    fileName = thisURL.substring(p+1)// gets gif from myFile.gif
    return fileName;
  }// end getFile Name
  
  if (infoType=="Drive"){
    p = thisURL.indexOf(":")
    if (p==1){   return thisURL.charAt(0) + ":"  }
  }// end getDrive

}// end function

function GetIDStrFromCheckboxes(controlName){
//Gets: a form control name (string). ex 'MyCheckBox', looks for checkboxes that begin with controlName 
//Returns: a comma delimited list of checkbox values
//Note: you would typically use this if you were using a series of checkboxes to capture multiple enters in the
//      form of a comma delimited list of ids. CB names are assumed to be numbered MyCheckBox0 .. MyCheckBox#
//      WARRNING: this doesn't look all that closely at the controlsName and acts on anything that *begins with* controlname
  var f = document.theForm;
  var a = document.getElementsByTagName("input")
  var j, returnStr=""
  for(j=0;j<a.length;j++){// loop through all the input type controls on the form
     if (a[j].type!=null && a[j].name!=null){// make sure everything has a type and name property
       if (a[j].type=="checkbox" && a[j].name.indexOf(controlName)==0){// this is a ckbox who name begins with the controlName
         if (a[j].checked==true){
           if (returnStr != ""){returnStr += ","}
           returnStr += a[j].value
         }// end item was checked
       }//end if, this was a  cb
     }// end if, no name property
  }//end for
  return returnStr
}// end function

function SetCheckboxes(controlName,cbAction){
//Gets controlName (string) the name of a series of checkboxes, and 
//     cbAction (string) values Check | Uncheck
//     check boxes are assumed to be unique and numbered controlName# ex. controlName0...controlName#
//Returns T/F
//Note: this is used to initialize a series of check boxes to all checked or not checked.
//      this would be used with a check All or uncheck all link.
//      the function finds all the checkbox elements that begin with controlName and set their state to cbAction
//      WARNING: this doesn't look very closely at names, it will act on any CB that *begins with* the controlName passed

  var f = document.theForm;
  var a = document.getElementsByTagName("input")
  var j, returnResult=true
  for(j=0;j<a.length;j++){//loop through a collection of checkbox elements
     if (a[j].type!=null && a[j].name!=null){
       if (a[j].type=="checkbox" && a[j].name.indexOf(controlName)==0){
         if (cbAction=="Check"){a[j].checked = true}else{a[j].checked=false}
       }//end if, this was a  cb
     }// end if, no type or name property
  }//end for
  return true  
}

// ADDED in 3.1
function GetItemFromNVArray(thisValue,nvArray){
//Gets: and integer or string, and an nvArray.
//Returns: the name corresponding the the value.
//Note:  returns MyValue from (...,MyValue,N,...) when N is passed
// this is a JS variant of the asp function
  var j,intCompareFlg = false
  if (IsNumeric(thisValue)){intCompareFlg=true}
  for (j=0; j < nvArray.length; j=j+2){
    if(intCompareFlg){
      if (IntegerCompare(thisValue,nvArray[j+1])){return nvArray[j];}
    }else{// string comparison
      if(thisValue==nvArray[j+1]){return nvArray[j];}
    }
  }
  return "";
}

function IntegerCompare(x,y){
//Gets two values.
//Returns true if both values are numeric and equal
  var returnVal = false
  if (x !=null && y != null){
    if (parseInt(x) ==  parseInt(y)){returnVal=true}
  }
  return returnVal
}

function IsInteger(n){
//<FunctionNotes>
//  <Name>IsInteger</Name>
//  <Gets>N/A</Gets>
//  <Returns>True or false</Returns>
//  <Author>kelleyd</Author>
//  <DateModified>12/6/2005</DateModified>
//  <Notes>Verifies whether or not a given value is an integer characters 0-9</Notes>
//</FunctionNotes>
//tests for 0-9 all numeric values.  returns true or false
	  var str = "0123456789";
	  for (var i = 0; i < n.length; i++){
	    if (str.indexOf(n.substring(i,i + 1)) == -1) return false;
	  }
	  return true;
}

function Has_Attribute(e,attrName){
//Gets an object reference to a form or dom element and attrName, string, any property
//NOTE: ie doesn't support the hasAttribute method, and browser are inconsistent in how they handle what is returned by
//      e.getAttribute(attrName), some return null, others return and empty string.  This function abstracts this, handle
//      differences in browsers and trues T/F based on whether the element has the property
  if(e.hasAttribute){
    // handles standards compliant browsers here
    return e.hasAttribute(attrName)
  }else{
    //handle ie which doesn't support this method
    if(e.getAttribute){
      return e.getAttribute(attrName)!=null
    }else{
      return false;
    }
  }
}

function CancelEvent(e){
//Gets an event, and prevent propgation of even up through the dom.
//Example  onclick=Dosomething();CancelEvent(event);
//Notes: works cross browser FF & IE
  if(!e){var e = window.event;}
	if(e.stopPropagation){e.stopPropagation();}else{e.cancelBubble = true;}
}

/*5/15/07 sb added additional form validation for email, zip, phone, and ssn*/
/*the ^ at the beginning of the valid strings and the $ at the end of the valid strings prevent whitespace from being a valid entry.*/
function IsSSN(fVal){
/*checks for 3 numbers followed by a - followed by 2 numbers followed by a - followed by 4 numbers or 9 numbers*/
  var validSSN = /^\d{3}-\d{2}-\d{4}$/;  /*equals 3 digits - 2 digits - 4 digits i.e. 123-45-6789*/
  var validSSN2 = /^\d{9}$/; /*equals 9-digits i.e. 123546789*/
  var val = fVal.replace(/\s/g,""); /*replace any whitespace with an empty string*/
  if(validSSN.test(val)||validSSN2.test(val)){return true;}else{return false;}
}

function IsZip(fVal){
/*checks for 5 numbers or 5 numbers followed by a - followed by 4 numbers.*/
  var val = fVal.replace(/\s/g,"");  /*replace any whitespace with an empty string*/
  var validZip  = /^(\d|-){5,10}$/;  /*any word character and - between 5 and 10 characters in length.*/
  if(!validZip.test(val)){return false;}else{return true;}
 }

function IsPhone(fVal){
  var val = fVal.replace(/\s/g,"");  /*replace any whitespace with an empty string*/
  var validPhone = /^(\d|-|\(|\)){7,25}$/;  /*allow any word characters and - as long as the length is between 7 and 25.*/
  if(validPhone.test(val)){return true;}else{return false;}
}

function IsEmail(fVal){
/*this should support anything from 1@1.tv to 1@1.inside.museum \w = any word character= a-zA-Z_0-9*/
  var val = fVal.replace(/\s/g,"");  /*replace any whitespace with an empty string*/
  var validEmail=/^([\w]([-.\w]*[\w])*@([\w][-\w]*[\w]\.)+[\w]{2,6})$/;  
  if(!validEmail.test(val)||val.length<=LibraryPrefs.MaxEmailLength){return false;}else{return true;}
}

function ConfirmEmail(f,email1FldName,email2FldName){
/*Gets: fieldNames of two email form fields on the page (strings) and f =object reference to theForm.*/
/*Returns: true or false, if false may throw an alert, or display a test field on the page and focus on it.*/
/*Notes: Use this to prompt for and confirm that the email address has been entered correctly. In order for this function to work properly each email field must have an id equal to the field name.*/
  var Email = f.email1FldName;
  var EmailConfirm = f.email2FldName;
  if(EmailConfirm.value!=""&&Email.value!=""){
    /*do string comparison and make sure they are equal*/
    if(EmailConfirm.value.toLowerCase()==Email.value.toLowerCase()){
      return true;
    }else{
      alert("Your email addresses do not match. Please fix this before continuing.");
      return false;
    }
  }else{
    if(EmailConfirm.value==""&&Email.value!=""){
      /*show Email Confirm field and bring focus to it*/
      document.getElementById(email2FldName).style.display="block";
      return false;
      EmailConfirm.focus();
    }else{
      /*something is really messed up and the user has somehow gotten the EmailConfirm value filled in without an Email*/
      document.getElementById(email2FldName).style.display="block";
      return false;
      Email.focus();
    }
  }
}
