"use strict";

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

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

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

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

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

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

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

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

var _debug = _interopRequireDefault(require("debug"));

var _axis = require("./axis");

var _grid = _interopRequireDefault(require("./grid"));

var _labels = require("./labels");

var _bg = _interopRequireDefault(require("./bg"));

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

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

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

var log = (0, _debug["default"])('pie-lib:graphing-solution-set:graph');
var graphPropTypes = {
  axesSettings: _propTypes["default"].shape(_axis.AxisPropTypes),
  backgroundMarks: _propTypes["default"].array,
  className: _propTypes["default"].string,
  collapsibleToolbar: _propTypes["default"].bool,
  collapsibleToolbarTitle: _propTypes["default"].string,
  disabledLabels: _propTypes["default"].bool,
  disabledTitle: _propTypes["default"].bool,
  domain: _plot.types.DomainType,
  labels: _propTypes["default"].shape(_labels.LabelType),
  labelModeEnabled: _propTypes["default"].bool,
  coordinatesOnHover: _propTypes["default"].bool,
  marks: _propTypes["default"].array,
  onChangeLabels: _propTypes["default"].func,
  onChangeMarks: _propTypes["default"].func,
  onChangeTitle: _propTypes["default"].func,
  range: _plot.types.DomainType,
  size: _propTypes["default"].shape({
    width: _propTypes["default"].number.isRequired,
    height: _propTypes["default"].number.isRequired
  }),
  showLabels: _propTypes["default"].bool,
  showPixelGuides: _propTypes["default"].bool,
  showTitle: _propTypes["default"].bool,
  title: _propTypes["default"].string,
  tools: _propTypes["default"].array
};
exports.graphPropTypes = graphPropTypes;

var getMaskSize = function getMaskSize(size) {
  return {
    x: -23,
    y: -23,
    width: size.width + 46,
    height: size.height + 46
  };
};

var removeBuildingToolIfCurrentToolDiffers = function removeBuildingToolIfCurrentToolDiffers(_ref) {
  var marks = _ref.marks,
      currentTool = _ref.currentTool;
  var buildingMark = marks.filter(function (m) {
    return m.building;
  })[0];
  var newMarks = (0, _cloneDeep["default"])(marks);

  if (buildingMark && currentTool && buildingMark.type !== currentTool.type) {
    var index = newMarks.findIndex(function (m) {
      return (0, _isEqual["default"])(m, buildingMark);
    });

    if (index >= 0) {
      newMarks.splice(index, 1);
    }
  }

  return newMarks;
};

