//$Id: catutils.js,v 1.12 2007/06/26 17:33:13 rrkramer Exp $
function warning(field, msg, verify) {
	if ( verify ) {
		if ( confirm(msg) ) return true;
	} else {
		alert(msg);
	}
	if (field && field.type != "hidden") {
		field.focus();
		field.select();
	}
	return false;
}	
function stripWhitespace(str) {
	var re = /\s/g;
	return str.replace(re,"");
}
function isInteger(str, blankOK) {
	str = stripWhitespace(str);
	if (! str.length ) return blankOK ? true : false;
	var re = /^-*\d+$/;
	return (str.match(re) == null) ? false : true;
}
function isEmpty(str) {
	return (stripWhitespace(str) == "" ) ? true : false;
}
function hasDigits(str) {
	var re = /\d/;
	if ( ! str.match(re)) {
		return false;
	}
	return true;
}
function skrunch(str) {
	if (typeof str == "undefined" || ! str) {
		return '';
	}
	str = str.toUpperCase();
	str = str.replace(/\.(\D|$)/g,"$1"); //remove periods not followed by a digit.
	return str.replace(/[^\.0-9A-Z]/g,""); //remove non-alphanums except periods.
}
function check_range(el, min, max) {
	var x = el.value;
	if ( ! isInteger(x, true)) {
		return warning(el, "Enter a whole number from "+min+" to "+max+" here, please.");
	}
	if (x == "") {
		el.value = 0;
	} else if (x < min || x > max) {
		return warning(el, "Enter a whole number from "+min+" to "+max+" here, please.");
	}
	return true;
}

