/**
* validate.js
* version 2.4
* Paul Randolph, January 2005
* Pilotfish Technology
*
* This file has functions for validating and formatting data fields.
* The code should work on most browsers, although it has been
* only tested on:
* Internet Explorer 5.5, 6.0
* Netscape 6.x
* Mozilla 1.1 - 1.6
* Firefox 1.0
*
* CHANGE LOG
* ver 1.0 - initial release
* ver 1.1 - added whole dollar format
* ver 1.2 - added leap year support, Date object support
* ver 1.3 - fixed bugs with isField() and isDollar()
* ver 1.4 - added feature to stripNumber()
* ver 1.5 - allow phone number to be N/A
* ver 1.6 - worked around IE stack overflow bug
* ver 1.7 - added floating point number support
* ver 1.8 - fixed email bug
* ver 1.9 - fixed weird JavaScript bug in fmtDate, added limited signed integer support
* ver 2.0 - added fmtSsn(),fmtZipCode() methods
* ver 2.1 - fixed the isEmpty function to detect all spaces
* ver 2.2 - added money type (dollars and cents)
* ver 2.3 - changed fmtDollar function to support floating point input
* ver 2.4 - added formatEmail function
*/


var defaultEmptyOK = false;

var days = new Array();
days[1]=31; days[7]=31; 
days[2]=28; days[8]=31;    
days[3]=31; days[9]=30;    
days[4]=30; days[10]=31;   
days[5]=31; days[11]=30;   
days[6]=30; days[12]=31;   
var ROUND = 0;
var ROUND_DOWN = -1;
var ROUND_UP = 1;
// Check whether string s is alphanumeric.
function isAlphanumeric(s){
	var re = /^[0-9A-Za-z \-\.]+$/;
	return re.test(s);
}

// Check whether string s is a date field.
function isDate(s){
	var re = /^\d{1,2}\D\d{1,2}\D(\d{1,2}|\d{4})$|^\d{8}$/;
	if(!re.test(s)) return false;
	//test values for valid ranges
	var values = new Array();
	values=s.split(/\D/);
	if (values.length != 3) return false;
	//check month
	var m = parseInt(values[0],10);
	if (m < 1 || m > 12) return false;
	//check day
	//adjust Feb. for leap year
	if (values[2]%4==0) days[2]=29
	var d = parseInt(values[1],10);
	if (d < 1 || d > days[m]) return false;
	//check year
	var y = parseInt(values[2],10);
	if (y > 99 && y < 1900) return false;
	return true;
}

//Determine if the character is numeric
function isDigit(c){ //What? no RE?
   return ((c >= "0") && (c <= "9"))
}

// Check whether string s is a valid dollar amount
function isDollar(s){
	var re = /^\d{1,6}|\$\d{1,3}|\$\d{1,3}\,\d{3}$/;
	return re.test(s);
}

// Check whether string s is a valid email address
//  Reference http://binarios.com/lnb/regexp.html
function isEmail(s){
	var re = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/
	return (re.test(s));
}
 
// Check whether string s is empty.
function isEmpty(s){
	if (s != null){
		s=trim(s);
	}
   return ((s == null) || (s.length == 0))
}

// Check whether string s is a valid floating point number
function isFloat(s){
	var re = /^(\d+)|(\d*\.{1}\d*)$/;
	return re.test(s);
}

// Check whether string s is a valid integer
function isInteger(s){
	var re = /^\d+$/;
	return re.test(s);
}

// Check whether string s is a valid phone number.
function isPhone(s){
	var re = /^\(\d{3}\)[ ]*\d{3}-\d{4}$|^\d{10}$/;
	return re.test(s);
}

// Check whether string s is a valid phone number.
// Allow N/A if allowNA is true
function isPhoneNA(s){
  if(s.toUpperCase()=="N/A") {
	return true;
  }
  return isPhone(s);
}

// Check whether string s is a valid signed integer
function isSigned(s){
	var re = /^[\-|\+]{0,1}\d+$/;
	return re.test(s);
}

// Check whether string s is a valid SSN.
function isSsn(s){
	var re = /^\d{3}-\d{2}-\d{4}$|^\d{9}$/;
	return re.test(s);
}

// Check whether string s is text.
function isText(s){
	var re = /^[A-Za-z \-\.]+$/;
	return (re.test(s));
}

