// VALIDATION FUNCTIONS
function $isInt() {
	var v = arguments[0];
	var re = /^[+-]?\d+$/;
	return re.test(v);
}

function $isFloat(){
	var v = arguments[0];
	var re = /^[-+]?\d*\.?\d*$/;
	return re.test(v) && !$isBlank(v);
}

function $isBlank() {
	var v = arguments[0];
	var re = /\S+/;
	return !re.test(v);
}

function $isNotBlank() {
	var v = arguments[0];
	var re = /\S+/;
	return re.test(v);
}

function $isEmail() {
	var v = arguments[0];
	var re = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$/i;
	return re.test(v);
}

function $isPassword() {
	var v = arguments[0];
	// THE FOLLOWING REGULAR EXPRESSION VALIDATES A PASSWORD THAT IS 6-20 CHARACTERS IN LENGTH AND CONTAINS
	// AT LEAST 1 DIGIT AND 1 LETTER. SINCE IT IS CASE INSENSITIVE, IT DOESN'T MATTER IF THE LETTER IS
	// LOWER CASE OR UPPER CASE AND WE ALSO DON'T CARE IF THEY USE SPECIAL CHARACTERS
	var re = /((?=.*\d)(?=.*[a-z]).{6,20})/i;
	return re.test(v);
}

function $isUSDate() {
	var v = arguments[0];
	// THE FOLLOWING REGULAR EXPRESSION WAS WRITTEN BY MICHAEL ASH. IT WAS FOUND AT http://regexlib.com/REDetails.aspx?regexp_id=113
	// IT VALIDATES LEAP YEARS AND IT HAS BEEN MODIFIED TO ONLY ALLOW THE THE M/D/Y FORMAT
	// (THE ORIGINAL SCRIPT ALLOWED . AND - IN ADDITION TO / AS SEPERATORS) LEADING ZEROS ARE OPTIONAL.
	var re = /^(?:(?:(?:0?[13578]|1[02])(\/)31)\1|(?:(?:0?[13-9]|1[0-2])(\/)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:0?2(\/)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/;
	return re.test(v);
	
	// ORIGINAL REGEX AS LISTED ON regexlib.com /^(?:(?:(?:0?[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0?[13-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:0?2(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/
}

function $isEuroDate() {
	var v = arguments[0];
	// THE FOLLOWING REGULAR EXPRESSION WAS WRITTEN BY MICHAEL ASH. IT WAS FOUND AT http://regexlib.com/REDetails.aspx?regexp_id=610
	// IT ALLOWS D/M/Y FORMATS (LEADING ZEROS OPTIONAL) AND IT VALIDATES LEAP YEARS TOO. THE TIME PORTION OF THIS SCRIPT HAS BEEN REMOVED.
	var re = /^(?=\d)(?:(?:31(?!.(?:0?[2469]|11))|(?:30|29)(?!.0?2)|29(?=.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:\x20|$))|(?:2[0-8]|1\d|0?[1-9]))([-./])(?:1[012]|0?[1-9])\1(?:1[6-9]|[2-9]\d)?\d\d(?:(?=\x20\d)\x20|$))?$/;
	return re.test(v);
	
//	ORIGINAL REGEX AS LISTED ON regexlib.com /^(?=\d)(?:(?:31(?!.(?:0?[2469]|11))|(?:30|29)(?!.0?2)|29(?=.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:\x20|$))|(?:2[0-8]|1\d|0?[1-9]))([-./])(?:1[012]|0?[1-9])\1(?:1[6-9]|[2-9]\d)?\d\d(?:(?=\x20\d)\x20|$))?(((0?[1-9]|1[012])(:[0-5]\d){0,2}(\x20[AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$/;
}

function $isCreditCardNumber() {
	var v = arguments[0]
	
	// THIS FUNCTION WAS TAKEN FROM THE CFFORM VALIDATION JAVASCRIPT
	// TRIM WHITESPACE BEFORE WE VALIDATE
    object_value = v.replace(/^\s+/,'').replace(/\s+$/,'');
	
	if (object_value.length == 0) {
		return false;
	}
	
	var white_space = " -";
	var creditcard_string="";
	var check_char;

	
	for (var i = 0; i < object_value.length; i++) {
		check_char = white_space.indexOf(object_value.charAt(i));
		if (check_char < 0)
			creditcard_string += object_value.substring(i, (i + 1));
	}	

	if (creditcard_string.length < 13 || creditcard_string.length > 19) {
		return false;
	}

	if (creditcard_string.charAt(0) == "+") {
		return false;
	}

	if (!$isInt(creditcard_string)) {
		return false;
	}

	var doubledigit = creditcard_string.length % 2 == 1 ? false : true;
	var checkdigit = 0;
	var tempdigit;

	for (var i = 0; i < creditcard_string.length; i++) {
		tempdigit = eval(creditcard_string.charAt(i));

		if (doubledigit) {
			tempdigit *= 2;
			checkdigit += (tempdigit % 10);

			if ((tempdigit / 10) >= 1.0)
				checkdigit++;

			doubledigit = false;
		}
		else {
			checkdigit += tempdigit;
			doubledigit = true;
		}
	}	

	return (checkdigit % 10) == 0 ? true : false;
}