
// Workfile:          RSDFieldValidation.js
// Copyright:         Copyright © 2000 recherché Software Development
// Created:           16-Aug-2000
// Author:            recherché
// Description:       
//
// Dependencies:      None
// Issues:            Requires Event Handlers to be defined for the respective
//						input text boxes, as well as teh event handlers to be defined
//						for Netscape (in the OnLoad event of the page).
//
//					  The following is an example of a text box definition:
//
//						<INPUT id=text1 name=text1 
//							OnFocus="gnTextFieldType = gnALPHA_ONLY; return true" 
//							OnKeyPress="return fnHandleKeyPressEvent(event);" 
//							OnBlur="return fnHandleBlurEvent(event);" 
//							maxLength=32
//						>
//
//
//=============================================
// Code Maintenance Log
//=============================================
//
// Developer:     RJH
// Change Date:   16-Aug-2000
// Reference:     SMR 2097 - Data Validation of Customer Inputs
//
// Description:   Created
//---------------------------------------------
// Developer:	  IB
// Change Date:	  03-June-2002
// Reference:	  RC002 - Regal Croft Interactive site
//
// Description:	  added Field Type constants gnACCOUNT, gnBSB and gnEXPDATE, and gnCURRENCY
//---------------------------------------------
// Developer:	  Gerardo Diaz
// Change Date:	  09/01/2007
// Reference:	  NEW025257   WEB: TAB key must be available to switch between the user id and password fields.
//
// Description:	  Added support for the TAB key to make it compatible with all browsers.
//----------------------------------------------------------

// Define the Field Type Constants that can be used
var gnDEFAULT		= -1;
var gnALPHA_ONLY	= 1;
var gnNUMERIC_ONLY	= 2;
var gnNAME			= 3;
var gnADDRESS		= 4;
var gnEMAIL_ADDRESS	= 5;
var gnDATE			= 6;
var gnPASSWORD		= 7;
var gnACCOUNT		= 8;
var gnBSB			= 9;
var gnEXPDATE		= 10;
var gnCURRENCY		= 11;
//----------------------------------------------------------
// Define the current field type set by controls onFocus event
var gnTextFieldType = -1;			

// Define the Patterns for Matching certain Characters
var gsALPHA_LOWERCASE_STRING	= "a-z";
var gsALPHA_UPPERCASE_STRING	= "A-Z";
var gsALPHA_STRING				= gsALPHA_UPPERCASE_STRING + gsALPHA_LOWERCASE_STRING;
var gsNUMERIC_STRING			= "0-9";
var gsALPHA_NUMERIC_STRING		= gsALPHA_STRING + gsNUMERIC_STRING;
var gsFOREIGN_LANGUAGE_STRING	= 'é';

function emailCheck (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>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.")
		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;
}

function fnValidateKeyCode(nTextFieldType, iKeyCode) {
//-----------------------------------------------------------------
//Description:   Validates a KeyCode againsy the TextFieldType passed in.
//Pass:          nTextFieldType - Indicates the type of text field to validate against.
//									1 = Alpha characters only, no spaces or special characters
//									2 = Numeric characters only, no spaces or special characters
//									3 = 
//				 iKeyCode		- The ASCII code of the character to validate
//
//Return:        Returns true if the character is valid for the type of field,
//				 false if it isn't.
//-----------------------------------------------------------------
//Date        Developer				Comments
//16/08/2000  RJH					Created.
//-----------------------------------------------------------------
	// Constant Definitions
	var nALPHANUMERIC	= 0;		
	var nNUMERICONLY	= 1;
	var nALPHAONLY		= 2;

	// Variable definitions
	var bReturn			= false;			// Return Value
	var nAlphaNumeric	= nALPHANUMERIC;	// General Field Type
	var sValidCharacterPattern = '';		// String containing ALL valid characters for Field

	// If the field type is DEFAULT and the character is not a control character
	// then let it through
	if ((nTextFieldType == gnDEFAULT) && (iKeyCode > 31))
		bReturn = true;

	// Initialise the Special Character Array and general field type variables
	switch(nTextFieldType) {
		// ALPHA_ONLY
		case 1: nAlphaNumeric = nALPHAONLY;		sValidCharacterPattern = "[" + gsALPHA_STRING + "]"; break;

		// NUMERIC_ONLY
		case 2: nAlphaNumeric = nNUMERICONLY;	sValidCharacterPattern = "[" + gsNUMERIC_STRING + "." + "]"; break;

		// NAME
		case 3: nAlphaNumeric = nALPHANUMERIC;	sValidCharacterPattern = "[" + gsALPHA_NUMERIC_STRING + " -+& \.()'" + "]"; break;

		// ADDRESS
		case 4: nAlphaNumeric = nALPHANUMERIC;	sValidCharacterPattern = "[" + gsALPHA_NUMERIC_STRING + " ',\.\/" + "]"; break;

		// EMAIL_ADDRESS
		case 5: nAlphaNumeric = nALPHANUMERIC;	sValidCharacterPattern = "[" + gsALPHA_NUMERIC_STRING + "-\.@" + "]"; break;

		// DATE (dd/mm/yyyy)
		case 6: nAlphaNumeric = nALPHANUMERIC;	sValidCharacterPattern = "[" + gsALPHA_NUMERIC_STRING + "-\.\/" + "]"; break;

		// PASSWORD
		case 7: nAlphaNumeric = nNUMERICONLY;	sValidCharacterPattern = "[" + gsALPHA_NUMERIC_STRING + "]"; break;
		
		// ACCOUNT
		case 8: nAlphaNumeric = nNUMERICONLY;	sValidCharacterPattern = "[" + gsNUMERIC_STRING + "*" + "]"; break;
		
		// BSB
		case 9: nAlphaNumeric = nNUMERICONLY;	sValidCharacterPattern = "[" + gsNUMERIC_STRING + "-" + "]"; break;
		
		// EXPDATE
		case 10: nAlphaNumeric = nNUMERICONLY;	sValidCharacterPattern = "[" + gsNUMERIC_STRING + "/" + "]"; break;
		
		// CURRENCY
		case 11: nAlphaNumeric = nNUMERICONLY;	sValidCharacterPattern = "[" + gsNUMERIC_STRING + "." + "]"; break;
	}

	// Perform a pattern match to see if the passed in character is in the list of allowed characters
	if (bReturn == false) {
		var sText = String.fromCharCode(iKeyCode);
		var reExpression = new RegExp(sValidCharacterPattern);

		bReturn = sText.search(reExpression) != -1;
	}
	
	return bReturn;
}