// Check whether string s is a valid Zip Code.
function isZipCode(s) {
	if(isEmpty(s)) return false;
	if(s=="00000") return false;
	var re = /^\d{5}-\d{4}$|^\d{5}$|^\d{9}$/;
	return re.test(s);
}

//return only ASCII digits in parameter s
function stripNumber(s) {
  if(isEmpty(s)) return "0";
  var new_s = "";
  for (var i=0; i<s.length; i++){
    var c = s.charAt(i);
    if (isDigit(c)) new_s += c;
	}
	return new_s;
}

//return only ASCII digits and ONE decimal point in parameter s
function stripFloat(s) {
	var dp_flag=false;
  if(isEmpty(s)) return "0.0";
  var new_s = "";
  for (var i=0; i<s.length; i++){
    var c = s.charAt(i);
    if(!dp_flag && c=='.') {
    	//allow only one decimal point
    	dp_flag=true;
    	new_s += c;
    	continue;
    	} //end-if
    if (isDigit(c)) new_s += c;
	}//end-for
	return new_s;
}

//return parameter s without leading and trailing spaces
function trim(s) {
	var text = false;
	var left = 0;
	var right = s.length;
	for (var i=0; i<s.length; i++){
		var c = s.charAt(i);
		if (c == " ") {
			left++;
		}
		else
		break;
	}
	for (var i=s.length-1; i>0; i--){
		var c = s.charAt(i);
		if (c == " ") {
			right--;
		}
		else
		break;
	}
	if (left >= right){
		return "";
	}else{
		return s.substring(left,right);
	}
}

// format the string s to a alphanumeric format
function formatAlpha(x) {
	if (isEmpty(x.value)) return "";
	if (!isAlphanumeric(x.value)) {
		alert('Invalid Characters');
		return x.value;
	}
	//valid alphanumeric
	return x.value;
}

// format the string s to a Date format 'mm/dd/yyyy'
function fmtDate(s) {
	if (isEmpty(s)) return s;
	if (!isDate(s)) {
		alert('Invalid Date');
		return s;
	}
	//possible valid Date
	var values = new Array(3);
	values = s.split(/\D/);
	// fix weird bug where 08 and 09 becomes 2000
	if(values[2]=='08')values[2]='2008';
	if(values[2]=='09')values[2]='2009';
	var y = parseInt(values[2]);
	//add leading zeroes to the month and day if less than ten
	if (values[0].length==1) values[0]="0" + values[0];
	if (values[1].length==1) values[1]="0" + values[1];
	//check year - year 30 is the cutoff between 19xx and 20xx
	if (y >= 0 && y <= 30) y+=2000;
	if (y > 30 && y <= 99) y+=1900;
	values[2]=y.toString();
	return values.join("/");
}

// format a text field value to a Date format 'mm/dd/yyyy'
function formatDate(x) {
	return fmtDate(x.value);
	}

// format the string s to a whole dollar value
function fmtDollar(s) {
	var strip=fmtFloat(s,0,ROUND);
	if(!isDollar(strip) || strip.length>9) {
	  alert('Invalid Dollar Amount');
	  return s;
	}
	//valid dollar
	strip=fmtNumber(strip);
	var fmt=strip;
	var l=strip.length;
	//add commas
	if(l>3) fmt=strip.substring(0,l-3) + "," + strip.substring(l-3,l);
	if(l>6) fmt=strip.substring(0,l-6) + "," + strip.substring(l-6,l-3) + "," + strip.substring(l-3,l);
	return "$" + fmt;
}
	
// format the text field x to a whole dollar value
function formatDollar(x) {
  return fmtDollar(x.value);
}

