// Copyright (c) 2009 John Heminghous
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var warnings = {
  "required" : "This field is required",
  "lettersOnly" : "Only letters are allowed in this field",
  "email" : "Enter a properly formatted email address (example@host.com)",
  "phone" : "Enter a properly formatted phone number",
  "recaptcha" : "Re-enter captcha"
}

var fields = new Array();

var containerId = "";
var submitId = "";

function initValidator(cid, sid)
{
  containerId = cid;
  submitId = sid;
  
  var content = document.getElementById(containerId);
  if (!content)
  {
    return;
  }
  
  var submitButton = document.getElementById(submitId);
  if (!submitButton)
  {
    return;
  }
  submitButton.disabled = true;
  
  var forms = document.getElementsByTagName("form");
  if (forms.length == 0)
  {
    return;
  }
  
  if (createRequest())
  {
    // Create new button to switch type to button from submit since 
    // IE doesn't support switching type
    var newButton = document.createElement("input");
    newButton.type = "button";
    newButton.name = submitButton.name;
    newButton.id = submitButton.id;
    newButton.value = submitButton.value;
    newButton.onclick = 
      function () { ajaxSubmit(forms[0].action); return false; };
    submitButton.parentNode.replaceChild(newButton, submitButton);
  }
  
  // Add handlers to validate inputs
  var inputs = content.getElementsByTagName("input");
  for (var i = 0; i < inputs.length; ++i)
  {
      assignValidationHandlers(inputs[i]);
      fields[fields.length] = inputs[i];
  }
  
  var textareas = content.getElementsByTagName("textarea");
  for (var i = 0; i < textareas.length; ++i)
  {
      assignValidationHandlers(textareas[i]);
      fields[fields.length] = textareas[i];
  }
  
  var selects = content.getElementsByTagName("select");
  for (var i = 0; i < selects.length; ++i)
  {
      assignValidationHandlers(selects[i]);
      fields[fields.length] = selects[i];
  }
  
  if (inputs.length != 0)
  {
    inputs[0].focus();
  }
}

var submitButtonValue = "";

function ajaxSubmit(url)
{
  var submitButton = document.getElementById(submitId);
  submitButtonValue = submitButton.value;
  submitButton.disabled = true;
  submitButton.value = "Processing...";
  
  var parameters = "ajax=&";
  for (var i = 0; i < fields.length; ++i)
  {
    if ((fields[i].type != "button" && fields[i].type != "submit" && 
      fields[i].type != "radio") ||
      (fields[i].type == "radio" && fields[i].checked))
    {
      parameters += fields[i].name + "=" + fields[i].value + "&";
    }
  }
  var challengeField = document.getElementById("recaptcha_challenge_field");
  var responseField = document.getElementById("recaptcha_response_field");
  if (challengeField && responseField)
  {
    parameters += challengeField.id + "=" + challengeField.value + "&";
    parameters += responseField.id + "=" + responseField.value;
  }
  
  ajaxFormPost(url, parameters, submitCallback);
}

function submitCallback(returnMsg)
{
  var submitButton = document.getElementById(submitId);
  var submitStatus = eval("("+returnMsg+")");
  
  if (submitStatus.status == "ok")
  {
    var content = document.getElementById(containerId);
    content.innerHTML = submitStatus.message;
  }
  else if (submitStatus.status == "recaptchaError")
  {
    unwarn(submitButton, "*");
    
    var recaptchaNode = document.getElementById("recaptcha");
    warn(recaptchaNode, "recaptcha");
    
    if (recaptchaNode && Recaptcha)
    {
      Recaptcha.create(
        "6LdPiAgAAAAAAEilgxUv_gJUiL6N4k0nQppPitMn",
        recaptchaNode,
        {
          theme: "white"
        });
    }
  }
  else
  {
    var recaptchaNode = document.getElementById("recaptcha");
    unwarn(recaptchaNode, "recaptcha");
    
    warnings[submitStatus.status] = submitStatus.message;
    warn(submitButton, submitStatus.status);
  }
  
  submitButton.disabled = false;
  submitButton.value = submitButtonValue;
}

function assignValidationHandlers(object)
{ 
  if (object.className.match("required"))
  {
    addEventHandler(object, "blur", requiredCheck);
    if (object.value == "") warn(object, "required");
  }
  if (object.className.match("lettersOnly"))
  {
    addEventHandler(object, "blur", lettersOnlyCheck);
  }
  if (object.className.match("email"))
  {
    addEventHandler(object, "blur", emailCheck);
  }
  if (object.className.match("phone"))
  {
    addEventHandler(object, "blur", phoneCheck);
  }
}

function requiredCheck(e)
{
  var object = getActivatedObject(e);
  if (object.value == "")
  {
    warn(object, "required");
  }
  else
  {
    unwarn(object, "required");
  }
}

function lettersOnlyCheck(e)
{
  var object = getActivatedObject(e);
  var nonAlpha = /[^a-zA-Z ,.]/;
  if (nonAlpha.test(object.value))
  {
    warn(object, "lettersOnly");
  }
  else
  {
    unwarn(object, "lettersOnly");
  }
}

function emailCheck(e)
{
  var object = getActivatedObject(e);
  var validEmail = /^[\w\.-_\+]+@[\w-]+(\.\w{2,4})+$/;
  if (!validEmail.test(object.value))
  {
    warn(object, "email");
  }
  else
  {
    unwarn(object, "email");
  }
}

function phoneCheck(e)
{
  var object = getActivatedObject(e);
  var validPhone = /^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,5})|(\(?\d{2,6}\)?))(-| )?(\d{3,4})(-| )?(\d{4})(( x| ext)\d{1,5}){0,1}$/
  if (!validPhone.test(object.value) && object.value != "")
  {
    warn(object, "phone");
  }
  else
  {
    unwarn(object, "phone");
  }
}

function warn(object, warningType)
{
  // Add a p element below the input element with a warning
  var parentNode = object.parentNode;
  if (parentNode.getElementsByTagName("p").length == 0)
  {
    var p = document.createElement("p");
    parentNode.appendChild(p);
    var warningNode = document.createTextNode(warnings[warningType]);
    p.appendChild(warningNode);
  }
  else
  {
    var p = parentNode.getElementsByTagName("p")[0];
    p.childNodes[0].nodeValue = warnings[warningType];
  }
  
  document.getElementById(submitId).disabled = true;
}

function unwarn(object, warningType)
{
  // Remove warning p element
  if (object.parentNode.getElementsByTagName("p").length > 0)
  {
    var p = object.parentNode.getElementsByTagName("p")[0];
    var currentWarning = p.childNodes[0].nodeValue;
    var warning = warnings[warningType];
    if (currentWarning == warning || warningType == "*")
    {
      object.parentNode.removeChild(p);
    }
  }
  
  // Check if any warnings are left and enable submission if not
  var fieldsets = 
    document.getElementById(containerId).getElementsByTagName("fieldset");
  for (var i = 0; i < fieldsets.length; ++i)
  {
    var fieldWarnings = fieldsets[i].getElementsByTagName("p").length;
    if (fieldWarnings > 0)
    {
      document.getElementById(submitId).disabled = true;
      return;
    }
  }
  document.getElementById(submitId).disabled = false;
}
