//
// Implemented interaction:
//  (1) onchange: the fragment is validated clientside
//  (2) onchange of a radio, checkbox or selectbox, the preconditions are verified to determine if part of the form has to be shown or not
//  (3) onsubmit: all fields, which are not validated yet are validated. When there are errors the form is not posted
//  (4) onsubmit: when the form is posted: fields which are not visible are cleared
//  (5) onload: the value and the visibility from the inputs are set. This is for the Firefox prefilling values
//

$(document).ready(function(event) {
   
  $('.wmpform').each(function() {
    var url = $(this).find('.csfw').val();
    var versionId = $(this).find('.csfw_versionId').val();
    var formId = $(this).attr("id");
    var formObj = $(this);

    if (typeof url != 'undefined') {
      $.ajax({
        url: url,
        async: true,
        success: function(data) {
          eval(data);
          var formState = WebmanagerFormStateRegistry[formId];
          
          $.getJSON('/web/wcbservlet/nl.gx.forms.wmpformelement.servlet?formVersionId=' + versionId, function(data) {
            $.each(data.values, function(i,item){
              if (typeof item.name != 'undefined') {
            
                var fragmentObj = FormsUtil.getObject(formState, item.name);
                if (fragmentObj != null) {    
                  fragmentObj.value = item.value;
                  fragmentObj.visible = item.visible;    
                }            

              }  
            });

          });

          init(formObj);
        }
      });
    } else {
      // do the old behavior
      init(formObj);
    }
  });
  
  function init(formObj) {
    //
    // (1) Set a change event on all inputs: we can determine clientside if other fields needs to be shown
    // This is not done by looping over the inputs, because this doesn't work for repeats
    //
    formObj.find(':input').change(function() {  
      changeFragment($(this), true);
    });

    // (3) validate all inputs when the form is submitted
    formObj.submit(function(event) {
      var formId = $(this).attr("id");
      var step = WebmanagerFormStateRegistry[formId].currentStep();

      validateForm(event, $(this), step);
    });
  
  
    //
    // Set a click event on all radio inputs and pipe it to the onChange
    // this to avoid problems in IE6/IE7/IE8 that have a different event model
    //
    formObj.find(':input:radio').click(function() {
      if (FormsUtil.isIE) {
        $(this).change();
      }
    });
  
    //
    // (5) Set the initial value and visibility
    //
    /*
    // FIXME: remove this part
    var inputsWithValue = new Array();
    // This is for the radio and checkboxes: we only need to set them once
    var done = new Array();
  
    $('.wmpform').find(':input').each(function() {
      var formId = $(this).parents('form:first').attr("id");
      var step = WebmanagerFormStateRegistry[formId].currentStep();
    
      var inputName = $(this).attr("name");
      var inputType = $(this).attr("type");
      if (inputName != '' && !FormsUtil.contains(done, inputName)) {
        if (inputType != 'hidden') {
          done.push(inputName);
        }
        
        var fragmentObj = FormsUtil.getObject(step, $(this).attr("name"));
  
        if (fragmentObj != null) {    
          var value = getValue($(this));
  
          fragmentObj.value = value;
          fragmentObj.visible = isVisible($(this));    
          if (value != '') {
            inputsWithValue.push($(this));
          }
        }
      }  
    });
    
    // trigger the change event after the value and visibility is set
    for (var i=0;i<inputsWithValue.length;i++) {
      changeFragment(inputsWithValue[i], false);
    }
    */

  
  
  
  
  }


  function changeFragment(obj, validate) {
    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
    if (fragmentObj != null) {
      fragmentObj.value = getValue(obj);
      fragmentObj.validated = false;
      
      // Revalidate the fragment
      if (validate) {
        validateFormFragment(inputName, fragmentObj);
      }
      
      // (2) we only check for conditions for radio, chechboxes and select boxes: this is the most likely use case and we don't want to create extra overhead
      // Added hidden, because you can have a hidden counter (eg for the repeater) which needs to trigger the checkConditions
      var inputType = obj.attr("type");
            
            
            log(step);
      if (inputType == 'radio' || inputType == 'checkbox' || inputType == 'select-one' || inputType == 'hidden') {
        var changes = FormsUtil.checkConditions(step, '', formId);
        for (var i=0; i < changes.length;i++) {
          if (changes[i].value == 'show') {
            var objToShow = $('#' + FormsUtil.normalize(changes[i].identifier));
            objToShow.show();          
            // throw high level event, so custom code can react on that
            objToShow.trigger('IAF_ShowFormFragment');
          } else {
            var objToHide = $('#' + FormsUtil.normalize(changes[i].identifier));
            objToHide.hide();          
            // throw high level event, so custom code can react on that
            objToHide.trigger('IAF_HideFormFragment');
          }
        }
      }
    }

  }

  //
  // Function to validate a form fragment
  //
  function validateFormFragment(inputName, fragmentObj) {
    var hasError = false;
    if (fragmentObj != null && !fragmentObj.validated) {

      // validate the input: only when visible
      if (fragmentObj.visible) {
        var validationResult = fragmentObj.validate();

        // gather the errors
        var errors = FormsUtil.join(validationResult,'</li><li>');
        hasError = (errors != '');

        if (errors != '') {
          $("#error_" + FormsUtil.normalize(inputName)).html('<ul><li>' + errors + '</li></ul>').show();
        } else {
          $("#error_" + FormsUtil.normalize(inputName)).empty().hide();
        }
      }
    }
    return hasError;
  }


  //
  // Function for validating the form: the inputs are validated and the form is not submitted, when there are errors
  //
  function validateForm(event, formObj, step) {
    // 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 = validateFormFragment(inputName, fragmentObj);
        if (fragmentError) {
          hasError = true;
        }

      }
    });

    // don't submit the form when there is an error
    if (hasError) {
      event.preventDefault();
    } else {
      // (4) make the value empty to prevent to be routed to the same step
      // issue: http://jira.gxdeveloperweb.com/jira/browse/GXWMF-626

      $(':input', formObj).each(function() {
        // skip the hidden inputs
        var inputName = $(this).attr("name");

        var fragmentObj = FormsUtil.getObject(step, inputName);
        if (fragmentObj != null && !fragmentObj.visible) {
          // 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="" />');
          }
        }
      });


    }
  };


});

//
// Utility functions with jQuery syntax, and thus not in the formutil.js
//


// Get the value(s) for an object. This implementation differs per input type
function getValue(obj) {
  value = obj.val();

  if (obj.attr("type") == 'radio') {
    value = $('input[name=' + obj.attr("name") + ']:checked').val();
  }
  // for checkboxes we pass the array of values
  if (obj.attr("type") == 'checkbox') {
    values = $('input:checkbox[name=' + obj.attr("name") + ']:checked') || [];
    value = new Array();

    i=0;
    values.each(function() {
      value.push($(this).val());
      i++;
    });
  }
  return value;
}

// checks if the object is visible
function isVisible(obj) {
  var visible = true;
  obj.parents().each(function() {
    if ($(this).css("display") == 'none') {
      visible = false;
      return false;      
    }
  });
  return visible;
}

