"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _pane = _interopRequireDefault(require("./pane"));
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
const DEFAULT_SPLITTER_SIZE = 4;

/**
 *
 * @midnight-gray-supported
 * @alpine-light-supported
 */
class Splitter extends _react.Component {
  static defaultProps = {
    horizontal: false,
    isDisabled: false,
    children: [],
    usePercentSize: false,
    onManualResize: () => {}
  };
  constructor(props) {
    super(props);
    this.state = {
      secondPaneSize: 0,
      resizing: false
    };
    this.onMouseMove = this.onMouseMove.bind(this);
    this.onMouseUp = this.onMouseUp.bind(this);
    this.onMouseDown = this.onMouseDown.bind(this);
    this.getPanes = this.getPanes.bind(this);
  }
  componentDidMount() {
    if (this.props.children.length > 2) {
      throw new Error('Splitter component cannot contain more than 2 children');
    }
    document.addEventListener('mouseup', this.onMouseUp);
    document.addEventListener('mousemove', this.onMouseMove);
    this.setSecondPaneSize();
  }
  componentWillUnmount() {
    document.removeEventListener('mouseup', this.onMouseUp);
    document.removeEventListener('mousemove', this.onMouseMove);
  }
  componentDidUpdate(prevProps) {
    if (prevProps.secondPaneSize !== this.props.secondPaneSize) {
      this.setSecondPaneSize();
    }
  }
  setSecondPaneSize() {
    if (this.props.secondPaneSize) {
      if (this.props.usePercentSize) {
        const parentEl = this.containerRef;
        const parentElSize = this.props.horizontal ? parentEl?.offsetHeight : parentEl?.offsetWidth;
        // Convert the percent value to a decimal to calculate pixel value.
        const secondPanelPercent = this.props.secondPaneSize / 100;
        return parentElSize ? this.setState({
          secondPaneSize: parentElSize * secondPanelPercent
        }) : null;
      }
      return this.setState({
        secondPaneSize: this.props.secondPaneSize
      });
    }
    const containerRect = this.containerRef?.getBoundingClientRect();
    const splitterRect = this.splitterRef ? this.splitterRef.getBoundingClientRect() : {
      width: DEFAULT_SPLITTER_SIZE,
      height: DEFAULT_SPLITTER_SIZE
    };
    let secondPaneSize;
    if (containerRect && splitterRect) {
      secondPaneSize = this.getsecondPaneSize(containerRect, splitterRect, {
        left: containerRect.left + (containerRect.width - splitterRect.width) / 2,
        top: containerRect.top + (containerRect.height - splitterRect.height) / 2
      }, false);
      this.setState({
        secondPaneSize
      });
    }
  }

  // To avoid the selection of text while moving splitter
  clearSelection() {
    const doc = document;
    if (doc.body.createTextRange) {
      const range = doc.body.createTextRange();
      range.collapse();
      range.select();
    } else if (window.getSelection) {
      if (window.getSelection()?.empty) {
        window.getSelection()?.empty();
      } else if (window.getSelection()?.removeAllRanges) {
        window.getSelection()?.removeAllRanges();
      }
    } else if (doc.selection) {
      doc.selection.empty();
    }
  }
  getsecondPaneSize(containerRect, splitterRect, clientPosition, offsetMouse) {
    const totalSize = this.props.horizontal ? containerRect.height : containerRect.width;
    const splitterSize = this.props.horizontal ? splitterRect.height : splitterRect.width;
    let offset = this.props.horizontal ? clientPosition.top - containerRect.top : clientPosition.left - containerRect.left;
    if (offsetMouse) {
      offset -= splitterSize / 2;
    }
    if (offset < 0) {
      offset = 0;
    } else if (offset > totalSize - splitterSize) {
      offset = totalSize - splitterSize;
    }
    const secondPaneSize = totalSize - splitterSize - offset;
    return secondPaneSize;
  }
  onMouseMove(e) {
    if (this.state.resizing) {
      const {
        onManualResize,
        usePercentSize
      } = this.props;
      const containerRect = this.containerRef?.getBoundingClientRect();
      const splitterRect = this.splitterRef?.getBoundingClientRect();
      let secondPaneSize;
      if (containerRect && splitterRect) {
        secondPaneSize = this.getsecondPaneSize(containerRect, splitterRect, {
          left: e.clientX,
          top: e.clientY
        }, true);
        this.clearSelection();
        if (onManualResize) {
          if (usePercentSize) {
            onManualResize(this.getPaneSizeInPercentage());
          } else {
            onManualResize(secondPaneSize);
          }
        }
        this.setState({
          secondPaneSize
        });
      }
    }
  }
  onMouseDown() {
    if (!this.props.isDisabled) {
      this.clearSelection();
      this.setState({
        resizing: true
      });
    }
  }
  onMouseUp() {
    // in order to not to set state while not dragging
    // we need to check prevState
    this.setState(prevState => prevState.resizing ? {
      resizing: false
    } : null);
  }

  // Wrap children in containers and setting default sizes
  getPanes() {
    const children = this.props.children;
    if (children.length === 0) {
      children.push(/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {}));
    }
    return children.map((child, i) => {
      const primary = i === 0;
      const size = primary ? null : this.state.secondPaneSize;
      return /*#__PURE__*/(0, _jsxRuntime.jsx)(_pane.default, {
        horizontal: this.props.horizontal,
        primary: primary,
        size: size,
        children: child
      }, i);
    });
  }
  getPaneSizeInPercentage() {
    const parentEl = this.containerRef;
    const parentElSize = this.props.horizontal ? parentEl?.offsetHeight : parentEl?.offsetWidth;
    return parentElSize ? Math.round(this.state.secondPaneSize / parentElSize * 100) : null;
  }
  render() {
    const panes = this.getPanes();
    return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
      "test-id": "splitter-layout",
      className: (0, _classnames.default)('splitter-layout', this.props.className, {
        'splitter-layout-horizontal': this.props.horizontal
      }),
      ref: r => {
        this.containerRef = r;
      },
      children: [panes[0], panes.length > 1 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
        children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
          "test-id": "splitter-handler",
          role: "separator",
          className: (0, _classnames.default)('layout-splitter', {
            'splitter-handler-horizontal': this.props.horizontal,
            'splitter-handler-vertical': !this.props.horizontal,
            'splitter-disabled': this.props.isDisabled
          }),
          ref: r => {
            this.splitterRef = r;
          },
          onMouseDown: this.onMouseDown
        }), panes[1]]
      })]
    });
  }
}
var _default = exports.default = Splitter;