// ----------------------------------------------------------------------
// Title: Javascript Form Verification
//
// Version Information:
// - Created By: Steve Gallo
// - Date: 3/6/2002
//
// Description:
//
// Javascript routines useful in form processing and validation.  The main
// routine called in the form's onSubmit handler is smg_validate_form().
// Form validation is handled as follows:
//
// Construct a form and include two optional elements for each form tag
// to be verified.  The first is a hidden tag named "validate_form" that
// tells the form validation routine specifics about the field to be verified
// and the second is an optional visual error marker named "err_<field_name>"
// that provides the user with visual feedback as to the source of the error.
// Only form fields with a corresponding "validate_form" tag will be validated.
// The value field of the "validate_form" tag is a carat (^) separated string of
// the form:
//
// (start code)
// "<field_name>^<type>^<o|r>^<user_friendly_text>^<error_message>"
// (end)
//
// Where:
//
// (start code)
// <field_name> is the name of the form field
// <type> is one of the following:
//   t = text
//   i = integer
//   a = alpha-numeric
//   p = phone number
//   e = email address
//   d = date
//   dt = date + time (composite made up of more than 1 form field)
//   s = select box, at least one element must be selected
// <o|r> stand for:
//   o = optional field, verify syntax only
//   r = required field, verify not empty and syntax
// <user_friendly_text> is a user-friendly string to be used when displaying errors
// <error_message> is the message to be displayed when a field contains invalid input,
//   or an empty string for no message
// (end)
//
// For example:
//
// <input type="hidden" name="validate_form" value="job_name^t^r^Job Name^Error entering Job Name">
// <input type="text" name="job_name" value="<?= $jobName ?>" size=50 max=128>
//
// The validation routine makes use of helper routines to validate the individual
// date types.  These helper routines return true if the field (or group of
// fields) is valid and false if not.  The helper routines also take an optional
// argument smg_ErrorObject that is used to return a descriptive error string
// to the validation routine to display to the user:
//
// if (result == null) {
//
//     // If an additional argument was passed in, assume it is the
//     // smg_ErrorObject and send back a descriptive error message.
//
//     if (arguments.length == 2) {
//            arguments[1].errorMessage = "The year must be an integer of the form YYYY";
//     }
// }  // if (result == null)
//
// In addition to verifying the form, if a DOM element with an ID of
// "err_<field_name>" exists (e.g., id="err_recipe_name") and there is an
// error, set the visibility of that DOM element to "visible".  If there was
// no error set the visibility to "hidden".  If no DOM element with that id
// exists do nothing.  This feature allows optional visual indication of
// the fields in error.  The following styles should be defined and the error
// indicators should have their tag set using these styles so they are initially
// hidden:
//
// TD.error { color: red; font-weight: bold; visibility: hidden; }
// SPAN.error { color: red; font-weight: bold; visibility: hidden; }
//
// For example:
//
// <td class="error" id="err_date_added_start">*</td>
//
// ----------------------------------------------------------------------
// Main Routines:
//
// smg_ErrorObject()
// Constructor for the object used to pass error messages back to the calling
// routine.  An object is needed because JavaScript always passes primitive
// types by value and objects by reference.
//
// smg_validate_form()
// Main form validation routine.  The form includes a handler in the form tag
// onSubmit="return smg_validate_form(this);"
//
// ----------------------------------------------------------------------
// Helper Routines
//
// smg_validate_email()
// smg_validate_date()
// smg_validate_dateTime()
// smg_validate_alphanumeric()
// smg_validate_integer()
// smg_validate_text()
// smg_validate_phoneNumber()
// smg_validate_year()
// smg_validate_month()
// smg_validate_day()
// smg_validate_hour()
// smg_validate_minute()
// smg_validate_second()
// smg_validate_isEmpty()
// smg_validate_isEmpty_datetime()
// smg_validate_selectBox()
//
// ----------------------------------------------------------------------


// ======================================================================
// Main Routines
// ======================================================================

// ----------------------------------------------------------------------
// Constructor for the error object used to return error messages from the
// validation routines.  We need an object to be able to pass a parameter by
// reference.
// ----------------------------------------------------------------------

