/**
 * © 2008 Artifice Investments, LLC
 *
 * This file and all of the source code contained within are the intellectual 
 * property of Artifice Investments, LLC. Any reproduction, description (either
 * written or verbal), or derivative of this code is strictly prohibited without
 * the written consent of Artifice Investments, LLC.
 *
 * -------------------------------------------------------------------------------
 *
 * Description: Validation functions.
 *      Author: Daniel Jennings (dsj@artificeinvestments.com)
 *    Revision: A
 *  References: None
 *       Notes: None
 */


//define global colors
var invalid_color = "yellow";
var valid_color = "white";


/**
 * Validate that a checkbox is checked.
 * @param checkbox The checkbox field.
 * @param errorString Error message string to display if not checked.
 * @retuen Error message string, empty if valid.
 */
function validateCheckbox(checkbox, errorString) {
	//initialize return value
	var ret = "";

	//get the checkbox field
	checkbox = getElement(checkbox);

	//make sure the checkbox is checked
	if (checkbox.checked == 0) {
		ret = errorString;
	}

	return ret;
} //end method validateCheckbox


/**
 * Validate the type of a field.
 * @param field Field to validate.
 * @param fieldName Name of the field to validate.
 * @param type Type to validate.
 * @return Error message string, empty if valid.
 */
function validateType(field, fieldName, type) {
    //initialize return value
	var ret = "";

	//get the field
	field = getElement(field);

	if (type == "int") {
		var int_val = parseInt(field.value);
		var float_val = parseFloat(field.value);

		if (isNaN(int_val) || (float_val != int_val)) {
			ret = fieldName + " is invalid.\n";
			field.style.background = invalid_color;
		}
		else {
			field.style.background = valid_color;
		}
	} //end if
	else if (type == "float") {
		var float_val = parseFloat(field.value);

		if (isNaN(float_val)) {
			ret = fieldName + " is invalid.\n";
			field.style.background = invalid_color;
		}
		else {
			field.style.background = valid_color;
		}
	}

    return ret;   
} //end method validateType


/**
 * Validate that the value of a field is within a given range.
 * @param field Field element DOM Element object (or element ID).
 * @param fieldName Name of the field to validate.
 * @param minValue Min value to allow.
 * @param maxValue Max value to allow.
 * @param inclusive Flag indicating whether the check should be inclusive or not
 * @return Error message string, empty if valid.
 */
function validateNumericRange(field, fieldName, minValue, maxValue, inclusive) {
	//initialize return value
	var ret = "";

	//get the element value
	field = getElement(field);
	var val = parseFloat(field.value);

	if (inclusive) {
		if ((val < minValue) || (val > maxValue)) {
			ret = "The value of " + fieldName + " must be between " + minValue + " and " + maxValue + ".\n";
			field.style.background = invalid_color;
		}
	}
	else {
		if ((val <= minValue) || (val >= maxValue)) {
			ret = "The value of " + fieldName + " must be between " + minValue + " and " + maxValue + ".\n";
			field.style.background = invalid_color;
		}
	}

	return ret;
} //end method validateNumericRange


/**
 * Validate that the value of a field is at least a certain value.
 * @param field Field to validate.
 * @param fieldName Name of the field to validate.
 * @param minValue Min value to allow.
 * @param inclusive Flag indicating whether the check should be inclusive or not
 * @return Error message string, empty if valid.
 */
function validateNumericMinimum(field, fieldName, minValue, inclusive) {
	//initialize return value
	var ret = "";

	//get the field
	field = getElement(field);

	if (inclusive) {
		if (field.value < minValue) {
			ret = "The value of " + fieldName + " must be at least " + minValue + ".\n";
			field.style.background = invalid_color;
		}
	}
	else {
		if (field.value <= minValue) {
			ret = "The value of " + fieldName + " must be greater than " + minValue + ".\n";
			field.style.background = invalid_color;
		}
	}

	return ret;
} //end method validateNumericMinimum


/**
 * Validate that a field is non-empty.
 * @param field Field to validate.
 * @param fieldName Name of the field to validate.
 * @return Error message string, empty if valid.
 */
function validateNonEmpty(field, fieldName) {
    //initialize return value
	var ret = "";

	//get the field
	field = getElement(field);
  
    if (field.value.length == 0) {
        ret = fieldName + " is a required field.\n";
		field.style.background = invalid_color;
    } 
	else {
        field.style.background = valid_color;
    }

    return ret;   
} //end method validateNonEmpty


/**
 * Validate that a field is of a certain length.
 * @param field Field to validate.
 * @param fieldName Name of the field to validate.
 * @param expectedLength The expected length.
 * @return Error message string, empty if valid.
 */
function validateLength(field, fieldName, expectedLength) {
    //initialize return value
	var ret = "";

	//get the field
	field = getElement(field);
  
    if (field.value.length != expectedLength) {
        ret = fieldName + " is invalid.\n";
		field.style.background = invalid_color;
    } 
	else {
        field.style.background = valid_color;
    }

    return ret;   
} //end method validateLength


/**
 * Validate that a select box element is not none.
 * @param field Field to validate.
 * @param fieldName Name of the field to validate.
 * @return Error message string, empty if valid.
 */
function validateNotNoneValue(field, fieldName) {
    //initialize return value
	var ret = "";
  
	//get the field
	field = getElement(field);

    if (field.value == "none") {
        ret = fieldName + " must be selected.\n";
		field.style.background = invalid_color;
    } 
	else {
        field.style.background = valid_color;
    }

    return ret;   
} //end method validateNotNoneValue


