// functions that return true or false indicating validity of a specific 
// type of input 
//
// to use, call the function and pass it input.
// 
// document.myForm.onSubmit = function() {
//	if (!isValidPhoneNumber(document.myForm.phone_number.value)) {
//		alert("the phone number you entered sucks!");
//		return false;
//	}
//	return true;
// }

function isValidPhoneNumber(s) {
	var temp = s.replace(/\D/g, "")
	return temp.length > 9 && temp.length < 26
}

function isValidZipCode(s) {
	var temp = s.replace(/\D/g, "")
	return temp.match(/^\d{5}$|^\d{9}$/) != null
}

function isValidCID(s,ccType) {
	var temp = s.replace(/\D/g, "")
	return temp.match(/^\d{3}$|^\d{3}$/) != null
}

function isValidSelectBox(o) {
	return (o.options[o.selectedIndex].value != "_none_" && 
			o.options[o.selectedIndex].value.trim() != "")
}

function isValidEmailAddress(s) {
  var temp = s.replace(/\s/g, "")
  return temp.length > 0;
  /*	
  var temp = s.replace(/\s/g, "")
	return (temp.match(/^[\w\.\-]+\x40[\w\.\-]+\.\w{2}\w?$/)) && 
			temp.charAt(0) != "." && !(temp.match(/\.\./))
  */
}
	
	
	


// 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 dateFieldBlurHandler() {
	var d = new Date(this.value)
	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);

		this.value = d.getHumanDateString()
	}
}

function timeFieldBlurHandler() {
	var t = new Time(this.value)
	if (!isNaN(t)) this.value = t.getHumanTimeString()
}

function phoneFieldBlurHandler() {
	var obj = arguments.length ? arguments[0] : this;
	var temp = obj.value.replace(/\D/g, "")

	if (temp.length > 9 && temp.length < 26)
		if (temp.length == 10) {
			obj.value = "" + temp.substring(0,3) + "" 
			obj.value += temp.substring(3,6) + "" + temp.substring(6,10)
		}
	}

function zipcodeFieldBlurHandler() {
	var temp = this.value.replace(/\D/g, "")

	if (temp.length == 5 || temp.length == 9) { 
		if (temp.length == 5) this.value = temp
		else this.value = temp.substring(0,5) + "-" + temp.substring(5,9)
	}
}

// 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 == "textarea") 
			el.onblur = textFieldBlurHandler
	}
}






// as convenient a place as any to store this...
var STD_ERROR_PREFIX = "There were one or more problems with the form values "
STD_ERROR_PREFIX += "you entered.\nPlease check the following and try submitting "
STD_ERROR_PREFIX += "the form again:\n\n"





// Extensions to the Date class:
// var myDate = new Date();
// myDate.getMonthName(); -> "February"
// myDate.getHumanDateString(); -> "February 29, 2000"
// myDate.getHumanTimeString(); -> "4:00 pm"


// returns the name of the month
Date.prototype.getMonthName = function() {
	return ["January","February","March","April","May","June","July","August",
			"September","October","November","December"][this.getMonth()]
}


// returns a nicely formatted date string
Date.prototype.getHumanDateString = function() {
return this.getMonthName() + " " + this.getDate() + ", " + this.getFullYear()
}


// returns a nicely formatted time string
Date.prototype.getHumanTimeString = function() {
	var h = this.getHours()
	var m = this.getMinutes()
	var t = h >= 12 ? "pm" : "am"

	if (h == 0) h = 24
	if (h > 12) h -= 12
	h = String(h)
	m = String(m)
	if (m.length == 1) m = "0" + m

	return h + ":" + m + " " + t
}





// Time is a wrapper class for the Date object
// it accepts a wide variety of strings representing the time
// and returns a date object representing the current date with the
// specified time.
//
// var myTime = new Time('4p');
// myTime now contains a date object representing today at 4PM.
//
// accepted formats include 4p, 4:p, 4:1p, 4:10p, 4:10pm, 16:00, 
// and a bunch more...
/*
function Time(sTimeStr) {
	var a = sTimeStr.match(/(\d{1,2})\s*\x3A?\s*(\d{0,2})\s*(am|pm|a|p)?/i)
	if (a) {
		var d = new Date()
		var h = a[1]
		var m = a[2]
		var t = a[3]
		if (t && t.charAt(0).toLowerCase() == "p") h = h % 12 + 12
		d.setHours(h)
		d.setMinutes(m)
		return d
	}
	return null
}
*/
function Time(sTimeStr) {
	if (sTimeStr.trim() != "")
	{
		var a = sTimeStr.match(/\d{1,2}/g)
		var t = sTimeStr.match(/(am|pm|a|p)/ig)
		if (a) {
			var d = new Date()
			var h = a[0]
			var m = a[1] ? a[1] : 0;
			if (t) t = String(t[0]);
			if (t && t.charAt(0).toLowerCase() == "p") h = h % 12 + 12
			d.setHours(h)
			d.setMinutes(m)
			return d
		}
		return null
	}
}