function smg_ErrorObject(s)
{
  this.errorMessage = null;
}


// ----------------------------------------------------------------------
// Validate a form.  The form will be validated using hidden fields named
// "validate_form" which contain a specification for how to validate specific
// form fields should be verified, their data type, a user-friendly string to
// be used when displaying errors, and an error message for invalid input.
// Zero or more "validate_form" fields may be present.
//
// In addition to verifying the form, if a DOM element with an id of
// "err_<field_name>" exists (e.g., id="err_recipe_name") and there is an
// error, set the visibility of that DOM element to "visible".  If there was
// no error set the visibility to "hidden".  If no DOM element with that id
// exists do nothing.  This feature allows optional visual indication of
// the error.
//
// See the documentation at the start of this file for specifics on the form
// validation procedure.
//
// Parameters:
//
// f - form to verify
//
// Returns:
//
// True if the form fields are valid according to the form_verify directives,
// False otheriwse.
// ----------------------------------------------------------------------

function smg_validate_form(f)
{
  var i;
  var errorMessage = "";     // Error message, no errors if empty
  var validateArray = null;  // Array containing validation instructions
	
  // Sanity checks

  if (f.validate_form == undefined) {
    return true;
  } 
	
  // Create the errorObject so we can pass an argument by reference to the
  // validation functions to get any custom error messages that they may want
  // to return.
	
  var errorObject = new smg_ErrorObject(null);
	
  // Normalize the form validation information into an array
	
  if (f.validate_form.length == undefined) {
    // Only one validate_form tag exists, create an array from it
    validateArray = new Array(f.validate_form);
  } else {
    validateArray = f.validate_form;
  }
	
  // Iterate through the elements and verify each form field
	
  for (i=0; i < validateArray.length; i++) {

    // Each validate array element field is made up of one verifiation
    // specification with elements separated by a '^'.  Break apart the
    // specifications and skip this field if there is no data.
		
    var specification = validateArray[i].value;
    if ( specification == "" ) { continue; }
		
    // Break each specification down into it's 4 elements
		
    var specificationArray = specification.split("^");
    var fieldName = specificationArray[0];
    var fieldType = specificationArray[1];
    var optional = (specificationArray[2] == "o" ? true : false);
    var friendlyName = specificationArray[3];
    var errorString = specificationArray[4];

   /*
    alert("fieldName=" + fieldName + ", friendlyName=" + friendlyName +
          ", fieldType=" + fieldType + ", optional=" + optional +
          ", errorString=" + errorString);
   */

    // In order to validate the field (or group of fieds) we need to
    // determine the type of this field which will in turn determine:
    //    1. the name of the function to check if the value is empty
    //    2. the name of the function to validate the field contents
    //    3. the arguments to the validation function
		
    switch (fieldType) {
		
		// The following values are for single form fields
		
    case "t":  /* text */
      validateFunctionName = "smg_validate_text";
      validateFunctionArgString = "f." + fieldName + ".value, errorObject";
      checkIfEmptyFuncString = "smg_checkIfEmpty(f, '" + fieldName + "')";
      break;
    case "i":  /* integer */
      validateFunctionName = "smg_validate_integer";
      validateFunctionArgString = "f." + fieldName + ".value, errorObject";
      checkIfEmptyFuncString = "smg_checkIfEmpty(f, '" + fieldName + "')";
      break;
    case "a":  /* alpha-numeric */
      validateFunctionName = "smg_validate_alphanumeric";
      validateFunctionArgString = "f." + fieldName + ".value, errorObject";
      checkIfEmptyFuncString = "smg_checkIfEmpty(f, '" + fieldName + "')";
      break;
    case "e":  /* email address */
      validateFunctionName = "smg_validate_email";
      validateFunctionArgString = "f." + fieldName + ".value, errorObject";
      checkIfEmptyFuncString = "smg_checkIfEmpty(f, '" + fieldName + "')";
      break;
    case "d":  /* date */
      validateFunctionName = "smg_validate_date";
      validateFunctionArgString = "f." + fieldName + ".value, errorObject";
      checkIfEmptyFuncString = "smg_checkIfEmpty(f, '" + fieldName + "')";
      break;
    case "p":  /* phone number */
      validateFunctionName = "smg_validate_phoneNumber";
      validateFunctionArgString = "f." + fieldName + ".value, errorObject";
      checkIfEmptyFuncString = "smg_checkIfEmpty(f, '" + fieldName + "')";
      break;
    case "s":  /* select box */
      validateFunctionName = "smg_validate_selectBox";
			
      // In a multiple select box, in order for PHP to treat it as an array
      // the select box name must end with [] (i.e., name="resources[]") and
      // this must be handled differently in javascript than if the tag name
      // was name="resources".
			
      if (fieldName.search(/\[\]$/) != -1) {
        validateFunctionArgString = "f.elements['" + fieldName + "'], errorObject";
      } else {
        validateFunctionArgString = "f." + fieldName + ".value, errorObject";
      }
			
      checkIfEmptyFuncString = "smg_checkIfEmpty_selectBox(f, '" + fieldName + "')";
      break;
		
		// The following values are for composite form fields
			
    case "dt":  /* date + time (YYYY-MM-DD HH:MM:SS */
      validateFunctionName = "smg_validate_dateTime";
      validateFunctionArgString = "f, '" + fieldName + "', errorObject";
      checkIfEmptyFuncString = "smg_checkIfEmpty_dateTime(f, '" + fieldName + "')";
      break;

    default:
      validateFunctionName = "";
      validateFunctionArgString = "";
      checkIfEmptyFuncString = "";
      alert ("Unknown field type in smg_validate_form() for field " + fieldName + ": " + fieldType);
      break;
    }
		
    // Construct strings to be eval()'d later.
		
    validateFunctionString = validateFunctionName + "(" + validateFunctionArgString + ")";
    errorElementIdString = "document.getElementById('err_" + fieldName + "')";
		
    // Evaluate the string to check if an element exists and is empty
		
    valid = true;
    isEmpty = eval(checkIfEmptyFuncString);
		
    // If the field is not optional but empty let the user know it is
    // required.  Otherwise, if it is not empty then validate it using
    // the validation routine.
		
    if ( ! optional && isEmpty ) {
      errorMessage += friendlyName + ": Required\n";
      valid = false;
    } else if ( ! isEmpty ) {
      valid = eval(validateFunctionString);

      if ( ! valid ) {

        // If the validation routine sent back an error message use
        // that message, otherwise use the message provided in the
        // form tag.
				
        if (errorObject.errorMessage != null) {
          errorMessage += friendlyName + ":\n" + errorObject.errorMessage + "\n";
        } else {
          errorMessage += friendlyName + ":\n" + errorString + "\n";
        }
      }  // if ( ! valid )
    }  // else if ( ! isEmpty )
		
    // IE5 and NS6/7 both support the document.getElementById() method so we
    // will use that over the document.all and document.layer[] properties.
    // NS4 has problems with this and visibility in general since it's stylesheet
    // support sucks.
    //
    // To make this work in NS4 you must define the style as an attribute of
    // the HTML element:
    //
    // <div id="err_test" style="position: relative; visibility: hidden;">
    //
    // And change the visibility using:
    //
    // document.layers['err_test'].visibility = "visible";
    //
    // If a DOM element id="err_<fieldName>" exists, set the visibility
    // according to the error status.  This is typically a DOM element
    // containing an error indicator set to visible when there is an error.
    //
    // For NS4:
    // if ( eval("document.layers[err_'" + fieldName + "']") ) {
    // 		eval("document.layers[err_'" + fieldName + "'].visibility = 'visible'");
    // }

    errorElement = eval(errorElementIdString);		
		
    if ( errorElement != null ) {
      if ( valid ) {
        errorElement.style.visibility = "hidden";
      } else {
        errorElement.style.visibility = "visible";
      }
    }  // if ( errorElement != null )
			
  }  // for (var i=0; i < validateArray.length; i++)
	
  if (errorMessage != "") {
    alert ("The following errors were found\n\n" + errorMessage);
    return false;
  }
	
  return true;
	
}  // smg_validate_form()


