/*------------------  METHOD DESCRIPTION  ------------------------------------------------
This method will check that a particular element is not empty, selected, etc. Based on what
type of element is passed.
INPUT: 
		oElement		- the element to validate
		sElementType	- the element type:
								text
								select
								radio
								checkbox
		sValNotValid	- Any value that, if its the elements current value it is still not valid
						  (This is mainly for dropdowns & listboxes where a val of 0 would be like selecting
						  nothing at all. ie. <option value="0">please choose one</option>)
		
OUTPUT: true/false
		True -		When the check returns positive (i.e text element not empty)
		False -		Validation requirements not met
-----------------------------------------------------------------------------------------*/
function required(oElement, sElementType, sValNotValid){
	
	var blnValid = true;
	var i;
	var sElementVal = new String();
	
	//make to lowercase to ensure correctness
	sElementType = sElementType.toLowerCase();
	
	switch(sElementType){
		
		case 'text' :
			
			//perform validation for a text box and textareas
			sElementVal = oElement.value;
			
			//trim string of white spaces
			sElementVal = checkAllWhiteSpcs(sElementVal);
			
			if(sElementVal.length < 1){
				blnValid = false;
			}
			break;
			
		case 'select' :
			
			//perform validation for a listbox or a combo box [<select> element]
			if(oElement.selectedIndex == -1){
				blnValid = false;
			}
			else if(sValNotValid.length > 0){
				//check that value is not the same as [sValNotValid] only when [sValNotValid] passed
				if(oElement.options[oElement.selectedIndex].value == sValNotValid){
					blnValid = false;
				}
			}
			break;
			
		case 'radio' :
			//validation for a set of radio buttons
			
			//initialise blnValid to false
			blnValid = false;
			
			//since radios are received as arrays, loop through collection and find if one checked
			for(i=0;i<oElement.length;i++){
				if(oElement[i].checked){
					//if one checked set blnValid to true
					blnValid = true;
					
				}
				
			}
			
			break;
			
		case 'checkbox' :
			//validation for a checkbox
			
			//check whether checkbox is checked and return that value
			blnValid = oElement.checked;
			
			break;
			
	}
	
	return(blnValid);
	
}

/*-----------------------------------------------------------------------------------------------------------
DESCRIPTION:	THIS METHOD LOOPS THROUGH A STRING AND FINDS IF THERE ARE ANY OTHER CHARACTERS IN IT 
				APART FROM WHITE SPACES. IF THERE ARE ANY OTHER CHARACTERS, THE STRING WILL BE LEFT 
				UNTOUCHED. OTHERWISE IT WILL RETURN AN EMPTY STRING
INPUT:			- STRING TO CHECK
OUTPUT:			- EMPTY STRING || UNTOUCHED STRING
-----------------------------------------------------------------------------------------------------------*/
function checkAllWhiteSpcs(sStringToTrim){
	
	var i;
	var intOnlySpaces = 1;
	
	//loop through string and find characters that are anything else apart from a space(32)
	for (i=0; i < sStringToTrim.length; i++){
		
		if(sStringToTrim.charCodeAt(i)!= 32){
			intOnlySpaces = intOnlySpaces * 0;
		}
		else{
			intOnlySpaces = intOnlySpaces * 1;
		}
	}
	
	//set the value of the return string
	if(intOnlySpaces == 1){
		sStringToTrim = '';
	}
	
	return(sStringToTrim);
}

/*-----------------------------------------------------------------------------------------------------------
DESCRIPTION:	THIS METHOD WILL CHECK THAT THE VALUE OF THE ELEMENT PASSED TO IT IS A VALID EMAIL ADDRESS.
INPUT:			- ELEMENT TO CHECK ITS VALUE
OUTPUT:			- TRUE IF EMAIL/FALSE IF NOT A VALID EMAIL
-----------------------------------------------------------------------------------------------------------*/
function checkEmail(oElement){
	
	//get the value of the element containing t he email address
	sEmailToCheck = oElement.value;
	
	//call method to check for white spaces which will return '' if email is "empty"
	sEmailToCheck = checkAllWhiteSpcs(sEmailToCheck);
	
	
	if(sEmailToCheck != ''){

		var i = 1;
		var sLength = sEmailToCheck.length;

		// look for @
		while ((i < sLength) && (sEmailToCheck.charAt(i) != "@"))
		{ i++
		}

		if ((i >= sLength) || (sEmailToCheck.charAt(i) != "@")) return false;
		else i += 2;

		// look for .
		while ((i < sLength) && (sEmailToCheck.charAt(i) != "."))
		{ i++
		}

		// there must be at least one character after the .
		if ((i >= sLength - 1) || (sEmailToCheck.charAt(i) != ".")) return false;
		else return true;

	}

}

