//FIXME: Finish the validation regexps

//var ccAmExRe = /^3[47]\d{2}-\d{4}-\d{4}-\d{3}$/;
var ccAmExRe = /^3[47]\d{13}$/;
//var ccMasterRe = /^5[1-5]\d{2}-\d{4}-\d{4}-\d{4}$/;
var ccMasterRe = /^5[1-5]\d{14}$/;
//var ccVisaRe = /^4((\d{3}-\d{4}-\d{4}-\d)|(\d{3}-\d{4}-\d{4}-\d{4}))$/;
var ccVisaRe = /^4((\d{12})|(\d{15}))$/;
//var ccDiscoverRe = /^6011-\d{4}-\d{4}-\d{4}$/;
var ccDiscoverRe = /^6011\d{12}$/;
var ccDinersclubRe = /^3[068]\d{2}-\d{4}-\d{4}-\d{2}$/;
var ccenRouteRe = /^(2014-\d{4}-\d{4}-\d{3})|(2149-\d{4}-\d{4}-\d{3})$/;
var ccJCBRe = /^(3088-\d{4}-\d{4}-\d{3})|(3096-\d{4}-\d{4}-\d{3})|(3112-\d{4}-\d{4}-\d{3})|(3158-\d{4}-\d{4}-\d{3})|(3337-\d{4}-\d{4}-\d{3})|(3528-\d{4}-\d{4}-\d{3})$/;

var ccVcodeVisaMasterRe = /^\d{3}$/;
var ccVcodeAmExRe = /^\d{4}$/;

var usZipRe = /^\d{5}(?:\-\d{4})?$/;
var usStateRe = /^(?:A[LKSZR]|C[AOT]|D[EC]|F[ML]|G[AU]|HI|I[DLNA]|K[SY]|LA|M[EHDAINSOTP]|N[EVHJMYCD]|O[HKR]|P[WAR]|RI|S[CD]|T[NX]|UT|V[IAT]|W[AVIY])$/;
var emailRe = /^[\x21\x23-\x27\x2A-\x2B\x2D\x2F\w\x3D\x3F]+(?:\.[\x21\x23-\x27\x2A-\x2B\x2D\x2F\w\x3D\x3F]+)*\@\w[-\w]*(?:\.\w[-\w]*)*|\[\d{1,3}(?:\.\d{1,3}){3}\]$/;

var usPhoneRe = /^\d{3}-\d{3}\-\d{4}$/;

function checkName(prefix, req, vals, regexps)
{
  var fname = vals[0];
  var mname = vals[1];
  var lname = vals[2];

  var fnameRegExp = regexps[0];
  var mnameRegExp = regexps[1];
  var lnameRegExp = regexps[2];

  var errors = "";

  if (!fname && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "First Name is a required field.\n";
  }
  else if (fname && fnameRegExp && !fnameRegExp.test(fname))
  {
    errors += ((prefix)?(prefix + " "):("")) + "First Name contains invalid characters.\n";
  }

  if (mname && mnameRegExp && !mnameRegExp.test(mname))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Middle Name contains invalid characters.\n";
  }

  if (!lname && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Last Name is a required field.\n";
  }
  else if (lname && lnameRegExp && !lnameRegExp.test(lname))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Last Name contains invalid characters.\n";
  }

  return errors;
}

function checkPhone(prefix, req, vals, regexps)
{
  var number = vals[0];
  var numberRegExp = regexps[0];

  var errors = "";

  if (!number && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Phone number is a required field.\n";
  }
  else if (number && numberRegExp && !numberRegExp.test(number))
  {
    errors +=  ((prefix)?(prefix + " "):("")) + "Phone number format invalid. Example format: 555-123-4567.\n"; 
  }
  
  return errors;
}

function checkCompany(prefix, req, vals, regexps)
{
  var company = vals[0];
  var companyRegExp = regexps[0];

  var errors = "";

  if (!company && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Company name is a required field.\n";
  }
  else if (company && companyRegExp && !companyRegExp.test(company))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Company contains invalid characters.";
  }

  return errors;
}

function checkTaxID(prefix, req, vals, regexps)
{
  var taxid = vals[0];
  var taxidRegExp = regexps[0];

  var errors = "";

  if (!taxid && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Tax ID is a required field.\n";
  }
  else if (taxid && taxidRegExp && !taxidRegExp.test(taxid))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Tax ID format invalid.\n";
  }

  return errors;
}

