<!--

//Javascript form validation.
//
//
//These routines are called from a forms onSubmit event.
//
//validateInput() accepts two parameters, the name of the form
//to be processed and a string that provides a mask against which 
//each field on the named form can be validated.
//
//This mask is the key to the functionality of this script. For each field on the form
//the corresponding character in the mask string tells the handler how to perform the 
//validation.
//
//The mask string can contain the following characters;
//
//	d = validate value as a date
//	t = validate value as text
//	n = validate value as a whole number (1234567890)
//	p = validate value as a phone number (+,(), 1234567890)
//	e = validate value as an e-mail address (@, .)
//  c = validate that checkbox is checked
//	u = unrequired - do not validate
//
//
//----------------------------------------------------------------------
//
//EXAMPLE OF USE.
//
//The form should have this:
//
//	 onSubmit="return validateInput(formname, 'maskstring')"
//
//NOTE. The number of characters in the string must be the same as 
//the number of form elements (including select lists, checkboxes 
//and radio buttons) on the form.
//
//An example <FORM> tag should read;
//
//<FORM  NAME="testfrm" METHOD="get" ACTION="success.htm" 
//	onSubmit="return validateInput(testfrm, 'duttnpeuu')">
//
//The mask string in this case covers 9 fields on a form.
//
//	1. d = date
//	2. u = unrequired
//	3. t = text
//	4. t = text
//	5. n = number
//	6. p = phone number
//	7. e = e-mail
//	8. u = unrequired
//	9. u = unrequired
//
//--------------------------------------------------------------------------
function validateInput(frm, mask)
{
    if (arguments.length == 4)  // optional parameters for checking length of textarea input
	{
	    var field = arguments[2];
		var maxlen = arguments[3];
    	if (!maxChars(field, maxlen)) return false;  // maxChars.js included from calling file
	}

	//Count the number of form elements
	var FrmLen = frm.elements.length;
 
	//Get the validation mask string
	var maskarr = mask;
	
	//Loop through all the form elements
	for (var i = 0; i < FrmLen; i++)
	{
		//obtain the validation mask character
		maskarr = mask.substring(i,i+1)

		//Initialise local variables
		var valdate = 1;
		var valtext = 1;
		var valnum = 1;
		var valtelenum = 1;
		var valemail = 1;
		var valcheck = 1;
		var valchoice = 1;
		
		//Test field against validation mask character
		if (maskarr == "d")
		{
			valdate = validateDate(frm.elements[i].value);
		}
		if (maskarr == "t")
		{
			valtext = validateText(frm.elements[i].value);
		}
		if (maskarr == "n")
		{
			valnum = validateNum(frm.elements[i].value);
		}
		if (maskarr == "p")
		{
			valtelenum = validateTeleNum(frm.elements[i].value);
		}
		if (maskarr == "e")
		{
			valemail = validateEmail(frm.elements[i].value);
		}
		if (maskarr == "c")
		{
			valcheck = validateCheck(frm.elements[i].value);
		}
		if (maskarr == "s")
		{
			valchoice = validateChoice(frm.elements[i].value);
		}
		
		//If the validation fails prompt the user
		if (! valchoice)
		{
			alert("Please select an entry from the drop-down list.");
			putFocus(frm.elements[i]);
			return false;
		}
		if (! valdate)
		{
			alert("The date you have entered is invalid.\nExample: mm/dd/yyyy");
			putFocus(frm.elements[i]);
			return false;
		}
		if (! valtext)
		{
			alert("The details you have entered are incomplete.\nPlease fill in all required form fields");
			putFocus(frm.elements[i]);
			return false;
		}
		if (! valnum)
		{
			alert("Please enter a valid number.\nExample: 1,2,3,4,5,6,7,8,9,0");
			putFocus(frm.elements[i]);
			return false;
		}
		if (! valtelenum)
		{
			alert("Please enter a valid telephone or extension number.\nExample: 999-999-9999");
			putFocus(frm.elements[i]);
			return false;
		}
		if (! valemail)
		{
	//		alert("The Email address you have entered is invalid.\nFor example: username@thedomain.com");  // Commented out so validateEmail can throw its alerts.
			putFocus(frm.elements[i]);
			return false;
		}
		if (! valcheck)
		{
			alert("Please check one of the CheckBox Options");
			putFocus(frm.elements[i]);
			return false;
		}
	}
	return true;
}

