
function validate(fRef) {
  var req = required[fRef.id];
  var reqFields = [];
  var reqFields2 = [];

  for (var field in req) {
    $('#'+field).removeClass('fixme')

    if ((fRef.elements[field].value == '') || (fRef.elements[field].value == 'error')) {
      reqFields.push(field);
    }

    else if ((field == 'ccnum') && ((!fRef.elements[field].value.replace(/\D/g,'').match(/\d{15}/)) || (fRef.elements[field].value.match(/[^ \d]/)) || (!luhncheck(fRef.elements[field].value)))) {
      reqFields2.push(field);
    }
    else if ((field == 'ccexp') && (!fRef.elements[field].value.match(/^\d{1,2}\/\d{2}$/))) {
      reqFields2.push(field);
    }
    else if (field.match(/email$/)) {
      if (fRef.elements[field].value == 'your@email.address') {
        fRef.elements[field].focus();
        return(false);
      }
      else {
        var bademail = false;
        if (window.RegExp) {
          var reg1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)|(\s)/;                         // not valid
          var reg2 = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/; // valid

          if (reg1.test(fRef.elements[field].value) || !reg2.test(fRef.elements[field].value)) {
            bademail = true;
          }
        }
        else if ((fRef.elements[field].value.indexOf('@') + '' == '-1') || (fRef.elements[field].value.indexOf('.') + '' == '-1')) {
          bademail = true;
        }
        if (bademail) {
          reqFields2.push(field);
        }
      }
    }
  }

  var $fmsg = $('.fmsg',fRef);
  if ((reqFields.length) || (reqFields2.length)) {
    var rmsg = "Please fill out these form fields - \n\n";
    var schar = ($fmsg.length > 0)?', ':'\n';
    var echar = ($fmsg.length > 0)?'. ':'\n';
    var rchar = ($fmsg.length > 0)?'':'\n';
    for (var i = 0; i < reqFields.length; i++) {
      fixme(reqFields[i]);
      if (i < 5) {
        if (i > 0) { rmsg += schar; }
        rmsg += req[reqFields[i]];
      }
      else if (i == 5) {
        rmsg += schar;
        rmsg += " and other fields highlighted below";
      }
    }
    var flag = (reqFields.length > 0)?true:false;
    if ((flag) && (reqFields2.length > 0)) { rmsg += echar+rchar+rchar; }
    for (var i = 0; i < reqFields2.length; i++) {
      fixme(reqFields2[i]);
      if (i > 0) { rmsg += '. '; }
      if (reqFields2[i] == 'email') { rmsg += secondly(flag,"Your email address has something wrong"); }
      else if (reqFields2[i] == 'ccnum') { rmsg += secondly(flag,"Please check your credit card number - it fails basic validation"); }
      else if (reqFields2[i] == 'ccexp') { rmsg += secondly(flag,"Please check your credit card expiration date"); }
      if (!i) { flag = false; }
    }
    rmsg += echar+rchar+'Thank you.';
    if ($fmsg.length > 0) {
      if ($.scrollTo) {
        $fmsg.fadeOut(100,function() {
          $.scrollTo(fRef,{duration:300,onAfter:function() {
            $fmsg.slideUp(300,function() {
              $fmsg.html('<p>'+rmsg+'</p>');
              $fmsg.fadeTo(1,0).slideDown(300,function() { $(this).fadeTo(300,1); });
            });
          }});
        });
      }
      else {
        $fmsg.slideUp(300,function() {
          $fmsg.html('<p>'+rmsg+'</p>');
          $fmsg.fadeTo(1,0).slideDown(300,function() { $(this).fadeTo(300,1); });
        });
      }
    }
    else { alert(rmsg); }
    return(false);
  }
  else {
    if ($fmsg.length > 0) { $fmsg.slideUp(300); }
    return(true);
  }
}

function secondly(flag,msg) {
  return((flag === false)?msg:'Also, '+msg.charAt(0).toLowerCase()+msg.substring(1,msg.length));
}

function fixme(field) {
  $('#'+field).addClass('fixme');
}

function formatemail(emailRef) {
  emailRef.value = emailRef.value.replace(/\s/g,'').replace(/\,/g,'.').replace(/\#/g,'@').replace(/\.+/g,'.');
}

function luhncheck(num) {
  var num = num.replace(/\D/g,'');
  var parity = (num.length % 2);
  var total = 0;

  for (var i = 0; i < num.length; i++) {
    var digit = num.charAt(i);
    if ((i % 2) == parity) {
      digit *= 2;
      if (digit > 9) { digit -= 9; }
    }
    total += parseFloat(digit);
  }

  if ((total % 10) == 0) { return true; }
  else { return false; }
}