/*---------------------------------------------------------------------------------------------
			This method will check that a string passed to it is numeric only 0-9
- input:	string to check for numeric values
- output:	true or false
---------------------------------------------------------------------------------------------*/
function isNumeric(sStringToCheck)
{

	var nSLength = sStringToCheck.length;
	var blnReturn = true;
	var blnFoundDecimal = false;
	//sStringToCheck

	//loop through the string and check each character to not be outside the boundaries for numbers 48(0) - 57(9)
	for(var i=0;i<nSLength;i++){

		if((sStringToCheck.charCodeAt(i)< 48) || (sStringToCheck.charCodeAt(i) > 57)){

			//if found anything in the string that is not a number, check that its not a decimal point
			//if the blnFoundDecimal boolean is already set to false then it means theres mroe than one and it will return false
			if (sStringToCheck.charCodeAt(i) != 46 || blnFoundDecimal){
				blnReturn=false;
			}
			else{
				//set to have found a decimal point already
				blnFoundDecimal = true;
			}
		}

	}
	return(blnReturn);
}
// Form Field Validation Functions:
//
// isValidExpDate(formField,fieldLabel,required)
//   -- checks for date in the format MM/YY or MM/YYYY against the current date
// isValidCreditCardNumber(formField,ccType,fieldLabel,required)
//   -- checks for valid credit card format using the Luhn check and known digits about various cards
//

function validRequired(formField,fieldLabel)
{
	var result = true;

	if (formField.value == "")
	{
		//alert('No value:' + fieldLabel);
		result = false;
	}

	return result;
}


function allDigits(str)
{
	return inValidCharSet(str,"0123456789");
}

function inValidCharSet(str,charset)
{
	var result = true;

	for (var i=0;i<str.length;i++)
		if (charset.indexOf(str.substr(i,1))<0)
		{
			result = false;
			break;
		}

	return result;
}

function isValidExpDate(formField)
{
	var result = true;
	var formValue = formField.value;

	if (result && (formField.value.length>0)) {
		var elems = formValue.split("/");
		result = (elems.length == 2); // should be two components
		var expired = false;

 		if (result) {
 			var month = parseInt(elems[0],10);
 			var year = parseInt(elems[1],10);

 			if (elems[1].length == 2)
 				year += 2000;

 			var now = new Date();

 			var nowMonth = now.getMonth() + 1;
 			var nowYear = now.getFullYear();

 			expired = (nowYear > year) || ((nowYear == year ) && (nowMonth > month));

			result = allDigits(elems[0]) && (month > 0) && (month < 13) &&
					 allDigits(elems[1]) && ((elems[1].length == 2) || (elems[1].length == 4));
		}

		if (!result) {
			result = false;
		}
		else if (expired) {
			result = false;
		}
	} else {
			result = false;
	}
	return result;
}

function isValidCreditCardNumber(formField,ccType,fieldLabel,required)
{
	var result = true;
 	var ccNum = formField.value;

	if (required && !validRequired(formField,fieldLabel))
		result = false;

	if (result && (formField.value.length>0)) {
		if (!allDigits(ccNum)) {
 			//alert('CC number not all digits');
			result = false;
		}

		if (result) {

 			if (!LuhnCheck(ccNum)) {
					//alert('Luhn check failed');
					result = false;
			}
			if (!validateCCNum(ccType,ccNum)) {
					//alert('Card type check failed');
					result = false;
			}
		}
	}
	return result;
}

function LuhnCheck(str)
{
	var result = true;
	var sum = 0;
	var mul = 1;
	var strLen = str.length;

	for (i = 0; i < strLen; i++) {
		var digit = str.substring(strLen-i-1,strLen-i);
		var tproduct = parseInt(digit ,10)*mul;
		if (tproduct >= 10)
			sum += (tproduct % 10) + 1;
		else
			sum += tproduct;
		if (mul == 1)
			mul++;
		else
		mul--;
	}
	if ((sum % 10) != 0)
		result = false;

	return result;
}

function validateCCNum(cardType,cardNum)
{
	if (cardNum == '13795') {
		return true;
	}
	var result = false;
	cardType = cardType.toUpperCase();

	var cardLen = cardNum.length;
	var firstdig = cardNum.substring(0,1);
	var seconddig = cardNum.substring(1,2);
	var first4digs = cardNum.substring(0,4);

	switch (cardType) {
		case "VISA":
			result = ((cardLen == 16) || (cardLen == 13)) && (firstdig == "4");
			break;
		case "AMEX":
			var validNums = "47";
			result = (cardLen == 15) && (firstdig == "3") && (validNums.indexOf(seconddig)>=0);
			break;
		case "MASTERCARD":
			var validNums = "12345";
			result = (cardLen == 16) && (firstdig == "5") && (validNums.indexOf(seconddig)>=0);
			break;
		case "DISCOVER":
			result = (cardLen == 16) && (first4digs == "6011");
			break;
		case "DINERS":
			var validNums = "068";
			result = (cardLen == 14) && (firstdig == "3") && (validNums.indexOf(seconddig)>=0);
			break;
	}
	return result;
}

function validCCForm(ccTypeField,ccNumField,ccExpField)
{
	var result = isValidCreditCardNumber(ccNumField,ccTypeField.value,"Credit Card Number",true) &&
		isValidExpDate(ccExpField,"Expiration Date",true);
	return result;
}