// ----------------------------------------------------------------------
// Run through the form and find all form fields.  Then hide any elements
// named err_<field name>.
//
// Parameters:
//
// f - form to examine
//
// Returns: Nothing
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_hideErrFields(f)
{
  var e, i;
	
  // Find all form element names.  If there is a corresponding entry with
  // an id of "err_<name>" and a stylesheet attribute of visible, hide it.
	
  for (i=0; i < f.length; i++) {
    elementName = f.elements[i].name;
    if ( (e = document.getElementById('err_' + elementName)) ) {
      if ( e.style.visibility == "visible" ) {
        e.style.visibility = "hidden";
      }
    }
  }
	
  // If there is a corresponding entiry with an id of "err_<name>" and a
  // stylesheet attribute of visible, hide it.
}


// ======================================================================
// Helper Routines
// ======================================================================

/*
  function smg_validate_template(s) {
  var retval = true;
  var pattern = /^[\s].*[\s]{0,}$/;
  var result = s.match(pattern);
	
  if (result == null) {
  if (arguments.length == 2) {
  arguments[1].errorMessage = "";
  }
  retval = false;
  }  // if (result == null)
	
  return retval;

  }  // smg_validate_template ()
*/


// ----------------------------------------------------------------------
// Validate the format of the email address entered.
// Ignore any whitespace before and after the string.
//
// Parameters:
//
// email - email address to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_email(email) {
  var retval = true;
  var pattern = /^[\s]{0,}[^@, ]+@[^.,@ ]+[.][^,@ ]+[\s]{0,}$/;
  var result = email.match(pattern);

  if (result == null) {

    if (arguments.length == 2) {
      arguments[1].errorMessage = "Email addresses must be of the form user@company.com";
    }
    retval = false;

  }
	
  return retval;

}  // smg_validate_email()


