"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.styles = exports.lineToolComponent = exports.lineTool = exports.lineBase = void 0;

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

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

var _isEqual = _interopRequireDefault(require("lodash/isEqual"));

var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep"));

var _point = require("../point");

var _plot = require("../../../../plot");

var _propTypes = _interopRequireDefault(require("prop-types"));

var _styles = require("../styles");

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

var _markLabel = _interopRequireDefault(require("../../../mark-label"));

var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));

var _renderUi = require("../../../../render-ui");

var _utils = require("../../../utils");

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }

function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

var lineTool = function lineTool(type, Component) {
  return function () {
    return {
      type: type,
      Component: Component,
      addPoint: function addPoint(point, mark) {
        if (mark && (0, _utils.equalPoints)(mark.root, point)) {
          return mark;
        }

        if (!mark) {
          return {
            type: type,
            building: true,
            from: point
          };
        }

        if ((0, _utils.equalPoints)(point, mark.from)) {
          return _objectSpread({}, mark);
        }

        return _objectSpread(_objectSpread({}, mark), {}, {
          building: false,
          to: point
        });
      }
    };
  };
};

exports.lineTool = lineTool;

var lineToolComponent = function lineToolComponent(Component) {
  var _class;

  return _class = /*#__PURE__*/function (_React$Component) {
    (0, _inherits2["default"])(LineToolComponent, _React$Component);

    var _super = _createSuper(LineToolComponent);

    function LineToolComponent(props) {
      var _this;

      (0, _classCallCheck2["default"])(this, LineToolComponent);
      _this = _super.call(this, props);
      (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "startDrag", function () {
        return _this.setState({
          mark: _objectSpread({}, _this.props.mark)
        });
      });
      (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "stopDrag", function () {
        var _this$props = _this.props,
            onChange = _this$props.onChange,
            mark = _this$props.mark;

        var update = _objectSpread({}, _this.state.mark);

        _this.setState({
          mark: undefined
        }, function () {
          var type = update.type;
          var shouldNotChange = type && (type === 'parabola' || type === 'sine') && (0, _utils.sameAxes)(update.from, update.to);

          if (!(0, _isEqual["default"])(mark, update) && !shouldNotChange) {
            onChange(mark, update);
          }
        });
      });
      (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "changeMark", function (_ref) {
        var from = _ref.from,
            to = _ref.to,
            middle = _ref.middle;

        var mark = _objectSpread(_objectSpread({}, _this.state.mark), {}, {
          from: from,
          to: to
        });

        if (middle) {
          mark = _objectSpread(_objectSpread({}, mark), {}, {
            middle: middle
          });
        }

        _this.setState({
          mark: mark
        });
      });
      (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "changeMarkProps", function (_ref2) {
        var from = _ref2.from,
            to = _ref2.to,
            middle = _ref2.middle;
        var _this$props2 = _this.props,
            onChange = _this$props2.onChange,
            mark = _this$props2.mark;

        var update = _objectSpread(_objectSpread({}, mark), _this.state.mark);

        if (from) {
          update = _objectSpread(_objectSpread({}, update), {}, {
            from: from
          });
        }

        if (to) {
          update = _objectSpread(_objectSpread({}, update), {}, {
            to: to
          });
        }

        if (middle) {
          update = _objectSpread(_objectSpread({}, update), {}, {
            middle: middle
          });
        }

        if (!(0, _isEqual["default"])(mark, update)) {
          onChange(mark, update);
        }
      });
      _this.state = {};
      return _this;
    }

    (0, _createClass2["default"])(LineToolComponent, [{
      key: "render",
      value: function render() {
        var _this$props3 = this.props,
            graphProps = _this$props3.graphProps,
            onClick = _this$props3.onClick,
            labelNode = _this$props3.labelNode,
            labelModeEnabled = _this$props3.labelModeEnabled,
            coordinatesOnHover = _this$props3.coordinatesOnHover;
        var mark = this.state.mark ? this.state.mark : this.props.mark;
        var from = (0, _cloneDeep["default"])(mark.from);
        var to = (0, _cloneDeep["default"])(mark.to);
        var middle = (0, _cloneDeep["default"])(mark.middle); // SET DISABLED
        // if it's a background mark, we need to force disable it

        if (from && mark.isBackground) {
          from.disabled = true;
        }

        if (to && mark.isBackground) {
          to.disabled = true;
        }

        if (middle && mark.isBackground) {
          middle.disabled = true;
        }

        return /*#__PURE__*/_react["default"].createElement(Component, {
          disabled: mark.disabled,
          coordinatesOnHover: coordinatesOnHover,
          correctness: mark.correctness,
          from: from,
          to: to,
          middle: middle,
          graphProps: graphProps,
          onChange: this.changeMark,
          changeMarkProps: this.changeMarkProps,
          onClick: onClick,
          onDragStart: this.startDrag,
          onDragStop: this.stopDrag,
          labelNode: labelNode,
          labelModeEnabled: labelModeEnabled
        });
      }
    }]);
    return LineToolComponent;
  }(_react["default"].Component), (0, _defineProperty2["default"])(_class, "propTypes", _objectSpread(_objectSpread({}, _plot.types.ToolPropTypeFields), {}, {
    graphProps: _plot.types.GraphPropsType.isRequired
  })), _class;
};

