"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 _propTypes = require("prop-types");

var _propTypes2 = _interopRequireDefault(_propTypes);

var _reactDom = require("react-dom");

var _reactDom2 = _interopRequireDefault(_reactDom);

var _inlineStylePrefixer = require("inline-style-prefixer");

var _inlineStylePrefixer2 = _interopRequireDefault(_inlineStylePrefixer);

var _reactStyleProptype = require("react-style-proptype");

var _reactStyleProptype2 = _interopRequireDefault(_reactStyleProptype);

var _Pane = require("./Pane");

var _Pane2 = _interopRequireDefault(_Pane);

var _Resizer = require("./Resizer");

var _Resizer2 = _interopRequireDefault(_Resizer);

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

var DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Safari/537.2";
var USER_AGENT = typeof navigator !== "undefined" ? navigator.userAgent : DEFAULT_USER_AGENT;

function unFocus(document, window) {
  if (document.selection) {
    document.selection.empty();
  } else {
    try {
      window.getSelection().removeAllRanges();
      // eslint-disable-next-line no-empty
    } catch (e) {}
  }
}

var SplitPane = function (_React$Component) {
  _inherits(SplitPane, _React$Component);

  function SplitPane() {
    _classCallCheck(this, SplitPane);

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

    _this.onMouseDown = _this.onMouseDown.bind(_this);
    _this.onTouchStart = _this.onTouchStart.bind(_this);
    _this.onMouseMove = _this.onMouseMove.bind(_this);
    _this.onTouchMove = _this.onTouchMove.bind(_this);
    _this.onMouseUp = _this.onMouseUp.bind(_this);

    _this.state = {
      active: false,
      resized: false
    };
    return _this;
  }

  _createClass(SplitPane, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      this.setSize(this.props, this.state);
      document.addEventListener("mouseup", this.onMouseUp);
      document.addEventListener("mousemove", this.onMouseMove);
      document.addEventListener("touchmove", this.onTouchMove);
    }
  }, {
    key: "componentWillReceiveProps",
    value: function componentWillReceiveProps(props) {
      this.setSize(props, this.state);
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      document.removeEventListener("mouseup", this.onMouseUp);
      document.removeEventListener("mousemove", this.onMouseMove);
      document.removeEventListener("touchmove", this.onTouchMove);
    }
  }, {
    key: "onMouseDown",
    value: function onMouseDown(event) {
      var eventWithTouches = Object.assign({}, event, {
        touches: [{ clientX: event.clientX, clientY: event.clientY }]
      });
      this.onTouchStart(eventWithTouches);
    }
  }, {
    key: "onTouchStart",
    value: function onTouchStart(event) {
      var _props = this.props,
          allowResize = _props.allowResize,
          onDragStarted = _props.onDragStarted,
          split = _props.split;

      if (allowResize) {
        unFocus(document, window);
        var position = split === "vertical" ? event.touches[0].clientX : event.touches[0].clientY;

        if (typeof onDragStarted === "function") {
          onDragStarted();
        }
        this.setState({
          active: true,
          position: position
        });
      }
    }
  }, {
    key: "onMouseMove",
    value: function onMouseMove(event) {
      var eventWithTouches = Object.assign({}, event, {
        touches: [{ clientX: event.clientX, clientY: event.clientY }]
      });
      this.onTouchMove(eventWithTouches);
    }
  }, {
    key: "onTouchMove",
    value: function onTouchMove(event) {
      var _props2 = this.props,
          allowResize = _props2.allowResize,
          maxSize = _props2.maxSize,
          minSize = _props2.minSize,
          onChange = _props2.onChange,
          split = _props2.split,
          step = _props2.step;
      var _state = this.state,
          active = _state.active,
          position = _state.position;

      if (allowResize && active) {
        unFocus(document, window);
        var isPrimaryFirst = this.props.primary === "first";
        var ref = isPrimaryFirst ? this.pane1 : this.pane2;
        if (ref) {
          var node = _reactDom2.default.findDOMNode(ref);

          if (node.getBoundingClientRect) {
            var width = node.getBoundingClientRect().width;
            var height = node.getBoundingClientRect().height;
            var current = split === "vertical" ? event.touches[0].clientX : event.touches[0].clientY;
            var size = split === "vertical" ? width : height;
            var positionDelta = position - current;
            if (step) {
              if (Math.abs(positionDelta) < step) {
                return;
              }
              // Integer division
              // eslint-disable-next-line no-bitwise
              positionDelta = ~~(positionDelta / step) * step;
            }
            var sizeDelta = isPrimaryFirst ? positionDelta : -positionDelta;

            var newMaxSize = maxSize;
            if (maxSize !== undefined && maxSize <= 0) {
              var splPane = this.splitPane;
              if (split === "vertical") {
                newMaxSize = splPane.getBoundingClientRect().width + maxSize;
              } else {
                newMaxSize = splPane.getBoundingClientRect().height + maxSize;
              }
            }

            var newSize = size - sizeDelta;
            var newPosition = position - positionDelta;

            if (newSize < minSize) {
              newSize = minSize;
            } else if (maxSize !== undefined && newSize > newMaxSize) {
              newSize = newMaxSize;
            } else {
              this.setState({
                position: newPosition,
                resized: true
              });
            }

            if (onChange) onChange(newSize);
            this.setState({ draggedSize: newSize });
            ref.setState({ size: newSize });
          }
        }
      }
    }
  }, {
    key: "onMouseUp",
    value: function onMouseUp() {
      var _props3 = this.props,
          allowResize = _props3.allowResize,
          onDragFinished = _props3.onDragFinished;
      var _state2 = this.state,
          active = _state2.active,
          draggedSize = _state2.draggedSize;

      if (allowResize && active) {
        if (typeof onDragFinished === "function") {
          onDragFinished(draggedSize);
        }
        this.setState({ active: false });
      }
    }
  }, {
    key: "setSize",
    value: function setSize(props, state) {
      var primary = this.props.primary;

      var ref = primary === "first" ? this.pane1 : this.pane2;
      var newSize = void 0;
      if (ref) {
        newSize = props.size || state && state.draggedSize || props.defaultSize || props.minSize;
        ref.setState({
          size: newSize
        });
        if (props.size !== state.draggedSize) {
          this.setState({
            draggedSize: newSize
          });
        }
      }
    }
  }, {
    key: "render",
    value: function render() {
      var _this2 = this;

      var _props4 = this.props,
          allowResize = _props4.allowResize,
          children = _props4.children,
          className = _props4.className,
          defaultSize = _props4.defaultSize,
          minSize = _props4.minSize,
          onResizerClick = _props4.onResizerClick,
          onResizerDoubleClick = _props4.onResizerDoubleClick,
          paneStyle = _props4.paneStyle,
          pane1StyleProps = _props4.pane1Style,
          pane2StyleProps = _props4.pane2Style,
          primary = _props4.primary,
          prefixer = _props4.prefixer,
          resizerClassName = _props4.resizerClassName,
          resizerStyle = _props4.resizerStyle,
          size = _props4.size,
          split = _props4.split,
          styleProps = _props4.style;

      var disabledClass = allowResize ? "" : "disabled";
      var resizerClassNamesIncludingDefault = resizerClassName ? resizerClassName + " " + _Resizer.RESIZER_DEFAULT_CLASSNAME : resizerClassName;

      var style = Object.assign({}, {
        display: "flex",
        flex: 1,
        height: "100%",
        position: "absolute",
        outline: "none",
        overflow: "hidden",
        MozUserSelect: "text",
        WebkitUserSelect: "text",
        msUserSelect: "text",
        userSelect: "text"
      }, styleProps || {});

      if (split === "vertical") {
        Object.assign(style, {
          flexDirection: "row",
          left: 0,
          right: 0
        });
      } else {
        Object.assign(style, {
          bottom: 0,
          flexDirection: "column",
          minHeight: "100%",
          top: 0,
          width: "100%"
        });
      }

      var classes = ["SplitPane", className, split, disabledClass];
      var pane1Style = prefixer.prefix(Object.assign({}, paneStyle || {}, pane1StyleProps || {}));
      var pane2Style = prefixer.prefix(Object.assign({}, paneStyle || {}, pane2StyleProps || {}));

      return _react2.default.createElement(
        "div",
        {
          className: classes.join(" "),
          ref: function ref(node) {
            _this2.splitPane = node;
          },
          style: prefixer.prefix(style)
        },
        _react2.default.createElement(
          _Pane2.default,
          {
            className: "Pane1",
            key: "pane1",
            ref: function ref(node) {
              _this2.pane1 = node;
            },
            size: primary === "first" ? size || defaultSize || minSize : undefined,
            split: split,
            style: pane1Style
          },
          children[0]
        ),
        _react2.default.createElement(_Resizer2.default, {
          className: disabledClass,
          onClick: onResizerClick,
          onDoubleClick: onResizerDoubleClick,
          onMouseDown: this.onMouseDown,
          onTouchStart: this.onTouchStart,
          onTouchEnd: this.onMouseUp,
          key: "resizer",
          ref: function ref(node) {
            _this2.resizer = node;
          },
          resizerClassName: resizerClassNamesIncludingDefault,
          split: split,
          style: resizerStyle || {}
        }),
        _react2.default.createElement(
          _Pane2.default,
          {
            className: "Pane2",
            key: "pane2",
            ref: function ref(node) {
              _this2.pane2 = node;
            },
            size: primary === "second" ? size || defaultSize || minSize : undefined,
            split: split,
            style: pane2Style
          },
          children[1]
        )
      );
    }
  }]);

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

