//Validates an email text field
//Parameter: oElement - the form element to validate
//Parameter: sFieldName - the string to display as the field name for error popups
//Parameter: bRequired - boolean as to whether the field is required.  This determines
//                       if it is considered an error if the field is blank
//Returns: boolean
function ValidateEmailField(oElement, sFieldName, bRequired)
{
	//Trim the field
	oElement.value = trim(oElement.value);
	
	//Make sure the field is not blank
	if (oElement.value == "" || oElement.value.length == 0)
	{
		//If blank and not required, exit true
		if (!bRequired)
		{
			return true;
		}
		else
		{
			//If blank and required, pop up a message, focus to the field, and exit false
			alert("Please enter a value for the \"" + sFieldName + "\" field.");
			oElement.focus();
			return false;
		}
	}
	
	//If maxlength is defined, make sure it is not exceeded
	if (oElement.maxLength != 2147483647 && oElement.maxLength != -1)
	{
	    if (oElement.value.length > oElement.maxLength)
	    {
			//If maxlength is exceeded, pop up a message, focus to the field, and exit false
			alert("The entered value for the \"" + sFieldName + "\" field is too long.  Please enter a value less than " + oElement.maxLength + " characters in length.");
			oElement.focus();
			return false;
	    }
	}	
	
	//Make sure all of the characters are valid
	if (!ValidateEmailChars(oElement.value))
	{
		alert("This website does not accept foreign characters. Please enter a valid characters for the \"" + sFieldName + "\" field.");
		oElement.focus();
		return false;
	}
	
	//Check the format
	if (!ValidateEmailFormat(oElement.value))
	{
		alert("Plase enter a valid email address in the \"" + sFieldName + "\" field.");
		oElement.focus();
		return false;
	}
	
	//If we get this far, everything is OK, so exit true
	return true;
}

//This is an e-mail address validation function. It allows the usual user@domain 
//syntax, but in addition allows user@[ip] format as well as "User with 
//Spaces"@domain or [ip], all of which are legal syntax, according to W3C. It also 
//checks that the user hasn't done anything silly like having multiple @'s or 
//continuous .'s in the address (e.g. jim@b@c.com and jim@c..b.co.uk).
//The code was found at http://javascript.internet.com/forms/check-email.html
function ValidateEmailFormat(emailStr)
{
	/* 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 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 an atom (basically a series of
	   non-special characters.) */
	var atom=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 coarse pattern to simply break up user@domain into
	   different pieces that are easy to analyze. */
	var matchArray=emailStr.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)")
		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.")
	    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!")
			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.")
	    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), and that there's a hostname preceding 
	   the domain or country. */

	/* 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>4) {
	   // 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.")
	   return false
	}

	// Make sure there's a host name preceding the domain.
	if (len<2) {
	   var errStr="This address is missing a hostname!"
	   //alert(errStr)
	   return false
	}

	// If we've gotten this far, everything's valid!
	return true;
}

//Validates an email address for invalid characters
//This is the same as validateStringChars but also allows the -@._ characters
//Parameter: sEmailToCheck - the email to check for invalid characters
//Returns: boolean
function ValidateEmailChars(sEmailToCheck)
{
	//String of allowable characters
	var checkOK = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzƒŠŒŽšœžŸÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ0123456789-@._";
	
	//Validate
	return ValidateChars(sEmailToCheck, checkOK);
}

//Validates a string to make sure all characters are allowable
//Parameter: sStringToCheck - the string to check for invalid characters
//Parameter: sCheckString - a string of allowable characters
//Returns: boolean
function ValidateChars(sStringToCheck, sCheckString)
{		
	//Spin through each character of the string to check
    for (var i = 0;  i < sStringToCheck.length;  i++)
    {		
		//Spin through each character of the of the string of valid characters
		for (var j = 0;  j < sCheckString.length;  j++)
        {
			//If we match a valid character, break out
			if (sStringToCheck.charAt(i) == sCheckString.charAt(j))
			{
				break;
			}
		}
		
		//If we made it through all the characters without breaking,
		//the character is invalid, so exit false
		if (j == sCheckString.length)
		{
		    //Allow crlf characters
		    if (!(sStringToCheck.charCodeAt(i) == 13 || sStringToCheck.charCodeAt(i) == 10))
            {
		        return false;
		    }
		}
    }
    
    //If we made it here, there were no invalid characters, so exit true
    return true;
}

//Performs a left trim on a string
//Parameter: s - the string to trim
//Returns: the left trimmed string
function ltrim (s)
{
	return s.replace( /^\s*/, "" );
}

//Performs a right trim on a string
//Parameter: s - the string to trim
//Returns: the right trimmed string
function rtrim(s)
{
	return s.replace( /\s*$/, "" );
}

//Trims a string
//Parameter: s - the string to be trimmed
//Returns: the trimmed string
function trim(s)
{
	return rtrim(ltrim(s));
}