function checkAddress(prefix, req, vals, regexps)
{
  var line1   = vals[0];
  var line2   = vals[1];
  var line3   = vals[2];
  var city    = vals[3];
  var state   = vals[4];
  var zip     = vals[5];
  var country = vals[6];

  var line1RegExp   = regexps[0];
  var line2RegExp   = regexps[1];
  var line3RegExp   = regexps[2];
  var cityRegExp    = regexps[3];
  var stateRegExp   = regexps[4];
  var zipRegExp     = regexps[5];
  var countryRegExp = regexps[6];

  var errors = "";

  if (!line1 && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Address Line 1 is a required field.\n";
  }
  else if (line1 && line1RegExp && line1RegExp.test(line1))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Line 1 contains invalid characters.\n";
  }

  if (line2 && line2RegExp && !line2RegExp.test(line2))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Line 2 contains invalid characters.\n";
  }

  if (line3 && line3RegExp && !line3RegExp.test(line3))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Line 3 contains invalid characters.\n";
  }

  if (!city && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "City is a required field.\n";
  }
  else if (city && cityRegExp && !cityRegExp.test(city))
  {
    errors += ((prefix)?(prefix + " "):("")) + "City is invalid.\n";
  }

  if (!state && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "State is a required field.\n";
  }
  else if (state && stateRegExp && !stateRegExp.test(state))
  {
    errors += ((prefix)?(prefix + " "):("")) + "State is invalid.\n";
  }

  if (!zip && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Zip is a required field.\n";
  }
  else if (zip && zipRegExp && !zipRegExp.test(zip))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Zip format invalid. Example format: 12345 or 12345-1234\n";
  }
    
  if (!country && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Country is a required field.\n";
  }
//    else if (country && !countryRegExp.test(country)
//    {
//	errors += "Country is invalid.");
//    }

//  if (country eq "US")
//  {
//      if (!&checkCityStateZip(city, state, zip))
//      {
//          errors += "No such City, State and Zip combination.")
//      }
//  }

  return errors;
}

function checkEmail(prefix, req, vals, regexps)
{
  var email = vals[0];
  var emailRegExp = regexps[0];

  var errors = "";

  if (!email && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Email is a required field.\n";
  }
  else if (email && emailRegExp && !emailRegExp.test(email))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Email address format is invalid.\n";
  }

  return errors;
}

function checkPass(prefix, req, vals, regexps)
{
  var pass = vals[0];
  var cpass = vals[1];

  var passRegExp = regexps[0];

  var errors = "";

  if (!pass && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Password is a required field.\n";  
  }
  else if (pass && passRegExp && passRegExp.test(pass))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Password is invalid. Password should be 5 to 8 characters long and only contain numbers or letters.\n";
  }

  if (!cpass && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Password (confirm) is a required field.\n";  
  }
  else if (cpass && passRegExp && passRegExp.test(cpass))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Password (confirm) is invalid. Password should be 5 to 8 characters long and only contain numbers or letters.\n";
  }

  if (pass != cpass)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Passwords do not match.\n";
  }

  return errors;
}

