'use strict';

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

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _addEventListener = require('../helpers/addEventListener');

var _addEventListener2 = _interopRequireDefault(_addEventListener);

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

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; }

/**
 * The abstract button class. Use for construct button like ui element.
 */
var AbstractButton = function (_React$Component) {
    _inherits(AbstractButton, _React$Component);

    function AbstractButton(props) {
        _classCallCheck(this, AbstractButton);

        var _this = _possibleConstructorReturn(this, (AbstractButton.__proto__ || Object.getPrototypeOf(AbstractButton)).call(this, props));

        _this.state = {
            isFocused: false,
            isHovered: false
        };

        if (props.isToggleMod) {
            _this.state.isChecked = props.isChecked;
        }

        _this._onFocusHandler = _this._onFocusHandler.bind(_this);
        _this._onBlurHandler = _this._onBlurHandler.bind(_this);
        _this._onMouseEnterHandler = _this._onMouseEnterHandler.bind(_this);
        _this._onMouseLeaveHandler = _this._onMouseLeaveHandler.bind(_this);
        _this._onClickHandler = _this._onClickHandler.bind(_this);
        _this._onMouseDownHandler = _this._onMouseDownHandler.bind(_this);
        _this._onKeyDownHandler = _this._onKeyDownHandler.bind(_this);
        _this._onKeyUpHandler = _this._onKeyUpHandler.bind(_this);
        _this._onMouseUpHandler = _this._onMouseUpHandler.bind(_this);
        return _this;
    }

    _createClass(AbstractButton, [{
        key: 'componentWillReceiveProps',
        value: function componentWillReceiveProps(newProps) {
            if (this.props.isToggleMod && typeof newProps.isChecked === 'boolean' && this.state.isChecked !== newProps.isChecked) {

                this.setState({ isChecked: newProps.isChecked });
            }
        }
    }, {
        key: 'componentWillUnmount',
        value: function componentWillUnmount() {
            this._mouseupListener && this._mouseupListener.remove();
        }
    }, {
        key: '_onClickHandler',
        value: function _onClickHandler(event) {
            var props = this.props;

            if (!props.isDisabled) {
                props.isToggleMod && this.setState({ isChecked: !this.state.isChecked });
                props.onClick && props.onClick(event);
            }
        }
    }, {
        key: '_onFocusHandler',
        value: function _onFocusHandler(event) {
            var props = this.props;

            this.setState({ isFocused: true });
            props.onFocus && props.onFocus(event);
        }
    }, {
        key: '_onBlurHandler',
        value: function _onBlurHandler(event) {
            var props = this.props;

            this.setState({ isFocused: false });
            props.onBlur && props.onBlur(event);
        }
    }, {
        key: '_onMouseEnterHandler',
        value: function _onMouseEnterHandler(event) {
            var props = this.props;

            props.isDisabled || this.setState({ isHovered: true });
            props.onMouseEnter && props.onMouseEnter(event);
        }
    }, {
        key: '_onMouseLeaveHandler',
        value: function _onMouseLeaveHandler(event) {
            var props = this.props;

            props.isDisabled || this.setState({ isHovered: false });
            props.onMouseLeave && props.onMouseLeave(event);
        }
    }, {
        key: '_onMouseDownHandler',
        value: function _onMouseDownHandler() {
            var _this2 = this;

            if (this.props.isDisabled) {
                return;
            }

            this._mouseupListener = (0, _addEventListener2.default)(document, 'mouseup', function () {
                _this2.setState({ isActive: false });
                _this2._mouseupListener && _this2._mouseupListener.remove();
            });

            this.setState({ isActive: true });
        }
    }, {
        key: '_onMouseUpHandler',
        value: function _onMouseUpHandler() {
            if (this.props.isDisabled) {
                return;
            }

            this.props.onMouseUp && this.props.onMouseUp();
        }
    }, {
        key: '_onKeyDownHandler',
        value: function _onKeyDownHandler(event) {
            var keyCode = event.keyCode;

            if (keyCode === 32 || keyCode === 13 && !this.props.isDisabled) {
                this.setState({ isActive: true });
            }
        }
    }, {
        key: '_onKeyUpHandler',
        value: function _onKeyUpHandler(event) {
            var keyCode = event.keyCode;

            if (keyCode === 32 || keyCode === 13 && !this.props.isDisabled) {
                this.setState({ isActive: false });
            }
        }
    }, {
        key: 'getDefaultRenderProps',
        value: function getDefaultRenderProps() {
            return {
                onFocus: this._onFocusHandler,
                onBlur: this._onBlurHandler,
                onMouseEnter: this._onMouseEnterHandler,
                onMouseLeave: this._onMouseLeaveHandler,
                onClick: this._onClickHandler,
                onMouseDown: this._onMouseDownHandler,
                onMouseUp: this._onMouseUpHandler,
                onKeyDown: this._onKeyDownHandler,
                onKeyUp: this._onKeyUpHandler,
                disabled: this.props.isDisabled
            };
        }

        /**
         * Build style list with strong ordering
         */

    }, {
        key: 'buildStyleList',
        value: function buildStyleList(styles, prefix) {
            var prefixAsString = Array.isArray(prefix) ? prefix.map(function (item, idx) {
                if (!idx) {
                    return item;
                }

                return item.replace(/^\w/, function (c) {
                    return c.toUpperCase();
                });
            }).join('') : prefix;

            return [styles[prefixAsString], this.state.isHovered && styles[prefixAsString + 'IsHovered'], this.state.isFocused && styles[prefixAsString + 'IsFocused'], this.state.isActive && styles[prefixAsString + 'IsActive'], this.state.isChecked && styles[prefixAsString + 'IsChecked'], this.props.isDisabled && styles[prefixAsString + 'IsDisabled']].filter(function (i) {
                return i;
            });
        }
    }, {
        key: 'render',
        value: function render() {
            return _react2.default.createElement(
                'button',
                this.getDefaultRenderProps(),
                this.props.children
            );
        }
    }]);

    return AbstractButton;
}(_react2.default.Component);

AbstractButton.defaultProps = {
    isDisabled: false,
    isToggleMod: false,
    isChecked: false
};
AbstractButton.BASE_ROOT_STYLE = {
    display: 'inline-block',
    verticalAlign: 'top',
    padding: 0,
    margin: 0,
    border: 0,
    outline: 'none',
    cursor: 'pointer',
    background: 'transparent'
};
exports.default = AbstractButton;