function checkStateCode (field, us_ca_intl, no_msg) {
	var str = skrunch(field.value);
	var types = new Array();
	var type = "";
	var n = 0;
	
	if ( str.length == 2 ) {
		var US = "|AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY|AE|AA|AE|AE|AP|";
		var CA = "|AB|BC|MB|NB|NL|NS|NT|ON|PE|QC|SK|YT|";
		var Intl = "|BL|AD|AE|AF|AG|AI|AL|AM|AN|AO|AQ|AR|AS|AT|AU|AW|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BJ|BM|BN|BO|BR|BS|BT|BV|BW|BY|BZ|CA|CC|CF|CG|CH|CI|CK|CL|CM|CN|CO|CR|CS|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EE|EG|EH|ER|ES|ET|FI|FJ|FK|FM|FO|FR|FX|GA|GB|GD|GE|GF|GH|GI|GL|GM|GN|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IN|IO|IQ|IR|IS|IT|JM|JO|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|MG|MH|MK|ML|MM|MN|MO|MP|MQ|MR|MS|MT|MU|MV|MW|MX|MY|MZ|NA|NC|NE|NF|NG|NI|NL|NO|NP|NR|NT|NU|NZ|OM|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PT|PW|PY|QA|RE|RO|RU|RW|SA|Sb|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SU|SV|SY|SZ|TC|TD|TF|TG|TH|TJ|TK|TM|TN|TO|TP|TR|TT|TV|TW|TZ|UA|UG|UK|UM|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|YE|YT|YU|ZA|ZM|ZR|ZW|";
		str = "|"+str+"|";
		if ( typeof us_ca_intl == "string" ) {
			us_ca_intl = us_ca_intl.toUpperCase();
			if ( us_ca_intl.indexOf("US") != -1 ) {
				types[n++] = " state";
				if ( US.indexOf(str) != -1 ) {
					return true;
				}
			}
			if ( us_ca_intl.indexOf("CA") != -1 ) {
				types[n++] = " provincial";
				if ( CA.indexOf(str) != -1 ) {
					return true;
				}
			}
			if ( us_ca_intl.indexOf("INT") != -1 ) {
				types[n++] = " international";
			 	if ( Intl.indexOf(str) != -1 ) {
					return true;
				}
			}
		} else {
			if ( US.indexOf(str) != -1 || CA.indexOf(str) != -1 || Intl.indexOf(str) != -1) {
				return true;
			}
		}
	}
	if ( no_msg ) {
		return false;
	}
	switch ( n ) {
	case 1:
		type = types[0];
		break;
	case 2:
		type = types[0]+" or"+types[1];
		break;
	case 3:
		type = types[0]+","+types[1]+" or"+types[2];
		break;
	default:
		type = " state, province or international";
	}
	return warning(field, "Not a good"+type+" code");
}
function checkUSPhone(field, emptyOK) {
	var re = / +/g;
	var str = field.value.replace(re, " ");
	if (( ! str.length || str == " " ) && emptyOK ) return true;
	if ( str.length ) {
		var re1 = /^ ?\( ?\d{3} ?\)[ .-]?\d\d\d[ .-]?\d{4}/;
		var re2 = /^ ?\d{3}[ .-]?\d{3}[ .-]?\d{4}/;
		var re3 = /^ ?\d{3}[ .-]?\d{4}/;
		if ( str.match(re1) || str.match(re2) || str.match(re3)) {
			return true;
		}
	}
	var verify = emptyOK || str.length > 1;
	var xmsg = verify ?  "Click Cancel to fix." : "";
	return warning(field, "Not a normal US/Canadian phone number."+xmsg, verify);
}
function checkZIPCode(field) {
	var ret = "";
	var re = /[^A-Z0-9]/g;
	var str = field.value.toUpperCase();
	str = str.replace(re,"");
	var re1 = /[A-Z]/;
	if ( ! str.match(re1) ) {
		if ( str.length == 5 ) { 
			ret = str;
		} else if (str.length == 9 ) {
			ret = str.substring(0,5)+"-"+str.substring(5,10);
		}
	} else {
		if ( str.length == 7 ) { 
			ret = str;
		} else if (str.length == 6 ) {
			ret = str.substring(0,3)+" "+str.substring(3,7);
		}
	}
	if ( ret ) {
		field.value = ret;
		return true;
	} else {
		return warning(field, "Not a proper ZIP or postal code.");
	}
}
function trim(str) {
	if ( typeof str == "undefined" ) return "";
	return str.replace(/(^ *)|( *$)/g, "");
}
function esc_email(str) {
	if ( typeof str == "undefined" ) return "";
	str = str.replace(/>/g, "&gt;");
	str = str.replace(/</g, "&lt;");
	str = str.replace(/\"/g, "&#34;");
	return str.replace(/\'/g, "&#39;");
}

function checkDate(field, force_year) {
	var m, d, y, c;
	var a = new Array();
	var days = new Array(0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
	var str = trim(field.value);
	var re = / +/;
	str = str.replace(re," ");
	var bad = /[^\d\/ ,.-]/;
	if ( ! str.match(bad)) {
		var p = str.search(/[\/ ,.-]/);
		if ( p > -1 ) {
			c = str.substring(p,p+1);
			a = str.split(c);
		}
		if ( a.length == 0 && (str.length == 6 || str.length == 8 )) {
			m = str.substring(0,2);
			d = str.substring(2,4);
			y = str.substring(4,9);
		} else if ( a.length == 1 && (a[0].length == 6 || a[0].length == 8 )) {
			m = a.substring(0,2);
			d = a.substring(2,4);
			y = a.substring(4,9);
		} else if ( a.length == 3 ) {
			m = a[0];
			d = a[1];
			y = a[2];
		}
		if ( Number(m)>=1 && Number(m)<=12 && Number(d)>=1 && Number(d)<=days[Number(m)] && (y.length==2 || y.length==4)) {
			if (force_year && y < 100) {
				y = Number(y);
				if (y > 70) {
					y += 1900;
				} else {
					y += 2000;
				}
			}
			field.value = m+"/"+d+"/"+y;
			return true;
		}
	} 
	return warning(field, "Not a proper date.");
}	
function checkCreditCard (cardType, ccn_field, exp_field) {
	var date = trim(exp_field.value);
	var bad = /[^\d\/ ,.-]/;
	var dateOK = false;
	if ( date > "" && ! date.match(bad)) {
		var a = date.split(/[\/ ,.-]/);
		var m,y;
		if ( a.length == 1 && date.length == 4) {
			m = a[0].substring(0,2);
			y = a[0].substring(2,4);
		} else if ( a.length == 2 ) {
			m = a[0];
			y = a[1];
		}
		if ( m>=1 && m<=12 ) {
			exp_field.value = m+"/"+y;
			dateOK = true;
		}
	} 
	if ( ! dateOK ) {
		return warning(exp_field, "Not a proper expiration date (MMYY).");
	}
	var re = / /;
	var CCN = ccn_field.value.replace(re,"");
	if (CCN.length < 6) {
       return warning(ccn_field, "This is not a proper credit card number.",false);
	}
   if (!isCardMatch(cardType, CCN)) {
       return warning(ccn_field, "This may not be a proper "+cardType +" credit card number. Click OK to use it, CANCEL to fix it.",true);
	}
	if ( cardType == "" && CCN == "" ) {
	 	ccn_field.value = "";
		return true;
	}
	return true;
}
function isCreditCard(st) {
	if (st.length > 19) {
		return (false);
	}
	var i, digit, tproduct, tot = 0, mul = 1, l = st.length;
	for (i = 0; i < l; i++) {
		digit = st.substring(l-i-1,l-i);
		tproduct = parseInt(digit ,10)*mul;
				if (tproduct >= 10) {
			tot += (tproduct % 10) + 1;
		} else {
			tot += tproduct;
		}
		if (mul == 1) {
			mul++;
		} else {
			mul--;
		}
	}

	if ((tot % 10) == 0) {
		return (true);
	} else {
		return (false);
	}
}
function isVisa(cc) {
	if (((cc.length == 16) || (cc.length == 13)) && (cc.substring(0,1) == 4)) {
		return isCreditCard(cc);
	}
	return false;
}
function isMasterCard(cc) {
	var firstdig = cc.substring(0,1);
	var seconddig = cc.substring(1,2);
	if ((cc.length == 16) && (firstdig == 5) && ((seconddig >= 1) && (seconddig <= 5))) {
		return isCreditCard(cc);
	}
	return false;
}
function isAmericanExpress(cc) {
	var firstdig = cc.substring(0,1);
	var seconddig = cc.substring(1,2);
	if ((cc.length == 15) && (firstdig == 3) && ((seconddig == 4) || (seconddig == 7))) {
		return isCreditCard(cc);
	}
	return false;
}
function isDinersClub(cc) {
	var firstdig = cc.substring(0,1);
	var seconddig = cc.substring(1,2);
	if ((cc.length == 14) && (firstdig == 3) && ((seconddig == 0) || (seconddig == 6) || (seconddig == 8))) {
		return isCreditCard(cc);
	}
	return false;
}
function isCarteBlanche(cc) {
	return isDinersClub(cc);
}
function isDiscover(cc) {
	var first4digs = cc.substring(0,4);
	if ((cc.length == 16) && (first4digs == "6011")) {
		return isCreditCard(cc);
	}
	return false;
}
function isEnRoute(cc) {
	var first4digs = cc.substring(0,4);
	if ((cc.length == 15) && ((first4digs == "2014") || (first4digs == "2149"))) {
		return isCreditCard(cc);
	}
	return false;
}
function isJCB(cc) {
	var first4digs = cc.substring(0,4);
	if ((cc.length == 16) && 
		((first4digs == "3088") ||
		(first4digs == "3096") ||
		(first4digs == "3112") ||
		(first4digs == "3158") ||
		(first4digs == "3337") ||
		(first4digs == "3528")))
	{
		return isCreditCard(cc);
	}
	return false;
}
function isAnyCard(cc) {
	if (!isCreditCard(cc)) {
		return false;
	}
	if (!isMasterCard(cc) && !isVisa(cc) && !isAmericanExpress(cc) && !isDinersClub(cc) &&
	!isDiscover(cc) && !isEnRoute(cc) && !isJCB(cc)) {
		return false;
	}
	return true;
}
function isCardMatch (cardType, cardNumber) {
	cardType = cardType.toUpperCase();
	var doesMatch = true;
	if ((cardType == "VISA") && (!isVisa(cardNumber))) {
		doesMatch = false;
	}
	if (((cardType == "MASTERCARD")||(cardType=="MASTER"))&&(!isMasterCard(cardNumber))) {
		doesMatch = false;
	}
	if (((cardType == "AMERICANEXPRESS") || (cardType == "AMEX") )
                && (!isAmericanExpress(cardNumber))) {
		doesMatch = false;
	}
	if ((cardType == "DISCOVER") && (!isDiscover(cardNumber))) {
		doesMatch = false;
	}
	if ((cardType == "JCB") && (!isJCB(cardNumber))) {
		doesMatch = false;
	}
	if ((cardType == "DINERS") && (!isDinersClub(cardNumber))) {
		doesMatch = false;
	}
	if ((cardType == "CARTEBLANCHE") && (!isCarteBlanche(cardNumber))) {
		doesMatch = false;
	}
	if ((cardType == "ENROUTE") && (!isEnRoute(cardNumber))) {
		doesMatch = false;
	}
	return doesMatch;
}