function checkPayment(prefix, req, vals, regexps)
{
  var ccname  = vals[0];
  var cctype  = vals[1];
  var ccmonth = vals[2];
  var ccyear  = vals[3];
  var ccnum   = vals[4];
  var ccvcode = vals[5];

  var ccnameRegExp = regexps[0];

  var errors = "";

  if (!ccname && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Name is a required field.\n";
  }
  else if (ccname && ccnameRegExp && !ccnameRegExp.test(ccname))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Name contains invalid characters.\n";
  }

  if (!ccnum && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Card Number is a required field.\n";
  }
    
  if (!ccvcode && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Verification Code is a required field.\n";
  }

  if (!req)
  {
    if (ccname && !ccnum && !ccvcode)
    {
      errors += ((prefix)?(prefix + " "):("")) + "Card Number is missing.\n";
      errors += ((prefix)?(prefix + " "):("")) + "Verification Code is missing.\n";
    }  
    else if (!ccname && ccnum && !ccvcode)
    {
      errors += ((prefix)?(prefix + " "):("")) + "Name is missing.\n";
      errors += ((prefix)?(prefix + " "):("")) + "Verification Code is missing.\n";
    }
    else if (!ccname && !ccnum && ccvcode)
    {
      errors += ((prefix)?(prefix + " "):("")) + "Name is missing.\n";
      errors += ((prefix)?(prefix + " "):("")) + "Card Number is missing.\n";
    }
    else if (ccname && ccnum && !ccvcode)
    {
      errors += ((prefix)?(prefix + " "):("")) + "Verification Code is missing.\n";
    }
    else if (ccname && !ccnum && ccvcode)
    {
      errors += ((prefix)?(prefix + " "):("")) + "Card Number is missing.\n";
    }
    else if (!ccname && ccnum && ccvcode)
    {
      errors += ((prefix)?(prefix + " "):("")) + "Name is missing.\n";
    }
  }

  if (ccnum && ccname && ccvcode)
  {
    if (!checkCardDate(ccmonth, ccyear))
    {
      errors += ((prefix)?(prefix + " "):("")) + "Card is expired.\n";
    }
	
    errors += checkCardType(cctype, ccnum);
	
    if(!checkCardNumber(ccnum))
    {
      errors += ((prefix)?(prefix + " "):("")) + "Card number is invalid.\n";
    }

    errors += checkCardVcode(cctype, ccvcode);
  }

  return errors;
}

function checkCardDate(ccmonth, ccyear)
{
  var today = new Date(); //get the current date
  var expiry = new Date(ccyear, ccmonth);

  if (today.getTime() > expiry.getTime())
    return false;
  else
    return true;
}

function checkCardType(cctype, ccnum)
{
  var errors = "";
  var num = ccnum.replace(/[^\d]/g, "");

  switch (cctype)
  {
    case "visa":
      if (!ccVisaRe.test(num))
      {
//        errors += "VISA card number format invalid. Card number must start with a 4 and be 13 or 16 digits long separated with dashes.\n";'
        errors += "VISA card number format invalid. Card number must start with a 4 and be 13 or 16 digits long.\n";
      }
      break;
    case "mastercard":
      if (!ccMasterRe.test(num))
      {
//        errors += "MasterCard number format invalid. Card number must start with 51, 52, 53, 54, or 55 and be 16 digits long separated with dashes.\n"
        errors += "MasterCard number format invalid. Card number must start with 51, 52, 53, 54, or 55 and be 16 digits long.\n";
      }
      break;
    case "amex":
      if (!ccAmExRe.test(num))
      {
//	errors += "American Express card number format invalid. Card number must start with 34 or 37 and be 15 digits long separated with dashes.\n";
	errors += "American Express card number format invalid. Card number must start with 34 or 37 and be 15 digits long.\n";
      }
      break;
    case "discover":
      if (!ccDiscoverRe.test(num))
      {
//	errors += "Discover card number format invalid. Card number must start with 6011 and be 16 digits long separated with dashes.\n";
	errors += "Discover card number format invalid. Card number must start with 6011 and be 16 digits long.\n";
      }
      break;
  }

  return errors;
}

function checkCardNumber(ccnum)
{
  var sum = 0;
  var digit = 0;
  var even  = false;
  //var num = ccnum.split("-").join("");
  var num = ccnum.replace(/[^\d]/g, "");

  for (var n = num.length - 1; n >= 0; n--) 
  {
    var digit = num.charAt(n);
    var digit = parseInt(digit, 10);

    if (even)
    {
      if ((digit *= 2) > 9)
        digit -= 9;
    }
        
    sum += digit;
    even = !even;
  }

  return ((sum % 10) == 0);  
}

function checkCardVcode(cctype, ccvcode)
{
  var errors = "";

  switch (cctype)
  {
    case "amex":
      if (!ccVcodeAmExRe.test(ccvcode))
      {
        errors += "Verification code contains invalid characters. An American Express verification code should be 4 digits long.\n";
      }
      break;
    case "visa":
    case "mastercard":
      if (!ccVcodeVisaMasterRe.test(ccvcode))
      {
        errors += "Verification code contains invalid characters. A VISA or MasterCard verification code should be 3 digits long.\n";
      }
      break;
  }

  return errors;
}



function isButtonGroupEmpty(theGroup)
{
  var empty = true;

  for (var i = 0; i < theGroup.length; ++i)
  {
    if (theGroup[i].checked)
      empty = false;
  }

  return empty;
}

