var whitespace = " \t\n\r";
var reInteger = /^\d+$/;
var reFloat = /^((\d+(\.\d*)?)|((\d*\.)?\d+))$/;
var reEmail = /^.+\@.+\..+$/;
var reDate = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
var ssnDelimeters = "- ";
var phoneDelimeters = "()- ";
var zipDelimeters = "- ";
var tagDelimeters = "PL- ";
var currencyDelimeters = "$,"

function isEmpty(s) { return ((s == null) || (s.length == 0)) }
function isInteger(s, isEmptyOK) { if (isEmpty(s)) return isEmptyOK; else return reInteger.test(s); }
function isFloat(s, isEmptyOK) { var flt = stripCharsInBag(s, currencyDelimeters); if (isEmpty(flt)) return isEmptyOK; else return reFloat.test(flt); }
function isEmail(s, isEmptyOK) { if (isEmpty(s)) return isEmptyOK; else return reEmail.test(s); }
function isSSN(s, isEmptyOK) { var ssn = stripCharsInBag(s, ssnDelimeters); if (isEmpty(ssn)) return isEmptyOK; else return (isInteger(ssn,false) && (ssn.length == 9)); }
function isZIP(s, isEmptyOK) { var zip = stripCharsInBag(s, zipDelimeters); if (isEmpty(zip)) return isEmptyOK; else return (isInteger(zip,false) && ((zip.length == 9) || (zip.length == 5))); }
function isTagNumber(s, isEmptyOK) { var tn = stripCharsInBag(s, tagDelimeters); if (isEmpty(tn)) return isEmptyOK; else return (isInteger(tn,false)); }
function isPhone(s, isEmptyOK) { var phone = stripCharsInBag(s, phoneDelimeters); if (isEmpty(phone)) return isEmptyOK; else return (isInteger(phone,false) && ((phone.length == 10) || (phone.length == 7))); }
function isDate(s, isEmptyOK) {
	if (isEmpty(s)) return isEmptyOK;
	
	var matchArray = s.match(reDate);

	if (matchArray == null) return false;

	var month = matchArray[1]; // p@rse date into variables
	var day = matchArray[3];
	var year = matchArray[5];

	if (month < 1 || month > 12) return false;
	if (day < 1 || day > 31) return false;
	if ((month==4 || month==6 || month==9 || month==11) && day==31) return false;
	if (month == 2) { // check for february 29th
		var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
		if (day > 29 || (day==29 && !isleap)) return false;
	}
	return true; // date is valid
}

function stripCharsInBag(s, bag) {
	var i;
	var returnString = "";

	for (i = 0; i < s.length; i++) {   
		var c = s.charAt(i);
		if (bag.indexOf(c) == -1) returnString += c;
	}
	return returnString;
}

function reformat(s) {
	var arg;
	var sPos = 0;
	var resultString = "";
	for (var i = 1; i < reformat.arguments.length; i++) {
		arg = reformat.arguments[i];
		if (i % 2 == 1) {
			resultString += arg;
		} else {
			resultString += s.substring(sPos, sPos + arg);
			sPos += arg;
		}
	}
	return resultString;
}

function reformatZIPCode(ZIPString) {
	var strippedZIPString = stripCharsInBag(ZIPString,zipDelimeters);

	if (strippedZIPString.length == 5) return strippedZIPString;
	else return (reformat (strippedZIPString, "", 5, "-", 4));
}

function reformatPhone(PhoneString) {
	var strippedPhoneString = stripCharsInBag(PhoneString,phoneDelimeters);

	return (reformat (strippedPhoneString, "(", 3, ") ", 3, "-", 4))
}

function reformatSSN(SSNString) {
	var strippedSSNString = stripCharsInBag(SSNString,ssnDelimeters);

	return (reformat (strippedSSNString, "", 3, "-", 2, "-", 4))
}

function checkAlertAndSetFocus(valid,object,msg) {
	if (!valid) {
		alert('\n' + msg + '.');
		if (object.type == "text") object.select();
		object.focus();
		return false;
	}
	return valid;
}

function validButton(btn) {
    for (var i = 0; i < btn.length; i++) {
        if (btn[i].checked) return true;
    }
    return false;
}
function valid_text(txtField) { return checkAlertAndSetFocus(!isEmpty(stripCharsInBag(txtField.value,whitespace)) && !(txtField.value == txtField.name), txtField, 'You must enter a value for ' + txtField.name); }
function valid_date(txtField,isEmptyOK) { return checkAlertAndSetFocus(isDate(txtField.value,isEmptyOK), txtField, 'You must enter a vadid Date (e.g. 12/31/2005)'); }
function valid_currency(txtField,isEmptyOK) { return checkAlertAndSetFocus(isFloat(txtField.value,isEmptyOK), txtField, 'You must enter a valid dollar amount for ' + txtField.name); }
function valid_integer(txtField,isEmptyOK) { return checkAlertAndSetFocus(isInteger(txtField.value,isEmptyOK), txtField, 'You must enter a valid integer amount for ' + txtField.name); }
function valid_ssn(txtField,isEmptyOK) { return checkAlertAndSetFocus(isSSN(txtField.value,isEmptyOK), txtField, 'You must enter a valid Social Security Number'); }
function valid_zip(txtField,isEmptyOK) { return checkAlertAndSetFocus(isZIP(txtField.value,isEmptyOK), txtField, 'You must enter a valid ZIP Code'); }
function valid_tag(txtField,isEmptyOK) { return checkAlertAndSetFocus(isTagNumber(txtField.value,isEmptyOK), txtField, 'You must enter a valid Tag Number ([P][#]#-######)'); }
function valid_phone(txtField,isEmptyOK) { return checkAlertAndSetFocus(isPhone(txtField.value,isEmptyOK), txtField, 'You must enter a valid Phone Number'); }
function valid_email(txtField,isEmptyOK){ return checkAlertAndSetFocus(isEmail(txtField.value,isEmptyOK), txtField, 'You must enter a valid E-mail Address'); }
function valid_checkbox(chkBox) { return checkAlertAndSetFocus(chkBox.checked, chkBox, 'Please indicate that you have completed this form by checking this checkbox'); }
function valid_selection(selList) { return checkAlertAndSetFocus(selList.selectedIndex != 0, selList, 'Please select a valid value for ' + selList.name); }
function valid_radio(radBtn) { return checkAlertAndSetFocus(validButton(radBtn), radBtn[0], 'Please select a valid value for ' + radBtn[0].name); }