// ----------------------------------------------------------------------
// Validate the format of the date string as mm/dd/yyyy
// Ignore any whitespace before and after the string.
//
// Parameters:
//
// date - date string to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_date(date) {
  var retval = true;
  var pattern = /^[\s]{0,}[0-9]{1,2}\/[0-3]?[0-9]\/[0-9]{4}[\s]{0,}$/;
  var result = date.match(pattern);
	
  if (result == null) {
	
    if (arguments.length == 2) {
      arguments[1].errorMessage = "The date must be of the form MM/DD/YYYY";
    }
    retval = false;
  }
	
  return retval;

}  // smg_validate_date()


// ----------------------------------------------------------------------
// Validate the format of a group of date & time fields.  These may include up
// to 6 fields, "year", "month", "day", "hour", "minute", "second" and are
// treated as a single entity.  The fields have default values of  "YYYY",
// "MM", "DD", "HH", "MM", "SS", respectively.
//
// Parameters:
//
// date - date string to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_dateTime(f, tagName) {
  var retval = true;
  var i;
  var errorMessage = "";
  var strings = new Array(6);
  var defaults = new Array(6);
  var exists = new Array(6);
  var values = new Array(6);
  var isEmpty = new Array(6);
  var errorObject = new smg_ErrorObject(null);
	
  // Define the element strings
	
  strings[0] = "f." + tagName + "_year";
  strings[1] = "f." + tagName + "_month";
  strings[2] = "f." + tagName + "_day";
  strings[3] = "f." + tagName + "_hour";
  strings[4] = "f." + tagName + "_minute";
  strings[5] = "f." + tagName + "_second";
	
  // Define the element defaults
	
  defaults[0] = "YYYY";
  defaults[1] = "MM";
  defaults[2] = "DD";
  defaults[3] = "HH";
  defaults[4] = "MM";
  defaults[5] = "SS";
	
  // Determine which fields exist, what their values are, and whether or not
  // the value field is empty (or at the default value)
	
  for (i = 0; i < 6; i++) {
    exists[i] = eval( "(" + strings[i] + " == null ? false : true)" );
    values[i] = ( exists[i] ? eval( strings[i] + ".value" ) : null);
    isEmpty[i] = ( values[i] == null || values[i] == "" || values[i] == defaults[i] );
  }
	
  // Validate the values for the fields that exist.  Users must enter a year
  // followed but a month, followed by a day, etc.  If a year is not entered
  // then ignore anything logically to the right of the year (i.e., month,
  // day, etc.)  The year is the only required field.
	
  yearOk = false;
  monthOk = true;
  dayOk = true;
  hourOk = true;
  minuteOk = true;
  secondOk = true;
	
  if ( ! isEmpty[0] ) {
    errorObject.errorMessage = null;
    yearOk = smg_validate_year(values[0], errorObject);
    if ( errorObject.errorMessage != null ) {
      errorMessage += "\t" + errorObject.errorMessage + "\n";
    }
  } else {
    errorMessage += "\tYou must supply a year.\n";
  }
	
  if ( ! isEmpty[1] ) {
    errorObject.errorMessage = null;
    monthOk = smg_validate_month(values[1], errorObject);
    if ( errorObject.errorMessage != null ) {
      errorMessage += "\t" + errorObject.errorMessage + "\n";
    }
  }
  if ( ! isEmpty[2] ) {
    errorObject.errorMessage = null;
    dayOk = smg_validate_day(values[2], errorObject);
    if ( errorObject.errorMessage != null ) {
      errorMessage += "\t" + errorObject.errorMessage + "\n";
    }
  }
  if ( ! isEmpty[3] ) {
    errorObject.errorMessage = null;
    hourOk = smg_validate_hour(values[3], errorObject);
    if ( errorObject.errorMessage != null ) {
      errorMessage += "\t" + errorObject.errorMessage + "\n";
    }
  }
  if ( ! isEmpty[4] ) {
    errorObject.errorMessage = null;
    minuteOk = smg_validate_minute(values[4], errorObject);
    if ( errorObject.errorMessage != null ) {
      errorMessage += "\t" + errorObject.errorMessage + "\n";
    }
  }
  if ( ! isEmpty[5] ) {
    errorObject.errorMessage = null;
    secondOk = smg_validate_second(values[5], errorObject);
    if ( errorObject.errorMessage != null ) {
      errorMessage += "\t" + errorObject.errorMessage + "\n";
    }
  }
	
  if (yearOk && monthOk && dayOk && hourOk && minuteOk && secondOk) {
    retval = true;
  } else {
    retval = false;
  }
	
  if (arguments.length == 3 && retval == false) {
    arguments[2].errorMessage = errorMessage;
  }

  return retval;

}  // smg_validate_dateTime()