function checkTaxInfo(prefix, req, vals, regexps)
{
  var errors = "";

  if (!req)
  {
    var isId = false;
    var taxids = vals.slice(4, 54);

    for (var i = 0; i < taxids.length; i++)
    {
      if(taxids[i])
        isId = true;
    }
    
    if (isId)
    {
      var taxErrs = "";

      taxErrs += checkTaxType("", true, vals.slice(0, 2), new Array());
      taxErrs += checkTaxDescrip("", true, vals.slice(2, 4), new Array());
      taxErrs += checkTaxSig("", true, vals.slice(55, 60), new Array());

      if (taxErrs)
      {
        errors += "\nYou entered one or more state tax IDs, however you must correct the following:\n\n";
        errors += taxErrs;
      }
    }
  }
  else
  {
      errors += checkTaxIDs("", true, vals.slice(4, 55), new Array());
      errors += checkTaxType("", true, vals.slice(0, 2), new Array());
      errors += checkTaxDescrip("", true, vals.slice(2, 4), new Array());
      errors += checkTaxSig("", true, vals.slice(55, 60), new Array());
  }
    
  return errors;
}

function checkTaxType(prefix, req, vals, regexps)
{
  var biztype   = vals[0];   
  var othertype = vals[1];

  var othertypeRegExp = regexps[0];

  var errors = "";

  if (isButtonGroupEmpty(biztype) && req)
  {
     errors += ((prefix)?(prefix + " "):("")) + "You must select one of the registered business types.\n";   
  }
  
  if (othertype && othertypeRegExp && !othertypeRegExp.test(othertype))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Other type text contains invalid characters.\n";
  }

  if (biztype[4].checked && !othertype)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Other type requires you to enter a description.\n";
  }

  return errors;
}

function checkTaxDescrip(prefix, req, vals, regexps)
{
  var bizdescrip   = vals[0];
  var goodsdescrip = vals[1];

  var errors = "";

  if (!bizdescrip && req)
  {
    errors += "You must enter a description of your " + ((prefix)?(prefix + " "):("")) + "business.\n";
  }

  if (!goodsdescrip && req)
  {
    errors += "You must enter a description of tangible property or taxable services to be purchased from the " + ((prefix)?(prefix + " "):("")) + "seller.\n";
  }

  return errors;
}

function checkTaxIDs(prefix, req, vals, regexps)
{
  var errors = "";

  var isId = false;

  for (var i = 0; i < vals.length; i++)
  {
    if(vals[i])
      isId = true;
  }

  if (!isId && req)
  {	
    errors += "You must enter at least one " + ((prefix)?(prefix + " "):("")) + "State Registration, " +((prefix)?(prefix + " "):("")) + "Sellers Permit, or " +((prefix)?(prefix + " "):("")) + "ID Number.\n";
  }

  return errors;
}

function checkTaxSig(prefix, req, vals, regexps)
{
  var agree = vals[0];
  var fname = vals[1];
  var mname = vals[2];
  var lname = vals[3];
  var title = vals[4];

  var fnameRegExp = regexps[0];
  var mnameRegExp = regexps[1];
  var lnameRegExp = regexps[2];
  var titleRegExp = regexps[3];

  var errors = "";

  if (!agree.checked && req)
  {
    errors += "You must check the " + ((prefix)?(prefix + " "):("")) + "box in the Tax Signature section to confirm you have read and agree with the statement.\n";
  }

  if (!fname && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "First Name in the Tax Signature section is a required field.\n";
  }
  else if (fname && fnameRegExp && fnameRegExp.test(fname))
  {
    errors += ((prefix)?(prefix + " "):("")) + "First Name in the Tax Signature section contains invalid characters.\n";
  }

  if (mname && mnameRegExp && mnameRegExp.test(mname))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Middle Name in the Tax Signature section contains invalid characters.\n";
  }

  if (!lname && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Last Name in the Tax Signature section is a required field.\n";
  }
  else if (lname && lnameRegExp && lnameRegExp.test(lname))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Last Name in the Tax Signature section contains invalid characters.\n";
  }

  if (!title && req)
  {
    errors += ((prefix)?(prefix + " "):("")) + "Title in the Tax Signature section is a required field.\n";
  }
  else if (title && titleRegExp && titleRegExp.test(title))
  {
    errors += ((prefix)?(prefix + " "):("")) + "Title in the Tax Signature section contains invalid characters.\n";
  }

  return errors;
}