var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

import React, { Component } from 'react';
import { Add } from 'grommet-icons/es6/icons/Add';
import { Subtract } from 'grommet-icons/es6/icons/Subtract';

import { MaskedInput } from '../MaskedInput';

var precision = function precision(n) {
  if (!isFinite(n)) return 0;
  var e = 1;
  var p = 0;
  while (Math.round(n * e) / e !== n) {
    e *= 10;
    p += 1;
  }
  return p;
};

var minMax = function minMax(_ref) {
  var value = _ref.value,
      min = _ref.min,
      max = _ref.max;

  var val = value;
  if (min !== undefined) {
    val = Math.max(val, min);
  }
  if (max !== undefined) {
    val = Math.min(val, max);
  }
  return val;
};

var NumberInput = function (_Component) {
  _inherits(NumberInput, _Component);

  function NumberInput() {
    var _temp, _this, _ret;

    _classCallCheck(this, NumberInput);

    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    return _ret = (_temp = (_this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.valueToNumber = function (value) {
      var _this$props = _this.props,
          prefix = _this$props.prefix,
          suffix = _this$props.suffix,
          thousandsSeparatorSymbol = _this$props.thousandsSeparatorSymbol,
          decimalSymbol = _this$props.decimalSymbol;

      return MaskedInput.maskedNumberValue({
        value: value, prefix: prefix, suffix: suffix, thousandsSeparatorSymbol: thousandsSeparatorSymbol, decimalSymbol: decimalSymbol
      });
    }, _this.addStep = function () {
      var _this$props2 = _this.props,
          max = _this$props2.max,
          min = _this$props2.min,
          step = _this$props2.step,
          value = _this$props2.value;

      var val = typeof value === 'number' && value !== undefined ? (_this.valueToNumber(value) + step).toFixed(precision(step)) : min || 0;
      if (Number.isNaN(val)) {
        if (min !== undefined) {
          val = min;
        } else {
          val = undefined;
        }
      } else {
        val = minMax({ value: val, min: min, max: max });
      }
      _this.upDateValue(val);
    }, _this.subtractStep = function () {
      var _this$props3 = _this.props,
          max = _this$props3.max,
          min = _this$props3.min,
          step = _this$props3.step,
          value = _this$props3.value;

      var val = typeof value === 'number' && value !== undefined ? (_this.valueToNumber(value) - step).toFixed(precision(step)) : max || 0;
      if (Number.isNaN(val)) {
        if (max !== undefined) {
          val = max;
        } else {
          val = undefined;
        }
      } else {
        val = minMax({ value: val, min: min, max: max });
      }
      _this.upDateValue(val);
    }, _this.onChange = function (e) {
      var _this$props4 = _this.props,
          onChange = _this$props4.onChange,
          updateToString = _this$props4.updateToString,
          emptyValue = _this$props4.emptyValue;

      if (onChange) {
        var value = updateToString ? e.target.value : _this.valueToNumber(e.target.value);
        if (_this.value !== value) {
          if (value === undefined) {
            value = emptyValue;
          }
          _this.value = value;
          onChange(_extends({}, e, { target: _extends({}, e.target, { value: value }) }));
        }
      }
    }, _temp), _possibleConstructorReturn(_this, _ret);
  }

  NumberInput.prototype.render = function render() {
    var _this2 = this;

    var _props = this.props,
        onChange = _props.onChange,
        min = _props.min,
        max = _props.max,
        step = _props.step,
        userPipe = _props.pipe,
        updateToString = _props.updateToString,
        prefix = _props.prefix,
        suffix = _props.suffix,
        thousandsSeparatorSymbol = _props.thousandsSeparatorSymbol,
        decimalSymbol = _props.decimalSymbol,
        decimals = _props.decimals,
        integers = _props.integers,
        a11yIncrement = _props.a11yIncrement,
        a11yDecrement = _props.a11yDecrement,
        userMask = _props.mask,
        addIcon = _props.addIcon,
        subtractIcon = _props.subtractIcon,
        disabled = _props.disabled,
        rest = _objectWithoutProperties(_props, ['onChange', 'min', 'max', 'step', 'pipe', 'updateToString', 'prefix', 'suffix', 'thousandsSeparatorSymbol', 'decimalSymbol', 'decimals', 'integers', 'a11yIncrement', 'a11yDecrement', 'mask', 'addIcon', 'subtractIcon', 'disabled']);

    var allowNegative = typeof min !== 'number' || min < 0;
    var includeThousandsSeparator = !!thousandsSeparatorSymbol;
    var allowDecimal = decimals === null || typeof decimals === 'number' && decimals > 0;
    var mask = userMask || MaskedInput.createNumberMask({
      prefix: prefix,
      suffix: suffix,
      includeThousandsSeparator: includeThousandsSeparator,
      thousandsSeparatorSymbol: thousandsSeparatorSymbol,
      allowDecimal: allowDecimal,
      decimalSymbol: decimalSymbol,
      decimalLimit: decimals,
      integerLimit: integers,
      allowNegative: allowNegative
    });
    var pipe = userPipe || MaskedInput.createMinMaxInputPipe(_extends({
      mask: mask, prefix: prefix, suffix: suffix, thousandsSeparatorSymbol: thousandsSeparatorSymbol, decimalSymbol: decimalSymbol, min: min, max: max }, rest));
    return React.createElement(MaskedInput, _extends({
      update: function update(_update) {
        _this2.upDateValue = _update;
      },
      pattern: '[0-9]*',
      inputMode: 'numeric',
      onKeyDown: this.subtractStep,
      onKeyUp: this.addStep,
      disabled: disabled,
      onChange: this.onChange,
      pipe: pipe,
      mask: mask,
      widgets: [{
        'icon': addIcon,
        'onClick': disabled ? undefined : this.addStep,
        'aria-label': a11yIncrement + ' ' + step
      }, {
        'icon': subtractIcon,
        'onClick': disabled ? undefined : this.subtractStep,
        'aria-label': a11yDecrement + ' ' + step
      }]
    }, rest));
  };

  return NumberInput;
}(Component);

NumberInput.defaultProps = {
  emptyValue: '',
  step: 1,
  addIcon: React.createElement(Add, null),
  subtractIcon: React.createElement(Subtract, null),
  prefix: '',
  suffix: '',
  thousandsSeparatorSymbol: '',
  decimalSymbol: '.',
  decimals: null,
  integers: null,
  updateToString: false,
  a11yIncrement: 'Increment by',
  a11yDecrement: 'Decrement by'

};


var NumberInputDoc = void 0;
if (process.env.NODE_ENV !== 'production') {
  NumberInputDoc = require('./doc').default(NumberInput); // eslint-disable-line global-require
}

var NumberInputWrapper = NumberInputDoc || NumberInput;

export { NumberInputWrapper as NumberInput };