// Phone number validation and formatting
// by Kevin Lynn Brown
// ©1999 All rights reserved
// for Myers Internet Services

function formatPhone(number,format) {
	// format = "0" | "none" | "";
	//          "1" | "()";
	//          "-" | (user selected separator);
	// Note: all above must be passed as strings
	// Otherwise generates an error in comparison
	var formattedNumber = number + "";
	var pre = "";
	var area = "";
	var trunk = "";
	var post = "";
	if (number.length == 11) {
		pre = number.substring(0,1);
		area = number.substring(1,4);
		trunk = number.substring(4,7);
		post = number.substring(7);
	}
	else if (number.length == 10) {
		area = number.substring(0,3);
		trunk = number.substring(3,6);
		post = number.substring(6);
	}
	else if (number.length == 7) {
		trunk = number.substring(0,3);
		post = number.substring(3);
	}
	if (format != "" || format != null) {
		// Use the default U.S. format: 1 (800) 123-4567
		if (format == "()" || format == "1") {
			if (number.length == 11) {
				formattedNumber = pre + " (" +  area + ") " + trunk + "-" + post;
			}
			else if (number.length == 10) {
				formattedNumber = "(" +  area + ") " + trunk + "-" + post;
			}
			else if (number.length == 7) {
				formattedNumber = trunk + "-" + post;
			}
		}
		// Use a passed separator to hyphenate the output
		else if (format != "()" || format != "1") {
			if (number.length == 11) {
				formattedNumber = pre + format +  area + format + trunk + format + post;
			}
			else if (number.length == 10) {
				formattedNumber = area + format + trunk + format + post;
			}
			else if (number.length == 7) {
				formattedNumber = trunk + format + post;
			}
		}
	}
	return formattedNumber;
}