SplitPane.propTypes = process.env.NODE_ENV !== "production" ? {
  allowResize: _propTypes2.default.bool,
  children: _propTypes2.default.arrayOf(_propTypes2.default.node).isRequired,
  className: _propTypes2.default.string,
  primary: _propTypes2.default.oneOf(["first", "second"]),
  minSize: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
  maxSize: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
  // eslint-disable-next-line react/no-unused-prop-types
  defaultSize: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
  size: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
  split: _propTypes2.default.oneOf(["vertical", "horizontal"]),
  onDragStarted: _propTypes2.default.func,
  onDragFinished: _propTypes2.default.func,
  onChange: _propTypes2.default.func,
  onResizerClick: _propTypes2.default.func,
  onResizerDoubleClick: _propTypes2.default.func,
  prefixer: _propTypes2.default.instanceOf(_inlineStylePrefixer2.default).isRequired,
  style: _reactStyleProptype2.default,
  resizerStyle: _reactStyleProptype2.default,
  paneStyle: _reactStyleProptype2.default,
  pane1Style: _reactStyleProptype2.default,
  pane2Style: _reactStyleProptype2.default,
  resizerClassName: _propTypes2.default.string,
  step: _propTypes2.default.number
} : {};

SplitPane.defaultProps = {
  allowResize: true,
  minSize: 50,
  prefixer: new _inlineStylePrefixer2.default({ userAgent: USER_AGENT }),
  primary: "first",
  split: "vertical"
};

exports.default = SplitPane;