// Header for confirmation table
var dlcFormConfirmHeader = "Data Entry Confirmation";

// Header for error table
var dlcFormErrorHeader = "Data Entry Errors";

// If there is a DIV with ID of "ErrorMessage", error HTML
// inserted into it. Otherwise, errors are displayed in alert box.
var dlcErrorMessageObject = null;

// If there is a DIV with ID of "ConfirmMessage", confirmation HTML
// inserted into it. Otherwise, data is sent to target.
var dlcConfirmMessageObject = null;

// Global used internally.
var dlcFormAction = "";
var dlcFormName = "";

var dlcTypeText        = 1;  // input type="text"
var dlcTypeRadio       = 2;  // input type="radio"
var dlcTypeTextarea    = 3;  // textarea
var dlcTypeCheckbox    = 4;  // input type="checkbox"
var dlcTypeSelect      = 5;  // select
var dlcTypeMultiselect = 6;  // select multiple
var dlcTypeFile        = 7;  // file
var dlcTypeHidden      = 8;  // hidden
var dlcTypePassword    = 9;  // password

var dlcReqNone         = 0;  // not required
var dlcReqNonblank     = 1;  // must be nonblank
var dlcReqEmail        = 2;  // must be valid email
var dlcReqNumeric      = 3;  // must be numeric
var dlcReqPhone        = 4;  // must be phone - 10 digits
var dlcReqZip          = 5;  // must be zip code, either 5 or 9 digits
var dlcReqDate         = 6;  // must be valid date = mm/dd/yyyy

var dlcHTMLOk          = 0;  // HTML ok in the field
var dlcHTMLNone        = 1;  // HTML not allowed in the field
var dlcHTMLAutofix     = 2;  // HTML automatically fixed

function dlcDoTrimWS(val)
// Remove leading and trailing whitespace.
{
  if (val == null)
  {
    return "";
  }
  val = val.toString();
  if (val.length <= 0)
  {
    return "";
  }
  val = val.replace(/^\s+/g, "");
  val = val.replace(/\s+$/g, "");
  return val;
}

function dlcIsBlank(val)
// Is value passed in blank or null?
{
  if (val == null)
  {
    return true;
  }
  val = val.toString();
  if (val.length <= 0)
  {
    return true;
  }
  if (val.search(/\w/) >= 0)
  {
    return false;
  }
  return true;
}

function dlcIsNumber(val)
// Is value passed in a number?
{
  var num = parseFloat(val);
  if (isNaN(num))
  {
    return false;
  }
  return true;
}

function dlcIsAnyHTML(val)
// Any HTML in the value passed in?
{
  // note that this also catches SSI
  if (dlcIsBlank(val))
  {
    return false;
  }
  if (val.search(/[\<|\>]+/) >= 0) // look for < or >
  {
    return true;
  }
  return false;
}

function dlcDoFixHTML(val)
// Fix any HTML in the value.
{
  // note that this also catches SSI
  if (dlcIsBlank(val))
  {
    return val;
  }
  val = val.replace(/\</g, "["); // replace < with [
  val = val.replace(/\>/g, "]"); // replace > with ]
  return val;
}

function dlcDoBreakToNewline(str)
// Convert <br> to newlines in textareas.
{
  return str.replace(/\<br\s*[\/]?\s*\>/g, "\n");
}

function dlcDoNewlineToBreak(str)
// Convert newlines to <br> in textareas.
{
  return str.replace(/\r*\n/g, "<br>");
}

function dlcDoCheckForm(frm,spamcheck)
// Check the form for errors. If Ok, get confirmation.
{
  var errmsg = "";
  var confmsg = "";
  var checkspam = false;
  if (arguments.length > 1)
  {
    checkspam = spamcheck;
  }

//  // Configure all the fields.
//  dlcDoConfigAllFields();
  
  // Check all the fields.
  errmsg = dlcDoCheckFields(frm,checkspam);

  // Show any errors.
  dlcDoShowFormErrors(errmsg);
  if (errmsg.length <= 0)
  {
    // Get confirmation.
    confmsg = dlcDoGetFormConfirm(frm);
    if (confmsg.length <= 0)
    {
      // Nothing to display, so submit it.
      frm.submit(); 
      return true;
    }
    else
    {
      // Show confirmation.
      dlcDoShowFormConfirm(confmsg);
      return true;
    }
  }
  return false;
}

