// This function takes the browser to the URL on this webserver, using HTTP protocol
function gotoURL(locString)
{
    var str = 'http://' + window.location.host + '/' + locString;
    parent.window.location.href = str;
}

// This function takes the browser to the URL on this webserver, using HTTPS protocol
function gotoSecureURL(locString)
{
    var str = 'https://' + window.location.host + '/' + locString;
    parent.window.location.href = str;
}

// This function returns true if a string contains only whitespace characters
function isblank (s)
{
  var i;
  var c;

  for (i = 0; i < s.length; i++)
  {
    c = s.charAt(i);
    if ((c != ' ') && (c != '\n') && (c != '\t'))
      return false;
  }
  return true;
}

// This function performs form verification. It will be invoked from the onSubmit()
// event handler. The handler should return whatever value this function returns.
// f is the form
// lf is 0 for no line feeds in the alert message, 1 for line feeds after each item
function verifyForm(f, lf)
{
  var msg;				// Message to display if not everything is filled out
  var empty_fields = "";		// Which fields are empty?
  var bad_values = "";			// Which fields have bad values?
  var e;				// Element
  var v;				// Numeric value
  var vstr;				// String value
  var checkNames = new Array();		// Array of check element names (radio buttons
					// and check boxes)
  var checkArray = new Array();		// Signals whether check element is checked
  var checkIndex = 0;			// Next free element in CheckNames array
  var i;				// Generic loop variable
  var j;				// Generic loop variable
  var QString;				// question number
  var previousQString="";		// previous question number
  var nameString;			// name of question
  var efStarted;			// Has the emptyFields string been started?

  // Loop through the elements of the form, looking for all text and textarea
  // elements that don't have an "optional" property defined. Then, check for
  // fields that are empty and make a list of them. Also, if any of these
  // elements have a "min" or "max" property defined, then verify that they are
  // numbers and that they are within the range. If they have an "equal" value defined,
  // make sure they are equal to the value. Put together error messages for fields that are wrong.

  for (i = 0; i < f.length; i++)
  {
    e = f.elements[i];
    if (((e.type == "text") || (e.type == "textarea") || (e.type == "password")) && !e.optional)
    {
      // Check if the field is empty
      if ((e.value == null) || (e.value == "") || isblank(e.value))
      {
        // see if the element is already in the array
        for (j = 0; (j < checkIndex) && (checkNames[j] != e.name); j++);

        if (j == checkIndex)
        {
          // It's not already in the array, so add it
          checkNames[j] = e.label;

          // This is used for debugging undefined labels in a form
          if (e.label == null)
	    checkNames[j] = "undefined("+ e.name + ")";

          checkArray[j] = false;
          checkIndex++;
        }
      }
      else
      {
        // This is used for debugging undefined labels in a form
        if (e.label == null)
	  vstr = "undefined("+ e.name + ")";
        else
          vstr = e.label;

        if (isNaN(e.value) && ((e.min != null) || (e.max != null) || (e.equals != null)))
          bad_values += "\t" + vstr + " has an illegal (non-numeric) value\n";
        else
        {
          v = parseInt(e.value);
          if (e.min != null)
          {
            if (v < e.min)
              bad_values += "\t" + vstr + " is below the minimum allowed value of " + e.min + "\n";
          }
          else if (e.max != null)
          {
            if (v > e.max)
              bad_values += "\t" + vstr + " is above the maximum allowed value of " + e.max + "\n";
          }
          if (e.equals != null)
          {
            if (v != e.equals)
              bad_values += "\t" + vstr + " must be equal to " + e.equals + "\n";
          }
        }

        // Convert string to lower case if the field is not case sensitive
        if (!e.case_sensitive)
          e.value = e.value.toLowerCase();
      }
    }
    else if (e.type == "radio")
    {
      // see if the element is already in the array
      for (j = 0; (j < checkIndex) && (checkNames[j] != e.name); j++);

      if (j == checkIndex)
      {
        // It's not already in the array, so add it
        checkNames[j] = e.label;

        // This is used for debugging undefined labels in a form
        if (e.label == null)
	  checkNames[j] = e.name;

        checkArray[j] = false;
        checkIndex++;
      }

      // OR the current checked value with the previous one
      if (e.optional)
        checkArray[j] = true;
      else
        checkArray[j] |= e.checked;
    }
    else if ((e.type == "hidden") || (e.type == "checkbox"))
    {
      // Truncate the part of the name after the option
      for (j = 0; (j < e.name.length) && (e.name.charAt(j) != 'O'); j++);
      // nameString = e.name.slice(0,j);
	nameString = e.label;

        // This is used for debugging undefined labels in a form
          if (e.label == null)
	    nameString = "undefined("+ e.name + ")";


      // see if the element is already in the array
      for (j = 0; (j < checkIndex) && (checkNames[j] != nameString); j++);

      if (j == checkIndex)
      {
        // It's not already in the array, so add it
        checkNames[j] = nameString;
        checkArray[j] = false;
        checkIndex++;
      }

      // OR the current checked value with the previous one
      if (e.optional)
        checkArray[j] = true;
      else if (e.type == "checkbox")
        checkArray[j] |= e.checked;
      else
      {
        if ((e.value != "null") && (e.value != "") && !isblank(e.value))
          checkArray[j] = true;
      }
    }
    else if ((e.type == "select-one") && (!e.optional))
    {
      vstr = "null";
      for (j = 0; j <e.options.length; j++)
      {
        if (e.options[j].selected)
        {
          vstr = e.options[j].value;
          break;
        }
      }

      // Check if the field is empty
      if (vstr == "null")
      {
        // see if the element is already in the array
        for (j = 0; (j < checkIndex) && (checkNames[j] != e.name); j++);

        if (j == checkIndex)
        {
          // It's not already in the array, so add it
          checkNames[j] = e.label;

          // This is used for debugging undefined labels in a form
           if (e.label == null)
	    checkNames[j] = "undefined("+ e.name + ")";

          checkArray[j] = false;
          checkIndex++;
        }
      }
    }
  }

  // Now examine each element to see if a value was entered
  efStarted = 0;
  for (i = 0; i < checkIndex; i++)
  {
    // Check if the element is unchecked
    if (!checkArray[i])
    {
      QString = checkNames[i]
      if (QString != previousQString)
      {
//          if ((lf == 1) || (efStarted == 0))
//            empty_fields += "\n";
//          if ((lf == 1) || (efStarted == 1))
//            empty_fields += "\t";
          empty_fields += "\n\t" + QString;
//          efStarted = 1;
      }
      previousQString = QString;
    }
  }

  // If there were any empty fields, display an error messages and return false to
  // prevent the form from being submitted. Otherwise return true.
  if (!empty_fields)
  {
    if (!bad_values)
      return true;
    msg = "The form cannot be submitted because the following fields have illegal values:\n" + bad_values;
  }
  else
    msg = "Please fill in all required fields.\nThe following fields have not been filled in: " + empty_fields;

  alert(msg);
  return false;
}

