"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.GraphVisualization = GraphVisualization;
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _d = _interopRequireDefault(require("d3"));
var _persistence = require("../../services/persistence");
var _icon_renderer = require("../icon_renderer");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */

function registerZooming(element) {
  const blockScroll = function () {
    _d.default.event.preventDefault();
  };
  _d.default.select(element).on('mousewheel', blockScroll).on('DOMMouseScroll', blockScroll).call(_d.default.behavior.zoom().on('zoom', () => {
    const event = _d.default.event;
    _d.default.select(element).select('g').attr('transform', 'translate(' + event.translate + ')' + 'scale(' + event.scale + ')').attr('style', 'stroke-width: ' + 1 / event.scale);
  }));
}
function makeEdgeId(edge) {
  return `${(0, _persistence.makeNodeId)(edge.source.data.field, edge.source.data.term)}-${(0, _persistence.makeNodeId)(edge.target.data.field, edge.target.data.term)}`;
}
function GraphVisualization({
  workspace,
  selectSelected,
  onSetControl,
  onSetMergeCandidates
}) {
  const svgRoot = (0, _react.useRef)(null);
  const nodeClick = (n, event) => {
    // Selection logic - shift key+click helps selects multiple nodes
    // Without the shift key we deselect all prior selections (perhaps not
    // a great idea for touch devices with no concept of shift key)
    if (!event.shiftKey) {
      const prevSelection = n.isSelected;
      workspace.selectNone();
      n.isSelected = prevSelection;
    }
    if (workspace.toggleNodeSelection(n)) {
      selectSelected(n);
    } else {
      onSetControl('none');
    }
    workspace.changeHandler();
  };
  const handleMergeCandidatesCallback = termIntersects => {
    const mergeCandidates = [...termIntersects];
    onSetMergeCandidates(mergeCandidates);
    onSetControl('mergeTerms');
  };
  const edgeClick = edge => {
    // no multiple selection for now
    const currentSelection = workspace.getEdgeSelection();
    if (currentSelection.length && currentSelection[0] !== edge) {
      workspace.clearEdgeSelection();
    }
    if (!edge.isSelected) {
      workspace.addEdgeToSelection(edge);
    } else {
      workspace.removeEdgeFromSelection(edge);
    }
    onSetControl('edgeSelection');
    if (edge.isSelected) {
      workspace.getAllIntersections(handleMergeCandidatesCallback, [edge.topSrc, edge.topTarget]);
    }
  };
  return /*#__PURE__*/_react.default.createElement("svg", {
    xmlns: "http://www.w3.org/2000/svg",
    className: "gphGraph",
    width: "100%",
    height: "100%",
    pointerEvents: "all",
    id: "graphSvg",
    ref: element => {
      if (element && svgRoot.current !== element) {
        svgRoot.current = element;
        registerZooming(element);
      }
    }
  }, /*#__PURE__*/_react.default.createElement("g", null, /*#__PURE__*/_react.default.createElement("g", null, workspace.edges && workspace.edges.map(edge => /*#__PURE__*/_react.default.createElement("g", {
    key: makeEdgeId(edge),
    className: "gphEdge--wrapper"
  }, /*#__PURE__*/_react.default.createElement("line", {
    x1: edge.topSrc.kx,
    y1: edge.topSrc.ky,
    x2: edge.topTarget.kx,
    y2: edge.topTarget.ky,
    className: (0, _classnames.default)('gphEdge', {
      'gphEdge--selected': edge.isSelected
    }),
    strokeLinecap: "round",
    style: {
      strokeWidth: edge.width
    }
  }), /*#__PURE__*/_react.default.createElement("line", {
    x1: edge.topSrc.kx,
    y1: edge.topSrc.ky,
    x2: edge.topTarget.kx,
    y2: edge.topTarget.ky,
    onClick: () => {
      edgeClick(edge);
    },
    className: "gphEdge gphEdge--clickable",
    style: {
      strokeWidth: Math.max(edge.width, 15)
    }
  })))), workspace.nodes && workspace.nodes.filter(node => !node.parent).map(node => {
    const iconOffset = (0, _icon_renderer.getIconOffset)(node.icon);
    const kx = node.kx || 0;
    const ky = node.ky || 0;
    return /*#__PURE__*/_react.default.createElement("g", {
      key: (0, _persistence.makeNodeId)(node.data.field, node.data.term),
      onClick: e => {
        nodeClick(node, e);
      },
      onMouseDown: e => {
        // avoid selecting text when selecting nodes
        if (e.ctrlKey || e.shiftKey) {
          e.preventDefault();
        }
      },
      className: "gphNode"
    }, /*#__PURE__*/_react.default.createElement("circle", {
      cx: kx,
      cy: ky,
      r: node.scaledSize,
      className: (0, _classnames.default)('gphNode__circle', {
        'gphNode__circle--selected': node.isSelected
      }),
      style: {
        fill: node.color
      }
    }), /*#__PURE__*/_react.default.createElement(_icon_renderer.IconRenderer, {
      icon: node.icon,
      color: node.color,
      x: kx - ((iconOffset === null || iconOffset === void 0 ? void 0 : iconOffset.x) || 0),
      y: ky - ((iconOffset === null || iconOffset === void 0 ? void 0 : iconOffset.y) || 0)
    }), node.label.length < 30 && /*#__PURE__*/_react.default.createElement("text", {
      className: "gphNode__label",
      textAnchor: "middle",
      transform: "translate(0,22)",
      x: kx,
      y: ky
    }, node.label), node.label.length >= 30 && /*#__PURE__*/_react.default.createElement("foreignObject", {
      width: "100",
      height: "20",
      transform: "translate(-50,15)",
      x: kx,
      y: ky
    }, /*#__PURE__*/_react.default.createElement("p", {
      className: "gphNode__label gphNode__label--html gphNoUserSelect"
    }, node.label)), node.numChildren > 0 && /*#__PURE__*/_react.default.createElement("g", null, /*#__PURE__*/_react.default.createElement("circle", {
      r: "5",
      className: "gphNode__markerCircle",
      transform: "translate(10,10)",
      cx: kx,
      cy: ky
    }), /*#__PURE__*/_react.default.createElement("text", {
      className: "gphNode__markerText",
      textAnchor: "middle",
      transform: "translate(10,12)",
      x: kx,
      y: ky
    }, node.numChildren)));
  })));
}