//
// function to trigger a change of a fragment. The fragment will be validated and other fields are checked for
// possible visual changes (shown or hidden)
//
FormValidation.changeFragment = function(obj, validate, triggerPreconditions) {
  if (obj.length != 0) {
    var formId = obj.parents('form:first').attr("id");
    var step = WebmanagerFormStateRegistry[formId].currentStep();

    var inputName = obj.attr("name");
    var fragmentObj = FormsUtil.getObject(step, inputName);

    // set the value in the scope
    var newValue = FormValidation.getFragmentValue(obj);
    var valueChanged = false;
    if (fragmentObj != null && fragmentObj.value != newValue) {
      valueChanged = true;
      //NN specific: set 'dirty' for auto submits
      obj.parents('form:first').data('iaForm').isDirty = true;

      // only trigger actions when the value is changed
      fragmentObj.value = newValue;
      fragmentObj.validated = false;

      // Revalidate the fragment
      if (validate) {
        FormValidation.validateFormFragment(obj, fragmentObj);
      }
    }
    
    if (triggerPreconditions || valueChanged) {
      // When a fragment has got a new value, check if other fields have to (dis)appear
      var changes = FormsUtil.checkConditions(step, '', formId);
      for (var i=0; i < changes.length;i++) {
      	// Set the condition flag equal to the visible flag to make preconditions function correctly
        var changedFragmentObj = FormsUtil.getObject(step, changes[i].identifier);
        if (changedFragmentObj != undefined) {
          changedFragmentObj.condition = changedFragmentObj.visible;
        }

        if (changes[i].value == 'show') {
          // throw high level event, so custom code can react on that
          $('#' + FormsUtil.normalize(changes[i].identifier)).trigger('IAF_ShowFormFragment');
        } else {
          // throw high level event, so custom code can react on that
          $('#' + FormsUtil.normalize(changes[i].identifier)).trigger('IAF_HideFormFragment');
        }
      }
    }
  }
}

//
// Function to validate a form fragment
// Returns true if an error has occurred
//
FormValidation.validateFormFragment = function(inputObj, fragmentObj, hideError) {
  var inputName = inputObj.attr("name");

  var hasError = false;
  if (fragmentObj != null && !fragmentObj.validated) {

    // validate the input: only when visible
    if (inputObj.is(":visible")) {
      var validationResult = fragmentObj.validate();

      // gather the errors
      var errors = FormsUtil.join(validationResult,',');
      hasError = (errors != '');

      if (hideError != true) {
        var errorDivId = "error_" + FormsUtil.normalize(inputName);
        var errorObj = $("#" + errorDivId);
        //NN specific, don't trigger on errorObj but on input
        if (errorObj.length > 0) {
          if (errors != '') {

            inputObj.trigger('IAF_ShowError',[errorDivId,validationResult]);
          } else {
            inputObj.trigger('IAF_HideError', errorDivId);
          }
        }
      }
    }
  }
  return hasError;
};

//
// Function for validating the form: the inputs are validated and the form is not submitted, when there are errors
//
FormValidation.validateForm = function(formObj, step, hideErrors) {
  // loop over the inputs
  var hasError = false;
  $(':input', formObj).each(function() {
    var inputName = $(this).attr("name");
    var inputType = $(this).attr("type");
    if (inputName != '' && inputType != 'hidden' && inputType != 'button' && inputType != 'submit') {

      // sanity check
      var fragmentObj = FormsUtil.getObject(step, inputName);
      var fragmentError = FormValidation.validateFormFragment($(this), fragmentObj, hideErrors);
      if (fragmentError) {
        hasError = true;
      }

    }
  });
  return hasError;
}

FormValidation.submitForm = function(formObj, step) {
  // (4) make the value empty to prevent to be routed to the same step
  // issue: http://jira.gxdeveloperweb.com/jira/browse/GXWMF-626

  // NN specific: don't unbind for AJAX enabled forms
  var useAjax = $("input[name='clientsideRouting']", formObj).val();
  if (useAjax != 'true') {
    formObj.unbind('submit');
  }

  $(':input', formObj).each(function() {
    // NN specific: clear inputs with displayNone parents
    var invisibleParents = ($(this).parents(".displayNone:not(.noprepare)").length > 0);
    
    // skip the hidden inputs
    var inputName = $(this).attr("name");
    
    if ($(this).hasClass("donotsubmit")) {
      //switch names:
      $("input:hidden[name='"+inputName+"-submit']").attr("name", inputName);
      $(this).attr("name", "");
    }

    var fragmentObj = FormsUtil.getObject(step, inputName);
    if (fragmentObj != null && (!fragmentObj.visible || invisibleParents)) {
      // clear the value
      switch(this.type) {
        case 'password':
        case 'select-multiple':
        case 'select-one':
        case 'text':
        case 'textarea':
          $(this).val('');
          break;
        case 'checkbox':
        case 'radio':
          $(this).removeAttr("checked");
          // add an empty input type="hidden": this because the browser doesn't send an empty radio
          formObj.append('<input type="hidden" name="' + inputName + '" value="" />');
      }
    }
  });
  formObj.trigger('IAF_SubmitForm');
};
