(function() {
  define(["underscore", "t5/core/dom", "t5/core/events", "t5/core/utils", "t5/core/validation"], function(_, dom, events, utils) {
    var countOptions, doRangeValidate, rangeValue;
    rangeValue = function(element, attribute, defaultValue) {
      var v;
      v = element.attr(attribute);
      if (v === null) {
        return defaultValue;
      } else {
        return parseInt(v);
      }
    };
    countOptions = function(e) {
      if (e.findParent(".palette")) {
        return e.element.options.length;
      } else {
        return _.filter(e.element.options, function(o) {
          return o.selected;
        }).length;
      }
    };
    doRangeValidate = function(element, value, memo) {
      var max, min;
      min = rangeValue(element, "data-range-min", 0);
      max = rangeValue(element, "data-range-max", Number.MAX_VALUE);
      if (_.isString(value)) {
        value = value.length;
      }
      if (!((min <= value && value <= max))) {
        memo.error = (element.attr("data-range-message")) || "RANGE ERROR";
        return false;
      }
      return true;
    };
    dom.onDocument(events.field.optional, "[data-optionality=prohibited]", function(event, memo) {
      if (!utils.isBlank(memo.value)) {
        memo.error = (this.attr("data-prohibited-message")) || "PROHIBITED";
        return false;
      }
      return true;
    });
    dom.onDocument(events.field.validate, "input[data-range-min], input[data-range-max], textarea[data-range-min], textarea[data-range-max]", function(event, memo) {
      return doRangeValidate(this, memo.translated, memo);
    });
    dom.onDocument(events.field.validate, "select[data-range-min], select[data-range-max]", function(event, memo) {
      return doRangeValidate(this, countOptions(this), memo);
    });
  });

}).call(this);