// ----------------------------------------------------------------------
// Validate the format of the year string as YYYY.
// Ignore any whitespace before and after the string.
//
// Parameters:
//
// s - string to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_year(s) {
  var retval = true;
  var pattern = /^[\s]{0,}[0-9]{4}[\s]{0,}$/;
  var result = s.match(pattern);
  if (result == null) {
	
    // If an additional argument was passed in, assume it is the
    // smg_ErrorObject and send back a descriptive error message.
	
    if (arguments.length == 2) {
      arguments[1].errorMessage = "The year must be an integer of the form YYYY";
    }
		
    retval = false;
  }
		
  return retval;
	
}  // smg_validate_year()

// ----------------------------------------------------------------------
// Validate the format of the month string as MM.
// Ignore any whitespace before and after the string.
//
// Parameters:
//
// s - string to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_month(s) {
  var retval = true;
  var pattern = /^[\s]{0,}[0-1][0-9][\s]{0,}$/;
  var result = s.match(pattern);
  var value = parseInt(result, 10);
  if (result == null || value < 1 || value > 12) {
	
    // If an additional argument was passed in, assume it is the
    // smg_ErrorObject and send back a descriptive error message.
	
    if (arguments.length == 2) {
      arguments[1].errorMessage = "The month must be an integer between 01 and 12 of the form MM";
    }
		
    retval = false;
  }
	
  return retval;
	
}  // smg_validate_month()


