"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _react = _interopRequireDefault(require("react"));

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

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _readOnlyError(name) { throw new Error("\"" + name + "\" is read-only"); }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

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

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

var Draggable =
/*#__PURE__*/
function (_React$Component) {
  _inherits(Draggable, _React$Component);

  function Draggable(props) {
    var _this;

    _classCallCheck(this, Draggable);

    _this = _possibleConstructorReturn(this, _getPrototypeOf(Draggable).call(this, props));
    _this.resizing = false;
    _this.resizingPosition = {
      x: 0,
      y: 0
    };
    _this.offsetFromParent = {
      left: 0,
      top: 0
    };
    _this.resizableElement = {
      current: null
    };

    _this.refDraggable = function (ref) {
      ref && (_this.draggable = ref);
    };

    _this.refResizable = function (resize) {
      resize && (_this.resizable = resize, _this.resizableElement.current = resize.resizable);
    };

    _this.state = {
      original: {
        x: 0,
        y: 0
      },
      bounds: {
        top: 0,
        right: 0,
        bottom: 0,
        left: 0
      },
      maxWidth: props.maxWidth,
      maxHeight: props.maxHeight
    };
    return _this;
  }

  _createClass(Draggable, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      this.updateOffsetFromParent();
      var _this$offsetFromParen = this.offsetFromParent,
          left = _this$offsetFromParen.left,
          top = _this$offsetFromParen.top;

      var _this$getDraggablePos = this.getDraggablePosition(),
          x = _this$getDraggablePos.x,
          y = _this$getDraggablePos.y;

      this.draggable.setState({
        x: x - left,
        y: y - top
      });
      this.forceUpdate();
    }
  }, {
    key: "getDraggablePosition",
    value: function getDraggablePosition() {
      var state = this.draggable.state;
      return {
        x: state.x,
        y: state.y
      };
    }
  }, {
    key: "getParent",
    value: function getParent() {
      return this.resizable && this.resizable.parentNode;
    }
  }, {
    key: "getParentSize",
    value: function getParentSize() {
      return this.resizable.getParentSize();
    }
  }, {
    key: "getMaxSizesFromProps",
    value: function getMaxSizesFromProps() {
      return {
        maxWidth: void 0 === this.props.maxWidth ? Number.MAX_SAFE_INTEGER : this.props.maxWidth,
        maxHeight: void 0 === this.props.maxHeight ? Number.MAX_SAFE_INTEGER : this.props.maxHeight
      };
    }
  }, {
    key: "getSelfElement",
    value: function getSelfElement() {
      return this.resizable && this.resizable.resizable;
    }
  }, {
    key: "getOffsetHeight",
    value: function getOffsetHeight(event) {
      var scale = this.props.scale;

      switch (this.props.bounds) {
        case "window":
          return window.innerHeight / scale;

        case "body":
          return document.body.offsetHeight / scale;

        default:
          return event.offsetHeight;
      }
    }
  }, {
    key: "getOffsetWidth",
    value: function getOffsetWidth(event) {
      var scale = this.props.scale;

      switch (this.props.bounds) {
        case "window":
          return window.innerWidth / scale;

        case "body":
          return document.body.offsetWidth / scale;

        default:
          return event.offsetWidth;
      }
    }
  }, {
    key: "onDragStart",
    value: function onDragStart(event, position) {
      if (this.props.onDragStart && this.props.onDragStart(event, position), this.props.bounds) {
        var _parent2 = this.getParent();

        var _scale = this.props.scale;

        var _parent3;

        if ("parent" === this.props.bounds) {
          _parent3 = _parent2;
        } else {
          if ("body" === this.props.bounds) {
            var rect = _parent2.getBoundingClientRect();

            var left = rect.left,
                top = rect.top;
            var domRect = document.body.getBoundingClientRect();
            var deltLeft = -(left - _parent2.offsetLeft * _scale - domRect.left) / _scale;
            var deltTop = -(top - _parent2.offsetTop * _scale - domRect.top) / _scale;
            var deltRight = (document.body.offsetWidth - this.resizable.size.width * _scale) / _scale + deltLeft;
            var deltBottom = (document.body.offsetHeight - this.resizable.size.height * _scale) / _scale + deltTop;
            return this.setState({
              bounds: {
                top: deltTop,
                right: deltRight,
                left: deltLeft,
                bottom: deltBottom
              }
            });
          }
        }

        _parent3 = document.querySelector(this.props.bounds);
      }

      if (_parent instanceof HTMLElement && parent instanceof HTMLElement) {
        var _rect = _parent.getBoundingClientRect();

        var _left = _rect.left,
            _top = _rect.top;
        var parentRect = parent.getBoundingClientRect();

        var _deltLeft = (_left - parentRect.left) / scale;

        var _deltTop = _top - _deltLeft.top;

        if (this.resizable) {
          this.updateOffsetFromParent();
          var fromParent = this.offsetFromParent;
          this.setState({
            bounds: {
              top: _deltTop - fromParent.top,
              right: _deltLeft + (_parent.offsetWidth - this.resizable.size.width) - fromParent.left / scale,
              bottom: _deltTop + (_parent.offsetHeight - this.resizable.size.height) - fromParent.top,
              left: _deltLeft = (_readOnlyError("deltLeft"), fromParent.left / scale)
            }
          });
        }
      }
    }
  }, {
    key: "onDrag",
    value: function onDrag(event, position) {
      if (this.props.onDrag) {
        var fromParent = this.offsetFromParent;
        return this.props.onDrag(event, Object.assign(Object.assign({}, position), {
          x: position.x - fromParent.left,
          y: position.y - fromParent.top
        }));
      }
    }
  }, {
    key: "onDragStop",
    value: function onDragStop(event, position) {
      if (this.props.onDragStop) {
        var fromParent = this.offsetFromParent;
        return this.props.onDragStop(event, Object.assign(Object.assign({}, position), {
          x: position.y + fromParent.left,
          y: position.y + fromParent.top
        }));
      }
    }
  }, {
    key: "onResizeStart",
    value: function onResizeStart(event, placment, callback) {
      event.stopPropagation();
      this.resizing = !0;
      var scale = this.props.scale;
      var fromParent = this.offsetFromParent;
      var dragPosition = this.getDraggablePosition();

      if (this.resizingPosition = {
        x: dragPosition.x + fromParent.left,
        y: dragPosition.y + fromParent.top
      }, this.setState({
        original: dragPosition
      }), this.props.bounds) {
        var _parent4 = this.getParent();

        var element = void 0;
        element = "parent" === this.props.bounds ? _parent4 : "body" === this.props.bounds ? document.body : "window" === this.props.bounds ? window : document.querySelector(this.props.bounds);
        var selfElement = this.getSelfElement();

        if (selfElement instanceof Element && (element instanceof HTMLElement || element === window) && _parent4 instanceof HTMLElement) {
          var maxSizeProps = this.getMaxSizesFromProps();
          var parentSize = this.getParentSize();
          var maxWidth = maxSizeProps.maxWidth,
              maxHeight = maxSizeProps.maxHeight;

          if (maxWidth && "string" == typeof maxWidth) {
            if (maxWidth.endsWith("%")) {
              var delt = Number(maxWidth.replace("%", "")) / 100;
              maxWidth = parentSize.width * delt;
            } else {
              maxWidth.endsWith("px") && (maxWidth = Number(maxWidth.replace("px", "")));
            }
          }

          if (maxHeight && "string" == typeof maxHeight) {
            if (maxHeight.endsWith("%")) {
              var _delt = Number(maxHeight.replace("%", "")) / 100;

              maxHeight = parentSize.width * _delt;
            } else {
              maxHeight.endsWith("px") && (maxHeight = Number(maxHeight.replace("px", "")));
              maxHeight.endsWith("px") && (maxHeight = Number(maxHeight.replace("px", "")));
            }
          }

          var rect = selfElement.getBoundingClientRect();

          var _rect_ = "window" === this.props.bounds ? {
            left: 0,
            top: 0
          } : element.getBoundingClientRect();

          var offsetWidth = this.getOffsetWidth();
          var offsetHeight = this.getOffsetHeight();
          var convertLeft = placment.toLowerCase().endsWith("left");
          var convertRight = placment.toLowerCase().endsWith("right");

          if (convertLeft && this.resizable) {
            var deltWidth = (rect.left - _rect_.left) / scale + this.resizable.size.width;
            this.setState({
              maxWidth: deltWidth > Number(maxWidth) ? maxWidth : deltWidth
            });
          }

          if (convertRight || this.props.lockAspectRatio && !convertLeft) {
            var _deltWidth = offsetWidth + (_rect_.left - rect.left) / scale;

            this.setState({
              maxWidth: _deltWidth > Number(maxWidth) ? maxWidth : _deltWidth
            });
          }

          if (placment.startsWith("top") && this.resizable) {
            var deltHeight = rect.top - _rect_.top + this.resizable.size.height;
            this.setState({
              maxHeight: deltHeight > Number(maxHeight) ? maxHeight : deltHeight
            });
          }

          if (placment.startsWith("bottom") || this.props.lockAspectRatio && !placment.startsWith("top")) {
            var _deltHeight = offsetHeight + (_rect_.top - rect.top) / scale;

            this.setState({
              maxHeight: _deltHeight > Number(maxHeight) ? maxHeight : _deltHeight
            });
          }
        }
      } else {
        this.setState({
          maxWidth: this.props.maxWidth,
          maxHeight: this.props.maxHeight
        });
      }

      this.props.onResizeStart && this.props.onResizeStart(event, placment, callback);
    }
  }, {
    key: "onResize",
    value: function onResize(event, placment, position, target) {
      var original = {
        x: this.state.original.x,
        y: this.state.original.y
      };
      var width = -target.width;
      var height = -target.height;
      -1 !== ["top", "left", "topLeft", "bottomLeft", "topRight"].indexOf(placment) && ("bottomLeft" === placment ? original.x += width : ("topRight" === placment || (original.x += width), original.y += height));
      original.x === this.draggable.state.x && original.y === this.draggable.state.y || this.draggable.setState(original);
      this.updateOffsetFromParent();
      var fromParent = this.offsetFromParent;
      var x = this.getDraggablePosition().x + fromParent.left;
      var y = this.getDraggablePosition().y + fromParent.top;
      this.resizingPosition = {
        x: x,
        y: y
      };
      this.props.onResize && this.props.onResize(event, placment, position, target, {
        x: x,
        y: y
      });
    }
  }, {
    key: "onResizeStop",
    value: function onResizeStop(event, placment, position, target) {
      this.resizing = !1;

      var _this$getMaxSizesFrom = this.getMaxSizesFromProps(),
          maxWidth = _this$getMaxSizesFrom.maxWidth,
          maxHeight = _this$getMaxSizesFrom.maxHeight;

      this.setState({
        maxHeight: maxHeight,
        maxWidth: maxWidth
      });
      this.props.onResizeStop && this.props.onResizeStop(event, placment, position, target, this.resizingPosition);
    }
  }, {
    key: "updateSize",
    value: function updateSize(target) {
      this.resizable && this.resizable.updateSize({
        width: target.width,
        height: target.height
      });
    }
  }, {
    key: "updatePosition",
    value: function updatePosition(position) {
      this.draggable.setState(position);
    }
  }, {
    key: "updateOffsetFromParent",
    value: function updateOffsetFromParent() {
      var scale = this.props.scale;
      var parent = this.getParent();
      var selfElement = this.getSelfElement();

      if (!parent || null === selfElement) {
        return {
          top: 0,
          left: 0
        };
      }

      var rect = parent.getBoundingClientRect();
      var selfRect = selfElement.getBoundingClientRect();
      var dragPosition = this.getDraggablePosition();
      this.offsetFromParent = {
        left: selfRect.left - rect.left - dragPosition.x * scale,
        top: selfRect.top - rect.top - dragPosition.y * scale
      };
    }
  }]);

  return Draggable;
}(_react["default"].Component);

Draggable.defaultProps = {
  maxWidth: Number.MAX_SAFE_INTEGER,
  maxHeight: Number.MAX_SAFE_INTEGER,
  scale: 1,
  onResizeStart: function onResizeStart() {},
  onResize: function onResize() {},
  onResizeStop: function onResizeStop() {},
  onDragStart: function onDragStart() {},
  onDrag: function onDrag() {},
  onDragStop: function onDragStop() {}
};
var _default = Draggable;
exports["default"] = _default;