/*
//////////////////////////////////////////////////////////////////////////////////////////////////////////
Template:	postalcodevalidation.js
Location:	/includes/js/
Developer:	Chad Hendrie
Date:		April 23, 2002

Purpose:	Verify a string is a valid postal code.

Notes:		

Revisions:
Name			Date		Issue	Details
---- 			----		-----	------- 
//////////////////////////////////////////////////////////////////////////////////////////////////////////
*/



/*
CanadianCharacterValidation ()

Description
----------- 
Given a character and a position, verify the alpha character follows the rules
for Canadian postal codes.

Returns
-------
-1 	: invalid position
0 	: no errors
1 	: invalid first position
2	: invalid and not the first position

Rules
-----
* Cannot contain D, F, I, O, Q or U.
* W or Z cannot be the first letters in the code.
* First letter must be one of A,B,C,E,G,H,J,K,L,M,N,P,R,S,T,V,X,Y

Notes
-----
A Canadian postal code contains 7 characters and JavaScript starts its string
arrays at 0.
*/
function CanadianCharacterValidation (character, position)
{

	// Local Variables
	var i;
	var aValidPositions		= new Array (0, 2, 5);
	var aInvalidFirstChars 	= new Array ("W", "Z");
	var aInvalidChars 		= new Array ("D", "F", "I", "O", "Q", "U");

	
	/* Position Parameter Check */

	// Verify the position parameter is valid.
	var bValid = false;
	for (i=0; i<aValidPositions.length; i++)
	{
		if (aValidPositions[i] == position)
		{
			bValid = true;
			break;
		}
	}
	
	// Check for an invalid position parameter.
	if (!bValid)
		return (-1);
	
	
	/* Validation */
	
	// Check if the request position is the first (zero in array terms).
	if (position == 0)
	{
		// Check if the first position contains an invalid first character.
		for (i=0; i<aInvalidFirstChars.length; i++)
			if (aInvalidFirstChars[i] == character)
				return (1);
	}

	// Check if the current position contains an invalid character.
	for (i=0; i<aInvalidChars.length; i++)
		if (aInvalidChars[i] == character)
			return (2);

	// Success!	
	return (0);
}



/*
PostalCodeValidation ()

Description
-----------
Given a postalcode string and a country (string or id), verifiy the string is in
the corrent format for either a United States postal code or a Canadian postal
code.

Parameters
----------
postalcode 	- postal code (string)
country		- a country id (string or integer)

Returns
-------
If the postal code is invalid, an error string is returned.
Otherwise, the string "UNITED_STATES" or "CANADA" is returned depending on the
type of postal code.

Notes
-----
Postal Code Formats
	- US
		* 5 digits
	- Canadian
		* 7 characters
		* alpha | numeric | alpha | space | numeric | alpha | numeric

Country Id
	- US 		=> 1 OR USA
	- Canada	=> 2 OR CANADA
*/
function PostalCodeValidation (postalcode, country)
{
	
	// Local Variables
	var i, j;
	
	
	/* Parameter Processing */
	
	country = country.toUpperCase();
	
	
	// Verify the country is valid.
	if (country != 1 && country != "USA" && country != 2 && country != "CANADA")
	{
		// Invalid Country Id
		
		return ("Invalid country id.");
	}
	
	
	/* Country */
	
	// Determine the postal code's associated country.
	if (country == 1 || country == "USA")
	{
		/* United States */

		
		/* Length */
	
		// Verify the postal code is the correct length.
		if (postalcode.length != 5 && postalcode.length != 9)
			return ("A United States postal code must be 5 or 9 characters.");
	
		
		/* Format */
		
		// Verify all characters are numeric.
		if (!IsPositiveInteger (postalcode))
			return ("A United States postal code must contain 5 or 9 digits.");
		
		// Valid
		return ("UNITED_STATES");
	
	}
	else if (country == 2 || country == "CANADA")
	{
		/* Canada */
		// If they forget the space in the middle position, don't consider it invalid.
		// However, this input should be corrected before being inserted in the database
		if( postalcode.length == 6 )
			postalcode = 	postalcode.charAt(0) + postalcode.charAt(1) + postalcode.charAt(2) + " " 
						+ 	postalcode.charAt(3) + postalcode.charAt(4) + postalcode.charAt(5);
		/* Length */
		// Verify the postal code is the correct length.
		if (postalcode.length != 7)
			return ("A Canadian postal code must be 7 characters.");
		
		
		/* Format */
		
		var bValid = true;

		// Push all alpha characters to upper case for processing.
		postalcode = postalcode.toUpperCase();
			
		// For each postal code character ...
		for (i=0; i<postalcode.length; i++)
		{
		
			// Store the current postal code character.
			var chCurrent = postalcode.charAt(i);

			// Process the current character.			
			switch (i)
			{
				// Alpha
				case 0:
						if (chCurrent < 'A' || chCurrent > 'Z')
							bValid = false;
						else
						{
							if (CanadianCharacterValidation (chCurrent, i))
							{
								bValid = false;
								break;
							}
						}
						break;
				
				// Numeric
				case 1:
						if (!IsPositiveInteger (chCurrent))
							bValid = false;
						break;

				// Alpha
				case 2:
						if (chCurrent < 'A' || chCurrent > 'Z')
							bValid = false;
						else
						{
							if (CanadianCharacterValidation (chCurrent, i))
							{
								bValid = false;
								break;
							}
						}
						break;

				// Space
				case 3:
						if (chCurrent != ' ')
							bValid = false;
						break;

				// Numeric
				case 4:
						if (!IsPositiveInteger (chCurrent))
							bValid = false;
						break;

				// Alpha
				case 5:
						if (chCurrent < 'A' || chCurrent > 'Z')
							bValid = false;
						else
						{
							if (CanadianCharacterValidation (chCurrent, i))
							{
								bValid = false;
								break;
							}
						}
						break;

				// Numeric
				case 6:
						if (!IsPositiveInteger (chCurrent))
							bValid = false;
						break;
			}	/* END: switch */

			// Check if the current character is INVALID.
			if (!bValid)
				break;

		}	/* END: for loop */

		// Check if the Canadian postal code is in the corrent format.		
		if (!bValid)
			return ("A Canadian postal code must be in the following format:'letter|number|letter|space|number|letter|number'");

		// Valid
		return ("CANADA");
	}	/* END: check for canadian postal code (7 characters) */
}
