<!--
//------------------------------------------------------------------------------
//
// validateFields
//
//------------------------------------------------------------------------------
//
// Field types are defined as follows:
//    0 - Text <input>
//    1 - Money
//    2 - Drop Down (single <select>)
//    4 - TextArea
//    5 - List Box (multiple <select>)
//    6 - Integer <input type=text>
//    7 - Decimal <input type=text>
//    8 - Numbers <input type=text>
//    9 - Equality, the two values must be equal (passwords)
//   10 - Text Dependence (if the referenced text field has a value)
//   11 - At Least X Checkbox/Radios (minimum number of items must be selected)
//   12 - Range, value A must be less than or equal to value B
//   13 - Aggregated upper limit - value A (Ref) must be less than or equal to 
//        value B (UL)
//   14 - File type - the file name passed in value A (objFld.value) must be of 
//        one of the types in the array passed in value B (Ref)
//   15 - Money unformatted or formatted correctly with upper limit
//   16 - Date range - date "From" must be less than or equal to date "To"
//   17 - Date - must be a valid date
//   18 - Word count must not exceed the upper limit
//   19 - Date range from date strings - can have a from without a to
//   20 - Valid email according to specs
//   21 - A string stripped of non numeric chars should contain a min # of 
//        digits
//   22 - Drop Down (single select) - selectedIndex > 0
//   23 - A string stripped of non alpha-numeric chars should contain a min # of 
//        alpha-num chars
//   24 - Inequality - the two values must be different
//   25 - Minimum/Maximum List items in multiple list box (not selected)
//   99 - Reserved - does nothing (used for stubbing where needed)
//
//------------------------------------------------------------------------------
//
// History
//
// Date   Author        Description
// ------ ------------- --------------------------------------------------------
// 051702 P Cardillo    Creation
//
//------------------------------------------------------------------------------