function dlcDoConfigField(frname, fname, ftype, fdesc, freq, fhtml, fmin, fmax)
  //Only fields called with Config Field are checked for errors and sent in confirm.
  
  //Configure the field based on specifications.
  //  frname = Form name - leave blank to use first form in document.
  //  fname = Field name - as specified in the form.
  //  ftype = Type - dlcType as defined above.
  //    (could get this from field object, but have some extras built in here)
  //  fdesc = Description - if you want to have descriptive name in error/confirm.
  //  freq = Required type - dlcReq as defined above.
  //  fhtml = HTML check/fix - dlcHTML as defined above.
  //  fmin = Minimum value - minimum value for numerics.
  //  fmax = Maximum value - maximum value for numerics.
{
  var fobj = null;
  var max, min;
  var ix;

  if (dlcIsBlank(fname))
  {
    return;
  }
  if (dlcIsBlank(frname))
  {
    frname = "forms[0]"; // default to first form in the document
  }
//  var ftype = dlcConvertFieldType(eval("document." + frname + "." + fname.type));
  if ((ftype <= 0) || (ftype == null))
  {
    return;
  }
  if ((ftype == dlcTypeText) || (ftype == dlcTypeTextarea))
  {
    fobj = eval("document." + frname + "." + fname);
    fobj.dlcType = ftype;
    fobj.dlcDesc = fdesc;
    fobj.dlcReq  = freq;
    if (!dlcIsBlank(fmax))
    {
      max = parseFloat(fmax);
      fobj.dlcMax = max;
    }
    if (!dlcIsBlank(fmin))
    {
      min = parseFloat(fmin);
      fobj.dlcMin = min;
    }
    fobj.dlcHTML = fhtml;
  }
  else if (ftype == dlcTypeRadio)
  {
    if (fname.search(/\[/) >= 0) // specified array?
    {
      fobj = eval("document." + frname + "." + fname);
      fobj.dlcType = ftype;
      fobj.dlcDesc = fdesc;
      fobj.dlcReq  = freq;
    }
    else  // just name, no array, for radio data
    {
      for (ix = 0; ix < (eval("document." + frname + "." + fname)).length; ix++)
      {
        fobj = eval("document." + frname + "." + fname + "[" + ix + "]");
        fobj.dlcType = ftype;
        fobj.dlcDesc = fdesc;
        fobj.dlcReq  = freq;
      }
    }
  }
  else if (ftype == dlcTypeCheckbox)
  {
    fobj = eval("document." + frname + "." + fname);
    fobj.dlcType = ftype;
    fobj.dlcDesc = fdesc;
    fobj.dlcReq  = freq;
  }
  else if ((ftype == dlcTypeSelect) || (ftype == dlcTypeMultiselect))
  {
    fobj = eval("document." + frname + "." + fname);
    fobj.dlcType = ftype;
    fobj.dlcDesc = fdesc;
    fobj.dlcReq  = freq;
  }
  else if (ftype == dlcTypeFile)
  {
    fobj = eval("document." + frname + "." + fname);
    fobj.dlcType = ftype;
    fobj.dlcDesc = fdesc;
    fobj.dlcReq  = freq;
  }
}

//function dlcConvertFieldType(htmltype)
//// Convert from HTML type to my type
//{
//  switch (htmltype)
//  {
//  case 'text':
//    return dlcTypeText;
//  case 'radio':
//    return dlcTypeRadio;
//  case 'textarea':
//    return dlcTypeTextarea;
//  case 'checkbox':
//    return dlcTypeCheckbox;
//  case 'select-one':
//    return dlcTypeSelect;
//  case 'select-multiple':
//    return dlcTypeMultiselect;
//  case 'file':
//    return dlcTypeFile;
//  case 'hidden':
//    return dlcTypeHidden;
//  case 'password':
//    return dlcTypePassword;
//  default:
//    return -1;
//  }
//}

function dlcDoCheckFields(frm,checkspam)
// Check the entered values of all configured fields.
// Builds newline delimited string of errors.
{
  var ix, elem, num, datatype, max, min, rx, tmp;
  var errormsg = "";

  dlcFormAction = frm.action; // save global for confirmation
  dlcFormName = frm.name; // save global for confirmation
  if (dlcFormName.length <= 0)
  {
    dlcFormName = "forms[0]";
  }

  var radios = new Array;        // names
  var radioschecked = new Array; // checked

  for (ix = 0; ix < frm.length; ix++)
  {
    elem = frm.elements[ix];
    datatype = elem.dlcType;
    if ((datatype != dlcTypeMultiselect) && (datatype != dlcTypeFile)) // don't mess up multiselect
    {
      elem.value = dlcDoTrimWS(elem.value);
    }
    if (dlcIsBlank(datatype))
    {
      continue;
    }
    if (dlcIsBlank(elem.dlcDesc))
    {
      elem.dlcDesc = elem.name;  // if no desc, use field name
    }
    switch (datatype)
    {
    case dlcTypeText:
    case dlcTypeTextarea:
    // string or number
      if (elem.dlcReq > dlcReqNone) // nonblank
      {
        if (dlcIsBlank(elem.value))
        {
          errormsg += elem.dlcDesc + " is blank.\n";
          break;
        }
      }
      if (checkspam)
      {
        if ((elem.value.match(/href\s*=/i) != null) ||
            (elem.value.match(/http:/i) != null))
        {
          errormsg += elem.dlcDesc + " contains HTML.\n";
          break;
        }
      }
      if (elem.dlcReq == dlcReqEmail)
      {
        if (elem.value.match(/^[\w\-\_\.]+\@[\w\.\-\_]+$/) == null)
        {
          errormsg += elem.dlcDesc + " is an invalid email address.\n";
          break;
        }
      }
      if (elem.dlcReq == dlcReqDate)
      {
        if (elem.value.match(/^\d{1,2}\/\d{1,2}\/\d{4,4}$/) == null)
        {
          errormsg += elem.dlcDesc + " is an invalid date.\n";
          break;
        }
      }
      if (elem.dlcReq == dlcReqNumeric) 
      {
        num = elem.value;
        if ((!dlcIsNumber(num)) && (elem.dlcReq > dlcReqNone))
        {
          errormsg += elem.dlcDesc + " is not numeric.\n";
          break;
        }
        else
        {
          num = parseFloat(elem.value);
          max = parseFloat(elem.dlcMax);
          min = parseFloat(elem.dlcMin);
          if (num < min)
          {
            errormsg += elem.dlcDesc + " is less than " + min + ".\n";
          }
          else if (num > max)
          {
            errormsg += elem.dlcDesc + " is greater than " + max + ".\n";
          }
        }
      }
      if (elem.dlcReq == dlcReqPhone)
      {
        tmp = elem.value;
        tmp = tmp.replace(/[^0-9]/g, "");
        if (tmp.length != 10)
        {
          errormsg += elem.dlcDesc + " is an invalid phone number.\n";
          break;
        }
        elem.value = "(" + tmp.substr(0,3) + ") " + tmp.substr(3,3) + "-" + tmp.substr(6,4);
      }
      if (elem.dlcReq == dlcReqZip)
      {
        tmp = elem.value;
        tmp = tmp.replace(/[^0-9]/g, "");
        if (!((tmp.length == 9) || (tmp.length == 5)))
        {
          errormsg += elem.dlcDesc + " is an invalid zip code.\n";
          break;
        }
        elem.value = tmp.substr(0,5);
        if (tmp.length> 5)
        {
          elem.value += "-" + tmp.substr(5,4);
        }
      }
      if (elem.dlcReq != dlcReqNumeric) // not numeric, check if HTML
      {
        if (dlcIsAnyHTML(elem.value))
        {
          if (elem.dlcHTML == dlcHTMLAutofix)
          {
            elem.value = dlcDoFixHTML(elem.value);
          }
          else if (elem.dlcHTML == dlcHTMLNone)
          {
            errormsg += elem.dlcDesc + " contains HTML.\n";
            break;
          }
          else if (elem.dlcHTML == dlcHTMLOk)
          {
            elem.value = dlcDoNewlineToBreak(elem.value);
          }
        }
      }
      break;
    case dlcTypeRadio:
      if (elem.dlcReq > dlcReqNone)
      {
        // already seen radio button with this name?
        rx = dlcDoFindInArray(elem.dlcDesc, radios);
        if (elem.checked)
        {
          if (rx >= 0)
          {
            // if already seen one with this name, set to checked
            radioschecked[rx] = 1;
          }
          else
          {
            // if not seen one with this name, add it to array
            radios.push(elem.dlcDesc);
            radioschecked.push(1);
          }
        }
        else
        {
          if (rx < 0)
          {
            // if not seen one with this name, add it to array
            radios.push(elem.dlcDesc);
            radioschecked.push(0);
          }
        }
      }
      break;
    case dlcTypeCheckbox:
      break;
    case dlcTypeSelect: // select
      if (elem.dlcReq > dlcReqNone) // nonblank
      {
        if (dlcIsBlank(elem.value))
        {
          errormsg += elem.dlcDesc + " is blank.\n";
          break;
        }
      }
      break;
    case dlcTypeMultiselect: // multi select
      if (elem.dlcReq > dlcReqNone) // nonblank
      {
        for (rx = 0; rx < elem.options.length; rx++)
        {
          if (elem.options[rx].selected)
          {
            break;
          }
        }
        if (rx >= elem.options.length)
        {
          errormsg += elem.dlcDesc + " is blank.\n";
          break;
        }
      }
      break;
    case dlcTypeFile:
      if (elem.dlcReq > dlcReqNone) // nonblank
      {
        if (dlcIsBlank(elem.value))
        {
          errormsg += elem.dlcDesc + " is blank.\n";
          break;
        }
      }
      break;
    case dlcTypeHidden:
      if (elem.dlcReq > dlcReqNone) // nonblank
      {
        if (dlcIsBlank(elem.value))
        {
          errormsg += elem.dlcDesc + " is blank.\n";
          break;
        }
      }
      break;
    case dlcTypePassword:
      if (elem.dlcReq > dlcReqNone) // nonblank
      {
        if (dlcIsBlank(elem.value))
        {
          errormsg += elem.dlcDesc + " is blank.\n";
          break;
        }
      }
      break;
    default:
      break;
    }
  }  

  // Now verify that any required radio buttons have a selected one.
  for (rx = 0; rx < radios.length; rx++)
  {
    if (!dlcIsBlank(radios[rx]) && (radioschecked[rx] != 1))
    {
      errormsg += radios[rx] + " is not selected.\n";
    }
  }
  return errormsg;
}

function dlcDoFindInArray(str, arr)
// Find a specified string value in specified array, returning index.
{
  var ix;
  for (ix = 0; ix < arr.length; ix++)
  {
    if (str == arr[ix])
    {
      return ix;
    }
  }
  return -1;
}

function dlcDoShowFormErrors(errmsg)
// Show form errors, either as HTML table or alert message box.
{ 
  var errs, ix;
  
  dlcErrorMessageObject = document.getElementById("ErrorMessage");
  if (dlcErrorMessageObject)
  // Always show, in case need to clear!
  {
    if (errmsg.length <= 0)
    {
      errmsg = ""
    }
    else
    {
      // Build HTML table of errors.
      errmsg = errmsg.substr(0,errmsg.length-1); // drop last \n
      errs = errmsg.split(/\n/);
      errmsg = "<table width='" + dlcErrorMessageObject.style.width + "' class='dlcFormErrorTableStyle'>\n";
      if (dlcFormErrorHeader)
      {
        errmsg += "<tr><td class='dlcFormErrorHeaderStyle'>" + dlcFormErrorHeader + "</td></tr>\n";
      }
      for (ix = 0; ix < errs.length; ix++)
      {
        errmsg += "<tr><td class='dlcFormErrorDataStyle'>" + errs[ix] + "</td></tr>\n";
      }
      errmsg += "<tr><td align='center' class='dlcFormErrorDataStyle'>" + 
                "<input type='button' value='Close' onclick='javascript:dlcDoShowFormErrors(\"\");'>" +
                "</td></tr>\n" +
                "</table>\n";
    }
    dlcErrorMessageObject.innerHTML = errmsg;
  }
  else if (errmsg.length)
  {
    // If no ErrorMessage object, display errors in alert box.
    alert(errmsg);
  }
}

function dlcDoGetFormConfirm(frm)
// Generate confirmation message.
{
  var ix, elem, datatype, value, rx, showvalue, saveelem;

  var confmsg = "";
  
  dlcConfirmMessageObject = document.getElementById("ConfirmMessage");
  if (dlcConfirmMessageObject)
  {
    for (ix = 0; ix < frm.length; ix++)
    {
      elem = frm.elements[ix];
      datatype = elem.dlcType;
      if (dlcIsBlank(datatype))
      {
        continue;
      }
      switch (datatype)
      {
      case dlcTypeRadio:
      case dlcTypeCheckbox:
        value = elem.value;
        if (!elem.checked)
        {
          showvalue = "";
        }
        else
        {
          showvalue = value;
        }
        break;
      case  dlcTypeMultiselect:
        value = "";
        showvalue = "";
        for (rx = 0; rx < elem.options.length; rx++)
        {
          if (elem.options[rx].selected)
          {
            if (value.length > 0)
            {
              value += ";";
            }
            value += elem.options[rx].value;
            showvalue += elem.options[rx].innerHTML;
          }
        }
        break;
      case dlcTypeSelect:
        value = elem.value;
        showvalue = elem.options[elem.selectedIndex].innerHTML;
        break;
      case dlcTypeText:
      case dlcTypeTextarea:
        value = elem.value;
        showvalue = dlcDoNewlineToBreak(value);
        break;
      default:
        value = elem.value;
        showvalue = value;
        break;
      }
      if (dlcIsBlank(showvalue))
      {
        continue;
      }

      confmsg += elem.dlcDesc + "\n"  + showvalue + "\n";
    }
  }
  return confmsg;
}

function dlcDoShowFormConfirm(confmsg)
// Show confirmation message.
{
  var confs, ix;
  if (!dlcConfirmMessageObject)
  {
    return;
  }
  if (dlcIsBlank(confmsg))
  {
    confmsg = "";
  }
  else
  {
    // Build confirmation HTML, using confirmation message (name/value display and hidden).
    // Add buttons.
    confmsg = confmsg.substr(0,confmsg.length-1); // drop last \n
    confs = confmsg.split(/\n/);
//    var confmsg = "<form enctype='multipart/form-data' name='ConfirmForm' method='post' action='" + dlcFormAction + "'>\n" +
//                  "<table width='" + dlcConfirmMessageObject.style.width + "' class='dlcFormConfirmDataStyle'>\n";
    var confmsg = "<table width='" + dlcConfirmMessageObject.style.width + "' class='dlcFormConfirmDataStyle'>\n";
    if (dlcFormConfirmHeader)
    {
      confmsg += "<tr><td colspan='2' class='dlcFormConfirmHeaderStyle'>" + dlcFormConfirmHeader + "</td></tr>\n";
    }                
    for (ix = 0; ix < confs.length; ix+=2)
    {
      confmsg += "<tr><td class='dlcFormConfirmDataStyle'>" + confs[ix] + "</td>" + "<td class='dlcFormConfirmDataStyle'>" + confs[ix+1] + "</td></tr>\n";
    }
    confmsg += "<tr><td align='center' colspan='2' class='dlcFormConfirmDataStyle'>" +
               "<input type='button' value='Confirm/Submit' onclick='javascript:this.value=\"Please wait...\";this.disabled=true;document." + dlcFormName + ".submit();'>" +
               "&nbsp;&nbsp;&nbsp;&nbsp;" +
               "<input type='button' value='Cancel/Change' onclick='javascript:dlcDoShowFormConfirm(\"\");'>" +
               "</td></tr>\n" +
               "</table>\n" +
               "\n";
//               "</form>\n";
  }
  dlcConfirmMessageObject.innerHTML = confmsg;
}
