/* Created By Grant Lester, April 2006
 ******************************************************************************
 * Description:
 *   The objective of creating this script is to allow for form checking that
 * is not intrusive in the page design or markup.  Only minimal footprints
 * will be visible in your markup, such as a one-character prefix to form input
 * names, the body onload property, and alt tags full of custom error messages.
 ******************************************************************************
 * Instructions:
 * 1. put this file in the include folder under the current directory
 * 2. include this line in the head of the document:
 *    <script type="text/javascript" src="include/forms.js"></script>
 * 3. add onload="initFormsJS();" to the body tag
 * 4. script will automatically attach to all forms on the page
 * 5. use prefixes for form element names to establish checks
 * 6. use alt property to deliver custom error messages
 ******************************************************************************/

var hiliteColor = "#FCC";
var normalColor = "#FFF";

function initFormsJS()
{ for(var I = 0; I < document.forms.length; I++)
  { document.forms[I].onsubmit = checkForm;
  }
}

/* checkForm checks to see if the form is properly filled out
 * properly filled out is defined as follows:
 *  1. All Radios whose names begin with underscore (_) must have a selection.
 *  2. All Inputs whose names begin with underscore (_) must not have blank values.
 *  3. All Inputs whose names begin with hash (#) must have integer values.
 *  4. All Inputs whose names begin with percent (%) must have integer values of length 'maxlength'.
 *  5. All Inputs whose names begin with dot (.) must have real number values.
 *  6. All Inputs whose names begin with at (@) must have email address values.
 ***************************************************************************************************/