function validateFields( aobjFlds ) {
  var i = 0;
  var objFld;
  var intLen = 0;
  var strTemp = '';
  var intTemp = 0;
  var intStatus = 0;
  var intIndex = 0;
  var intGoFld = -1;
  var intSelected = 0;
  var strWarnMessage = '';
  var strErrMsg = '';
  var blnSuccess = false;
  var intChecks = 0;
  var strCtrlType = '';
  var strPlural = '';
  var strForward = '';

  var strMsgs = new Array
    ( 
    '',
    '',
    'The following fields contain invalid values and need to be corrected before continuing:\n\n'
    );

  //--------------------------------------------------------------------------
  // Check the field validation rules
  //--------------------------------------------------------------------------

  for ( intIndex=0; intIndex < aobjFlds.length; intIndex++ ) {

    objFld = aobjFlds[intIndex];

    intStatus = 0;
    switch ( objFld.Type ) {
/*
      case 1: // Money
        vntTemp = trim(aobjFlds[intIndex].Fld.value).length;
        if ( vntTemp < aobjFlds[intIndex].LL ) {
          if ( intGoFld == -1 ) intGoFld = intIndex;
          strErrMsg += aobjFlds[intIndex].Txt + "\n";
          }
        else {
          vntTemp = aobjFlds[intIndex].Fld.value;
          vntTemp = sCharStrip( sCharStrip( sCharStrip(vntTemp, '$'), ',' ), '.' );
          if ( ! bNumbers(vntTemp) || isNaN(parseInt(vntTemp)) )  {
            if ( intGoFld == -1 ) intGoFld = intIndex;
            strErrMsg += aobjFlds[intIndex].Txt + ' - (enter a valid money value)\n';
            }
          }
        break;

      case 4: // TextArea
        vntTemp = trim(aobjFlds[intIndex].Fld.value).length;
        if ( vntTemp < aobjFlds[intIndex].LL ) {
          if ( intGoFld == -1 ) intGoFld = intIndex;
          strErrMsg += aobjFlds[intIndex].Txt + "\n";
          }
        if ( vntTemp > aobjFlds[intIndex].UL )
          strWarnMessage += aobjFlds[intIndex].Txt + ' - ' + vntTemp + ' (' + aobjFlds[intIndex].UL + ' limit)\n';
        break;

      case 5: // List Box (multiple select)
        vntTemp = aobjFlds[intIndex].Fld.options.length;
        for ( i=0, intSelected=0; i<vntTemp; i++ ) 
          if ( aobjFlds[intIndex].Fld.options[i].selected ) 
            intSelected++;
        if ( (intSelected < aobjFlds[intIndex].LL) ||
             (intSelected > aobjFlds[intIndex].UL) ) {
          if ( intGoFld == -1 ) intGoFld = intIndex;
          strErrMsg += aobjFlds[intIndex].Txt + ' - (select at least ' + aobjFlds[intIndex].LL + ' but not more than ' + aobjFlds[intIndex].UL + ')\n';
          }
        break;
*/
      case 0: // Plain text
        strTemp = trim( objFld.Fld.value );
        intLen = strTemp.length;
        if ( ! checkRequired(intLen, objFld.Req) )
          intStatus = 1;
        else 
          if ( intLen != 0 )
            if ( ! checkMinMax(intLen, objFld.Min, objFld.Max) )
              intStatus = 2;
        break;
      
      case 1: // Money
        strTemp = trim( objFld.Fld.value );
        intLen = strTemp.length;
        if ( ! checkRequired(intLen, objFld.Req) )  {
          intStatus = 1;
        }
        else  { 
          //strTemp = sCharStrip( sCharStrip( sCharStrip(strTemp, '$'), ',' ), '.' );
          strTemp = sCharStrip( sCharStrip(strTemp, '$'), ',' );
          if ( countChars( strTemp, '.') > 0 ) {
              intStatus = 2;
          }          
          else  {  
            if ( isNaN(strTemp) ) {
              intStatus = 3;
            }
            else  {
            intLen = strTemp.length;
              if ( ! checkMinMax(intLen, objFld.Min, objFld.Max) )  {
                intStatus = 4;
              }
            }
          }
        }
        break;
            
      case 2: // Drop Down (single select)
        strTemp = objFld.Fld[objFld.Fld.selectedIndex].value;
        intLen = ( (strTemp == objFld.Trig) ? 0 : strTemp.length );
        if ( ! checkRequired(intLen, objFld.Req) )
          intStatus = 1;
        break;

      case 6: // Integer
        strTemp = trim( objFld.Fld.value );
        intLen = strTemp.length;
        if ( ! checkRequired(intLen, objFld.Req) )
          intStatus = 1;
        else
          if ( intLen != 0 )
            if ( ! checkMinMax(intLen, objFld.Min, objFld.Max) )
              intStatus = 2;
            else 
              if ( ! isInteger(strTemp) ) 
                intStatus = 3;
              else 
                if ( ! inRange( strToInt(strTemp), objFld.LL, objFld.UL ) ) 
                  if ( objFld.Val == 1 ) {
                    intStatus = 5;
                  }
                  else
                  { 
                    intStatus = 4;
                  }
        break;

      case 7: // Decimal
        strTemp = trim( objFld.Fld.value );
        intLen = strTemp.length;
        if ( ! checkRequired(intLen, objFld.Req) )
          intStatus = 1;
        else
          if ( intLen != 0 )
            if ( ! checkMinMax(intLen, objFld.Min, objFld.Max) )
              intStatus = 2;
            else
              if ( ! isDecimal(strTemp, objFld.Prec, objFld.Scale) )
                intStatus = 3;
              else
                if ( ! inRange( strTemp, objFld.LL, objFld.UL ) )
                  intStatus = 4;
        break;

      case 8: // Numbers - checks that each character in the field is a numeric digit
        strTemp = trim( objFld.Fld.value );
        intLen = strTemp.length;
        if ( ! checkRequired(intLen, objFld.Req) ) 
          intStatus = 1;
        else 
          if ( intLen != 0 )
            if ( ! checkMinMax(intLen, objFld.Min, objFld.Max) )
              intStatus = 2;
            else if ( ! isInteger(strTemp) )
              intStatus = 3;
        break;

      case 9: // Equality - the two values must be equal
        strTemp = trim( objFld.Fld.value );
        if ( strTemp != trim(objFld.Ref.value) )
          intStatus = 1;
        break;

      case 10: // Text Dependence (if the referenced text field has a value)
        strTemp = trim( objFld.Fld.value );
        intLen = strTemp.length;
        if ( trim(objFld.Ref.value).length > 0 )
          if ( intLen == 0 )
            intStatus = 1;
        break;

      case 11: // At least X checkbox/radios (minimum number of items must be selected)
        intChecks = 0;
        if ( objFld.Fld.length == null ) {
          if ( objFld.Fld.checked ) intChecks++;
          }
        else
          for ( intChkBoxes=0; intChkBoxes<objFld.Fld.length; intChkBoxes++ ) {
            if ( objFld.Fld[intChkBoxes].checked ) intChecks++;
            }

        if ( intChecks < objFld.Min ) 
          intStatus = 1;
        break;

      case 12: // Range check - value A (Fld) must be less than or equal to value B (Ref)
        if ( objFld.Fld.type == 'select-one' ) {
          if ( parseFloat(objFld.Fld.options[objFld.Fld.selectedIndex].value) > parseFloat(objFld.Ref.options[objFld.Ref.selectedIndex].value) )
            intStatus = 1;
          }
        else {
          if ( parseFloat(objFld.Fld.value) > parseFloat(objFld.Ref.value) )
            intStatus = 1;
          }

        break;
        
      case 13: // Aggregated upper limit check - value A (Ref) must be less than or equal to value B (UL)
      
        if ( parseInt(objFld.Ref) > parseInt(objFld.UL) )
          intStatus = 1;
         
        break;
        
      case 14: // File type check - the file name passed in value A (objFld.value) must be of one of the types in the array passed in value B (Ref)
        
        strTemp = trim(objFld.Fld.value);
        if ( (strTemp != "") && (objFld.Ref.length > 0) ) {
          intStatus = 1;
          for (i=0; i<objFld.Ref.length; i++)
            if ((strTemp.substr(strTemp.length - 3).toLowerCase()) == objFld.Ref[i])
              intStatus = 0;
        }  
        break;
        
      case 15: // Money with limit
        
        strTemp = trim( objFld.Fld.value );
        intLen = strTemp.length;
        var objREReplace = /[\$,]/g;
        var objREMoney = /\d{1,3}(,\d{3})*(\.\d{2})*/;
        var sngUpperLimit = objFld.UL.replace(objREReplace,"");
        
        if ( ! checkRequired(intLen, objFld.Req) )
          intStatus = 1;
        else
          if ( intLen != 0 ) 
          {
            var iDecimal = strTemp.lastIndexOf(".");
            var iComma = strTemp.lastIndexOf(","); 
            if ( (iDecimal > -1) || (iComma > -1) )  //then check for valid format
              if (! objREMoney.exec(strTemp))
                intStatus = 2;
              else
                strTemp = strTemp.replace(objREReplace,"");
            
            if ( intStatus != 2)
              if ( isNaN(strTemp) )
                intStatus = 3;
              else 
                if ( parseFloat(strTemp) > parseFloat(sngUpperLimit) )
                  intStatus = 4;
             
          }
        break;

      case 16: // Date range - date "From" must be less than or equal to date "to"
        if ( (objFld.Ref.getTime() - objFld.Ref2.getTime()) > 0 )
          intStatus = 1;
        break;
      
      case 17: // Date - must be a valid date
        
        strTemp = trim( objFld.Fld.value );
        intLen = strTemp.length;
        
        if ( ! checkRequired (intLen, objFld.Req) )
          intStatus = 1;
        else
          if ( intLen != 0 )
            if ( ! bIsDate(strTemp) )
              intStatus = 2;
        break;
      
      case 18: // Word count must not exceed the upper limit
        
        strTemp = trim( objFld.Fld.value );
        
        if (strTemp.length>0) 
          if (strTemp.match(/(\S\s)|(\S$)/g).length > objFld.UL)
            intStatus = 1;
        
        break;
      
      case 19: // Date range from date strings - can have a from without a to
      
        strTemp = trim(objFld.Ref.value);
        var strTemp2 = trim(objFld.Ref2.value);
        
        intLen = strTemp.length;
        
        if (intLen == 0) {
          if (strTemp2.length != 0)
            intStatus = 1; // can't have to without from
        }
        else {
          if (bIsDate(strTemp))
            if (strTemp2.length != 0)
              if (bIsDate(strTemp2)) {
                var date1 = new Date(strTemp);
                var date2 = new Date(strTemp2);
                if ((date1.getTime() - date2.getTime()) > 0)
                  intStatus = 2 // to is greater than from
              }
        }
        break;
        
      case 20: // Valid email according to specs
        
        strTemp = trim(objFld.Fld.value);
        intLen = strTemp.length;
        var objREEmail = /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
        
        if (intLen != 0)
          if (! objREEmail.exec(strTemp))
            intStatus = 1;
        
        break;
       
      case 21: // A string stripped of non numeric chars should contain a minimum # of digits
        
        strTemp = trim(objFld.Fld.value);  
        
        var objREReplace = /\D/g;
        var objREDigitsOnly = /\d/g;
        
        if (intLen != 0) {
          strTemp = strTemp.replace(objREReplace,"");
          intLen = strTemp.match(objREDigitsOnly);
          if (intLen) {
            if (intLen.length < objFld.Min)
              intStatus = 1;
            }
          else
            intStatus = 1;
          }
        break;

      case 22: // Drop Down (single select) - selectedIndex > 0

        intLen = objFld.Fld.selectedIndex;

        if ( ! checkRequired(intLen, objFld.Req) )
          intStatus = 1;
        break;

      case 23: // A string stripped of non alpha-numeric chars should contain at minimum # of alpha-numeric chars
       
        strTemp = trim(objFld.Fld.value);  
        intLen = strTemp.length;
                   
        var objREReplace = /[^a-zA-Z0-9]/g;
        var objREAlphaNumericOnly = /[a-zA-Z0-9]/g;
                   
        if (intLen != 0) {
          strTemp = strTemp.replace(objREReplace,"");
          intLen = strTemp.match(objREAlphaNumericOnly);
          if (intLen) {
            if (intLen.length < objFld.Min)
              intStatus = 1;
            }
          else
            intStatus = 1;
          }
        break;
 
      case 24: // Inequality
        if ( trim(objFld.Fld.value) == trim(objFld.Ref.value) )
          intStatus = 1;
        break;

      case 25: // Min/Max items in list
        intLen = objFld.Fld.length;
        if ( ! checkRequired (intLen, objFld.Req) )
          intStatus = 1;
        else
          if ( (objFld.Fld.length < objFld.Min) || (objFld.Fld.length > objFld.Max) )
            intStatus = 2;

        break;

      }  /* end switch */

    //--------------------------------------------------------------------------
    // Now build the message string
    //--------------------------------------------------------------------------

    if ( intStatus > 0 ) {
      if ( intGoFld == -1 ) intGoFld = intIndex;
      strErrMsg += objFld.Txt + '  -  ';
      // for ( i=1; i<=Math.ceil((33-objFld.Txt.length)/8); i++, strErrMsg+='/t');
      }

    switch ( objFld.Type ) {
      case 0: // Plain text
        switch ( intStatus ) {
          case 1: strErrMsg += '(field is required)\n'; break;
          case 2: strErrMsg += '(field requires ' + objFld.Min + ' ';
                  if ( objFld.Min != objFld.Max ) strErrMsg += 'to ' + objFld.Max + ' ';
                  strErrMsg += 'characters)\n'; break;
          }
        break;

      case 1: // Money
        switch ( intStatus ) {
          case 1: strErrMsg += '(field is required)\n'; break;
          case 2: strErrMsg += '(field requires whole dollars only)\n'; break;
          case 3: strErrMsg += '(field requires a valid money value)\n'; break;
          case 4: strErrMsg += '(field requires ' + objFld.Min + ' ';
                  if ( objFld.Min != objFld.Max ) strErrMsg += 'to ' + objFld.Max + ' ';
                  strErrMsg += 'digits)\n'; break;
          }
        break;

      case 2: // Drop down (single select)
        switch ( intStatus ) {
          case 1: strErrMsg += '(field is required)\n'; break;
          }
        break;

      case 6: // Integer
        switch ( intStatus ) {
          case 1: strErrMsg += '(field is required)\n'; break;
          case 2: strErrMsg += '(field requires ' + objFld.Min + ' ';
                  if ( objFld.Min != objFld.Max ) strErrMsg += 'to ' + objFld.Max + ' ';
                  strErrMsg += 'digits)\n'; break;
          case 3: strErrMsg += '(field must contain only numbers)\n'; break;
          case 4: strErrMsg += '(enter a value between ' + objFld.LL + ' and ' + objFld.UL + ')\n'; break;
          case 5: strErrMsg += '(the value must equal ' + objFld.UL + ')\n'; break;
          }
        break;

      case 7: // Decimal
        switch ( intStatus ) {
          case 1: strErrMsg += '(field is required)\n'; break;
          case 2: strErrMsg += '(field requires ' + objFld.Min + ' ';
                  if ( objFld.Min != objFld.Max ) strErrMsg += 'to ' + objFld.Max + ' ';
                  strErrMsg += 'characters)\n'; break;
          case 3: strErrMsg += '(incorrect decimal value/format, use: '; 
                  for ( i=0; i<(objFld.Prec-objFld.Scale-1); i++ ) strErrMsg += 'x';
                  strErrMsg += '.';
                  for ( i=0; i<objFld.Scale; i++ ) strErrMsg += 'x';
                  strErrMsg += ')\n';
                  break;
          case 4: strErrMsg += '(enter a value between ' + objFld.LL + ' and ' + objFld.UL + ')\n'; break;
          }
        break;

      case 8: // Numbers - checks that each character in the field is a numeric digit
        switch ( intStatus ) {
          case 1: strErrMsg += '(field is required)\n'; break;
          case 2: strErrMsg += '(field requires ' + objFld.Min + ' ';
                  if ( objFld.Min != objFld.Max ) strErrMsg += 'to ' + objFld.Max + ' ';
                  strErrMsg += 'digits)\n'; break;
          case 3: strErrMsg += '(field must contain only numbers)\n'; break;
          }
        break;

      case 9: // Equality - the two values must be equal
        if ( intStatus == 1 )
          strErrMsg += '(must match the ' + objFld.Txt2 + ' field)\n';
        break;

      case 10: // Text Dependence (if the referenced text field has a value)
        if ( intStatus == 1 )
          strErrMsg += '(field is required)\n';
        break;

      case 11: // Minimum number of Checkbox/Radios selected
        if ( intStatus == 1 ) {

          if ( objFld.Fld.length == null )
            strCtrlType = objFld.Fld.type;
          else
            strCtrlType = objFld.Fld[0].type;

          if ( strCtrlType == "radio" ) {
            strCtrlType += " button";
            strPlural = (objFld.Min == 1) ? '': 's';
            }
          else {
            strForward = 'at least ';
            strPlural = (objFld.Min == 1) ? '': 'es';
            }

          strCtrlType += strPlural
          strErrMsg += '(' + strForward + objFld.Min + ' ' + strCtrlType + ' must be selected)\n';
          }
        break;

      case 12: // Range check - value A (Fld) must be less than or equal to value B (Ref)
        if ( intStatus == 1 )
          strErrMsg += '(invalid Range)\n';
        break;
        
      case 13: // Aggregated upper limit check - value A (Ref) must be less than or equal to value B (UL)
        if ( intStatus == 1 )
          strErrMsg += '(cannot exceed ' + objFld.UL + ')\n';
        break;

      case 14: // File type check - the file name passed in value A (objFld.value) must be of one of the types in the array passed in value B (Ref)
        if ( intStatus == 1 )
          strErrMsg += '(image is of the wrong type)\n';
        break;

      case 15: // Money with limit
        switch ( intStatus ) {
          case 1: strErrMsg += '(field is required)\n'; break;
          case 2: strErrMsg += '(needs valid format - commas in correct place and two decimal places)\n'; break;
          case 3: strErrMsg += '(field must contain only currency amounts)\n'; break;
          case 4: strErrMsg += '(enter a value no greater than ' + objFld.UL + ')\n'; break;
          }
        break;        

      case 16: // Date range - date "From" must be less than or equal to date "To"
        if ( intStatus == 1 )
          strErrMsg += '(invalid from/to date range)\n';
        break;

      case 17: // Date - must be a valid date
        switch ( intStatus ) {
          case 1: strErrMsg += '(field is required)\n'; break;
          case 2: strErrMsg += '(invalid date value/format)\n'; break;
        }
        break;
        
      case 18: // Word count must not exceed the upper limit
        if (intStatus == 1)
          strErrMsg += '(number of words must not exceed ' + objFld.UL + ')\n';
        
        break;
        
      case 19: // Date range from date strings - can have a from without a to
        switch ( intStatus ) {
          case 1: strErrMsg += '(cannot have a to date without a from date)\n'; break;
          case 2: strErrMsg += '(invalid date range)\n'; break;
        }
        break;
        
      case 20: // Valid email according to specs
        if (intStatus == 1)
          strErrMsg += '(invalid email address)\n';
        break; 
             
      case 21: // A string stripped of non numeric chars should contain a min # of chars
        if (intStatus == 1)
          strErrMsg += '(invalid ' + objFld.Ref + ')\n';
        break;   
        
      case 22: // Drop Down (single select) - selectedIndex > 0
        if (intStatus == 1)
          strErrMsg += '(field is required)\n';
        break;   
        
      case 23: // A string stripped of non alpha-numeric chars should contain a min # of alpha-numeric chars
        if (intStatus == 1)
          strErrMsg += '(invalid ' + objFld.Ref + ')\n';
        break;   

      case 24: // Inequality
        if (intStatus == 1)
          strErrMsg += '(' + objFld.Txt + ' must be different than ' + objFld.Txt2 + ')\n';
        break;   

      case 25: // Min/Max items in list
        switch ( intStatus ) {
          case 1: strErrMsg += '(field is required)\n'; break;
          case 2: strErrMsg += '( must contain between ' + objFld.Min + ' and ' + objFld.Max + ' items)\n'; break;
          }
        break;   

      }  /* switch */

    }  /* end for */

  //----------------------------------------------------------------------------
  // Complete the error message string if present
  //----------------------------------------------------------------------------

  if ( strErrMsg.length != 0 ) {
    strErrMsg = strMsgs[2] + strErrMsg + "\n";
    alert(strErrMsg);
    
    if ( aobjFlds[intGoFld].Dis != 1 )  
      if ( aobjFlds[intGoFld].Fld.length > 0 )
        if ( (aobjFlds[intGoFld].Fld[0].type == "checkbox") ||
             (aobjFlds[intGoFld].Fld[0].type == "radio") )
          aobjFlds[intGoFld].Fld[0].focus();
        else
          aobjFlds[intGoFld].Fld.focus();
      else
        aobjFlds[intGoFld].Fld.focus();
    return false;
    }

  //----------------------------------------------------------------------------
  // Complete the warning message string if present
  //----------------------------------------------------------------------------

  if ( strWarnMessage.length != 0 ) {
    strWarnMessage = strMsgs[1] + strWarnMessage + "\n";
    if ( ! confirm( strWarnMessage ) )
      return false;
    }

  return true;
}


//------------------------------------------------------------------------------
// checkMinMax
//------------------------------------------------------------------------------

function checkMinMax( intLen, intMin, intMax ) {
  if ( (intLen >= intMin) && (intLen <= intMax) )
    return true;

  return false;
  }

//------------------------------------------------------------------------------
// checkRequired
//------------------------------------------------------------------------------

function checkRequired( intLen, blnRequired ) {
  if ( (blnRequired == 1) && (intLen == 0) )
    return false;

  return true;
  }
//-->