'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _defineProperty2 = require('babel-runtime/helpers/defineProperty');

var _defineProperty3 = _interopRequireDefault(_defineProperty2);

var _extends2 = require('babel-runtime/helpers/extends');

var _extends3 = _interopRequireDefault(_extends2);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _createReactClass = require('create-react-class');

var _createReactClass2 = _interopRequireDefault(_createReactClass);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _mixin = require('./mixin');

var _mixin2 = _interopRequireDefault(_mixin);

var _InputHandler = require('./InputHandler');

var _InputHandler2 = _interopRequireDefault(_InputHandler);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function noop() {}

function preventDefault(e) {
  e.preventDefault();
}

var InputNumber = (0, _createReactClass2['default'])({
  displayName: 'InputNumber',

  propTypes: {
    focusOnUpDown: _propTypes2['default'].bool,
    onChange: _propTypes2['default'].func,
    onKeyDown: _propTypes2['default'].func,
    onKeyUp: _propTypes2['default'].func,
    prefixCls: _propTypes2['default'].string,
    tabIndex: _propTypes2['default'].string,
    disabled: _propTypes2['default'].bool,
    onFocus: _propTypes2['default'].func,
    onBlur: _propTypes2['default'].func,
    readOnly: _propTypes2['default'].bool,
    max: _propTypes2['default'].number,
    min: _propTypes2['default'].number,
    step: _propTypes2['default'].oneOfType([_propTypes2['default'].number, _propTypes2['default'].string]),
    upHandler: _propTypes2['default'].node,
    downHandler: _propTypes2['default'].node,
    useTouch: _propTypes2['default'].bool,
    formatter: _propTypes2['default'].func,
    parser: _propTypes2['default'].func,
    onMouseEnter: _propTypes2['default'].func,
    onMouseLeave: _propTypes2['default'].func,
    onMouseOver: _propTypes2['default'].func,
    onMouseOut: _propTypes2['default'].func,
    precision: _propTypes2['default'].number
  },

  mixins: [_mixin2['default']],

  getDefaultProps: function getDefaultProps() {
    return {
      focusOnUpDown: true,
      useTouch: false,
      prefixCls: 'rc-input-number'
    };
  },
  componentDidMount: function componentDidMount() {
    this.componentDidUpdate();
  },
  componentWillUpdate: function componentWillUpdate() {
    try {
      this.start = this.refs.input.selectionStart;
      this.end = this.refs.input.selectionEnd;
    } catch (e) {
      // Fix error in Chrome:
      // Failed to read the 'selectionStart' property from 'HTMLInputElement'
      // http://stackoverflow.com/q/21177489/3040605
    }
  },
  componentDidUpdate: function componentDidUpdate() {
    if (this.props.focusOnUpDown && this.state.focused) {
      var selectionRange = this.refs.input.setSelectionRange;
      if (selectionRange && typeof selectionRange === 'function' && this.start !== undefined && this.end !== undefined && this.start !== this.end) {
        this.refs.input.setSelectionRange(this.start, this.end);
      } else {
        this.focus();
      }
    }
  },
  onKeyDown: function onKeyDown(e) {
    if (e.keyCode === 38) {
      var ratio = this.getRatio(e);
      this.up(e, ratio);
      this.stop();
    } else if (e.keyCode === 40) {
      var _ratio = this.getRatio(e);
      this.down(e, _ratio);
      this.stop();
    }
    var onKeyDown = this.props.onKeyDown;

    if (onKeyDown) {
      for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
        args[_key - 1] = arguments[_key];
      }

      onKeyDown.apply(undefined, [e].concat(args));
    }
  },
  onKeyUp: function onKeyUp(e) {
    this.stop();
    var onKeyUp = this.props.onKeyUp;

    if (onKeyUp) {
      for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
        args[_key2 - 1] = arguments[_key2];
      }

      onKeyUp.apply(undefined, [e].concat(args));
    }
  },
  getRatio: function getRatio(e) {
    var ratio = 1;
    if (e.metaKey || e.ctrlKey) {
      ratio = 0.1;
    } else if (e.shiftKey) {
      ratio = 10;
    }
    return ratio;
  },
  getValueFromEvent: function getValueFromEvent(e) {
    return e.target.value;
  },
  focus: function focus() {
    this.refs.input.focus();
  },
  formatWrapper: function formatWrapper(num) {
    if (this.props.formatter) {
      return this.props.formatter(num);
    }
    return num;
  },
  render: function render() {
    var _classNames;

    var props = (0, _extends3['default'])({}, this.props);
    var prefixCls = props.prefixCls,
        disabled = props.disabled,
        readOnly = props.readOnly,
        useTouch = props.useTouch;

    var classes = (0, _classnames2['default'])((_classNames = {}, (0, _defineProperty3['default'])(_classNames, prefixCls, true), (0, _defineProperty3['default'])(_classNames, props.className, !!props.className), (0, _defineProperty3['default'])(_classNames, prefixCls + '-disabled', disabled), (0, _defineProperty3['default'])(_classNames, prefixCls + '-focused', this.state.focused), _classNames));
    var upDisabledClass = '';
    var downDisabledClass = '';
    var value = this.state.value;

    if (value) {
      if (!isNaN(value)) {
        var val = Number(value);
        if (val >= props.max) {
          upDisabledClass = prefixCls + '-handler-up-disabled';
        }
        if (val <= props.min) {
          downDisabledClass = prefixCls + '-handler-down-disabled';
        }
      } else {
        upDisabledClass = prefixCls + '-handler-up-disabled';
        downDisabledClass = prefixCls + '-handler-down-disabled';
      }
    }

    var editable = !props.readOnly && !props.disabled;

    // focus state, show input value
    // unfocus state, show valid value
    var inputDisplayValue = void 0;
    if (this.state.focused) {
      inputDisplayValue = this.state.inputValue;
    } else {
      inputDisplayValue = this.toPrecisionAsStep(this.state.value);
    }

    if (inputDisplayValue === undefined || inputDisplayValue === null) {
      inputDisplayValue = '';
    }

    var upEvents = void 0;
    var downEvents = void 0;
    if (useTouch) {
      upEvents = {
        onTouchStart: editable && !upDisabledClass ? this.up : noop,
        onTouchEnd: this.stop
      };
      downEvents = {
        onTouchStart: editable && !downDisabledClass ? this.down : noop,
        onTouchEnd: this.stop
      };
    } else {
      upEvents = {
        onMouseDown: editable && !upDisabledClass ? this.up : noop,
        onMouseUp: this.stop,
        onMouseLeave: this.stop
      };
      downEvents = {
        onMouseDown: editable && !downDisabledClass ? this.down : noop,
        onMouseUp: this.stop,
        onMouseLeave: this.stop
      };
    }
    var inputDisplayValueFormat = this.formatWrapper(inputDisplayValue);
    var isUpDisabled = !!upDisabledClass || disabled || readOnly;
    var isDownDisabled = !!downDisabledClass || disabled || readOnly;
    // ref for test
    return _react2['default'].createElement(
      'div',
      {
        className: classes,
        style: props.style,
        onMouseEnter: props.onMouseEnter,
        onMouseLeave: props.onMouseLeave,
        onMouseOver: props.onMouseOver,
        onMouseOut: props.onMouseOut
      },
      _react2['default'].createElement(
        'div',
        { className: prefixCls + '-handler-wrap' },
        _react2['default'].createElement(
          _InputHandler2['default'],
          (0, _extends3['default'])({
            ref: 'up',
            disabled: isUpDisabled,
            prefixCls: prefixCls,
            unselectable: 'unselectable'
          }, upEvents, {
            role: 'button',
            'aria-label': 'Increase Value',
            'aria-disabled': !!isUpDisabled,
            className: prefixCls + '-handler ' + prefixCls + '-handler-up ' + upDisabledClass
          }),
          this.props.upHandler || _react2['default'].createElement('span', {
            unselectable: 'unselectable',
            className: prefixCls + '-handler-up-inner',
            onClick: preventDefault
          })
        ),
        _react2['default'].createElement(
          _InputHandler2['default'],
          (0, _extends3['default'])({
            ref: 'down',
            disabled: isDownDisabled,
            prefixCls: prefixCls,
            unselectable: 'unselectable'
          }, downEvents, {
            role: 'button',
            'aria-label': 'Decrease Value',
            'aria-disabled': !!isDownDisabled,
            className: prefixCls + '-handler ' + prefixCls + '-handler-down ' + downDisabledClass
          }),
          this.props.downHandler || _react2['default'].createElement('span', {
            unselectable: 'unselectable',
            className: prefixCls + '-handler-down-inner',
            onClick: preventDefault
          })
        )
      ),
      _react2['default'].createElement(
        'div',
        {
          className: prefixCls + '-input-wrap',
          role: 'spinbutton',
          'aria-valuemin': props.min,
          'aria-valuemax': props.max,
          'aria-valuenow': value
        },
        _react2['default'].createElement('input', {
          type: props.type,
          placeholder: props.placeholder,
          onClick: props.onClick,
          className: prefixCls + '-input',
          tabIndex: props.tabIndex,
          autoComplete: 'off',
          onFocus: this.onFocus,
          onBlur: this.onBlur,
          onKeyDown: editable ? this.onKeyDown : noop,
          onKeyUp: editable ? this.onKeyUp : noop,
          autoFocus: props.autoFocus,
          maxLength: props.maxLength,
          readOnly: props.readOnly,
          disabled: props.disabled,
          max: props.max,
          min: props.min,
          step: props.step,
          name: props.name,
          id: props.id,
          onChange: this.onChange,
          ref: 'input',
          value: inputDisplayValueFormat
        })
      )
    );
  }
});

exports['default'] = InputNumber;
module.exports = exports['default'];