//Date validation function
function validateDate(s)
{
  if (s.length != 10) { return false }

  for (j=0; j<s.length; j++) {
    if ((j == 2) || (j == 5)) {
      if (s.charAt(j) != "/") { return false }
    } else {
      if ((s.charAt(j) < "0") || (s.charAt(j) > "9")) { return false }
    }
  }

  var month = s.charAt(0) == "0" ? parseInt(s.substring(1,2)) : parseInt(s.substring(0,2));
  var day = s.charAt(3) == "0" ? parseInt(s.substring(4,5)) : parseInt(s.substring(3,5));
  var begin = s.charAt(6) == "0" ? (s.charAt(7) == "0" ? (s.charAt(8) == "0" ? 9 : 8) : 7) : 6;
  var year = parseInt(s.substring(begin, 10));

  if (day == 0) { return false }
  if (month == 0 || month > 12) { return false }
  if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
    if (day > 31) { return false }
  } else {
    if (month == 4 || month == 6 || month == 9 || month == 11) {
      if (day > 30) { return false }
    } else {
      if (year%4 != 0) {
        if (day > 28) { return false }
      } else {
        if (day > 29) { return false }
      }
    }
  }
  return true;
}

//Text validation function
function validateText(s)
{
	//test for a string
	if (s.length > 0)
	{
		return true;
	}
	return false;
}

//Text validation function
function validateChoice(s)
{
    if (!validateText(s)) return false;
	// test for a selection
	if (s == "CHOOSE ONE") return false;
	else return true;
}

//Number validation function
function validateNum(s)
{
	//Test to see if the value converts to a number
	if (parseInt(s) > 0)
	{
		return true;
	}
	return false;
}

//Telephone Number validation function
function validateTeleNum(s)
{
  if (s.length != 12) { return false }
  for (j=0; j<s.length; j++) {
    if ((j == 3) || (j == 7)) {
      if (s.charAt(j) != "-") { return false }
    } else {
      if ((s.charAt(j) < "0") || (s.charAt(j) > "9")) { return false }
    }
  }
  return true;
}


//{
//Test for a string
//	if (s.length > 0)
//	{
//		for (i = 0;  i < s.length;  i++)
//		{
//		    	ch = s.charAt(i);
//			if(! own_instring(ch))
//			{
//			return false;
//			}
//		}
//		return true;
//	}
//	return false;
//}