exports.lineToolComponent = lineToolComponent;

var dragOpts = function dragOpts() {
  return {
    bounds: function bounds(props, _ref3) {
      var domain = _ref3.domain,
          range = _ref3.range;

      var area = _plot.utils.lineToArea(props.from, props.to);

      return _plot.utils.bounds(area, domain, range);
    },
    anchorPoint: function anchorPoint(props) {
      var from = props.from;
      return from;
    },
    fromDelta: function fromDelta(props, delta) {
      var from = props.from,
          to = props.to;
      return {
        from: _plot.utils.point(from).add(_plot.utils.point(delta)),
        to: _plot.utils.point(to).add(_plot.utils.point(delta))
      };
    }
  };
};

var lineBase = function lineBase(Comp, opts) {
  var DraggableComp = (0, _plot.gridDraggable)(dragOpts())(Comp);
  var FromPoint = opts && opts.from ? opts.from : _point.BasePoint;
  var ToPoint = opts && opts.to ? opts.to : _point.BasePoint;

  var LineBase = /*#__PURE__*/function (_React$Component2) {
    (0, _inherits2["default"])(LineBase, _React$Component2);

    var _super2 = _createSuper(LineBase);

    function LineBase() {
      var _this2;

      (0, _classCallCheck2["default"])(this, LineBase);

      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      _this2 = _super2.call.apply(_super2, [this].concat(args));
      (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this2), "onChangePoint", function (point) {
        var _this2$props = _this2.props,
            middle = _this2$props.middle,
            onChange = _this2$props.onChange;
        var from = point.from,
            to = point.to; // because point.from.label and point.to.label can be different

        if (!(0, _utils.equalPoints)(from, to)) {
          if (middle) {
            point.middle = _objectSpread(_objectSpread({}, middle), (0, _utils.getMiddleOfTwoPoints)(from, to));
          }

          onChange(point);
        }
      });
      (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this2), "dragComp", function (_ref4) {
        var draggedFrom = _ref4.from,
            draggedTo = _ref4.to;
        var _this2$props2 = _this2.props,
            from = _this2$props2.from,
            to = _this2$props2.to,
            onChange = _this2$props2.onChange,
            middle = _this2$props2.middle;

        if (from.label) {
          draggedFrom.label = from.label;
        }

        if (to.label) {
          draggedTo.label = to.label;
        }

        var updated = {
          from: draggedFrom,
          to: draggedTo
        };

        if (middle) {
          updated.middle = _objectSpread(_objectSpread({}, middle), (0, _utils.getMiddleOfTwoPoints)(draggedFrom, draggedTo));
        }

        onChange(updated);
      });
      (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this2), "dragFrom", function (draggedFrom) {
        var _this2$props3 = _this2.props,
            from = _this2$props3.from,
            to = _this2$props3.to;

        if (from.label) {
          draggedFrom.label = from.label;
        }

        if (!(0, _utils.equalPoints)(draggedFrom, to)) {
          _this2.onChangePoint({
            from: draggedFrom,
            to: to
          });
        }
      });
      (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this2), "dragTo", function (draggedTo) {
        var _this2$props4 = _this2.props,
            from = _this2$props4.from,
            to = _this2$props4.to;

        if (to.label) {
          draggedTo.label = to.label;
        }

        if (!(0, _utils.equalPoints)(from, draggedTo)) {
          _this2.onChangePoint({
            from: from,
            to: draggedTo
          });
        }
      });
      (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this2), "labelChange", function (point, type) {
        var changeMarkProps = _this2.props.changeMarkProps;

        var update = _objectSpread({}, point);

        if (!point.label || (0, _isEmpty["default"])(point.label)) {
          delete update.label;
        }

        changeMarkProps((0, _defineProperty2["default"])({}, type, update));
      });
      (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this2), "clickPoint", function (point, type) {
        var _this2$props5 = _this2.props,
            changeMarkProps = _this2$props5.changeMarkProps,
            from = _this2$props5.from,
            to = _this2$props5.to;

        if (type === 'middle' && !point && from && to) {
          point = _objectSpread(_objectSpread({}, point), (0, _utils.getMiddleOfTwoPoints)(from, to));
        }

        changeMarkProps((0, _defineProperty2["default"])({
          from: from,
          to: to
        }, type, _objectSpread({
          label: ''
        }, point)));

        if (_this2.input[type]) {
          _this2.input[type].focus();
        }
      });
      (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this2), "input", {});
      return _this2;
    }

    (0, _createClass2["default"])(LineBase, [{
      key: "render",
      value: function render() {
        var _this3 = this;

        var _this$props4 = this.props,
            coordinatesOnHover = _this$props4.coordinatesOnHover,
            graphProps = _this$props4.graphProps,
            onDragStart = _this$props4.onDragStart,
            onDragStop = _this$props4.onDragStop,
            from = _this$props4.from,
            to = _this$props4.to,
            middle = _this$props4.middle,
            disabled = _this$props4.disabled,
            correctness = _this$props4.correctness,
            onClick = _this$props4.onClick,
            labelNode = _this$props4.labelNode,
            labelModeEnabled = _this$props4.labelModeEnabled;
        var common = {
          graphProps: graphProps,
          onDragStart: onDragStart,
          onDragStop: onDragStop,
          disabled: disabled,
          correctness: correctness,
          onClick: onClick
        };
        var angle = to ? _plot.trig.toDegrees(_plot.trig.angle(from, to)) : 0;
        var fromLabelNode = null;
        var toLabelNode = null;
        var lineLabelNode = null;

        if (labelNode) {
          if (from && from.hasOwnProperty('label')) {
            fromLabelNode = /*#__PURE__*/_reactDom["default"].createPortal( /*#__PURE__*/_react["default"].createElement(_markLabel["default"], {
              inputRef: function inputRef(r) {
                return _this3.input.from = r;
              },
              disabled: !labelModeEnabled,
              mark: from,
              graphProps: graphProps,
              onChange: function onChange(label) {
                return _this3.labelChange(_objectSpread(_objectSpread({}, from), {}, {
                  label: label
                }), 'from');
              }
            }), labelNode);
          }

          if (to && to.hasOwnProperty('label')) {
            toLabelNode = /*#__PURE__*/_reactDom["default"].createPortal( /*#__PURE__*/_react["default"].createElement(_markLabel["default"], {
              inputRef: function inputRef(r) {
                return _this3.input.to = r;
              },
              disabled: !labelModeEnabled,
              mark: to,
              graphProps: graphProps,
              onChange: function onChange(label) {
                return _this3.labelChange(_objectSpread(_objectSpread({}, to), {}, {
                  label: label
                }), 'to');
              }
            }), labelNode);
          }

          if (middle && middle.hasOwnProperty('label')) {
            lineLabelNode = /*#__PURE__*/_reactDom["default"].createPortal( /*#__PURE__*/_react["default"].createElement(_markLabel["default"], {
              inputRef: function inputRef(r) {
                return _this3.input.middle = r;
              },
              disabled: !labelModeEnabled,
              mark: middle,
              graphProps: graphProps,
              onChange: function onChange(label) {
                return _this3.labelChange(_objectSpread(_objectSpread({}, middle), {}, {
                  label: label
                }), 'middle');
              }
            }), labelNode);
          }
        }

        return /*#__PURE__*/_react["default"].createElement("g", null, to && /*#__PURE__*/_react["default"].createElement(DraggableComp, (0, _extends2["default"])({
          from: from,
          to: to,
          middle: middle,
          onDrag: this.dragComp
        }, common, {
          onClick: labelModeEnabled ? function () {
            return _this3.clickPoint(middle, 'middle');
          } : common.onClick
        })), lineLabelNode, /*#__PURE__*/_react["default"].createElement(FromPoint, (0, _extends2["default"])({
          x: from.x,
          y: from.y,
          labelNode: labelNode,
          coordinatesOnHover: coordinatesOnHover,
          onDrag: this.dragFrom
        }, common, {
          onClick: labelModeEnabled ? function () {
            return _this3.clickPoint(from, 'from');
          } : common.onClick
        })), fromLabelNode, to && /*#__PURE__*/_react["default"].createElement(ToPoint, (0, _extends2["default"])({
          x: to.x,
          y: to.y,
          angle: angle //angle + 45}
          ,
          labelNode: labelNode,
          coordinatesOnHover: coordinatesOnHover,
          onDrag: this.dragTo
        }, common, {
          onClick: labelModeEnabled ? function () {
            return _this3.clickPoint(to, 'to');
          } : common.onClick
        })), toLabelNode);
      }
    }]);
    return LineBase;
  }(_react["default"].Component);

  (0, _defineProperty2["default"])(LineBase, "propTypes", {
    coordinatesOnHover: _propTypes["default"].bool,
    graphProps: _plot.types.GraphPropsType,
    from: _plot.types.PointType,
    to: _plot.types.PointType,
    middle: _plot.types.PointType,
    onChange: _propTypes["default"].func,
    onDragStart: _propTypes["default"].func,
    onDragStop: _propTypes["default"].func,
    onClick: _propTypes["default"].func,
    correctness: _propTypes["default"].string,
    disabled: _propTypes["default"].bool,
    labelNode: _propTypes["default"].object,
    labelModeEnabled: _propTypes["default"].bool,
    changeMarkProps: _propTypes["default"].func
  });
  return LineBase;
};

exports.lineBase = lineBase;
var styles = {
  line: function line() {
    return {
      fill: 'transparent',
      stroke: _renderUi.color.primaryLight(),
      strokeWidth: 3,
      transition: 'stroke 200ms ease-in, stroke-width 200ms ease-in',
      '&:hover': {
        strokeWidth: 6,
        stroke: _renderUi.color.primaryDark()
      }
    };
  },
  arrow: function arrow() {
    return {
      fill: _renderUi.color.secondary()
    };
  },
  disabledArrow: function disabledArrow() {
    return _objectSpread({}, (0, _styles.disabled)());
  },
  disabled: function disabled() {
    return _objectSpread(_objectSpread({}, (0, _styles.disabled)('stroke')), {}, {
      strokeWidth: 2
    });
  },
  correct: function correct(theme, key) {
    return _objectSpread({}, (0, _styles.correct)(key));
  },
  incorrect: function incorrect(theme, key) {
    return _objectSpread({}, (0, _styles.incorrect)(key));
  },
  missing: function missing(theme, key) {
    return _objectSpread({}, (0, _styles.missing)(key));
  }
};
exports.styles = styles;
//# sourceMappingURL=index.js.map