// alert user of an invalid email address
function formatEmail(x) {
	if (isEmpty(x.value)) return x.value;
	if (!isEmail(x.value)) {
		alert('Invalid Email Address');
		return x.value;
	}
	return x.value;
}
// format the string s to a floating point number
function fmtFloat(s,n,r) {
  var fmt = stripFloat(s);
  var values = new Array(2);
  var whole='';
  var frac='';
  var point='';
  if(!isFloat(fmt)) {
    fmt='0.0';
  }
  var fv = parseFloat(fmt);
  var round =0;
  // use default values for missing parameters
  if (fmtFloat.arguments.length<3) {
  	r=ROUND;
  }
  if (fmtFloat.arguments.length<2) {
  	n=2;
  }
  switch (r) {
  case ROUND:
  	round = (Math.round(fv*Math.pow(10,n)))/Math.pow(10,n);
  	break;
  case ROUND_DOWN:
  	round = (Math.floor(fv*Math.pow(10,n)))/Math.pow(10,n);
  	break;
  case ROUND_UP:
  	round = (Math.ceil(fv*Math.pow(10,n)))/Math.pow(10,n);
  	break;
  }//end-switch
  fmt=round.toString();
  values = fmt.split(/\./);
  whole  = values[0];
  if(isEmpty(whole)) {
  	whole='0';
  }
  if(values.length==2) {
	  frac  = values[1];
	  point ='.';
	  for(i=0;i=(frac.length-n);i++) {
	  	frac = frac + '0';
	  }//end-for
  }//end-if
  if(values.length==1 && n>0) {
	  point ='.';
	  for(i=0;i<n;i++) {
	  	frac = frac + '0';
	  }//end-for
  }//end-if
	return whole+point+frac;
}

// overload the fmtFloat function to use ROUND and 2 decimal places
/*function fmtFloat(s) {
return fmtFloat(s,2,ROUND);
}
*/
// format the text field x to a floating point value with n decimal places
function formatFloat(x,n) {
	var s = fmtFloat(x.value,n,ROUND);
	if (!isFloat(s)) {
		alert('Invalid Number');
		return x.value;
	}
	return s
}

// format the string s to a dollar and cents value
function fmtMoney(s) {
	var strip = stripFloat(s);
	if(!isFloat(strip)) {
	  return s;
	}
	//valid float
	var fmt = fmtFloat(s,2,ROUND);
	var moneyFmt = fmt;
	var l=fmt.length;
	//add commas
	if(l>6) moneyFmt=fmt.substring(0,l-6) + "," + fmt.substring(l-6,l);
	if(l>9) moneyFmt=fmt.substring(0,l-9) + "," + fmt.substring(l-9,l-6) + "," + fmt.substring(l-6,l);
	return "$" + moneyFmt;
}
	
// format the string s to a number
function fmtNumber(s) {
  var fmt = stripNumber(s);
  if(!isInteger(fmt)) {
    return s;
  }
   //strip leading zeros
   //leave the last digit, even if it's zero
   var left = 0;
   var size = fmt.length;
	for (var i=0; i<size-1; i++){
		var c = fmt.charAt(i);
		if (c == "0") {
			left++;
		}
		else break;
	}//for
   return fmt.substring(left,size);
}
	
function formatNumber(x) {
	return fmtNumber(x.value);
}

// format the string s to a phone format '(ddd) ddd-dddd'
function formatPhone(x) {
	if (isEmpty(x.value)) return x.value;
	strip=stripNumber(x.value);
	if (!isPhone(strip)) {
		alert('Invalid Phone Number');
		return x.value;
	}
	//valid Phone
	return "("+strip.substring(0,3)+") "+strip.substring(3,6)+"-"+strip.substring(6,10);
}

// format the string s to a phone format '(ddd) ddd-dddd'
// Allow 'N/A' for a value
function formatPhoneNA(x) {
  if (isEmpty(x.value)) return "";
  if(x.value.toUpperCase()=="N/A") {
	return "N/A";
  }
  return formatPhone(x);
}

// format the string s to a signed integer
function fmtSigned(s) {
	var minus = (s.charAt(0)=='-')?'-':'';
  var fmt = stripNumber(s);
  if(!isSigned(fmt)) {
    return s;
  }
   //strip leading zeros
   //leave the last digit, even if it's zero
   var left = 0;
   var size = fmt.length;
	for (var i=0; i<size-1; i++){
		var c = fmt.charAt(i);
		if (c == "0") {
			left++;
		}
		else break;
	}//for
   return minus+fmt.substring(left,size);
}

function formatSigned(x) {
	return fmtSigned(x.value);
}

// format the string s into an SSN 'ddd-dd-dddd'
function fmtSsn(s) {
	var strip=stripNumber(s);
	if(strip.length!=9) return s;
	return strip.substring(0,3)+"-"+strip.substring(3,5)+"-"+strip.substring(5,9);
}

