// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import { GNode, DEFAULT_NODE_BUBBLE_RADIUS } from "../src/node";
import { Graph } from "./graph";

export const MINIMUM_EDGE_SEPARATION = 20;

export class Edge {
  target: GNode;
  source: GNode;
  index: number;
  type: string;
  backEdgeNumber: number;
  visible: boolean;

  constructor(target: GNode, index: number, source: GNode, type: string) {
    this.target = target;
    this.source = source;
    this.index = index;
    this.type = type;
    this.backEdgeNumber = 0;
    this.visible = false;
  }

  stringID() {
    return this.source.id + "," + this.index + "," + this.target.id;
  }

  isVisible() {
    return this.visible && this.source.visible && this.target.visible;
  }

  getInputHorizontalPosition(graph: Graph, showTypes: boolean) {
    if (this.backEdgeNumber > 0) {
      return graph.maxGraphNodeX + this.backEdgeNumber * MINIMUM_EDGE_SEPARATION;
    }
    const source = this.source;
    const target = this.target;
    const index = this.index;
    const inputX = target.x + target.getInputX(index);
    const inputApproach = target.getInputApproach(this.index);
    const outputApproach = source.getOutputApproach(showTypes);
    if (inputApproach > outputApproach) {
      return inputX;
    } else {
      const inputOffset = MINIMUM_EDGE_SEPARATION * (index + 1);
      return (target.x < source.x)
        ? (target.x + target.getTotalNodeWidth() + inputOffset)
        : (target.x - inputOffset);
    }
  }

  generatePath(graph: Graph, showTypes: boolean) {
    const target = this.target;
    const source = this.source;
    const inputX = target.x + target.getInputX(this.index);
    const arrowheadHeight = 7;
    const inputY = target.y - 2 * DEFAULT_NODE_BUBBLE_RADIUS - arrowheadHeight;
    const outputX = source.x + source.getOutputX();
    const outputY = source.y + source.getNodeHeight(showTypes) + DEFAULT_NODE_BUBBLE_RADIUS;
    let inputApproach = target.getInputApproach(this.index);
    const outputApproach = source.getOutputApproach(showTypes);
    const horizontalPos = this.getInputHorizontalPosition(graph, showTypes);

    let result = "M" + outputX + "," + outputY +
      "L" + outputX + "," + outputApproach +
      "L" + horizontalPos + "," + outputApproach;

    if (horizontalPos != inputX) {
      result += "L" + horizontalPos + "," + inputApproach;
    } else {
      if (inputApproach < outputApproach) {
        inputApproach = outputApproach;
      }
    }

    result += "L" + inputX + "," + inputApproach +
      "L" + inputX + "," + inputY;
    return result;
  }

  isBackEdge() {
    return this.target.hasBackEdges() && (this.target.rank < this.source.rank);
  }

}

export const edgeToStr = (e: Edge) => e.stringID();