function fnHandleKeyPressEvent(evt) {
//-----------------------------------------------------------------
//Description:   Event handler for the KeyPress event
//Pass:          evt - the event data
//Return:        Returns true if the character is valid for the type of field,
//				 false if it isn't.
//-----------------------------------------------------------------
//Date        Developer				Comments
//16/08/2000  RJH					Created.
//21/06/2002  IB					Added code to enable user to use backspace key
//09/01/2007  Gerardo Diaz			NEW025257   WEB: TAB key must be available to switch between the user id and password fields.
//									Added code to enable user to use TAB key. Apparently some browsers do not support the TAB key natively as IE does.							
//-----------------------------------------------------------------
	var iKeyCode;
	
	if (navigator.appName == 'Microsoft Internet Explorer') 
		iKeyCode = evt.keyCode;
	else
		iKeyCode = evt.which;
	
	//allow user to use backspace key
	//09/01/2007  Gerardo Diaz			NEW025257   WEB: TAB key must be available to switch between the user id and password fields.
	//									Strange behaviour of the keycode value for the TAB key.
	
	if (iKeyCode == 8 || iKeyCode == 0)
		return true;
	//09/01/2007  Gerardo Diaz			NEW025257   END
	
	if (fnValidateKeyCode(gnTextFieldType, iKeyCode)) 
		return true;
	else
		iKeyCode=0;
		return false;
}

function fnHandleBlurEvent(evt) {
//-----------------------------------------------------------------
//Description:   Event Handler for the Blur event.  This validates all
//				 characters in the field to prevent copy/paste of invalid characters.
//Pass:          evt - The Event Data
//Return:        Returns true if all characters are valid for the type of field,
//				 false if they aren't.
//-----------------------------------------------------------------
//Date        Developer				Comments
//16/08/2000  RJH					Created.
//-----------------------------------------------------------------
	var objSrcElement;
	
	// Get the Element which raised the Event
	if (navigator.appName == 'Microsoft Internet Explorer') 
		objSrcElement = evt.srcElement;
	else
		objSrcElement = evt.target;
		
	var sText = objSrcElement.value;
	var i = 0;
	var bReturn = true;
	
	if ((sText != null) && (sText != "")) {
		// Validate all the characters in the field.
		while ((i < sText.length) && (bReturn == true)) {
			if (!fnValidateKeyCode(gnTextFieldType, sText.charCodeAt(i)))
				bReturn = false;
			i++;
		}
		
		// If the field is OK and it is an Email field then check the Email address
		if ((bReturn == true) && (gnTextFieldType == gnEMAIL_ADDRESS)) {
			if ((bReturn = emailCheck(sText)) == false) {
				alert('The Email address is not valid.');
				objSrcElement.focus();
				objSrcElement.select();
			}
		}
		// Otherwise if there was an error then generate an error message
		else if (bReturn == false) {
			alert('The field contains invalid characters.');
			objSrcElement.focus();
			objSrcElement.select();
		}
	}
	
	return bReturn;
}



