import { mixin, isNumber, createHashMap } from "../../../../../zrender@5.4.4/node_modules/zrender/lib/core/util.mjs";
function generateNodeKey(id) {
  return "_EC_" + id;
}
var Graph = (
  /** @class */
  function() {
    function Graph2(directed) {
      this.type = "graph";
      this.nodes = [];
      this.edges = [];
      this._nodesMap = {};
      this._edgesMap = {};
      this._directed = directed || false;
    }
    Graph2.prototype.isDirected = function() {
      return this._directed;
    };
    Graph2.prototype.addNode = function(id, dataIndex) {
      id = id == null ? "" + dataIndex : "" + id;
      var nodesMap = this._nodesMap;
      if (nodesMap[generateNodeKey(id)]) {
        if (process.env.NODE_ENV !== "production") {
          console.error("Graph nodes have duplicate name or id");
        }
        return;
      }
      var node = new GraphNode(id, dataIndex);
      node.hostGraph = this;
      this.nodes.push(node);
      nodesMap[generateNodeKey(id)] = node;
      return node;
    };
    Graph2.prototype.getNodeByIndex = function(dataIndex) {
      var rawIdx = this.data.getRawIndex(dataIndex);
      return this.nodes[rawIdx];
    };
    Graph2.prototype.getNodeById = function(id) {
      return this._nodesMap[generateNodeKey(id)];
    };
    Graph2.prototype.addEdge = function(n1, n2, dataIndex) {
      var nodesMap = this._nodesMap;
      var edgesMap = this._edgesMap;
      if (isNumber(n1)) {
        n1 = this.nodes[n1];
      }
      if (isNumber(n2)) {
        n2 = this.nodes[n2];
      }
      if (!(n1 instanceof GraphNode)) {
        n1 = nodesMap[generateNodeKey(n1)];
      }
      if (!(n2 instanceof GraphNode)) {
        n2 = nodesMap[generateNodeKey(n2)];
      }
      if (!n1 || !n2) {
        return;
      }
      var key = n1.id + "-" + n2.id;
      var edge = new GraphEdge(n1, n2, dataIndex);
      edge.hostGraph = this;
      if (this._directed) {
        n1.outEdges.push(edge);
        n2.inEdges.push(edge);
      }
      n1.edges.push(edge);
      if (n1 !== n2) {
        n2.edges.push(edge);
      }
      this.edges.push(edge);
      edgesMap[key] = edge;
      return edge;
    };
    Graph2.prototype.getEdgeByIndex = function(dataIndex) {
      var rawIdx = this.edgeData.getRawIndex(dataIndex);
      return this.edges[rawIdx];
    };
    Graph2.prototype.getEdge = function(n1, n2) {
      if (n1 instanceof GraphNode) {
        n1 = n1.id;
      }
      if (n2 instanceof GraphNode) {
        n2 = n2.id;
      }
      var edgesMap = this._edgesMap;
      if (this._directed) {
        return edgesMap[n1 + "-" + n2];
      } else {
        return edgesMap[n1 + "-" + n2] || edgesMap[n2 + "-" + n1];
      }
    };
    Graph2.prototype.eachNode = function(cb, context) {
      var nodes = this.nodes;
      var len = nodes.length;
      for (var i = 0; i < len; i++) {
        if (nodes[i].dataIndex >= 0) {
          cb.call(context, nodes[i], i);
        }
      }
    };
    Graph2.prototype.eachEdge = function(cb, context) {
      var edges = this.edges;
      var len = edges.length;
      for (var i = 0; i < len; i++) {
        if (edges[i].dataIndex >= 0 && edges[i].node1.dataIndex >= 0 && edges[i].node2.dataIndex >= 0) {
          cb.call(context, edges[i], i);
        }
      }
    };
    Graph2.prototype.breadthFirstTraverse = function(cb, startNode, direction, context) {
      if (!(startNode instanceof GraphNode)) {
        startNode = this._nodesMap[generateNodeKey(startNode)];
      }
      if (!startNode) {
        return;
      }
      var edgeType = direction === "out" ? "outEdges" : direction === "in" ? "inEdges" : "edges";
      for (var i = 0; i < this.nodes.length; i++) {
        this.nodes[i].__visited = false;
      }
      if (cb.call(context, startNode, null)) {
        return;
      }
      var queue = [startNode];
      while (queue.length) {
        var currentNode = queue.shift();
        var edges = currentNode[edgeType];
        for (var i = 0; i < edges.length; i++) {
          var e = edges[i];
          var otherNode = e.node1 === currentNode ? e.node2 : e.node1;
          if (!otherNode.__visited) {
            if (cb.call(context, otherNode, currentNode)) {
              return;
            }
            queue.push(otherNode);
            otherNode.__visited = true;
          }
        }
      }
    };
    Graph2.prototype.update = function() {
      var data = this.data;
      var edgeData = this.edgeData;
      var nodes = this.nodes;
      var edges = this.edges;
      for (var i = 0, len = nodes.length; i < len; i++) {
        nodes[i].dataIndex = -1;
      }
      for (var i = 0, len = data.count(); i < len; i++) {
        nodes[data.getRawIndex(i)].dataIndex = i;
      }
      edgeData.filterSelf(function(idx) {
        var edge = edges[edgeData.getRawIndex(idx)];
        return edge.node1.dataIndex >= 0 && edge.node2.dataIndex >= 0;
      });
      for (var i = 0, len = edges.length; i < len; i++) {
        edges[i].dataIndex = -1;
      }
      for (var i = 0, len = edgeData.count(); i < len; i++) {
        edges[edgeData.getRawIndex(i)].dataIndex = i;
      }
    };
    Graph2.prototype.clone = function() {
      var graph = new Graph2(this._directed);
      var nodes = this.nodes;
      var edges = this.edges;
      for (var i = 0; i < nodes.length; i++) {
        graph.addNode(nodes[i].id, nodes[i].dataIndex);
      }
      for (var i = 0; i < edges.length; i++) {
        var e = edges[i];
        graph.addEdge(e.node1.id, e.node2.id, e.dataIndex);
      }
      return graph;
    };
    return Graph2;
  }()
);
var GraphNode = (
  /** @class */
  function() {
    function GraphNode2(id, dataIndex) {
      this.inEdges = [];
      this.outEdges = [];
      this.edges = [];
      this.dataIndex = -1;
      this.id = id == null ? "" : id;
      this.dataIndex = dataIndex == null ? -1 : dataIndex;
    }
    GraphNode2.prototype.degree = function() {
      return this.edges.length;
    };
    GraphNode2.prototype.inDegree = function() {
      return this.inEdges.length;
    };
    GraphNode2.prototype.outDegree = function() {
      return this.outEdges.length;
    };
    GraphNode2.prototype.getModel = function(path) {
      if (this.dataIndex < 0) {
        return;
      }
      var graph = this.hostGraph;
      var itemModel = graph.data.getItemModel(this.dataIndex);
      return itemModel.getModel(path);
    };
    GraphNode2.prototype.getAdjacentDataIndices = function() {
      var dataIndices = {
        edge: [],
        node: []
      };
      for (var i = 0; i < this.edges.length; i++) {
        var adjacentEdge = this.edges[i];
        if (adjacentEdge.dataIndex < 0) {
          continue;
        }
        dataIndices.edge.push(adjacentEdge.dataIndex);
        dataIndices.node.push(adjacentEdge.node1.dataIndex, adjacentEdge.node2.dataIndex);
      }
      return dataIndices;
    };
    GraphNode2.prototype.getTrajectoryDataIndices = function() {
      var connectedEdgesMap = createHashMap();
      var connectedNodesMap = createHashMap();
      for (var i = 0; i < this.edges.length; i++) {
        var adjacentEdge = this.edges[i];
        if (adjacentEdge.dataIndex < 0) {
          continue;
        }
        connectedEdgesMap.set(adjacentEdge.dataIndex, true);
        var sourceNodesQueue = [adjacentEdge.node1];
        var targetNodesQueue = [adjacentEdge.node2];
        var nodeIteratorIndex = 0;
        while (nodeIteratorIndex < sourceNodesQueue.length) {
          var sourceNode = sourceNodesQueue[nodeIteratorIndex];
          nodeIteratorIndex++;
          connectedNodesMap.set(sourceNode.dataIndex, true);
          for (var j = 0; j < sourceNode.inEdges.length; j++) {
            connectedEdgesMap.set(sourceNode.inEdges[j].dataIndex, true);
            sourceNodesQueue.push(sourceNode.inEdges[j].node1);
          }
        }
        nodeIteratorIndex = 0;
        while (nodeIteratorIndex < targetNodesQueue.length) {
          var targetNode = targetNodesQueue[nodeIteratorIndex];
          nodeIteratorIndex++;
          connectedNodesMap.set(targetNode.dataIndex, true);
          for (var j = 0; j < targetNode.outEdges.length; j++) {
            connectedEdgesMap.set(targetNode.outEdges[j].dataIndex, true);
            targetNodesQueue.push(targetNode.outEdges[j].node2);
          }
        }
      }
      return {
        edge: connectedEdgesMap.keys(),
        node: connectedNodesMap.keys()
      };
    };
    return GraphNode2;
  }()
);
var GraphEdge = (
  /** @class */
  function() {
    function GraphEdge2(n1, n2, dataIndex) {
      this.dataIndex = -1;
      this.node1 = n1;
      this.node2 = n2;
      this.dataIndex = dataIndex == null ? -1 : dataIndex;
    }
    GraphEdge2.prototype.getModel = function(path) {
      if (this.dataIndex < 0) {
        return;
      }
      var graph = this.hostGraph;
      var itemModel = graph.edgeData.getItemModel(this.dataIndex);
      return itemModel.getModel(path);
    };
    GraphEdge2.prototype.getAdjacentDataIndices = function() {
      return {
        edge: [this.dataIndex],
        node: [this.node1.dataIndex, this.node2.dataIndex]
      };
    };
    GraphEdge2.prototype.getTrajectoryDataIndices = function() {
      var connectedEdgesMap = createHashMap();
      var connectedNodesMap = createHashMap();
      connectedEdgesMap.set(this.dataIndex, true);
      var sourceNodes = [this.node1];
      var targetNodes = [this.node2];
      var nodeIteratorIndex = 0;
      while (nodeIteratorIndex < sourceNodes.length) {
        var sourceNode = sourceNodes[nodeIteratorIndex];
        nodeIteratorIndex++;
        connectedNodesMap.set(sourceNode.dataIndex, true);
        for (var j = 0; j < sourceNode.inEdges.length; j++) {
          connectedEdgesMap.set(sourceNode.inEdges[j].dataIndex, true);
          sourceNodes.push(sourceNode.inEdges[j].node1);
        }
      }
      nodeIteratorIndex = 0;
      while (nodeIteratorIndex < targetNodes.length) {
        var targetNode = targetNodes[nodeIteratorIndex];
        nodeIteratorIndex++;
        connectedNodesMap.set(targetNode.dataIndex, true);
        for (var j = 0; j < targetNode.outEdges.length; j++) {
          connectedEdgesMap.set(targetNode.outEdges[j].dataIndex, true);
          targetNodes.push(targetNode.outEdges[j].node2);
        }
      }
      return {
        edge: connectedEdgesMap.keys(),
        node: connectedNodesMap.keys()
      };
    };
    return GraphEdge2;
  }()
);
function createGraphDataProxyMixin(hostName, dataName) {
  return {
    /**
     * @param Default 'value'. can be 'a', 'b', 'c', 'd', 'e'.
     */
    getValue: function(dimension) {
      var data = this[hostName][dataName];
      return data.getStore().get(data.getDimensionIndex(dimension || "value"), this.dataIndex);
    },
    // TODO: TYPE stricter type.
    setVisual: function(key, value) {
      this.dataIndex >= 0 && this[hostName][dataName].setItemVisual(this.dataIndex, key, value);
    },
    getVisual: function(key) {
      return this[hostName][dataName].getItemVisual(this.dataIndex, key);
    },
    setLayout: function(layout, merge) {
      this.dataIndex >= 0 && this[hostName][dataName].setItemLayout(this.dataIndex, layout, merge);
    },
    getLayout: function() {
      return this[hostName][dataName].getItemLayout(this.dataIndex);
    },
    getGraphicEl: function() {
      return this[hostName][dataName].getItemGraphicEl(this.dataIndex);
    },
    getRawIndex: function() {
      return this[hostName][dataName].getRawIndex(this.dataIndex);
    }
  };
}
mixin(GraphNode, createGraphDataProxyMixin("hostGraph", "data"));
mixin(GraphEdge, createGraphDataProxyMixin("hostGraph", "edgeData"));
const Graph$1 = Graph;
export {
  GraphEdge,
  GraphNode,
  Graph$1 as default
};
