import edit from './edit.js';
import parse from './parse.js';
import format from './format.js';
import { isReadOnly, getOperation, getSelection, getCaretPosition, setCaretPosition } from './dom.js';

function onChange(event, input, _parse, _format, on_change) {
  formatInputText(input, _parse, _format, undefined, on_change);
} // "Delete" and "Backspace" keys are special
// in a way that they're not handled by the regular `onChange()` handler
// and instead are intercepted and re-applied manually.
// The reason is that normally hitting "Backspace" or "Delete"
// results in erasing a character, but that character might be any character,
// while it would be a better "user experience" if it erased not just any character
// but the closest "meaningful" character.
// For example, if a template is `(xxx) xxx-xxxx`,
// and the `<input/>` value is `(111) 222-3333`,
// then, if a user begins erasing the `3333` part via "Backspace"
// and reaches the "-" character, then it would just erase the "-" character.
// Nothing wrong with that, but it would be a better "user experience"
// if hitting "Backspace" at that position would erase the closest "meaningful"
// character, which would be the rightmost `2`.
// So, what this `onKeyDown()` handler does is it intercepts
// "Backspace" and "Delete" keys and re-applies those operations manually
// following the logic described above.

function onKeyDown(event, input, _parse, _format, on_change) {
  if (isReadOnly(input)) {
    return;
  }

  var operation = getOperation(event);

  switch (operation) {
    case 'Delete':
    case 'Backspace':
      // Intercept this operation and perform it manually.
      event.preventDefault();
      var selection = getSelection(input); // If a selection is made, just erase the selected text.

      if (selection) {
        eraseSelection(input, selection);
        return formatInputText(input, _parse, _format, undefined, on_change);
      } // Else, perform the (character erasing) operation manually.


      return formatInputText(input, _parse, _format, operation, on_change);

  }
}
/**
 * Erases the selected text inside an `<input/>`.
 * @param  {DOMElement} input
 * @param  {Selection} selection
 */

function eraseSelection(input, selection) {
  var text = input.value;
  text = text.slice(0, selection.start) + text.slice(selection.end);
  input.value = text;
  setCaretPosition(input, selection.start);
}
/**
 * Parses and re-formats `<input/>` textual value.
 * E.g. when a user enters something into the `<input/>`
 * that raw input must first be parsed and the re-formatted properly.
 * Is called either after some user input (e.g. entered a character, pasted something)
 * or after the user performed an `operation` (e.g. "Backspace", "Delete").
 * @param  {DOMElement} input
 * @param  {Function} parse
 * @param  {Function} format
 * @param  {string} [operation] - The operation that triggered `<input/>` textual value change. E.g. "Backspace", "Delete".
 * @param  {Function} onChange
 */


function formatInputText(input, _parse, _format, operation, on_change) {
  // Parse `<input/>` textual value.
  // Get the `value` and `caret` position.
  var _parse2 = parse(input.value, getCaretPosition(input), _parse),
      value = _parse2.value,
      caret = _parse2.caret; // If a user performed an operation ("Backspace", "Delete")
  // then apply that operation and get the new `value` and `caret` position.


  if (operation) {
    var newValueAndCaret = edit(value, caret, operation);
    value = newValueAndCaret.value;
    caret = newValueAndCaret.caret;
  } // Format the `value`.
  // (and reposition the caret accordingly)


  var formatted = format(value, caret, _format);
  var text = formatted.text;
  caret = formatted.caret; // Set `<input/>` textual value manually
  // to prevent React from resetting the caret position
  // later inside a subsequent `render()`.
  // Doesn't work for custom `inputComponent`s for some reason.

  input.value = text; // Position the caret properly.

  setCaretPosition(input, caret); // If the `<input/>` textual value did change,
  // then the parsed `value` may have changed too.

  if (on_change) {
    on_change(value);
  }
}

export { onChange, onKeyDown };
//# sourceMappingURL=inputControl.js.map
