/**
 * STRING Object Extensions
 */
if( !String.upperCaseFirst )
String.prototype.upperCaseFirst = function() {
  t = this.toLowerCase();
  
  alphas = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  
  start = 0;
  while( alphas.indexOf(t.substr(start,1).toUpperCase()) == -1 )
    start++;
  
  fletter = t.substr(start,1).toUpperCase();
  last = t.substr(start+1, t.length-start);
  
  ret = t.substr(0, start) + fletter + last;

  return ret;
};

if( !String.upperCaseWords )
String.prototype.upperCaseWords = function() {
  ret = new String("");
  aret = new Array();
  
  a = new Array();
  re = /\s\s+/gi;
  
  //Replace Back-to-Back Spaces with a single space
  strPhrase = this.replace( re, " " );

  a = strPhrase.split(" ");
  for(index = 0; index < a.length; index++) {
    aret[index] = a[index].upperCaseFirst();
  };
  
  ret = aret.join(" ");

  return ret;
};

if( !String.trim )
String.prototype.trim = function() {
  re = /(^[\s\t\r\n]+|[\s\t\r\n]+$)+/gi;
  
  ret = this.replace( re, "" );
  
  return ret;
};

if( !Number.trim )
Number.prototype.trim = function() {
  strValue = '' + this;
  
  return parseFloat(strValue.trim());
};

if( !Array.pop )
Array.prototype.pop = function() {
  var b = this[this.length-1];
  this.length--;
  return b;
};

if( !Array.push )
Array.prototype.push = function() {
  for( var i = 0, b = this.length, a = arguments, l = a.length; i<l; i++ ) {
    this[b+i] = a[i];
  }
  
  return this.length;
};

if( !Array.empty )
Array.prototype.empty = function() {
  this.length = 0;
};


if( !window.getObject )
function getObject( obj ) {
  var type = typeof(obj);
  obj = ( type.toLowerCase() == "string" )? document.getElementById(obj) : obj;
  
  return obj;
};

/**
 * FormValidator Object
 */
 
function FormValidator() {
  this.errors = new Array();

  this.version = "1.2";
  this.buildDate = "2006-09-05 13:31:45 EDT";
};

FormValidator.prototype.STRING_MIN_LENGTH = 3;
FormValidator.prototype.CAPTCHA_MIN_LENGTH = 6;

FormValidator.prototype.parseErrors = function() {
  ret = this.errors.join("\n");

  return ret;
};

FormValidator.prototype.isValid = function(validatorName, value, bIsRequired) {
  try {
  
    functionName = "isValid" + this._normalizeValidator(validatorName);
  
    if( !this[functionName] ) {
      throw 'Validation Rule Parser Not Found ('+functionName+')';
    };

	isValidValue = this[functionName](value, bIsRequired);
	
	return isValidValue;
	
  } catch(e) {
    alert(e);
  };
};


FormValidator.prototype._normalizeValidator = function(validatorName) { 
  ret = validatorName.upperCaseFirst(); return ret;
};

//Validation Rules

FormValidator.prototype.isValidRequired = function(value, bIsRequired) {
  test = value.trim();
  
  bReturn = true;

  if( bIsRequired == true || bIsRequired == 'true' ) {
    if( test=='' || test.length < 1 ) {
      this.errors.push("is a required field.");
      bReturn = false;
	};
  };

  return bReturn;
};

FormValidator.prototype.isValidNumeric = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  ret = ( isNaN(value) )? false : true;
  
  if( !ret ) {
    this.errors.push("must contain only numeric values.");
	return false;
  };

  return ret;    
};

FormValidator.prototype.isValidString = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  if( value.trim().length > 0 && value.trim().length < this.STRING_MIN_LENGTH ) {
    this.errors.push("must be at least "+this.STRING_MIN_LENGTH+" characters long.");
  
    return false;
  };
  
  return true;
};

FormValidator.prototype.isValidStateprovince = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  SP_MIN_LENGTH = 2;

  if( value.trim().length > 0 && value.trim().length < SP_MIN_LENGTH ) {
    this.errors.push("must be at least "+SP_MIN_LENGTH+" characters long.");
  
    return false;
  };
  
  return true;
};

FormValidator.prototype.isValidPostalcode = function(value, bIsRequired) {

  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  POSTALCODE_MIN_LENGTH = 5;
  POSTALCODE_MAX_LENGTH = 14;
  
  re = /[\s\t\r\n\-\_]+/gi;
  test = value.replace( re, '' );

  if( test.length > 0 && test.length < POSTALCODE_MIN_LENGTH ) {
    this.errors.push("must be at least "+POSTALCODE_MIN_LENGTH+" characters.");
    return false;
  };
  
  if( test.length > POSTALCODE_MAX_LENGTH ) {
    this.errors.push("cannot exceed "+POSTALCODE_MAX_LENGTH+" characters.");
    return false;
  };
  
  return true;
};

FormValidator.prototype.isValidCountry = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  COUNTRY_MIN_LENGTH = 2;

  if( value.trim().length > 0 && value.trim().length < COUNTRY_MIN_LENGTH ) {
    this.errors.push("must be at least "+COUNTRY_MIN_LENGTH+" characters long.");
  
    return false;
  };
  
  return true;
};