function checkForm()
{ var valid = true;
  var alertText = "";
  cleanForm(this);

  var nameChanges = new Array();
  var alertedRadios = new Array();

  var element;
  var theInputs = this.getElementsByTagName("input");
  var skipRadios = 0;
  for(var I = 0; I < theInputs.length; I++)
  { element = theInputs[I];
    element.value = trim(element.value);

    if(element.type == "radio" && element.name.indexOf("_") == 0)
    { if(!radioIsChecked(element.name))
      { element.parentNode.style.backgroundColor = hiliteColor;
        valid = false;
        if(valueInArray(alertedRadios, element.name))
        { //do not alert a second time for the same name
        }
        else
        { if(element.alt != "")
          { alertText += element.alt + "\n";
          }
          else
          { if(skipRadios == 0){
                alert(element.name.substring(1))
                switch (element.name.substring(1))
                {
                    case "C0":  // this is the beginner training courses.
                    case "C1":              // class is optional
                    case "C2":              // class is optional
                      break;

                    case "C3" :
                      alertText +=  "A Thursday 1:30 pm - 2:45 pm class is required.\n"
                      break;
                    case "C4" :
                      alertText +=  "A Thursday 3:00 pm - 4:15 pm class is required. \n"
                      break;
                    case "C5" :
                      alertText +=  "A Friday 9:00 am - 10:15 am class is required. \n"
                      break;
                    case "C6" :
                      alertText +=  "A Friday 10:30 am - 11:45 am class is required. \n"
                      break;
                    case "C7" :
                      alertText +=  "A Friday 12:45 pm - 2:00 pm class is required. \n"
                      break;
                    case "C8" :
                      alertText +=  "A Friday 2:15 pm - 3:30 pm class is required. \n"
                      break;
                    case "C9" :
                      alertText +=  "A Friday 3:45 pm - 5:00 pm class is required. \n"
                      break;
                    default:
                      alertText += element.name.substring(1) + " must be selected.\n";
                      break;
                }
          }  //if(skipRadios = 0)
          }
          alertedRadios[alertedRadios.length] = element.name;
        }
      }  // if(!radioIsChecked(element.name))
      else{
        if ( element.name == '_C0' ) {
          skipRadios = 1;
        }
         // alert("checked radio name:" + element.name)
      }
    }

    //inputs with _ must not be blank
    else if(element.name.indexOf("_") == 0)
    { if(element.value == "" || element.value == null)
      { element.style.backgroundColor = hiliteColor;
        if(element.alt != "")
        { alertText += element.alt + "\n";
        }
        else
        { alertText += element.name.substring(1) + " must not be left blank.\n";
        }
        valid = false;
      }
      else
      { nameChanges[nameChanges.length] = element.name;
      }
    }

    //inputs with # must be integers
    else if(element.name.indexOf("#") == 0)
    { //inputs with ## must be integers with length maxlength
      if(element.name.charAt(1) == "#")
      { if(element.value.length != element.maxLength)
        { element.style.backgroundColor = hiliteColor;
          alertText += "This field requires exactly " + element.maxLength + " digits.\n";
          valid = false;
        }
        else
        { nameChanges[nameChanges.length] = element.name;
        }
      }
      if(element.value.match(/^[0-9]+$/) == null)
      { element.style.backgroundColor = hiliteColor;
        if(element.alt != "")
        { alertText += element.alt + "\n";
        }
        else
        { alertText += element.name.substring(1) + " must be a number.\n";
        }
        valid = false;
      }
      else
      { nameChanges[nameChanges.length] = element.name;
      }
    }

    //inputs with % must be integers of length 'maxlength'
    else if(element.name.indexOf("%") == 0)
    { if(element.value.length != element.maxLength || element.value.match(/^[0-9]+$/) == null)
      { element.style.backgroundColor = hiliteColor;
        if(element.alt != "")
        { alertText += element.alt + "\n";
        }
        else
        { alertText += element.name.substring(1) + " must be a number with " + element.maxLength + " digits.\n";
        }
        valid = false;
      }
      else
      { nameChanges[nameChanges.length] = element.name;
      }
    }

    //inputs with . must be real numbers
    else if(element.name.indexOf(".") == 0)
    { if(element.value.match(/^[\-]?[0-9]+[\.]?[0-9]*$/) == null)
      { element.style.backgroundColor = hiliteColor;
        if(element.alt != "")
        { alertText += element.alt + "\n";
        }
        else
        { alertText += element.name.substring(1) + " must have a numeric value.\n";
        }
        valid = false;
      }
      else
      { nameChanges[nameChanges.length] = element.name;
      }
    }

    //inputs with @ must be email addresses
    else if(element.name.indexOf("@") == 0)
    { if(element.value.match(/^[a-zA-Z0-9\.\-\_]+\@[a-zA-Z0-9\.\-\_]+\.[a-zA-Z]+$/) == null)
      { element.style.backgroundColor = hiliteColor;
        if(element.alt != "")
        { alertText += element.alt + "\n";
        }
        else
        { alertText += element.name.substring(1) + " must be an email address.\n";
        }
        valid = false;
      }
      else
      { nameChanges[nameChanges.length] = element.name;
      }
    }
  }

  if(valid)
  { for(var J = 0; J < nameChanges.length; J++)
    { element = document.getElementsByName(nameChanges[J]);
      element[0].name = element[0].name.substring(1);
    }

    for(var J = 0; J < this.length; J++)
    { element = this.elements[J];
      if(element.tagName == "INPUT" || element.tagName == "SELECT")
      { this.elements[J].value = this.elements[J].value.replace(/[']/g, "''");
        this.elements[J].value = this.elements[J].value.replace(/[^'0-9A-Za-z\ \_\@\.\,\(\)\&\-\/]/g, "#");
      }
    }
    return true;
  }
  else
  { if(alertText == '')
    {
    for(var J = 0; J < nameChanges.length; J++)
    { element = document.getElementsByName(nameChanges[J]);
      element[0].name = element[0].name.substring(1);
    }

    for(var J = 0; J < this.length; J++)
    { element = this.elements[J];
      if(element.tagName == "INPUT" || element.tagName == "SELECT")
      { this.elements[J].value = this.elements[J].value.replace(/[']/g, "''");
        this.elements[J].value = this.elements[J].value.replace(/[^'0-9A-Za-z\ \_\@\.\,\(\)\&\-\/]/g, "#");
      }
    }

      return true;
    }
    else{
      alert("The following problems were encountered:\n\n" + alertText );
      return false;
    }
  }
}

/* radioIsChecked checks to see if any item in the radio button group is checked
 * if at least one radio button in this group is checked, return true
 * otherwise, return false
 *******************************************************************************/
function radioIsChecked(radioName)
{ var radios = document.getElementsByName(radioName);

  for(var A = 0; A < radios.length; A++)
  { if(radios[A].checked)
    { return true;
    }
  }
  return false;
}

/* valueInArray checks to see if theValue is == to any element in the array theArray
 * if it matches at least one element, return true
 * otherwise, return false
 ***********************************************************************************/
function valueInArray(theArray, theValue)
{ for(var A = 0; A < theArray.length; A++)
  { if(theArray[A] == theValue)
    { return true;
    }
  }
  return false;
}

/* cleanForm removes all background coloring from form elements inside the specified form
 ****************************************************************************************/
function cleanForm(theForm)
{ var element;
  for(var A = 0; A < theForm.length; A++)
  { element = theForm.elements[A];
    if(element.tagName != "input" && element.tagName != "INPUT" && element.tagName != "select" && element.tagName != "SELECT")
    { continue;
    }
    if(element.type == "radio" && element.name.indexOf("_") == 0)
    { element.parentNode.style.backgroundColor = normalColor;
    }
    else
    { element.style.backgroundColor = normalColor;
    }
  }
}

/* trim takes a string and returns that string without leading or trailing whitespace
 ************************************************************************************/
function trim(s)
{ s = s.replace(/^[\s]+/, "");
  s = s.replace(/[\s]+$/, "");
  return s;
}

function arrayToString(theArray)
{ var theString = "";
  for(var P = 0; P < theArray.length; P++)
  { theString += P + ": " + theArray[P] + "\n";
  }
  return theString;
}