// ----------------------------------------------------------------------
// Validate the format of the day string as DD.
// Ignore any whitespace before and after the string.
//
// Parameters:
//
// s - string to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_day(s) {
  var retval = true;
  var pattern = /^[\s]{0,}[0-3][0-9][\s]{0,}$/;
  var result = s.match(pattern);
  var value = parseInt(result, 10);
  if (result == null || value < 1 || value > 31) {
	
    // If an additional argument was passed in, assume it is the
    // smg_ErrorObject and send back a descriptive error message.
	
    if (arguments.length == 2) {
      arguments[1].errorMessage = "The day must be an integer between 01 and 31 of the form DD";
    }
		
    retval = false;
  }
	
  return retval;
	
}  // smg_validate_day()


// ----------------------------------------------------------------------
// Validate the format of the hour string as HH.
// Ignore any whitespace before and after the string.
//
// Parameters:
//
// s - string to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_hour(s) {
  var retval = true;
  var pattern = /^[\s]{0,}[0-2][0-9][\s]{0,}$/;
  var result = s.match(pattern);
  var value = parseInt(result, 10);
  if (result == null || value < 1 || value > 23) {
	
    // If an additional argument was passed in, assume it is the
    // smg_ErrorObject and send back a descriptive error message.
	
    if (arguments.length == 2) {
      arguments[1].errorMessage = "The hour must be an integer between 01 and 24 of the form HH";
    }
		
    retval = false;
  }
	
  return retval;
	
}  // smg_validate_hour()


// ----------------------------------------------------------------------
// Validate the format of the minute (or second) string as MM (or SS).
// Ignore any whitespace before and after the string.
//
// Parameters:
//
// s - string to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_minute(s) {
  var retval = true;
  var pattern = /^[\s]{0,}[0-6][0-9][\s]{0,}$/;
  var result = s.match(pattern);
  var value = parseInt(result, 10);
  if (result == null || value < 1 || value > 60) {
	
    // If an additional argument was passed in, assume it is the
    // smg_ErrorObject and send back a descriptive error message.
	
    if (arguments.length == 2) {
      arguments[1].errorMessage = "The minute must be an integer between 01 and 60 of the form MM";
    }
		
    retval = false;
  }
	
  return retval;
	
}  // smg_validate_minute()


// ----------------------------------------------------------------------
// Validate the format of the minute (or second) string as MM (or SS).
// Ignore any whitespace before and after the string.
//
// Parameters:
//
// s - string to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_second(s) {
  var retval = true;
  var pattern = /^[\s]{0,}[0-6][0-9][\s]{0,}$/;
  var result = s.match(pattern);
  var value = parseInt(result, 10);
  if (result == null || value < 1 || value > 60) {
	
    // If an additional argument was passed in, assume it is the
    // smg_ErrorObject and send back a descriptive error message.
	
    if (arguments.length == 2) {
      arguments[1].errorMessage = "The second must be an integer between 01 and 60 of the form SS";
    }
		
    retval = false;
  }
	
  return retval;
	
}  // smg_validate_second()


// ----------------------------------------------------------------------
// Validate that the text string is not empty.
//
// Parameters:
//
// s - string to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_text(s) {
  var retval = true;
  if (s == null || s == "" || s.match(/^[\s]+$/) ) { retval = false; }
  return retval;
}  // smg_validate_text()


// ----------------------------------------------------------------------
// Validate that the string contains only alpha-numeric characters.
// Ignore any whitespace before and after the string.
//
// Parameters:
//
// s - string to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_alphanumeric(s) {
  var retval = true;
  var pattern = /^[\s]{0,}[0-9a-zA-Z]{1,}[\s]{0,}$/;
  var result = s.match(pattern);
	
  if (result == null) { retval = false; }
  return retval;

}  // smg_validate_alphanumeric()


// ----------------------------------------------------------------------
// Validate the string contains a phone number.  Ignore any whitespace before
// and after the string.
//
// Parameters:
//
// s - string to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_integer(s) {
  var retval = true;
  var pattern = /^[\s]{0,}[0-9]{1,}[\s]{0,}$/;
  var result = s.match(pattern);
	
  if (result == null) { retval = false; }
  return retval;

}  // smg_validate_integer()


