(function() {
  define(["underscore", "./dom", "./events", "./forms"], function(_, dom, events) {
    var REENABLE, SELECTOR, disableInputFields, hide, linkTrigger, renableInputFields, updateFields;
    SELECTOR = "[data-component-type='core/FormFragment']";
    REENABLE = "data-re-enable-when-fragment-visible";
    disableInputFields = function(fragment) {
      var field, i, len, ref, results;
      ref = fragment.find("input:not(:disabled)");
      results = [];
      for (i = 0, len = ref.length; i < len; i++) {
        field = ref[i];
        field.attr("disabled", true);
        results.push(field.attr(REENABLE, true));
      }
      return results;
    };
    renableInputFields = function(fragment) {
      var field, i, len, ref, results;
      ref = fragment.find("input[" + REENABLE + "]");
      results = [];
      for (i = 0, len = ref.length; i < len; i++) {
        field = ref[i];
        field.attr("disabled", null);
        results.push(field.attr(REENABLE, null));
      }
      return results;
    };
    updateFields = function(fragment, makeVisible) {
      var f;
      if (fragment.attr("data-always-submit")) {
        return;
      }
      f = makeVisible ? renableInputFields : disableInputFields;
      return f(fragment);
    };
    dom.onDocument(events.formfragment.changeVisibility, SELECTOR, function(event) {
      var makeVisible;
      makeVisible = event.memo.visible;
      this[makeVisible ? "show" : "hide"]();
      updateFields(this, makeVisible);
      this.trigger(events.element[makeVisible ? "didShow" : "didHide"]);
      return false;
    });
    hide = function(id) {
      var field;
      field = dom(id);
      return updateFields(field, false);
    };
    linkTrigger = function(spec) {
      var fragment, invert, trigger, update;
      if (spec.triggerId == null) {
        throw new Error("Incomplete parameters, triggerId is null");
      }
      if (spec.fragmentId == null) {
        throw new Error("Incomplete parameters, fragmentId is null");
      }
      trigger = dom(spec.triggerId);
      fragment = dom(spec.fragmentId);
      if (fragment === null) {
        throw new Error("Invalid configuration, fragment with id " + spec.fragmentId + " not found");
      }
      invert = spec.invert || false;
      update = function() {
        var checked, makeVisible;
        checked = trigger.element.checked;
        makeVisible = checked !== invert;
        fragment.trigger(events.formfragment.changeVisibility, {
          visible: makeVisible
        });
      };
      if (trigger.element.type === "radio") {
        return dom.on(trigger.element.form, "click", update);
      } else {
        return trigger.on("click", update);
      }
    };
    return {
      linkTrigger: linkTrigger,
      hide: hide
    };
  });

}).call(this);