//E-Mail address validation function
function validateEmail(s) {

	/* The following pattern is used to check if the entered e-mail address
   fits the user@domain format.  It also is used to separate the username
   from the domain. */
   
	var emailPat=/^(.+)@(.+)$/
	
	/* The following string represents the pattern for matching all special
   characters.  We don't want to allow special characters in the address. 
   These characters include ( ) < > @ , ; : \ " . [ ]    */
   
	var specialChars="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"
	
	/* The following string represents the range of characters allowed in a 
   username or domainname.  It really states which chars aren't allowed. */
   
	var validChars="\[^\\s" + specialChars + "\]"
	
	/* The following pattern represents the range of characters allowed as
   the first character in a valid username or domain.  I just made it
   the same as above, but if you want to add a different constraint,
   you would change it here. */
   
	var firstChars=validChars
	
	/* The following pattern applies if the "user" is a quoted string (in
   which case, there are no rules about which characters are allowed
   and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
   is a legal e-mail address. */
   
	var quotedUser="(\"[^\"]*\")"
	
	/* The following pattern applies for domains that are IP addresses,
   rather than symbolic names.  E.g. joe@[123.124.233.4] is a legal
   e-mail address. NOTE: The square brackets are required. */
   
	var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
	
	/* The following string represents at atom (basically a series of
   non-special characters.) */
   
	var atom="(" + firstChars + validChars + "*" + ")"

	/* The following string represents one word in the typical username.
   For example, in john.doe@somewhere.com, john and doe are words.
   Basically, a word is either an atom or quoted string. */
   
	var word="(" + atom + "|" + quotedUser + ")"

	// The following pattern describes the structure of the user

	var userPat=new RegExp("^" + word + "(\\." + word + ")*$")

	/* The following pattern describes the structure of a normal symbolic
   domain, as opposed to ipDomainPat, shown above. */
   
	var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$")


	/* Finally, let's start trying to figure out if the supplied address is
   valid. */

	/* Begin with the course pattern to simply break up user@domain into
   different pieces that are easy to analyze. */
   
	var matchArray=s.match(emailPat)
	if (matchArray==null) {

  		/* Too many/few @'s or something; basically, this address doesn't
     	even fit the general mould of a valid e-mail address. */
	 
		alert("Email address seems incorrect (check @ and .'s)\nExample: username@domain.com")
		return false
	}
	var user=matchArray[1]
	var domain=matchArray[2]

	// See if "user" is valid 

	if (user.match(userPat)==null) {
	
    // user is not valid
	
    	alert("The username doesn't seem to be valid.\nPlease enter a valid username.")
    	return false
	}
	
	/* if the e-mail address is at an IP address (as opposed to a symbolic
   host name) make sure the IP address is valid. */
   
	var IPArray=domain.match(ipDomainPat)
	if (IPArray!=null) {
	
    	// this is an IP address
		
	  	for (var i=1;i<=4;i++) {
	    	if (IPArray[i]>255) {
	        	alert("Destination IP address is invalid!\nPlease enter a valid IP address.")
			return false
	    	}
    	}
    	return true
	}

	// Domain is symbolic name
	
	var domainArray=domain.match(domainPat)
	if (domainArray==null) {
		alert("The domain name doesn't seem to be valid.\nPlease enter a valid domain name.")
    	return false
	}
	
	/* domain name seems valid, but now make sure that it ends in a
   three-letter word (like com, edu, gov) or a two-letter word,
   representing country (uk, nl).
   If there's a country code at the end of the address, the full domain
   must include a hostname and category (e.g. host.co.uk or host.pub.nl).
   If it ends in a .com or something, make sure there's a hostname.*/

	/* Now we need to break up the domain to get a count of how many atoms
   it consists of. */
   
	var atomPat=new RegExp(atom,"g")
	var domArr=domain.match(atomPat)
	var len=domArr.length
	if (domArr[domArr.length-1].length<2 || 
    	domArr[domArr.length-1].length>3) {
		
   		// the address must end in a two letter or three letter word.
		
   		alert("The address must end in a three-letter domain, or two letter country.\nExample: .com, .net, .co, .pu, .ca")
   		return false
	}

	/* If it ends in a country code, we want to make sure there are at
   least 2 atoms preceding it (representing host and category (i.e.
   com, gov, etc.)) */
   
	if (domArr[domArr.length-1].length==2 && len<3) {
   		var errStr="This address ends in two characters, which is a country a code."
   			errStr+="\nCountry codes must be preceded by a hostname and category."
   			errStr+="\nExample .com, .co, .pub, .pu"
   		alert(errStr)
   		return false
	}

	/* If it just ends in .com, .gov, etc., make sure there's a host name.
   This case can never actually happen because earlier checks take
   care of this implicitly, but we'll do it anyway. */
   
	if (domArr[domArr.length-1].length==3 && len<2) {
   		var errStr="This address is missing a hostname!\nExample: username@HOSTNAME.com"
   		alert(errStr)
   		return false
	}
	
	// If we've gotten this far, everything's valid!
	
	return true;
}



//In string function to test for valid substring, accomodates JavaScripts lack of VBScripts InStr() function
function own_instring(c)
{
	var checkOK = "0123456789-+-. ()\t\r\n\f";
	var ret  = false;

  		for (j = 0;  j < checkOK.length;  j++)
		{
      			if (c != checkOK.charAt(j))
			{
			continue;
			}
			else
			{
			ret = true;
			break;
			}
		}
	return ret;
}

//String split function to accomodate JScripts lack of JavaScripts split function
function own_split(arr, str, delim)
{
	//Initialise local variables
	var pos = 0;
	var num = 0;
	var start = 0;
	
	//Loop while there are characters in the string
	while (pos < str.length)
	{
		//Loop while there are delimiters in the string
		while((str.substring (pos, pos+1) != delim) && (pos < str.length))
		{
		pos++;
		}
		//Add the new characters to the output array
		arr[num] = str.substring(start,pos);
		num++;
		start = pos+1;
		pos++;
	}
}

//--------------------------------------------------------------------------------------------------------------------
//
//JavaScript form focus handler
//
//Does not work on IE 3.0 but does not cause errors. 
//
//This function is called by the page onLoad event, the forms
//reset button and the validateInput() function. 
//
//It sets focus on either the first text box on the form (in the onLoad and form reset),
//or in the text box that fails the validation test (from the call in validateInput()).
//
//--------------------------------------------------------------------------------------------------------------------

function putFocus(elementStr)
   {
   elementStr.value="";
   elementStr.focus();
   }
   
//-->
