/*
 * Power Validator Script
 * By Dell Sala
 */

function validateForm(f, required, formatted) {

   // f: the form to check
   // required: array of field names to be checked for empty input
   // formatted: array of field names to be checked for special formatting
   // formatChecker: function for checking 
   
   try {

   var errorList = [];
   
   // this loop tests required fields
   for (var i=0; i < required.length; i++) {
      var field = f[required[i]];
      if (field == null) {                                     // field missing from form
         alert("Required field '" + required[i] +
            "' does not exists. Terminating form validation.");
         return false;
      } else if (field.type === undefined) {                  // checkbox/radio input found
         if (! hasCheckedElements(field)) {
            errorList.push({
               name: field[0].name,
               inputType: 'checkbox',
               errorType: 'empty',
               message: "unchecked option: " + field[0].name
            });
         }
      } else if (field.options !== undefined) {                   // select input found
         if (! hasCheckedElements(field.options)) {
            errorList.push({
               name: field.name,
               inputType: 'select',
               errorType: 'empty',
               message: "unselected option: " + field.name
            });
         }
      } else {                                                    // string input found
         //alert("Testing simple string field: " + field.name);  // DEBUG
         if (isEmpty(field.value)) {
            errorList.push({
               name: field.name,
               inputType: 'text',
               errorType: 'empty',
               message: "empty field: " + field.name
            });
         }
      }
   }
   
   // this loop tests formatted fields
   // to add special format checking, add a new case to switch
   for (var i=0; i < formatted.length; i++) {
      var field = formatted[i];
      if (f[field] == null) {
         alert("Formatted field '" + field +
            "' does not exists. Terminating form validation.");
         return false;
      }
      switch (field) {
         case 'email':
            // this case checks for a valid email string
            if ((! isEmpty(f[field].value)) && ! isValidEmail(f[field].value)) {
               errorList.push({
                  name: field,
                  inputType: 'text',
                  errorType: 'format',
                  formatType: 'email',
                  message: "invalid email format: " + field
               });
            }
            break;
         case 'pickup_phone_home':
         case 'delivery_phone_home':
         case 'phone_home':
         case 'phone_work':
         case 'phone_cell':
            if ((!isEmpty(f[field].value)) && ! isValidPhone(f[field].value)) {
               errorList.push({
                  name: field,
                  inputType: 'text',
                  errorType: 'format',
                  formatType: 'phone',
                  message: "invalid phone number format: " + field
               });
            }
            break;
         case 'vehicle_running_condition':
            if (f.vehicle_running[0].checked && ! hasCheckedElements(f[field].options)) {
               errorList.push({
                  name: field,
                  inputType: 'select',
                  errorType: 'format',
                  formatType: 'phone',
                  message: "unselect select field: " + field
               });
            }
            break;
         case 'agree':
            if (hasCheckedElements(f[field]) && ! f[field][0].checked) {
               alert("You must agree the Terms and Conditions for your order to processed.");
               return false;
            }
            break;
         default:
            alert("Formatted field '" + field +
               "' has not been assigned validation code. Termination form validation.");
            return false;
            break;                              
      }
   }

   // reset background colors to none
   allFields = required.concat(formatted);
   //alert(allFields.toString());
   for (var i=0; i < allFields.length; i++) {
      //if (f[allFields[i]].parentNode == null) { //DEBUG
      //   alert(f[allFields[i]]);                //DEBUG
      //}                                         //DEBUG
      var parent = f[allFields[i]].parentNode;
      parent = parent != null ? parent : f[allFields[i]][0].parentNode;
      //alert(parent);
      parent.style.backgroundColor = 'white';
   }

   if (errorList.length == 0) {
      //alert("Form input valid.");  // DEBUG
      return true;
   } else {
      if (handleErrors == null) {            // look for handleErrors() function
         alert("Form has invalid input.");
      } else {
         handleErrors(f, errorList);
      }
      return false;
   }

   } catch (ex) {
      alert(ex);
      return false;
   }
}

// Defines how form submission errors should be handled.
function handleErrors(f, e) {
   // f: form target
   // e: error list
   var errorMessage = "";
   for (var i=0; i < e.length; i++) {
      
      errorMessage += e[i].message + "\n";
      
      var parent = f[e[i].name].parentNode;
      parent = parent != null ? parent : f[e[i].name][0].parentNode;
      //alert(e[i].name + "'s parent: " + parent);
      parent.style.backgroundColor = 'red';
   }
   //alert("There are some problems with your submission. Fields with problems are highlighted in red.");
   alert("There are some problems with your submission:\n\n" + errorMessage);
}


// --- helper functions for basic field formatting --- //

function isEmpty(str) {
      //alert('isEmpty(' + str + ')'); // DEBUG
      //alert("match results: " + str.match(/^\s*$/i)); // DEBUG
      if (str.match(/^\s*$/i) == null) {
         return false;
      } else {
         return true;
      }

}

function hasCheckedElements(checkboxes) {
   var totalChecked = 0;
   for (var j=0; j < checkboxes.length; j++) {
      if (checkboxes[j].checked || (checkboxes[j].selected && (! isEmpty(checkboxes[j].value))) ) {
         totalChecked++;
      }
   }
   return totalChecked;
}

function isValidEmail(str) {
   //alert('isValidEmail(' + str + ')');
   if (str.match(/^\s*[._a-z0-9-]+@[.a-z0-9-]+[.]{1}[a-z]{2,4}\s*$/gi) == null) {
      return false;
   } else {
      return true;
   }
}

function isValidPhone(str) {
   if (str.match(/^\s*1?[- ]?\(?\d{3}\)?[- ]?\d{3}[- ]?\d{4}\s*$/g) == null) {
      return false;
   } else {
      return true;
   }
}

