// Created by Rob Siklos
// Copyright Rob Siklos, April 2005.

// Licensed for free use and distribution


// validation types
var VALI_STRING    = 1;  // make sure there is a value
var VALI_NUMBER    = 2;  // if there is a value, make sure it is a number
var VALI_RADIO     = 3;  // make sure there is a selection
var VALI_CHECKBOX  = 4;  // make sure there is a selection
var VALI_DROPDOWN  = 5;  // make sure there is a non-empty selection
var VALI_VERSION   = 6;  // make sure there is a proper version (e.g. 5.1.2.3)
var VALI_REGEXP    = 7;  // if there is a value, make sure it matches the provided regexp
var VALI_DATE      = 8;  // make sure the value can be parsed as a valid date in the format: YYYY-mm-dd hh:mm:ss
var VALI_DATE2     = 9;  // same as above, but the format is dd-Mmm-yyyy
var VALI_DATE3     = 10; // make sure the value can be parsed as a valid date in the format: YYYY-mm-dd
var VALI_EMAIL     = 11; // if there is a value, make sure it is a proper e-mail address
var VALI_EMAILLIST = 12; // if there is a value, make sure it is a proper e-mail list
var VALI_EMAILLIST_GROUP = 13; // if there is a value, make sure it is a colon-delimited
                               // string of valid e-mail lists
var VALI_INRANGE   = 14; // if there is a value, make sure it is numeric and between
                         // the provided min and max (inclusive).  Min and max are
                         // provided as the 4th parameter, as an array.
var VALI_INT       = 15;  // if there is a value, make sure it is a integer

function checkObj(elem_obj, elem_id) {
  if (elem_obj == null) {
    alert ("SCRIPT ERROR: invalid object: " + elem_id);
    return false;
  }
  return true;
}

function trim(sInString) {
  sInString = sInString.replace( /^\s+/g, "" );// strip leading
  return sInString.replace( /\s+$/g, "" );// strip trailing
}

/* validate()
 *
 * Description: Validates form data according to the validation configuration
 *              stored in the global "validations" variable.
 * Params:      none
 * Returns:     true if validation passes, false otherwise
 * Precondition: validations global variable must exist
 *
 * Example "validations" structure:
 *   var validations = new Array(
 *      Array('Submitter' , "Submitter's Name", VALI_STRING)
 *     ,Array('Company'   , "Company Name"    , VALI_STRING)
 *     ,Array('Email'     , "E-mail"          , VALI_STRING)
 *     ,Array('Email'     , "E-mail"          , VALI_EMAIL)
 *     ,Array('Cc'        , "Cc"              , VALI_EMAILLIST)
 *     ,Array('Phone'     , "Phone Number"    , VALI_STRING)
 *     ,Array('Issue_Type', "Issue Type"      , VALI_RADIO)
 *     ,Array('Impact'    , "Impact"          , VALI_RADIO)
 *     ,Array('Product'   , "Product"         , VALI_DROPDOWN)
 *     ,Array('Version[]' , "Version"         , VALI_VERSION)
 *     ,Array('Synopsis'  , "Synopsis"        , VALI_STRING)
 *     ,Array('Details'   , "Details"         , VALI_STRING)
 *     ,Array('percent'   , "Percent"         , VALI_INRANGE, Array(0,100))
 *   );
 *
 * Where the nested array parameters are:
 *   1) DOM id of the element to check
 *   2) Element Description
 *   3) Type of Validation
 */
