"use strict";

exports.__esModule = true;
require("core-js/modules/es.array.push.js");
require("core-js/modules/es.error.cause.js");
var _element = require("../../../helpers/dom/element");
var _event = require("../../../helpers/dom/event");
var _array = require("../../../helpers/array");
var _unicode = require("../../../helpers/unicode");
var _object = require("../../../helpers/object");
var C = _interopRequireWildcard(require("../../../i18n/constants"));
var _base = require("./_base");
var _constants2 = _interopRequireWildcard(require("../constants"));
var _input = require("../ui/input");
var _select = require("../ui/select");
var _conditionRegisterer = require("../conditionRegisterer");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
/**
 * @private
 * @class ConditionComponent
 */
var _onConditionSelect = /*#__PURE__*/new WeakSet();
var _onInputKeyDown = /*#__PURE__*/new WeakSet();
class ConditionComponent extends _base.BaseComponent {
  constructor(hotInstance, options) {
    super(hotInstance, {
      id: options.id,
      stateless: false
    });
    /**
     * Key down listener.
     *
     * @param {Event} event The DOM event object.
     */
    _classPrivateMethodInitSpec(this, _onInputKeyDown);
    /**
     * On condition select listener.
     *
     * @param {object} command Menu item object (command).
     */
    _classPrivateMethodInitSpec(this, _onConditionSelect);
    this.name = options.name;
    this.addSeparator = options.addSeparator;
    this.elements.push(new _select.SelectUI(this.hot, {
      menuContainer: options.menuContainer
    }));
    this.elements.push(new _input.InputUI(this.hot, {
      placeholder: C.FILTERS_BUTTONS_PLACEHOLDER_VALUE
    }));
    this.elements.push(new _input.InputUI(this.hot, {
      placeholder: C.FILTERS_BUTTONS_PLACEHOLDER_SECOND_VALUE
    }));
    this.registerHooks();
  }

  /**
   * Register all necessary hooks.
   *
   * @private
   */
  registerHooks() {
    this.getSelectElement().addLocalHook('select', command => _classPrivateMethodGet(this, _onConditionSelect, _onConditionSelect2).call(this, command)).addLocalHook('afterClose', () => this.runLocalHooks('afterClose')).addLocalHook('tabKeydown', event => this.runLocalHooks('selectTabKeydown', event));
    (0, _array.arrayEach)(this.getInputElements(), input => {
      input.addLocalHook('keydown', event => _classPrivateMethodGet(this, _onInputKeyDown, _onInputKeyDown2).call(this, event));
    });
  }

  /**
   * Set state of the component.
   *
   * @param {object} value State to restore.
   */
  setState(value) {
    this.reset();
    if (!value) {
      return;
    }
    const copyOfCommand = (0, _object.clone)(value.command);
    if (copyOfCommand.name.startsWith(C.FILTERS_CONDITIONS_NAMESPACE)) {
      copyOfCommand.name = this.hot.getTranslatedPhrase(copyOfCommand.name);
    }
    this.getSelectElement().setValue(copyOfCommand);
    (0, _array.arrayEach)(value.args, (arg, index) => {
      if (index > copyOfCommand.inputsCount - 1) {
        return false;
      }
      const element = this.getInputElement(index);
      element.setValue(arg);
      element[copyOfCommand.inputsCount > index ? 'show' : 'hide']();
      if (!index) {
        this.hot._registerTimeout(() => element.focus(), 10);
      }
    });
  }

  /**
   * Export state of the component (get selected filter and filter arguments).
   *
   * @returns {object} Returns object where `command` key keeps used condition filter and `args` key its arguments.
   */
  getState() {
    const command = this.getSelectElement().getValue() || (0, _conditionRegisterer.getConditionDescriptor)(_constants2.CONDITION_NONE);
    const args = [];
    (0, _array.arrayEach)(this.getInputElements(), (element, index) => {
      if (command.inputsCount > index) {
        args.push(element.getValue());
      }
    });
    return {
      command,
      args
    };
  }

  /**
   * Update state of component.
   *
   * @param {object} condition The condition object.
   * @param {object} condition.command The command object with condition name as `key` property.
   * @param {Array} condition.args An array of values to compare.
   * @param {number} column Physical column index.
   */
  updateState(condition, column) {
    const command = condition ? (0, _conditionRegisterer.getConditionDescriptor)(condition.name) : (0, _conditionRegisterer.getConditionDescriptor)(_constants2.CONDITION_NONE);
    this.state.setValueAtIndex(column, {
      command,
      args: condition ? condition.args : []
    });
    if (!condition) {
      (0, _array.arrayEach)(this.getInputElements(), element => element.setValue(null));
    }
  }

  /**
   * Get select element.
   *
   * @returns {SelectUI}
   */
  getSelectElement() {
    return this.elements.filter(element => element instanceof _select.SelectUI)[0];
  }

  /**
   * Get input element.
   *
   * @param {number} index Index an array of elements.
   * @returns {InputUI}
   */
  getInputElement() {
    let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
    return this.getInputElements()[index];
  }

  /**
   * Get input elements.
   *
   * @returns {Array}
   */
  getInputElements() {
    return this.elements.filter(element => element instanceof _input.InputUI);
  }

  /**
   * Get menu object descriptor.
   *
   * @returns {object}
   */
  getMenuItemDescriptor() {
    return {
      key: this.id,
      name: this.name,
      isCommand: false,
      disableSelection: true,
      hidden: () => this.isHidden(),
      renderer: (hot, wrapper, row, col, prop, value) => {
        (0, _element.addClass)(wrapper.parentNode, 'htFiltersMenuCondition');
        if (this.addSeparator) {
          (0, _element.addClass)(wrapper.parentNode, 'border');
        }
        const label = this.hot.rootDocument.createElement('div');
        (0, _element.addClass)(label, 'htFiltersMenuLabel');
        label.textContent = value;
        wrapper.appendChild(label);
        (0, _array.arrayEach)(this.elements, ui => wrapper.appendChild(ui.element));
        return wrapper;
      }
    };
  }

  /**
   * Reset elements to their initial state.
   */
  reset() {
    const selectedColumn = this.hot.getPlugin('filters').getSelectedColumn();
    let items = [(0, _conditionRegisterer.getConditionDescriptor)(_constants2.CONDITION_NONE)];
    if (selectedColumn !== null) {
      const {
        visualIndex
      } = selectedColumn;
      items = (0, _constants2.default)(this.hot.getDataType(0, visualIndex, this.hot.countRows(), visualIndex));
    }
    (0, _array.arrayEach)(this.getInputElements(), element => element.hide());
    this.getSelectElement().setItems(items);
    super.reset();
    // Select element as default 'None'
    this.getSelectElement().setValue(items[0]);
  }
}
exports.ConditionComponent = ConditionComponent;
function _onConditionSelect2(command) {
  (0, _array.arrayEach)(this.getInputElements(), (element, index) => {
    element[command.inputsCount > index ? 'show' : 'hide']();
    if (index === 0) {
      this.hot._registerTimeout(() => element.focus(), 10);
    }
  });
  this.runLocalHooks('change', command);
}
function _onInputKeyDown2(event) {
  if ((0, _unicode.isKey)(event.keyCode, 'ESCAPE')) {
    this.runLocalHooks('cancel');
    (0, _event.stopImmediatePropagation)(event);
  }
}