// ----------------------------------------------------------------------
// Validate the string contains a phone number.
// Ignore any whitespace before and after the integer.
//
// Parameters:
//
// s - string to verify
//
// Returns:
//
// True if valid, false otherwise.
// ----------------------------------------------------------------------

function smg_validate_phoneNumber(s) {
  var retval = true;
  var pattern = /^[\s]{0,}[0-9()+x -]{7,}[\s]{0,}$/;
  var result = s.match(pattern);
	
  if (result == null) { retval = false; }
  return retval;

}  // smg_validate_phoneNumber()


// ----------------------------------------------------------------------
// Validate the select box by returning true since the user can't enter their
// own values.
//
// Parameters:
//
// s - string to verify
//
// Returns: True
//
// ----------------------------------------------------------------------

function smg_validate_selectBox(s) {
  return true;
}  // smg_validate_selectBox()

// ----------------------------------------------------------------------
// Check to see if the named tag exists and is empty on the specified form.
//
// Parameters:
//
// f - reference to the form to check
// tagName - name of the tag to verify
//
// Returns:
//
// True if the named tag does not exist or has no value, false otherwise.
// ----------------------------------------------------------------------

function smg_checkIfEmpty(f, tagName)
{
  string = "f." + tagName;
  if ( eval(string + " == null") || eval(string + ".value == ''") ) {
    return true;
  } else {
    return false;
  }
	
}  // smg_checkIfEmpty()


// ----------------------------------------------------------------------
// Check to see if the named tag exists and is empty on the specified form.
//
// Parameters:
//
// f - reference to the form to check
// tagName - name of the tag to verify
//
// Returns:
//
// True if the named tag does not exist or has no value, false otherwise.
// ----------------------------------------------------------------------

function smg_checkIfEmpty_selectBox(f, tagName)
{
  if (tagName.search(/\[\]$/) != -1) {
    string = "f.elements['" + tagName + "']";
  } else {
    string = "f." + tagName;
  }
			
  if ( eval(string + " == null") ) {
    return true;
  }
	
  var optionsList = eval(string + ".options");
  var numOptions = optionsList.length;
  var isEmpty = true;
		
  for (var i = 0; i < numOptions; i++) {
    if (optionsList[i].selected == true) {
      isEmpty = false;
      break;
    }
  }  // for (i < numOptions)

  return isEmpty;
			
}  // smg_checkIfEmpty_selectBox()


// ----------------------------------------------------------------------
// Check to see if the named date & time tags exist and are empty on the
// specified form.  The date & time tags are a group of tags that are
// logically grouped together.
//
// Parameters:
//
// f - reference to the form to check
// tagName - name of the tag to verify
//
// Returns:
//
// True if the named tag does not exist or has no value, false otherwise.
// ----------------------------------------------------------------------

function smg_checkIfEmpty_dateTime(f, tagName) {
  var retval = true;
  var i;
  var strings = new Array(6);
  var defaults = new Array(6);
  var exists = new Array(6);
  var values = new Array(6);
  var isEmpty = new Array(6);
	
  // Define the element strings
	
  strings[0] = "f." + tagName + "_year";
  strings[1] = "f." + tagName + "_month";
  strings[2] = "f." + tagName + "_day";
  strings[3] = "f." + tagName + "_hour";
  strings[4] = "f." + tagName + "_minute";
  strings[5] = "f." + tagName + "_second";
	
  // Define the element defaults
	
  defaults[0] = "YYYY";
  defaults[1] = "MM";
  defaults[2] = "DD";
  defaults[3] = "HH";
  defaults[4] = "MM";
  defaults[5] = "SS";
	
  // Determine which fields exist
	
  for (i = 0; i < 6; i++) {
    exists[i] = eval( "(" + strings[i] + " == null ? false : true)" );
    values[i] = ( exists[i] ? eval( strings[i] + ".value" ) : null);
    isEmpty[i] = ( values[i] == null || values[i] == "" || values[i] == defaults[i] );
    if ( ! isEmpty[i] ) { retval = false; }
  }
	
  return retval;

}  // smg_checkIfEmpty_dateTime()