// Extensions to the String class:
// var myStr = "  yomomma.mpg "
// myStr.trim() -> myStr now contains "hotdogs!"
// myStr.hasFileExtension(".mpg") -> true


// like Trim( ) in vbscript. removes trailing and 
// leading whitespace from a string
String.prototype.trim = function() {
	return this.replace(/^\s*|\s*$/g, "")
}


// determines whether or not a filename has one of the specified extensions
String.prototype.endsWith = function() {
	var bOk = false
	for (var i = 0; i < arguments.length; i++) {
		if (this.indexOf(arguments[i]) == this.length - arguments[i].length) {
			bOk = true
			break
		}
	}
	return bOk
}



// push is a quite useful method of arrays in newer 
// javascript implementations, but not in ie5-
Array.prototype.push = function(v) {
	this[this.length] = v
	return v
}

// checks credit card expiration date for mm/yy format and if expired
function inValidCharSet(str,charset)
{
	var result = true;
	
	for (var i=0;i<str.length;i++)
		if (charset.indexOf(str.substr(i,1))<0)
		{
			result = false;
			break;
		}
	
	return result;
}
function allDigits(str)
{
	return inValidCharSet(str,"0123456789");
}

function isExp(formField,fieldLabel,required)
{
	var result = true;
	var formValue = formField.value;
	var msg = "";
  
 	if (result && (formField.value.length>0))
 	{
 		var elems = formValue.split("/");
 		
 		result = (elems.length == 2); // should be two components
 		var expired = false;
 		
 		if (result)
 		{
 			var month = parseInt(elems[0],10);
 			var year = parseInt(elems[1],10);
 			
 			if (elems[1].length == 2)
 				year += 2000;
 			
 			var now = new Date();
 			
 			var nowMonth = now.getMonth() + 1;
 			var nowYear = now.getFullYear();
 			
 			expired = (nowYear > year) || ((nowYear == year ) && (nowMonth > month));
 			
			result = allDigits(elems[0]) && (month > 0) && (month < 13) &&
					 allDigits(elems[1]) && ((elems[1].length == 2) || (elems[1].length == 4));
 		}
 		
  		if (!result)
 		{
 			result = false;
			//msg = 'Please enter a date in the format MM/YY';
		}
		else if (expired)
		{
 			result = false;
 			//msg = 'The date has expired.';
		}
	} 
  return result;
}

//checks for validity of credit card for type, and number combinations
function LuhnCheck(str){
  var result = true;

  var sum = 0; 
  var mul = 1; 
  var strLen = str.length;
  
  for (i = 0; i < strLen; i++) 
  {
    var digit = str.substring(strLen-i-1,strLen-i);
    var tproduct = parseInt(digit ,10)*mul;
    if (tproduct >= 10)
      sum += (tproduct % 10) + 1;
    else
      sum += tproduct;
    if (mul == 1)
      mul++;
    else
      mul--;
  }
  if ((sum % 10) != 0)
    result = false;
    
  return result;
}

function isValidCCType(cardType,cardNum)
{
	var result = false;
	//cardType = cardType.toUpperCase();
	
	var cardLen = cardNum.length;
	var firstdig = cardNum.substring(0,1);
	var seconddig = cardNum.substring(1,2);
	var first4digs = cardNum.substring(0,4);

	switch (cardType)
	{
		case "VISA":
			result = (((cardLen == 16) || (cardLen == 13)) && (firstdig == "4"));
			break;
		case "VISA-DEBIT":
			result = (((cardLen == 16) || (cardLen == 13)) && (firstdig == "4"));
			break;
		case "AMEX":
			var validNums = "47";
			result = ((cardLen == 15) && (firstdig == "3") && (validNums.indexOf(seconddig)>=0));
			break;
		case "MASTERCARD":
			var validNums = "12345";
			result = ((cardLen == 16) && (firstdig == "5") && (validNums.indexOf(seconddig)>=0));
			break;
		case "MASTERCARD-DEBIT":
			var validNums = "12345";
			result = ((cardLen == 16) && (firstdig == "5") && (validNums.indexOf(seconddig)>=0));
			break;
		case "DISC":
			result = ((cardLen == 16) && (first4digs == "6011"));
			break;
		case "Check":
			result = true;
			break;
		case "Money Order":
			result = true;
			break;
		case "CC over Phone":
			result = true;
			break;
	}
	return result;
}

function isValidCCNumber(ccNum,ccType,required)
{
	var result = true;
 	var ccNum = ccNum
	var ccType = ccType
	var cardLen = ccNum.length
   
  	if (result && (cardLen>0)){ 
 				if (!allDigits(ccNum) || !LuhnCheck(ccNum) || !isValidCCType(ccType,ccNum)){
					result = false;
				
				}
		} 
		
	
	return result;
}