// format the element x value to a SSN format 'ddd-dd-dddd'
function formatSsn(x) {
	if (isEmpty(x.value)) return x.value;
	s=fmtSsn(x.value);
	if (!isSsn(s)) {
		alert('Invalid SSN');
		return x.value;
	}
	//valid SSN
	return s;
}

// format the string s to a zip code 'ddddd-dddd'
function fmtZipCode(s) {
	if (isEmpty(s)) return "";
	var strip=stripNumber(s);
	if (!isZipCode(strip)) {
		return s;
	}
	//valid Zip
	if (strip.length==5) return strip;
	if (strip.length==9) return strip.substring(0,5)+"-"+strip.substring(5,9);
}

// format the element x value to a zip code 'ddddd-dddd'
// this function supports both the 5 digit zip and 9 digit "zip+4" format
function formatZipCode(x) {
	if (isEmpty(x.value)) return "";
	s=fmtZipCode(x.value);
	if (!isZipCode(s)) {
		alert('Invalid Zip Code');
		return x.value;
	}
	return s;
}

//generic formatting function based on the 'field' property
// parameter x is a form element (text box, checkbox, etc.)
function format(x) {
//  alert('running validate.js format(x) method');
  var s;
  var tmp = '';
  var fld = '';
  
  tmp = x.field;
  try{
    tmp = x.field;
  }catch(err){
    fld = '';
  }finally{
    fld = x.alt.toString();
  } 
  if (isEmpty(fld)){
    return s.value;
  }
//  alert('fld = '+fld);
  switch (fld) {
    case 'alpha':
      s=trim(formatAlpha(x));
      break;
    case 'button':
      s=x.value;
      break;
    case 'check':
      s=x.value;
      break;
    case 'date':
      s=formatDate(x);
      break;
    case 'email':
      if (isEmpty(x.value)) {
    	  s="";
    	  break;
    	}
      if (!isEmail(x.value)) alert('Invalid Email');
      s=x.value;
      break;
    case 'float'://default to 2 decimal places
    	s=formatFloat(x,2);
    	break;
    case 'number':
      s=x.value;
      break;
    case 'phone':
    	s=formatPhone(x);
    	break;
    case 'phonena':
    	s=formatPhoneNA(x);
    	break;
    case 'signed':
    	s=formatSigned(x);
    	break;
    case 'ssn':
    	s=formatSsn(x);
    	break;
    case 'text':
    	if (!isText(x.value)) alert('Invalid Text');
    	s=trim(x.value);
    	break;
    case 'zipcode':
    	s=formatZipCode(x);
    	break;
	}//switch
return s;
}

//generic validation function based on the 'field' property
// parameter x is a form element (text box, checkbox, etc.)
// parameter EmptyOK is what is returned if x.value is empty
function isField(x, EmptyOK) {
  //ignore elements without the field property set
  if (isEmpty(x.field)) {
    return true;
  }
  if (isEmpty(x.value)) {
    return EmptyOK;
  }
  switch (x.field.toLowerCase()) {
    case 'alpha':
         return isAlpha(x.value);
         break;
	 case 'button':
         return true;
         break;
	 case 'check':
         return true;
         break;
	 case 'date':
         return isDate(x.value);
         break;
	 case 'dollar':
         return isDollar(x.value);
         break;
	 case 'email':
         return isEmail(x.value);
         break;
	 case 'float':
         return isFloat(x.value);
         break;
	 case 'number':
         return isInteger(x.value);
         break;
	 case 'phone':
         return isPhone(x.value);
         break;
	 case 'phonena':
         return isPhoneNA(x.value);
         break;
	 case 'signed':
         return isSigned(x.value);
         break;
	 case 'ssn':
         return isSsn(x.value);
         break;
	 case 'text':
         return isText(x.value);
         break;
	 case 'zipcode':
         return isZipCode(x.value);
         break;
  }//switch
  return true;
}

// take a date string in "mm/dd/yyyy" or "mm-dd-yyyy" format and return a Date object
function dateObj(s) {
  var v = s.split(/\D/);
  return new Date(v[2],v[0]-1,v[1]);
}

function validate_ver(){
	return '2.4';
}