function validPhone(phNumber,format,form,field,required) {
	// Pass in form and field name
	// Makes the function reusable
	// format = "0" | "none" | "";
	//          "1" | "()";
	//          "-" | (user selected separator);
	// Note: all above must be passed as quoted strings
	// Otherwise generates an error in comparison
	
	// required = 0 | false | null for optional;
	//            1 | true for required;
	// Note: the above are boolean|numeric, no quotes
	
	// VARIABLES USED:
	//   killForm = a numeric flag used to stop or post the form
	//    special = a string of special characters to strip out for validation
	//     phOrig = the stored original user input
	//      phNum = the same, but will be manipulated/changed by the script
	//    phTrunc = the phone number truncated, minus any Ext.; will be changed by the script
	//  phLowCase = the phone number in lowercase; to find "Ext.", "ext", etc.
	// phLowCaseX = phTrunc in lowercase; to find "x000", "X 000", etc.
	//    phNoExt = the changed number without any extension; sent to the format function
	//        ext = holds the value "Ext" || "ext" || "ex." etc. (if found in the phone number)
	//          x = holds the value "x" || "X" (if found in the phone number)
	//     before = a section of the phone number before an illegal character
	//      after = a section of the phone number after an illegal character
	// formattedPhone = the final output of both functions

	var i = 0;
	var j = 0;
	var killForm = 0;
	var useForm = false;
	if (validPhone.arguments.length == 2) {
		useForm = false;
		var phOrig = validPhone.arguments[0];
		var phNum = validPhone.arguments[0];
		var phTrunc = validPhone.arguments[0];
		var phNoExt = validPhone.arguments[0];
	}
	else if (validPhone.arguments.length > 2) {
		if (form != null && field != null && form != "" && field != "") {
			useForm = true;
			var phOrig = document[form][field].value;
			var phNum = document[form][field].value;
			var phTrunc = document[form][field].value;
			var phNoExt = document[form][field].value;
		}
		else {
			useForm = false;
			var phOrig = validPhone.arguments[0];
			var phNum = validPhone.arguments[0];
			var phTrunc = validPhone.arguments[0];
			var phNoExt = validPhone.arguments[0];
		}
	}
	var formattedPhone = "";
	var phLowCase = "";
	var phLowCaseX = "";
	var before = "";
	var after = "";
	var x = "";
	var ext = "";
	var extension = "";
	// Add any special characters to strip out here:
	var special = "()-. ,:;/\|*+#@&=";
	// If blank and required, kill the form
	if (phNum == "" && (required == 1 || required == true)) {
		alert('Sorry!  A phone number is required.')
		// Put the offending field in focus
		if (useForm)
		document[form][field].focus();
		// Stop the form post
		return false;
	}
	// If it's blank but not required, let it through
	else if (phNum == "") {
		return true;
	}
	else {
		// Find "Ext. 000" extensions and separate them out
		phLowCase = phNum.toLowerCase();
		ext = phLowCase.lastIndexOf("ext");
		if (ext != -1) {
			extension = phOrig.substring(ext,phOrig.length);
			phTrunc = phNum.substring(0,ext);
			phNoExt = phNum.substring(0,ext);
		}
		else {
			extension = "";
		}
		// This strips out formatting characters for length comparison
		for (i=0;i<phTrunc.length;i++) {
			var phChar = phTrunc.charAt(i);
			for (j=0;j<special.length;j++) {
				if (phChar == special.charAt(j)) {
					before = phTrunc.substring(0,i);
					after = phTrunc.substring(i+1);
					phTrunc = before + after;
					// If 2 illegal characters are consecutive, we have to test again using
					// the current value of phNum.charAt(i) before incrementing i, otherwise we will miss it.
					i--;
				}
			}
		}
// Obsoleted.  Could not filter out X contained in the number if no extension present
// ==================================================================================
//		// Find x000 extensions.  Must be done after stripping extra characters
//		// because then x denoting an extension would only appear at character 7, 10 or 11
//		if (extension == "") {
//			phLowCaseX = phTrunc.toLowerCase();
//			// Don't want to mistakenly match an X that is part of the phone number itself
//			x = phLowCaseX.lastIndexOf("x");
//			if (phTrunc.length > 7 && x != -1 && (x == 7 || x == 10 || x == 11)) {
//				extension = phTrunc.substring(x,phTrunc.length);
//				phTrunc = phTrunc.substring(0,x);
//				phNoExt = phNum.substring(0,phNum.indexOf(extension));
//			}
//		}
// ==================================================================================
		if (phTrunc.length == 11) {
			// Make sure the first 4 characters (1-800) are numeric
			for (i=0;i<4;i++) {
				if (parseInt(phTrunc.charAt(i)) + "" == Number.NaN + "") {
					killForm = 1;
				}
			}
			// There is no such thing as 2-800 or 1-000
			if (phTrunc.charAt(0) != "1" && phTrunc.charAt(0) != "0" || phTrunc.charAt(1) == "0") {
				killForm = 1;
			}
		}
		else if (phTrunc.length == 10) {
			// Make sure the area code is numeric
			for (i=0;i<3;i++) {
				if (parseInt(phTrunc.charAt(i)) + "" == Number.NaN + "") {
					killForm = 1;
				}
			}
			// No area codes begin with 0 or 1
			if (phTrunc.charAt(0) == "0" || phTrunc.charAt(0) == "1") {
				killForm = 1;		
			}
		}
		
		// A proper US ph# should be 10 or 11 characters now
		else if (phTrunc.length != 10 && phTrunc.length != 11) {
			killForm = 1;
		}
	}
	if (killForm == 1) {
		// Prompt for proper phone number...
		var msg = "Sorry!\n\nYou have entered an invalid phone number.\n\n"
			+"Phone numbers must include an area code and contain 10 or 11 numbers. \n\nPlease check the number and try again.";
		alert(msg);
		// Automatically select and focus the phone number form field for easy user correction
		if (useForm) {
			document[form][field].select();
			document[form][field].focus();
		}
		// Stop the form post
		return false;
	}
	else {
		if (format && format != null && format != "" && format != "none" && format != "0") {
			// If calling field requires phone number formatting
			phNum = formatPhone(phTrunc,format) + " " + extension;
		}
		formattedPhone = phNum;
		if (useForm)
		document[form][field].value = formattedPhone;
		// Garbage collection.  Some variables seemed to retain their modified values after exiting?
		phOrig = phNum = phTrunc = i = j = killForm = formattedPhone = phLowCase = phLowCaseX = phNoExt = before = after = x = ext = extension = null;
		if (useForm) {
			return true;
		}
		else {
			return formattedPhone;
		}
	}
}