function Validate() {
	var fArray = null;
	var lArray = null;
	var errMsg = "";
	var confirmMsg = "";
	var notBlank = true;
	var ccNumber = null;
	var ccExpiry = null;
	var email = null;
	var confirmEmail = null;
	
	var argv = Validate.arguments;
	var argc = Validate.arguments.length;
	var formObject = argv[0];
	
	for (var i=1; i<argc; i++) {
		switch (argv[i]) {
			case "blank" :
				//*** Check for blank fields against list in "validateFields" array.  
				//    Return error messages in "validateLabels" array.
				notBlank = requiredFields(formObject,validateFields,validateLabels);
				if (!notBlank) {
					showError("Blank");
					return false;
				}
				break;
			case "cc_valid" :
				//*** To use this check, a variable called "ccField" must define the name of the credit card field
				ccNumber = formObject[ccField].value;	
				if (!luhnCheck(ccNumber)) {
					showError("CCError");
					highlightError(formObject[ccField]);
					return false;
				}
				break;
			case "cc_expiry" :
				//*** To use this check, a variable called "ccExpiryField" must define the name of the credit card field
				ccExpiry = formObject[ccExpiryField].value;	
				if (!expiryCheck(ccExpiry)) {
					showError("CCExpired");
					highlightError(formObject[ccExpiryField]);
					return false;
				}
				break;
			case "email_confirm" :
				//*** To use this check, variables named "emailField" and "confirmEmailField" must be defined
				var email = formObject[emailField].value;
				var confirmEmail = formObject[confirmEmailField].value;
				if (!isEmail(email)) {
					showError("EmailError");
					highlightError(formObject[emailField]);
					return false;
				} else if (email != confirmEmail) {
					showError("MatchError");
					highlightError(formObject[emailField],formObject[confirmEmailField]);
					return false;
				}
				break;
		}
	}
	return true;
} //*** Validate

function showError(errType) {
	var msg = document.getElementById("formError");
	var errorMsg = null;
	
	switch (errType) {
		case "Blank" :
			errorMsg = blankMsg;
			break;
		case "CCError" :
			errorMsg = ccMsg;
			break;
		case "CCExpired" :
			errorMsg = ccExpiredMsg;
			break;
		case "EmailError" :
			errorMsg = emailMsg;
			break;
		case "MatchError" :
			errorMsg = matchMsg;
			break;
	}
	msg.innerHTML = errorMsg;
	window.scrollTo(0,0);
}

function highlightError() {
	var argv = highlightError.arguments;
	var argc = highlightError.arguments.length;
	
	for (var i=0; i<argc; i++) {
		argv[i].className += '-error';
	}

}

function requiredFields(formObject, fieldArray, labelArray) {
	var errMsg = "";
	var ctl = null;
	var ctlType = "";
	var ctlName = "";
	var ctlVal = "";
	var ctlIndex = 0;
	var ctlDisabled = false;
	var success = true;
	var border = "";
	
	for (var i = 0; i<fieldArray.length; i++) {
		
		if (fieldArray[i].indexOf("AND") != -1)
			continue;
		if (!isUndefined(formObject[fieldArray[i]])) {
			ctl = formObject[fieldArray[i]];
			ctlDisabled = ctl.disabled;
			ctlVal = getCtlVal(ctl);

			//*** This section assumes that you've defined class names like 
			//		"input-text" and "input-text-error" for your input fields
			ctl.className = ctl.className.replace( '-error', '' );
			if(ctlVal == "" && !ctlDisabled) {
				success = false;
				ctl.className += '-error';
			}
			if (ctlDisabled)
				ctl.style.background = "#EBEBE4";
		}
	} //*** for (var i = 0; i<fieldArray.length; i++) 
	return success;
} //*** function requiredFields

//*** Uses Luhn algorithm to generate checksum for credit card number
function luhnCheck(ccNumber) {

	if (! isNumeric(ccNumber)) {
		return false;
	}
	
	var digitCount = ccNumber.length;
	var parity = digitCount & 1;
	var sum = 0;
	
	for (var i=0; i < digitCount; i++) {
		var digit = parseInt(ccNumber.charAt(i));
		if (!((i & 1) ^ parity)) {
			digit *= 2;
		if (digit > 9)
			digit -= 9;
		}
		sum += digit;
	}
	return (sum % 10 == 0)
}

function isEmail (s) {

    // there must be >= 1 character before @, so we
    // start looking at character position 1 
    // (i.e. second character)
    var i = 1;
    var sLength = s.length;

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

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

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

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

function expiryCheck(ccExpiry) {
	var dateParts = ccExpiry.split("-");
	var year = dateParts[1];
	var month = dateParts[0];

	if (!isNumeric(year+""))
		return false;
	if (!isNumeric(month+""))
		return false;
	today = new Date();
	expiry = new Date(year, month);
	if (today.getTime() > expiry.getTime())
		return false;
	else
		return true;
}

function isNumeric(sText) {
	var validChars = "0123456789.";
	var isNumber=true;
	var thisChar;
	
	for (i=0; i<sText.length && isNumber == true; i++) { 
		thisChar = sText.charAt(i); 
		if (validChars.indexOf(thisChar) == -1) {
			isNumber = false;
		}
	}
	return isNumber;
}
//*** Gets current value of any type of control
function getCtlVal(ctl) {
	var ctlVal = "";
	switch (ctl.type) {
		case "select-one" :
		case "select-multiple" :
			ctlIndex = ctl.selectedIndex;
			if (ctlIndex != -1)
				ctlVal = ctl.options[ctlIndex].value;
			break;
		case "radio" :
			//if (radioTested) break;
			//if (!checkRadio(formObject))
				//ctlVal = "";
			//radioTested = true;
			break;
		default :
			ctlVal = ctl.value;
			break;
	}
	return ctlVal;
}
