// inspired by validation functions from youngpup.net
//  altered and expanded rather a lot by af

function isValid(type, str, reg) {
	var temp = str.trim();
	
	if (type == 'text') {
		if (reg != '') {
			return isValidReg(temp, reg);
		} else {
			return temp.length > 0;
		}
		
	} else if (type == 'num') {
		if (reg != '') {
			var bounds = reg.split(',');
			return isValidBoundedNumber(temp, bounds[0], bounds[1]);
		} else {
			return isValidNumber(temp);
		}
	
	} else if (type == 'phone') {
		return isValidPhoneNumber(temp);
	
	} else if (type == 'email') {
		return isValidEmailAddress(temp);
	
	} else if (type == 'zip') {
		return isValidZipCode(temp);
	
	} else if (type == 'cc') {
		return isValidCCNumber(temp);
	
	} else if (type == 'usd') {
		return isValidUSDAmount(temp);
	}
	return false;
}


function isValidReg(s, reg) {
	var regEx = eval("/" + reg + "/g");
	return s.match(reg);
}

function isValidNumber(s) {
	var temp = s.replace(/\D/g, "") + "";
	return (temp != '' && !isNaN(temp));
}
function isValidBoundedNumber(s, min, max) {
	var temp = s.replace(/\D/g, "");
	return (temp != '' && !isNaN(temp) && temp >= min && temp <= max);
}

function isValidPhoneNumber(s) {
	var temp = s.replace(/\D/g, "") + "";
	return (temp.length == 10 && (s.substring(0,1)-0) > 1);
}

function isValidZipCode(s) {
	var temp = s.replace(/\D/g, "");
	return (temp.length == 5 || temp.length == 9);
}

function isValidBox(varName) {
	var v = val(varName);
	return (v != '');
}

function isValidSelect(o) {
	if (o.options.length == 0) 
		return false;
	var v = o.options[o.selectedIndex].value;
	return (v.trim() != "" && !v.match(/Select.../));
}

function isValidEmailAddress(s) {
	var temp = s.replace(/\s/g, "");
	return (temp.match(/^[\w.+-]+@[\w.-]+\.\w{2,4}$/)) && 
			temp.charAt(0) != "." && !(temp.match(/\.\./));
}

function isValidUSDAmount(s) {
	var temp = s.replace(/[^\d.-]/g, "");
	return temp.match(/^-?\d+\.\d\d$/) != null;
}


function isValidCCNumber(s) {
	s = s.replace(/\D/g, "");
	
	if (s.match(/^0+$/)) 
		return false;  // special case
	
	var ccType = getCCType(s);
	if (!ccType) 
		return false;

	if (mod10(s)) 
		return ccType;
	else return false;
}

function mod10(s) {
	var checksum = 0, digit;
	var even = false;
	
	for (var n = s.length - 1;  n >= 0;  n--) {
		digit = parseInt(s.charAt(n), 10);
		if (even) {
			if ((digit *= 2) > 9)
				digit -= 9;
		}
		checksum += digit;
		even = !even;
	}
	return (checksum % 10 == 0);
}

function getCCType(s) {
	s = s.replace(/\D/g, "");
	var len = s.length;
	
	var ccType = false;
	
	if (s.match(/^4/) && (len == 13 || len == 16)) 
		ccType = 'visa';
	
	else if (s.match(/^3[47]/) && len == 15) 
		ccType = 'amex';
	
	else if (s.match(/^5[1-5]/) && len == 16) 
		ccType = 'mc';
	
	else if (s.match(/^(30[0-5]|3[68])/) && len == 14) 
		ccType = 'diners';
	
	else if (s.match(/^6011/) && len == 16) 
		ccType = 'discover';
	
	else if (s.match(/^(3|1800|2131)/) && (len == 15 || len == 16)) 
		ccType = 'jcb';
	
	return ccType;
}

function ccFormat(s) {
	s = s.replace(/\D/g, "");
	s = s.substring(0,16);
	var t = getCCType(s);
	if (!t) {
		return s;
	}
	var out = '';
	if (s.length >= 16) {
		out = s.substring(0,4) + "-" + s.substring(4,8);
		out += "-" + s.substring(8,12) + "-" + s.substring(12,16);
	
	} else if (s.length == 15 && s.substring(0,1) == '3') {
		out = s.substring(0,4) + "-" + s.substring(4,10);
		out += "-" + s.substring(10,15);
	
	} else if (s.length == 13 && s.substring(0,1) == '4') {
		out = s.substring(0,4) + "-" + s.substring(4,7);
		out += "-" + s.substring(7,10) + "-" + s.substring(10,13);
	
	} else {
		out = s;
	}
	return out;
}