// This is, at best, a perfunctory test of email address 
// entry validity.  Is there an "@" sign and sufficient
// letters prefixing it. Alert user if questioned.
function emailCheck(email)
{
  var suffix = "";		// email string after '@'
  var at_index;			// index of '@' sign in email
  var dot_index = 0;		// index of '.' within suffix

  at_index = email.indexOf("@");
  if ((at_index != email.length-1) && (at_index > 0))
  {
    suffix = email.substring(at_index+1);
    dot_index = suffix.indexOf(".");
  }

  if ((suffix.length < 3) || (dot_index == suffix.length-1) ||
      (at_index <= 0)  || (dot_index <= 0))
  {
    alert("Your email address was not entered correctly.");
    return false;
  }
  return true;
}

// This tests that the date is valid.
function dateCheck(month, day, year)
{
  if ((month < 1) || (month > 12))
  {
	alert("Please select a valid month.");
	return false;
  }

  if (day < 1)
  {
	alert("Please select a valid day.");
	return false;
  }

  if (year < 2004)
  {
	alert("Please select a valid year.");
	return false;
  }

  if ((month == 9) || (month == 4) || (month == 6) || (month == 11))
  {
    // Thirty days has September, April, June and November
	if (day > 30)
    {
	  alert("Please select a valid date.");
	  return false;
    }
  }
  else if (month == 2)
  {
	// February, leap month
	// Is the year divisible by 4?
	if ((year/4) == parseInt(year/4))
	{
	  // Is the year divisible by 100?
	  if ((year/100) == parseInt(year/100))
	  {
	    // Not a leap year
        if (day > 28)
        {
  	      alert("Please select a valid date.");
          return false;
        }
 	  }
	  else
	  {
	    // Leap year
        if (day > 29)
        {
  	      alert("Please select a valid date.");
          return false;
        }
	  }
	}
	else
	{
	  // Not a leap year
      if (day > 28)
      {
  	    alert("Please select a valid date.");
        return false;
      }
	}
  }
  else
  {
    // All the rest have 31
	if (day > 31)
    {
	  alert("Please select a valid date.");
	  return false;
    }
  }

  return true;
}