/**
 * Validates an email address.
 * @param email Email form field.
 * @param retypeEmail Retyped email form field.
 * @return Error message string, empty if valid.
 */
function validateEmail(email, retypeEmail) {
	//initialize return value
	var ret = "";

	//define regular expressions
	var email_filter = /^[^@]+@[^@.]+\.[^@]*\w\w$/;
    var illegal_chars = /[\(\)\<\>\,\;\:\\\"\[\]]/;

	//make sure emails are the same
	if (email.value !== retypeEmail.value) {
		ret = "Email addresses do not match.\n";
		email.style.background = invalid_color;
		retypeEmail.style.background = invalid_color; 
	}
	//validate the syntax
	else if (!email_filter.test(email.value)) {
		ret = "Email address is invalid.\n";
        email.style.background = invalid_color;
		retypeEmail.style.background = invalid_color;
    } 
	else if (illegal_chars.test(email.value)) {
		ret = "Email address is invalid.\n";
		email.style.background = invalid_color;
		retypeEmail.style.background = invalid_color;
	}
	else {
		email.style.background = valid_color;
		retypeEmail.style.background = valid_color; 
	}

	return ret;
} //end function validateEmail


/**
 * Validates a credit card number.
 * @param fullName Full name form field.
 * @param cardNumber Credit card number form field.
 * @param cvvNumber CVV number form field
 * @return Error message string, empty if valid.
 */
function validateCreditCard(fullName, cardNumber, cvvNumber) {
	//initialize return value
	var ret = "";

	//test the full name field
	if (fullName.value.length == 0) {
		ret += "Pleade provide your full name as it appears on your credit card.\n";
		fullName.style.background = invalid_color;
	}
	else {
		fullName.style.background = valid_color;
	}
	
	//test the card number field
	var card_number_regexp = /[0-9]{16}/;
	if (!card_number_regexp.test(cardNumber.value)) {
		ret += "Credit card number is invalid.\n";
		cardNumber.style.background = invalid_color;
	}
	else {
		cardNumber.style.background = valid_color;
	}

	//test the cvv number field
	var cvv_regexp_one = /[0-9]{3}/;
	var cvv_regexp_two = /[0-9]{4}/;
	if (!cvv_regexp_one.test(cvvNumber.value) && !cvv_regexp_two.test(cvvNumber.value)) {
		ret += "Credit card CVV/CVS number is invalid.\n";
		cvvNumber.style.background = invalid_color;
	}
	else {
		cvvNumber.style.background = valid_color;
	}

	return ret;
} //end function validateCreditCard


/**
 * Validates a username.
 * @param username Username form field.
 * @return Error message string, empty if valid.
 */
function validateUsername(username) {
	//initialize return value
	var ret = "";

	//define illegal characters
	//allow letters, numbers, and underscores
	var illegal_chars = /[\W_]/; 

	if (username.value.length < 5) {
        ret = "Username must be at least 5 characters long.\n";
		username.style.background = invalid_color; 
	}
	else if (illegal_chars.test(username.value)) {
		ret = "Username contains illegal characters.\n";
		username.style.background = invalid_color; 
	}
	else {
		username.style.background = valid_color; 
	}

	return ret;
} //end function validateUsername


/**
 * Validates a password.
 * @param password Password form field.
 * @param retypePassword Retyped password form field.
 * @return Error message string, empty if valid.
 */
function validatePassword(password, retypePassword) {
	//initialize return value
	var ret = "";

	if (password.value.length < 6) {
		ret = "Password must be at least six characters long.\n";
		password.style.background = invalid_color;
		retypePassword.style.background = invalid_color;
	}
	else if (password.value !== retypePassword.value) {
		ret = "Passwords do not match.\n";
		password.style.background = invalid_color;
		retypePassword.style.background = invalid_color;
	}
	else {
		password.style.background = valid_color;
		retypePassword.style.background = valid_color;
	}

	return ret;
} //end function validatePassword


/**
 * Validates a zip code.
 * @param zipCode Zip code form field.
 * @return Error message string, empty if valid.
 */
function validateZipCode(zipCode) {
	//initialize return value
	var ret = "";

	//define regular expressions
	var regexp_one = /[0-9]{5}/;
	var regexp_two = /[0-9]{5}-[0-9]{4}/;
	
	if ((zipCode.value.length == 5) && regexp_one.test(zipCode.value)) {
		//standard 5 digit format
		zipCode.style.background = valid_color;
	}
	else if ((zipCode.value.length == 10) && regexp_two.test(zipCode.value)) {
		//5 digit-4 digit format
		zipCode.style.background = valid_color;
	}
	else {
		ret = "Zip code is invalid.\n";
		zipCode.style.background = invalid_color;
	}

	return ret;
} //end function validateZipCode



/**
 * Validates a phone number in the following format 000-000-0000.
 * @param phoneNumber Phone number form field.
 * @return Error message string, empty if valid.
 */
function validatePhoneNumber(phoneNumber) {
	//initialize return value
	var ret = "";

	//define regular expression
	var regexp = /[0-9]{3}-[0-9]{3}-[0-9]{4}/;

	if ((phoneNumber.value.length != 12) || (!regexp.test(phoneNumber.value)))  {
		ret = "Phone number is invalid.\n";
		phoneNumber.style.background = invalid_color;
	}
	else {
		phoneNumber.style.background = valid_color;
	}

	return ret;
} //end function validatePhoneNumber