// masking functions - attempt to parse and reformat 
// element's values as a specific datatype
// to use, tack them to the form field's onblur handler.
// document.myForm.phone_number.onblur = phoneFieldBlurHandler	
//   -> this field will now mask for phone numbers onblur

function textFieldBlurHandler() {
	this.value = this.value.trim();
}

function numFieldBlurHandler() {
	this.value = fieldFormat(this.value, 'num');
}

function dateFieldBlurHandler() {
	this.value = fieldFormat(this.value, 'date');
}

function timeFieldBlurHandler() {
	this.value = fieldFormat(this.value, 'time');
}

function emailFieldBlurHandler() {
	this.value = this.value.trim();
	this.value = this.value.replace(/\s/g, "");
}

function phoneFieldBlurHandler() {
	this.value = fieldFormat(this.value, 'phone');
}

function zipFieldBlurHandler() {
	this.value = fieldFormat(this.value, 'zip');
}

function ccFieldBlurHandler() {
	this.value = ccFormat(this.value);
}

function usdFieldBlurHandler() {
	this.value = fieldFormat(this.value, 'usd');
}

function vinFieldBlurHandler() {
	this.value = fieldFormat(this.value, 'vin');
}

function fileFieldBlurHandler() {
	return;
}


function usd(n) {
	n = Math.round(n * 100) / 100;
	n += "";
	n = n.replace(/[^\d.-]/g, "");
	if (n.match(/^\d+$/)) 
		n += '.00';
	if (n.match(/^\./)) 
		n = '0' + temp;
	if (n.match(/\.$/)) 
		n += '00';
	else if (n.match(/\.\d$/)) 
		n += '0';
	return n;
}


function fieldFormat(str, type) {
	
	if (type == 'num') {
		str = str.replace(/\D/g, "");
		if (isNaN(str)) 
			str = "";
	
	} else if (type == 'phone') {
		str = str.replace(/\D/g, "");
		str = str.replace(/^[01]+/, "");
	
		if (str.length >= 10) {
			//this.value = "(" + temp.substring(0,3) + ") ";
			str = str.substring(0,3) + "-" + str.substring(3,6) + "-" + str.substring(6,10);
		}
	
	} else if (type == 'zip') {
		str = str.replace(/\D/g, "");
	
		if (str.length >= 5 && str.length < 9) {
			str = str.substring(0,5);
		
		} else if (str.length >= 9) {
			str = str.substring(0,5) + "-" + str.substring(5,9);
		}
	
	} else if (type == 'vin') {
		str = str.replace(/\s/g, '');
		str = str.toUpperCase();
		str = str.replace(/[^A-Z0-9]|[IOQ]/g, "");
		str = str.substring(0, 17);
	
	
	} else if (type == 'time') {
		var t = new Time(str);
		if (!isNaN(t)) 
			str = t.getHumanTimeString();
	
	
	} else if (type == 'date') {
		var d = new Date(str);
		if (!isNaN(d)) {
			// if the user didn't specify the century/millenium, then assume the present.
			if (this.value.search(/\d{3}/) == -1) {
				d.setYear(Math.floor((new Date()).getFullYear() / 100) * 100 + d.getFullYear() % 100);
			}
			str = d.getHumanDateString();
		}
	
	} else if (type == 'usd') {
		str = usd(str);
	
	} else if (type == 'cc') {
		str = ccFormat(str);
	
	} else {
		str = str.trim();
	}
	return str;
}


function elFormat(el, type) {
	if (el.type != 'text') 
		return false;
	var v = fieldFormat(el.value, type);
	el.value = v;
	return v;
}


// convenience function.
// attaches textFieldBlurHandler to the onblur event 
// of every text or textarea element in f
// var myForm = document.myForm
// attachAllTextHandlers(myForm) 
//		-> every text element in myForm now will call 
//		   textFieldBlurHandler (above) onblur
function attachAllTextHandlers(f) {
	var el;
	for (var i = 0; (el = f.elements[i]); i++) {
		if (el.type == "text" || el.type == "password"/* || el.type == "textarea" */) 
			el.onblur = textFieldBlurHandler;
	}
}


// not currently used, but could be handy as keyup handler
function numOnly(el) {
	el.value = el.value.replace(/\D/g, "");
}