exports.removeBuildingToolIfCurrentToolDiffers = removeBuildingToolIfCurrentToolDiffers;

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

  var _super = _createSuper(Graph);

  function Graph(props) {
    var _this;

    (0, _classCallCheck2["default"])(this, Graph);
    _this = _super.call(this, props);
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", {});
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "componentDidMount", function () {
      return _this.setState({
        labelNode: _this.labelNode
      });
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "changeMark", function (oldMark, newMark) {
      var _this$props = _this.props,
          onChangeMarks = _this$props.onChangeMarks,
          marks = _this$props.marks,
          gssLineData = _this$props.gssLineData;

      if ((gssLineData === null || gssLineData === void 0 ? void 0 : gssLineData.selectedTool) === 'solutionSet') {
        return;
      }

      var newMarks = (0, _cloneDeep["default"])(marks);
      var index = newMarks.findIndex(function (m) {
        return (0, _isEqual["default"])(m, oldMark);
      });

      if (index >= 0 && !(0, _utils.isDuplicatedMark)(newMark, marks, oldMark)) {
        newMarks.splice(index, 1, newMark);
        onChangeMarks(newMarks);
      }
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "completeMark", function (markData) {
      var _this$props2 = _this.props,
          currentTool = _this$props2.currentTool,
          marks = _this$props2.marks;
      var buildingMark = marks.filter(function (m) {
        return m.building;
      })[0];
      if (!buildingMark || !currentTool) return;
      var updatedMark = currentTool.complete(buildingMark, markData);

      _this.updateMarks(buildingMark, updatedMark);
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "updateMarks", function (existing, update) {
      var addIfMissing = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
      var _this$props3 = _this.props,
          onChangeMarks = _this$props3.onChangeMarks,
          marks = _this$props3.marks;
      var newMarks = (0, _cloneDeep["default"])(marks);

      if (!update || !update.building && (0, _utils.isDuplicatedMark)(update, marks)) {
        return;
      }

      var index = newMarks.findIndex(function (m) {
        return (0, _isEqual["default"])(m, existing);
      });

      if (index >= 0) {
        newMarks.splice(index, 1, update);
        onChangeMarks(newMarks);
      } else if (addIfMissing) {
        onChangeMarks([].concat((0, _toConsumableArray2["default"])(newMarks), [update]));
      }
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getComponent", function (mark) {
      if (!mark) return null;
      var tool = (_this.props.tools || []).find(function (t) {
        return t.type === mark.type;
      });
      return tool && tool.Component || null;
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onBgClick", function (point) {
      var _ref2 = point || {},
          x = _ref2.x,
          y = _ref2.y;

      var _this$props4 = _this.props,
          labelModeEnabled = _this$props4.labelModeEnabled,
          currentTool = _this$props4.currentTool,
          marks = _this$props4.marks,
          gssLineData = _this$props4.gssLineData,
          onSolutionSetSelected = _this$props4.onSolutionSetSelected;

      if (gssLineData) {
        if (gssLineData.selectedTool === 'solutionSet') {
          onSolutionSetSelected(point);
          return;
        }

        if (gssLineData.numberOfLines === 1 && gssLineData.selectedTool === 'lineA' && marks.length === 1 && !marks[0].building) {
          return;
        }

        if (gssLineData.numberOfLines === 2 && gssLineData.selectedTool === 'lineA' && marks.length === 2) {
          return;
        }

        if (gssLineData.numberOfLines === 2 && gssLineData.selectedTool === 'lineA' && marks.length === 1 && !marks[0].building) {
          return;
        }

        if (gssLineData.numberOfLines === 2 && gssLineData.selectedTool === 'lineB' && marks.length === 2 && !marks[1].building) {
          return;
        }
      }

      if (labelModeEnabled || !currentTool || [null, undefined].includes(x) || [null, undefined].includes(y)) {
        return;
      }

      log('[onBgClick] x,y: ', x, y);
      var buildingMark = marks.filter(function (m) {
        return m.building;
      })[0];
      var updatedMark; // if the building mark has a different type, we just replace it

      if (buildingMark && currentTool && buildingMark.type === currentTool.type) {
        updatedMark = currentTool.addPoint({
          x: x,
          y: y
        }, _objectSpread({}, buildingMark));
      } else {
        updatedMark = currentTool.addPoint({
          x: x,
          y: y
        }, undefined);
      }

      _this.updateMarks(buildingMark, updatedMark, true);
    });
    _this.maskUid = _this.generateMaskId();
    return _this;
  }

  (0, _createClass2["default"])(Graph, [{
    key: "generateMaskId",
    value: function generateMaskId() {
      return 'graph-' + (Math.random() * 10000).toFixed();
    }
  }, {
    key: "render",
    value: function render() {
      var _this2 = this;

      var _this$props5 = this.props,
          axesSettings = _this$props5.axesSettings,
          currentTool = _this$props5.currentTool,
          coordinatesOnHover = _this$props5.coordinatesOnHover,
          size = _this$props5.size,
          disabledLabels = _this$props5.disabledLabels,
          disabledTitle = _this$props5.disabledTitle,
          domain = _this$props5.domain,
          backgroundMarks = _this$props5.backgroundMarks,
          range = _this$props5.range,
          title = _this$props5.title,
          labels = _this$props5.labels,
          labelModeEnabled = _this$props5.labelModeEnabled,
          labelsPlaceholders = _this$props5.labelsPlaceholders,
          showLabels = _this$props5.showLabels,
          showPixelGuides = _this$props5.showPixelGuides,
          showTitle = _this$props5.showTitle,
          titlePlaceholder = _this$props5.titlePlaceholder,
          onChangeLabels = _this$props5.onChangeLabels,
          onChangeTitle = _this$props5.onChangeTitle,
          _this$props5$mathMlOp = _this$props5.mathMlOptions,
          mathMlOptions = _this$props5$mathMlOp === void 0 ? {} : _this$props5$mathMlOp,
          gssLineData = _this$props5.gssLineData,
          disabled = _this$props5.disabled;
      var marks = this.props.marks;
      var graphProps = (0, _plot.createGraphProps)(domain, range, size, function () {
        return _this2.rootNode;
      });
      var maskSize = getMaskSize(size);
      var common = {
        graphProps: graphProps,
        labelModeEnabled: labelModeEnabled,
        gssLineData: gssLineData
      };
      marks = removeBuildingToolIfCurrentToolDiffers({
        marks: marks || [],
        currentTool: currentTool
      });
      var solutionSet = marks.filter(function (mark) {
        return mark.type === 'polygon';
      });

      if (gssLineData && gssLineData.selectedTool === 'solutionSet') {
        gssLineData.sections.forEach(function (section) {
          if (solutionSet.length === 0 || !(0, _utils.areArraysOfObjectsEqual)(section, solutionSet[0].points)) {
            var polygon = {
              type: 'polygon',
              building: false,
              closed: true,
              points: section,
              isSolution: false
            };
            if (!disabled) marks.push(polygon);
          }
        });
      } //Adjusted layering of added svg elements so that polygons will be added first and lines will be added second


      var newMarks = [];
      newMarks.push.apply(newMarks, (0, _toConsumableArray2["default"])(marks.filter(function (mark) {
        return mark.type === 'polygon';
      })));
      newMarks.push.apply(newMarks, (0, _toConsumableArray2["default"])(marks.filter(function (mark) {
        return mark.type === 'line';
      })));
      return /*#__PURE__*/_react["default"].createElement(_plot.Root, (0, _extends2["default"])({
        rootRef: function rootRef(r) {
          return _this2.rootNode = r;
        },
        disabledTitle: disabledTitle,
        disabledLabels: disabledLabels,
        labels: labels,
        labelsPlaceholders: labelsPlaceholders || {},
        showPixelGuides: showPixelGuides,
        showLabels: showLabels,
        showTitle: showTitle,
        title: title,
        titlePlaceholder: titlePlaceholder,
        onChangeTitle: onChangeTitle,
        onChangeLabels: onChangeLabels,
        mathMlOptions: mathMlOptions
      }, common), /*#__PURE__*/_react["default"].createElement("g", {
        transform: domain && domain.padding && domain.range ? "translate(".concat(domain.padding, ", ").concat(range.padding, ")") : undefined
      }, /*#__PURE__*/_react["default"].createElement(_grid["default"], common), /*#__PURE__*/_react["default"].createElement(_axis.Axes, (0, _extends2["default"])({}, axesSettings, common)), /*#__PURE__*/_react["default"].createElement(_bg["default"], (0, _extends2["default"])({}, size, {
        onClick: this.onBgClick
      }, common)), /*#__PURE__*/_react["default"].createElement("mask", {
        id: "".concat(this.maskUid)
      }, /*#__PURE__*/_react["default"].createElement("rect", (0, _extends2["default"])({}, maskSize, {
        fill: "white"
      })), " "), /*#__PURE__*/_react["default"].createElement("g", {
        id: "marks",
        mask: "url('#".concat(this.maskUid, "')")
      }, (backgroundMarks || []).map(function (m, index) {
        var Component = _this2.getComponent(m);

        var markType = m.type;
        return /*#__PURE__*/_react["default"].createElement(Component, (0, _extends2["default"])({
          key: "".concat(markType, "-").concat(index, "-bg"),
          mark: _objectSpread(_objectSpread({}, m), {}, {
            disabled: true,
            isBackground: true
          }),
          labelNode: _this2.state.labelNode,
          onClick: _this2.onBgClick
        }, common));
      }), newMarks.map(function (m, index) {
        var Component = _this2.getComponent(m);

        var markType = m.type;
        return /*#__PURE__*/_react["default"].createElement(Component, (0, _extends2["default"])({
          key: "".concat(markType, "-").concat(index),
          mark: m,
          coordinatesOnHover: coordinatesOnHover,
          onChange: _this2.changeMark,
          onComplete: _this2.completeMark,
          onClick: _this2.onBgClick,
          onDragStart: _this2.startDrag,
          onDragStop: _this2.stopDrag,
          labelNode: _this2.state.labelNode,
          isToolActive: currentTool && markType === currentTool.type
        }, common));
      }), /*#__PURE__*/_react["default"].createElement("foreignObject", (0, _extends2["default"])({
        ref: function ref(labelNode) {
          return _this2.labelNode = labelNode;
        },
        x: "0",
        y: "0"
      }, size, {
        style: {
          pointerEvents: 'none',
          fontSize: '14px'
        }
      })))));
    }
  }]);
  return Graph;
}(_react["default"].Component);

exports.Graph = Graph;
(0, _defineProperty2["default"])(Graph, "propTypes", _objectSpread(_objectSpread({}, graphPropTypes), {}, {
  currentTool: _propTypes["default"].object
}));
(0, _defineProperty2["default"])(Graph, "defaultProps", {
  onChangeMarks: function onChangeMarks() {},
  disabledLabels: false,
  disabledTitle: false
});
var _default = Graph;
exports["default"] = _default;
//# sourceMappingURL=graph.js.map