FormValidator.prototype.isValidPhone = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  PHONE_MIN_LENGTH = 10;
  PHONE_MAX_LENGTH = 20;

  re = /\D+/gi;
  test = value.replace( re, "");
  
  if( bIsRequired == true && test.trim().length == 0 ) {
    this.errors.push("contains no Numbers.  It must contain at least "+PHONE_MIN_LENGTH+" digits.");
	return false;
  };
  
  if( test.length > 0 && test.trim().length < PHONE_MIN_LENGTH ) {
    this.errors.push("must contain at least "+PHONE_MIN_LENGTH+" digits.");
	return false;
  };
  
  if( test.trim().length > PHONE_MAX_LENGTH ) {
    this.errors.push("cannot exceed "+PHONE_MIN_LENGTH+" digits.");
	return false;
  };
  
  return true;  
};

FormValidator.prototype.isValidEmail = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  re = /^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)+$/gi;
  results = value.match( re );

  if( !results && value.length > 0 ) {
    this.errors.push("is formatted invalidly.  please re-enter.");
	return false;
  };

  return true;
};

FormValidator.prototype.isValidCaptcha = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  if( value.trim().length > 0 && value.trim().length < this.CAPTCHA_MIN_LENGTH ) {
    this.errors.push("must be at least "+this.CAPTCHA_MIN_LENGTH+" characters long.");
  
    return false;
  };
  
  return true;
};

FormValidator.prototype.isValidPassword = function( value, bIsRequired ) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  /**
   * Min Length is an Optional 3rd Parameter
   * If not provided, defaults to 8
   */
  abs_min_length = 8;

  /**
   * Max Length is an Optional 3rd Parameter
   * If not provided, defaults to 12
   */
  abs_max_length = 12;

  min_length = ( arguments[2] && this.isValidInteger(arguments[2], true) )? this.isValidInteger(arguments[2]) : abs_min_length;
  max_length = ( arguments[3] && this.isValidInteger(arguments[3], true) )? this.isValidInteger(arguments[3]) : abs_max_length;


  if( value.trim() < min_length ) {
    this.errors.push("must be at least "+min_length+" characters long.");
    return false;
  }

  if( value.trim() > max_length ) {
    this.errors.push("cannot exceed "+max_length+" characters.");
    return false;
  }

  return true;
};


//Datatype Validation Rules

FormValidator.prototype.isValidInteger = function(value, bIsRequired) {
  INT_MAX = 65535;

  if( !this.isValidNumeric(value, bIsRequired) ) {    
	return false;
  };
  
  tempInt = (value < 0)? value * (-1) : value;
  testInt = INT_MAX - Math.ceil(tempInt);
  
  if( testInt < 0 ) {
    this.errors.push("invalid integer value (passed as 'Double').");
	return false;
  };
  
  return true;
};

FormValidator.prototype.isValidLong = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  LNG_MAX = 16777215;
  
  if( !this.isValidNumeric(value, bIsRequired) ) {    
	return false;
  };
  
  tempLng = (value < 0)? value * (-1) : value;
  testLng = LNG_MAX - Math.ceil(tempLng);
  
  if( testLng < 0 ) {
    this.errors.push("invalid integer value (passed as 'Double').");
	return false;
  };
  
  return true;
};

FormValidator.prototype.isValidFloat = function(value, bIsRequired) {
  FLT_MAX = 4294967295;
  
  if( !this.isValidNumeric(value, bIsRequired) ) {    
	return false;
  };
  
  tempFlt = (value < 0)? value * (-1) : value;
  testFlt = FLT_MAX - Math.ceil(tempFlt);
  
  if( testFlt < 0 ) {
    this.errors.push("invalid float value (passed as 'Double').");
	return false;
  };
  
  return true;
};

FormValidator.prototype.isValidDouble = function(value, bIsRequired) {
  DBL_MAX = 18446744073709551615;

  if( !this.isValidNumeric(value, bIsRequired) ) {    
	return false;
  };
  
  tempDbl = (value < 0)? value * (-1) : value;
  testDbl = DBL_MAX - Math.ceil(tempDbl);
  
  if( testDbl < 0 ) {
    this.errors.push("invalid double value (passed as 'Double').");
	return false;
  };
  
  return true;
};

FormValidator.prototype.isValidCurrency = function(value, bIsRequired) {
  if( !this.isValidNumeric( Math.ceil(value) , bIsRequired) ) {    
	return false;
  };
  
  re = /(\.[\d]{3})$/gi;

  str = '' + value;

  if( str.match(re) ) {
    this.errors.push("has too many significant digits (decimal places).");
	return false;
  };
  
  return true;
};

FormValidator.prototype.isValidCreditcard = function(value, bIsRequired) {
  CC_MIN_LENGTH = CC_MAX_LENGTH = 16;

  if( !this.isValidNumeric( value , bIsRequired) ) {    
	return false;
  };
  
  temp = ""+value;
  
  if( temp.length < CC_MIN_LENGTH ) {
    this.errors.push("less than "+CC_MIN_LENGTH+" digits.");
	return false;
  };
  
  if( temp.length > CC_MAX_LENGTH ) {
    this.errors.push("cannot exceed "+CC_MAX_LENGTH+" digits.");
	return false;
  };

  checkCC = new Function('s', 'var i, n, c, r, t; r = ""; for (i = 0; i < s.length; i++) {c = parseInt(s.charAt(i), 10); if (c >= 0 && c <= 9) r = c + r;}; if (r.length <= 1) return false; t = ""; for (i = 0; i < r.length; i++) { c = parseInt(r.charAt(i), 10); if (i % 2 != 0) c *= 2; t = t + c; }; n = 0; for (i = 0; i < t.length; i++) {c = parseInt(t.charAt(i), 10); n = n + c; }; if (n != 0 && n % 10 == 0) return true; else return false;');
  test = checkCC(value);
  
  if( !test ) {
    this.errors.push("is Invalid (Bad Checksum).  Please Re-Enter.");
	return false;
  };
  
  return true;
};