function validate() {
  var i, j;
  var item;

  if (!window.validations) {
    alert("SCRIPT ERROR: form validation configuration is invalid or does not exist.\n" +
          "\n" +
          "Please inform the administrator.");
    return false;
  }

  for (i = 0; item = validations[i]; ++i) {
    var elem_id    = item[0];
    var elem_label = item[1];
    var cond_type  = item[2];

    if (!elem_id) break;
    if (!elem_label) elem_label = elem_id;
    if (!cond_type) {
      alert("SCRIPT ERROR: no condition type specified in validation routine:\n" +
            "elem_id = " + elem_id + "\nelem_label = " + elem_label);
      return false;
    }

    switch (cond_type) {
      case VALI_STRING:
      case VALI_DROPDOWN:
        var elem_obj = document.getElementById(elem_id);
        if (!checkObj(elem_obj, elem_id)) return false;

        if (elem_obj.value == null || elem_obj.value == '') {
          alert("Please enter a value for \"" + elem_label + "\".");
          elem_obj.focus();
          return false;
        }
        break;
      case VALI_RADIO:
      case VALI_CHECKBOX:
        var elem_arr = document.getElementsByName(elem_id);
        var isChecked = false;
        var k;
        for (k = 0; radio_obj = elem_arr[k]; ++k){
          if (radio_obj.checked) {
            isChecked = true;
            break;
          }
        }
        if (!isChecked) {
          alert("Please select a value for \"" + elem_label + "\".");
          elem_arr[0].focus();
          return false;
        }
        break;
      case VALI_VERSION:
        var elem_arr = document.getElementsByName(elem_id);
        var k;
        var invalid = false;
        for (k = 0; txt_obj = elem_arr[k]; ++k){
          if (txt_obj.value == null || txt_obj.value == '' || !(/^\d{1,3}$/.test(txt_obj.value))) {
            invalid = true;
            break;
          }
        }
        if (invalid) {
          alert("Please specify a valid version.\n\nExample: 5.4.8.24");
          elem_arr[0].focus();
          return false;
        }
        break;
      case VALI_REGEXP:
        var elem_obj = document.getElementById(elem_id);
        if (!checkObj(elem_obj, elem_id)) return false;

        var val = elem_obj.value;
        if (val) {
          if (!item[3].test(elem_obj.value)) {
            alert("Please enter a valid value for \"" + elem_label + "\".");
            elem_obj.focus();
            return false;
          }
        }
        break;
      case VALI_DATE:

        var elem_obj = document.getElementById(elem_id);
        if (!checkObj(elem_obj, elem_id)) return false;

        var timevalue;
        timevalue = elem_obj.value
        dateRegex = /^[1-2]\d{3}-([0][1-9]|[1][0-2])-([0][1-9]|[1-2]\d|[3][0-1]) ([0-1]\d|[2][0-3]):[0-5]\d:[0-5]\d$/;
        //dateRegex = /^a+/;
        if( !timevalue.match( dateRegex )){
          alert("'" + elem_obj.value + "' is not a valid date.");
          elem_obj.focus();
          return false;
        }


        break;
      case VALI_DATE2:
        var elem_obj = document.getElementById(elem_id);
        if (!checkObj(elem_obj, elem_id)) return false;

        var months_short = [
            'jan',
            'feb',
            'mar',
            'apr',
            'may',
            'jun',
            'jul',
            'aug',
            'sep',
            'oct',
            'nov',
            'dec'
        ];

        var err = false;
        var arr = elem_obj.value.split('-');
        var day = arr[0];
        var month = arr[1];
        var year = arr[2];
        if (!Date.parse(month + " " + day + ", " + year)) {
          err = true;
          alert('err=true on date.parse');
        }
        else {
          var d = new Date(month + " " + day + ", " + year);
          if ((day != d.getDate())
              || (month.toLowerCase() != months_short[d.getMonth()])
              || ((year != d.getYear()) && (year != d.getYear() + 1900) )) {
            err = true;
          }

        }
        if (err) {
          alert("'" + elem_obj.value + "' is not a valid date.");
          elem_obj.focus();
          return false;
        }
        break;
      case VALI_DATE3:

        var elem_obj = document.getElementById(elem_id);
        if (!checkObj(elem_obj, elem_id)) return false;

        var timevalue;
        timevalue = elem_obj.value
        dateRegex = /^[1-2]\d{3}-([0][1-9]|[1][0-2])-([0][1-9]|[1-2]\d|[3][0-1])$/;
        if( !timevalue.match( dateRegex )){
          alert("'" + elem_obj.value + "' is not a valid date.");
          elem_obj.focus();
          return false;
        }


        break;
      case VALI_EMAIL:
        /* if a value is specified, make sure it is a valid plain e-mail address
         * acceptable e-mail address formats:
         *    e.g. joe.user@example.com
         */
        var elem_obj = document.getElementById(elem_id);
        if (!checkObj(elem_obj, elem_id)) return false;


        var val = elem_obj.value;
        if (val) {
          if (!/^\s*[\w\.\+\-=]+@[\w\.\-]+\.[\w\-]+\s*$/.test(val)) {
            alert("'" + val + "' is not a valid e-mail address.\n\n" +
                  "The e-mail address must be in the following format:\n" +
                  "    joe.example@example.com\n");
            elem_obj.focus();
            return false;
          }
        }
        break;
      case VALI_EMAILLIST:
        var elem_obj = document.getElementById(elem_id);
        if (!checkObj(elem_obj, elem_id)) return false;

        if (elem_obj.value) {
          var arr = elem_obj.value.split(",");
          var k;
          var val;
          for (k = 0; val = arr[k]; ++k) {
            if (!/^\s*[\w\.\+\-=]+@[\w\.\-]+\.[\w\-]+\s*$/.test(val)) {
              alert("The '" + elem_label + "' field contains the following invalid e-mail address: '" + val + "'.\n" +
                    "\n" +
                    "The e-mail address must be in the following format:\n" +
                    "    joe.example@example.com\n" +
                    "\n" +
                    "Email addresses in a list must be separated by commas."
                    );
              elem_obj.focus();
              return false;
            }
          }
        }
        break;
      case VALI_EMAILLIST_GROUP:
        var elem_obj = document.getElementById(elem_id);
        if (!checkObj(elem_obj, elem_id)) return false;

        if (!elem_obj.value) break;

        var j, k;
        var val, item;
        var group_arr = elem_obj.value.split(":");
        for (j = 0; item = group_arr[j]; ++j) {
          var arr = item.split(",");
          for (k = 0; val = arr[k]; ++k) {
            if (!/^\s*[\w\.\+\-=]+@[\w\.\-]+\.[\w\-]+\s*$/.test(val)) {
              alert("The '" + elem_label + "' field contains the following invalid e-mail address: '" + val + "'.\n" +
                    "\n" +
                    "The e-mail address must be in the following format:\n" +
                    "    joe.example@example.com\n" +
                    "\n" +
                    "Email addresses in a list must be separated by commas."
                    );
              elem_obj.focus();
              return false;
            }
          }
        }

        break;
      case VALI_NUMBER:
         var elem_obj = document.getElementById(elem_id);
         if (!checkObj(elem_obj, elem_id)) return false;

         var val = elem_obj.value;
         if (!val) {
             break;
         }
         if ( isNaN(val) ){
             alert("'" + elem_obj.value + "' is not a valid number.");
             elem_obj.focus();
             return false;
         }

         break;
      case VALI_INT:
         var elem_obj = document.getElementById(elem_id);
         if (!checkObj(elem_obj, elem_id)) return false;

         var val = elem_obj.value;
         if (!val) {
             break;
         }

         var value;
         value = elem_obj.value
         intRegex = /^[+|-]?\d+$/;
         if( !value.match( intRegex )){
           alert("'" + elem_obj.value + "' is not a valid integer.");
           elem_obj.focus();
           return false;
         }
         break;

      case VALI_INRANGE:
        var elem_obj = document.getElementById(elem_id);
        if (!checkObj(elem_obj, elem_id)) return false;

        var val = elem_obj.value;
        if (!val) {
          break;
        }
        var arr = item[3];
        var minval = arr[0];
        var maxval = arr[1];
        if ( isNaN(val) ){
          alert("'" + elem_obj.value + "' is not a valid number.");
          elem_obj.focus();
          return false;
        }
        if (val < minval || val > maxval) {
          alert("'" + elem_label + "' must be between " + minval + " and " + maxval + ".");
          elem_obj.focus();
          return false;
        }
        break;

      default:
        alert("SCRIPT ERROR: invalid condition type specified in validation routine\n" +
              "elem_id = " + elem_id + "\n" +
              "elem_label = " + elem_label + "\n" +
              "cond_type = " + cond_type);
        return false;
        break;
    }
  }
  return true;
}

/* for debugging purposes - print out all the validations contained
 * in the provided array
 */
function showValidations() {
  var i, j;
  var item;

  var txt = "";
  for (i = 0; item = validations[i]; ++i) {
    var elem_id    = item[0];
    var elem_label = item[1];
    var cond_type  = item[2];

    txt += elem_id + ", " + elem_label + ', ' + cond_type + "\n";
  }

  alert("Debug: \n" + txt);

  return true;
}
