// Copyright 2015 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 * as d3 from "d3";
import { layoutNodeGraph } from "../src/graph-layout";
import { GNode, nodeToStr } from "../src/node";
import { NODE_INPUT_WIDTH } from "../src/node";
import { DEFAULT_NODE_BUBBLE_RADIUS } from "../src/node";
import { Edge, edgeToStr } from "../src/edge";
import { PhaseView } from "../src/view";
import { MySelection } from "../src/selection";
import { partial } from "../src/util";
import { NodeSelectionHandler, ClearableHandler } from "./selection-handler";
import { Graph } from "./graph";
import { SelectionBroker } from "./selection-broker";

function nodeToStringKey(n: GNode) {
  return "" + n.id;
}

interface GraphState {
  showTypes: boolean;
  selection: MySelection;
  mouseDownNode: any;
  justDragged: boolean;
  justScaleTransGraph: boolean;
  hideDead: boolean;
}

export class GraphView extends PhaseView {
  divElement: d3.Selection<any, any, any, any>;
  svg: d3.Selection<any, any, any, any>;
  showPhaseByName: (p: string, s: Set<any>) => void;
  state: GraphState;
  selectionHandler: NodeSelectionHandler & ClearableHandler;
  graphElement: d3.Selection<any, any, any, any>;
  visibleNodes: d3.Selection<any, GNode, any, any>;
  visibleEdges: d3.Selection<any, Edge, any, any>;
  drag: d3.DragBehavior<any, GNode, GNode>;
  panZoom: d3.ZoomBehavior<SVGElement, any>;
  visibleBubbles: d3.Selection<any, any, any, any>;
  transitionTimout: number;
  graph: Graph;
  broker: SelectionBroker;
  phaseName: string;
  toolbox: HTMLElement;

  createViewElement() {
    const pane = document.createElement('div');
    pane.setAttribute('id', "graph");
    return pane;
  }

  constructor(idOrContainer: string | HTMLElement, broker: SelectionBroker,
    showPhaseByName: (s: string) => void, toolbox: HTMLElement) {
    super(idOrContainer);
    const view = this;
    this.broker = broker;
    this.showPhaseByName = showPhaseByName;
    this.divElement = d3.select(this.divNode);
    this.phaseName = "";
    this.toolbox = toolbox;
    const svg = this.divElement.append("svg")
      .attr('version', '2.0')
      .attr("width", "100%")
      .attr("height", "100%");
    svg.on("click", function (d) {
      view.selectionHandler.clear();
    });
    // Listen for key events. Note that the focus handler seems
    // to be important even if it does nothing.
    svg
      .attr("focusable", false)
      .on("focus", e => { })
      .on("keydown", e => { view.svgKeyDown(); });

    view.svg = svg;

    this.state = {
      selection: null,
      mouseDownNode: null,
      justDragged: false,
      justScaleTransGraph: false,
      showTypes: false,
      hideDead: false
    };

    this.selectionHandler = {
      clear: function () {
        view.state.selection.clear();
        broker.broadcastClear(this);
        view.updateGraphVisibility();
      },
      select: function (nodes: Array<GNode>, selected: boolean) {
        const locations = [];
        for (const node of nodes) {
          if (node.nodeLabel.sourcePosition) {
            locations.push(node.nodeLabel.sourcePosition);
          }
          if (node.nodeLabel.origin && node.nodeLabel.origin.bytecodePosition) {
            locations.push({ bytecodePosition: node.nodeLabel.origin.bytecodePosition });
          }
        }
        view.state.selection.select(nodes, selected);
        broker.broadcastSourcePositionSelect(this, locations, selected);
        view.updateGraphVisibility();
      },
      brokeredNodeSelect: function (locations, selected: boolean) {
        if (!view.graph) return;
        const selection = view.graph.nodes(n => {
          return locations.has(nodeToStringKey(n))
            && (!view.state.hideDead || n.isLive());
        });
        view.state.selection.select(selection, selected);
        // Update edge visibility based on selection.
        for (const n of view.graph.nodes()) {
          if (view.state.selection.isSelected(n)) {
            n.visible = true;
            n.inputs.forEach(e => {
              e.visible = e.visible || view.state.selection.isSelected(e.source);
            });
            n.outputs.forEach(e => {
              e.visible = e.visible || view.state.selection.isSelected(e.target);
            });
          }
        }
        view.updateGraphVisibility();
      },
      brokeredClear: function () {
        view.state.selection.clear();
        view.updateGraphVisibility();
      }
    };

    view.state.selection = new MySelection(nodeToStringKey);

    const defs = svg.append('svg:defs');
    defs.append('svg:marker')
      .attr('id', 'end-arrow')
      .attr('viewBox', '0 -4 8 8')
      .attr('refX', 2)
      .attr('markerWidth', 2.5)
      .attr('markerHeight', 2.5)
      .attr('orient', 'auto')
      .append('svg:path')
      .attr('d', 'M0,-4L8,0L0,4');

    this.graphElement = svg.append("g");
    view.visibleEdges = this.graphElement.append("g");
    view.visibleNodes = this.graphElement.append("g");

    view.drag = d3.drag<any, GNode, GNode>()
      .on("drag", function (d) {
        d.x += d3.event.dx;
        d.y += d3.event.dy;
        view.updateGraphVisibility();
      });

    function zoomed() {
      if (d3.event.shiftKey) return false;
      view.graphElement.attr("transform", d3.event.transform);
      return true;
    }

    const zoomSvg = d3.zoom<SVGElement, any>()
      .scaleExtent([0.2, 40])
      .on("zoom", zoomed)
      .on("start", function () {
        if (d3.event.shiftKey) return;
        d3.select('body').style("cursor", "move");
      })
      .on("end", function () {
        d3.select('body').style("cursor", "auto");
      });

    svg.call(zoomSvg).on("dblclick.zoom", null);

    view.panZoom = zoomSvg;

  }

  getEdgeFrontier(nodes: Iterable<GNode>, inEdges: boolean,
    edgeFilter: (e: Edge, i: number) => boolean) {
    const frontier: Set<Edge> = new Set();
    for (const n of nodes) {
      const edges = inEdges ? n.inputs : n.outputs;
      let edgeNumber = 0;
      edges.forEach((edge: Edge) => {
        if (edgeFilter == undefined || edgeFilter(edge, edgeNumber)) {
          frontier.add(edge);
        }
        ++edgeNumber;
      });
    }
    return frontier;
  }

  getNodeFrontier(nodes: Iterable<GNode>, inEdges: boolean,
    edgeFilter: (e: Edge, i: number) => boolean) {
    const view = this;
    const frontier: Set<GNode> = new Set();
    let newState = true;
    const edgeFrontier = view.getEdgeFrontier(nodes, inEdges, edgeFilter);
    // Control key toggles edges rather than just turning them on
    if (d3.event.ctrlKey) {
      edgeFrontier.forEach(function (edge: Edge) {
        if (edge.visible) {
          newState = false;
        }
      });
    }
    edgeFrontier.forEach(function (edge: Edge) {
      edge.visible = newState;
      if (newState) {
        const node = inEdges ? edge.source : edge.target;
        node.visible = true;
        frontier.add(node);
      }
    });
    view.updateGraphVisibility();
    if (newState) {
      return frontier;
    } else {
      return undefined;
    }
  }

  initializeContent(data, rememberedSelection) {
    this.show();
    function createImgInput(id: string, title: string, onClick): HTMLElement {
      const input = document.createElement("input");
      input.setAttribute("id", id);
      input.setAttribute("type", "image");
      input.setAttribute("title", title);
      input.setAttribute("src", `img/${id}-icon.png`);
      input.className = "button-input graph-toolbox-item";
      input.addEventListener("click", onClick);
      return input;
    }
    this.toolbox.appendChild(createImgInput("layout", "layout graph",
      partial(this.layoutAction, this)));
    this.toolbox.appendChild(createImgInput("show-all", "show all nodes",
      partial(this.showAllAction, this)));
    this.toolbox.appendChild(createImgInput("show-control", "show only control nodes",
      partial(this.showControlAction, this)));
    this.toolbox.appendChild(createImgInput("toggle-hide-dead", "toggle hide dead nodes",
      partial(this.toggleHideDead, this)));
    this.toolbox.appendChild(createImgInput("hide-unselected", "hide unselected",
      partial(this.hideUnselectedAction, this)));
    this.toolbox.appendChild(createImgInput("hide-selected", "hide selected",
      partial(this.hideSelectedAction, this)));
    this.toolbox.appendChild(createImgInput("zoom-selection", "zoom selection",
      partial(this.zoomSelectionAction, this)));
    this.toolbox.appendChild(createImgInput("toggle-types", "toggle types",
      partial(this.toggleTypesAction, this)));

    this.phaseName = data.name;
    this.createGraph(data.data, rememberedSelection);
    this.broker.addNodeHandler(this.selectionHandler);

    if (rememberedSelection != null && rememberedSelection.size > 0) {
      this.attachSelection(rememberedSelection);
      this.connectVisibleSelectedNodes();
      this.viewSelection();
    } else {
      this.viewWholeGraph();
    }
  }

  deleteContent() {
    for (const item of this.toolbox.querySelectorAll(".graph-toolbox-item")) {
      item.parentElement.removeChild(item);
    }

    for (const n of this.graph.nodes()) {
      n.visible = false;
    }
    this.graph.forEachEdge((e: Edge) => {
      e.visible = false;
    });
    this.updateGraphVisibility();
  }

  public hide(): void {
    super.hide();
    this.deleteContent();
  }

  createGraph(data, rememberedSelection) {
    this.graph = new Graph(data);

    this.showControlAction(this);

    if (rememberedSelection != undefined) {
      for (const n of this.graph.nodes()) {
        n.visible = n.visible || rememberedSelection.has(nodeToStringKey(n));
      }
    }

    this.graph.forEachEdge(e => e.visible = e.source.visible && e.target.visible);

    this.layoutGraph();
    this.updateGraphVisibility();
  }

  connectVisibleSelectedNodes() {
    const view = this;
    for (const n of view.state.selection) {
      n.inputs.forEach(function (edge: Edge) {
        if (edge.source.visible && edge.target.visible) {
          edge.visible = true;
        }
      });
      n.outputs.forEach(function (edge: Edge) {
        if (edge.source.visible && edge.target.visible) {
          edge.visible = true;
        }
      });
    }
  }

  updateInputAndOutputBubbles() {
    const view = this;
    const g = this.graph;
    const s = this.visibleBubbles;
    s.classed("filledBubbleStyle", function (c) {
      const components = this.id.split(',');
      if (components[0] == "ib") {
        const edge = g.nodeMap[components[3]].inputs[components[2]];
        return edge.isVisible();
      } else {
        return g.nodeMap[components[1]].areAnyOutputsVisible() == 2;
      }
    }).classed("halfFilledBubbleStyle", function (c) {
      const components = this.id.split(',');
      if (components[0] == "ib") {
        return false;
      } else {
        return g.nodeMap[components[1]].areAnyOutputsVisible() == 1;
      }
    }).classed("bubbleStyle", function (c) {
      const components = this.id.split(',');
      if (components[0] == "ib") {
        const edge = g.nodeMap[components[3]].inputs[components[2]];
        return !edge.isVisible();
      } else {
        return g.nodeMap[components[1]].areAnyOutputsVisible() == 0;
      }
    });
    s.each(function (c) {
      const components = this.id.split(',');
      if (components[0] == "ob") {
        const from = g.nodeMap[components[1]];
        const x = from.getOutputX();
        const y = from.getNodeHeight(view.state.showTypes) + DEFAULT_NODE_BUBBLE_RADIUS;
        const transform = "translate(" + x + "," + y + ")";
        this.setAttribute('transform', transform);
      }
    });
  }

  attachSelection(s) {
    if (!(s instanceof Set)) return;
    this.selectionHandler.clear();
    const selected = [...this.graph.nodes(n =>
      s.has(this.state.selection.stringKey(n)) && (!this.state.hideDead || n.isLive()))];
    this.selectionHandler.select(selected, true);
  }

  detachSelection() {
    return this.state.selection.detachSelection();
  }

  selectAllNodes() {
    if (!d3.event.shiftKey) {
      this.state.selection.clear();
    }
    const allVisibleNodes = [...this.graph.nodes(n => n.visible)];
    this.state.selection.select(allVisibleNodes, true);
    this.updateGraphVisibility();
  }

  layoutAction(graph: GraphView) {
    graph.layoutGraph();
    graph.updateGraphVisibility();
    graph.viewWholeGraph();
  }

  showAllAction(view: GraphView) {
    for (const n of view.graph.nodes()) {
      n.visible = !view.state.hideDead || n.isLive();
    }
    view.graph.forEachEdge((e: Edge) => {
      e.visible = e.source.visible || e.target.visible;
    });
    view.updateGraphVisibility();
    view.viewWholeGraph();
  }

  showControlAction(view: GraphView) {
    for (const n of view.graph.nodes()) {
      n.visible = n.cfg && (!view.state.hideDead || n.isLive());
    }
    view.graph.forEachEdge((e: Edge) => {
      e.visible = e.type == 'control' && e.source.visible && e.target.visible;
    });
    view.updateGraphVisibility();
    view.viewWholeGraph();
  }

  toggleHideDead(view: GraphView) {
    view.state.hideDead = !view.state.hideDead;
    if (view.state.hideDead) {
      view.hideDead();
    } else {
      view.showDead();
    }
    const element = document.getElementById('toggle-hide-dead');
    element.classList.toggle('button-input-toggled', view.state.hideDead);
  }

  hideDead() {
    for (const n of this.graph.nodes()) {
      if (!n.isLive()) {
        n.visible = false;
        this.state.selection.select([n], false);
      }
    }
    this.updateGraphVisibility();
  }

  showDead() {
    for (const n of this.graph.nodes()) {
      if (!n.isLive()) {
        n.visible = true;
      }
    }
    this.updateGraphVisibility();
  }

  hideUnselectedAction(view: GraphView) {
    for (const n of view.graph.nodes()) {
      if (!view.state.selection.isSelected(n)) {
        n.visible = false;
      }
    }
    view.updateGraphVisibility();
  }

  hideSelectedAction(view: GraphView) {
    for (const n of view.graph.nodes()) {
      if (view.state.selection.isSelected(n)) {
        n.visible = false;
      }
    }
    view.selectionHandler.clear();
  }

  zoomSelectionAction(view: GraphView) {
    view.viewSelection();
  }

  toggleTypesAction(view: GraphView) {
    view.toggleTypes();
  }

  searchInputAction(searchBar: HTMLInputElement, e: KeyboardEvent, onlyVisible: boolean) {
    if (e.keyCode == 13) {
      this.selectionHandler.clear();
      const query = searchBar.value;
      window.sessionStorage.setItem("lastSearch", query);
      if (query.length == 0) return;

      const reg = new RegExp(query);
      const filterFunction = (n: GNode) => {
        return (reg.exec(n.getDisplayLabel()) != null ||
          (this.state.showTypes && reg.exec(n.getDisplayType())) ||
          (reg.exec(n.getTitle())) ||
          reg.exec(n.nodeLabel.opcode) != null);
      };

      const selection = [...this.graph.nodes(n => {
        if ((e.ctrlKey || n.visible || !onlyVisible) && filterFunction(n)) {
          if (e.ctrlKey || !onlyVisible) n.visible = true;
          return true;
        }
        return false;
      })];

      this.selectionHandler.select(selection, true);
      this.connectVisibleSelectedNodes();
      this.updateGraphVisibility();
      searchBar.blur();
      this.viewSelection();
    }
    e.stopPropagation();
  }

  svgKeyDown() {
    const view = this;
    const state = this.state;

    const showSelectionFrontierNodes = (inEdges: boolean, filter: (e: Edge, i: number) => boolean, doSelect: boolean) => {
      const frontier = view.getNodeFrontier(state.selection, inEdges, filter);
      if (frontier != undefined && frontier.size) {
        if (doSelect) {
          if (!d3.event.shiftKey) {
            state.selection.clear();
          }
          state.selection.select([...frontier], true);
        }
        view.updateGraphVisibility();
      }
    };

    let eventHandled = true; // unless the below switch defaults
    switch (d3.event.keyCode) {
      case 49:
      case 50:
      case 51:
      case 52:
      case 53:
      case 54:
      case 55:
      case 56:
      case 57:
        // '1'-'9'
        showSelectionFrontierNodes(true,
          (edge: Edge, index: number) => index == (d3.event.keyCode - 49),
          !d3.event.ctrlKey);
        break;
      case 97:
      case 98:
      case 99:
      case 100:
      case 101:
      case 102:
      case 103:
      case 104:
      case 105:
        // 'numpad 1'-'numpad 9'
        showSelectionFrontierNodes(true,
          (edge, index) => index == (d3.event.keyCode - 97),
          !d3.event.ctrlKey);
        break;
      case 67:
        // 'c'
        showSelectionFrontierNodes(d3.event.altKey,
          (edge, index) => edge.type == 'control',
          true);
        break;
      case 69:
        // 'e'
        showSelectionFrontierNodes(d3.event.altKey,
          (edge, index) => edge.type == 'effect',
          true);
        break;
      case 79:
        // 'o'
        showSelectionFrontierNodes(false, undefined, false);
        break;
      case 73:
        // 'i'
        if (!d3.event.ctrlKey && !d3.event.shiftKey) {
          showSelectionFrontierNodes(true, undefined, false);
        } else {
          eventHandled = false;
        }
        break;
      case 65:
        // 'a'
        view.selectAllNodes();
        break;
      case 38:
      // UP
      case 40: {
        // DOWN
        showSelectionFrontierNodes(d3.event.keyCode == 38, undefined, true);
        break;
      }
      case 82:
        // 'r'
        if (!d3.event.ctrlKey && !d3.event.shiftKey) {
          this.layoutAction(this);
        } else {
          eventHandled = false;
        }
        break;
      case 83:
        // 's'
        view.selectOrigins();
        break;
      default:
        eventHandled = false;
        break;
    }
    if (eventHandled) {
      d3.event.preventDefault();
    }
  }

  layoutGraph() {
    console.time("layoutGraph");
    layoutNodeGraph(this.graph, this.state.showTypes);
    const extent = this.graph.redetermineGraphBoundingBox(this.state.showTypes);
    this.panZoom.translateExtent(extent);
    this.minScale();
    console.timeEnd("layoutGraph");
  }

  selectOrigins() {
    const state = this.state;
    const origins = [];
    let phase = this.phaseName;
    const selection = new Set<any>();
    for (const n of state.selection) {
      const origin = n.nodeLabel.origin;
      if (origin) {
        phase = origin.phase;
        const node = this.graph.nodeMap[origin.nodeId];
        if (phase === this.phaseName && node) {
          origins.push(node);
        } else {
          selection.add(`${origin.nodeId}`);
        }
      }
    }
    // Only go through phase reselection if we actually need
    // to display another phase.
    if (selection.size > 0 && phase !== this.phaseName) {
      this.showPhaseByName(phase, selection);
    } else if (origins.length > 0) {
      this.selectionHandler.clear();
      this.selectionHandler.select(origins, true);
    }
  }

  // call to propagate changes to graph
  updateGraphVisibility() {
    const view = this;
    const graph = this.graph;
    const state = this.state;
    if (!graph) return;

    const filteredEdges = [...graph.filteredEdges(function (e) {
      return e.source.visible && e.target.visible;
    })];
    const selEdges = view.visibleEdges.selectAll<SVGPathElement, Edge>("path").data(filteredEdges, edgeToStr);

    // remove old links
    selEdges.exit().remove();

    // add new paths
    const newEdges = selEdges.enter()
      .append('path');

    newEdges.style('marker-end', 'url(#end-arrow)')
      .attr("id", function (edge) { return "e," + edge.stringID(); })
      .on("click", function (edge) {
        d3.event.stopPropagation();
        if (!d3.event.shiftKey) {
          view.selectionHandler.clear();
        }
        view.selectionHandler.select([edge.source, edge.target], true);
      })
      .attr("adjacentToHover", "false")
      .classed('value', function (e) {
        return e.type == 'value' || e.type == 'context';
      }).classed('control', function (e) {
        return e.type == 'control';
      }).classed('effect', function (e) {
        return e.type == 'effect';
      }).classed('frame-state', function (e) {
        return e.type == 'frame-state';
      }).attr('stroke-dasharray', function (e) {
        if (e.type == 'frame-state') return "10,10";
        return (e.type == 'effect') ? "5,5" : "";
      });

    const newAndOldEdges = newEdges.merge(selEdges);

    newAndOldEdges.classed('hidden', e => !e.isVisible());

    // select existing nodes
    const filteredNodes = [...graph.nodes(n => n.visible)];
    const allNodes = view.visibleNodes.selectAll<SVGGElement, GNode>("g");
    const selNodes = allNodes.data(filteredNodes, nodeToStr);

    // remove old nodes
    selNodes.exit().remove();

    // add new nodes
    const newGs = selNodes.enter()
      .append("g");

    newGs.classed("turbonode", function (n) { return true; })
      .classed("control", function (n) { return n.isControl(); })
      .classed("live", function (n) { return n.isLive(); })
      .classed("dead", function (n) { return !n.isLive(); })
      .classed("javascript", function (n) { return n.isJavaScript(); })
      .classed("input", function (n) { return n.isInput(); })
      .classed("simplified", function (n) { return n.isSimplified(); })
      .classed("machine", function (n) { return n.isMachine(); })
      .on('mouseenter', function (node) {
        const visibleEdges = view.visibleEdges.selectAll<SVGPathElement, Edge>('path');
        const adjInputEdges = visibleEdges.filter(e => e.target === node);
        const adjOutputEdges = visibleEdges.filter(e => e.source === node);
        adjInputEdges.attr('relToHover', "input");
        adjOutputEdges.attr('relToHover', "output");
        const adjInputNodes = adjInputEdges.data().map(e => e.source);
        const visibleNodes = view.visibleNodes.selectAll<SVGGElement, GNode>("g");
        visibleNodes.data<GNode>(adjInputNodes, nodeToStr).attr('relToHover', "input");
        const adjOutputNodes = adjOutputEdges.data().map(e => e.target);
        visibleNodes.data<GNode>(adjOutputNodes, nodeToStr).attr('relToHover', "output");
        view.updateGraphVisibility();
      })
      .on('mouseleave', function (node) {
        const visibleEdges = view.visibleEdges.selectAll<SVGPathElement, Edge>('path');
        const adjEdges = visibleEdges.filter(e => e.target === node || e.source === node);
        adjEdges.attr('relToHover', "none");
        const adjNodes = adjEdges.data().map(e => e.target).concat(adjEdges.data().map(e => e.source));
        const visibleNodes = view.visibleNodes.selectAll<SVGPathElement, GNode>("g");
        visibleNodes.data(adjNodes, nodeToStr).attr('relToHover', "none");
        view.updateGraphVisibility();
      })
      .on("click", d => {
        if (!d3.event.shiftKey) view.selectionHandler.clear();
        view.selectionHandler.select([d], undefined);
        d3.event.stopPropagation();
      })
      .call(view.drag);

    newGs.append("rect")
      .attr("rx", 10)
      .attr("ry", 10)
      .attr('width', function (d) {
        return d.getTotalNodeWidth();
      })
      .attr('height', function (d) {
        return d.getNodeHeight(view.state.showTypes);
      });

    function appendInputAndOutputBubbles(g, d) {
      for (let i = 0; i < d.inputs.length; ++i) {
        const x = d.getInputX(i);
        const y = -DEFAULT_NODE_BUBBLE_RADIUS;
        g.append('circle')
          .classed("filledBubbleStyle", function (c) {
            return d.inputs[i].isVisible();
          })
          .classed("bubbleStyle", function (c) {
            return !d.inputs[i].isVisible();
          })
          .attr("id", "ib," + d.inputs[i].stringID())
          .attr("r", DEFAULT_NODE_BUBBLE_RADIUS)
          .attr("transform", function (d) {
            return "translate(" + x + "," + y + ")";
          })
          .on("click", function (this: SVGCircleElement, d) {
            const components = this.id.split(',');
            const node = graph.nodeMap[components[3]];
            const edge = node.inputs[components[2]];
            const visible = !edge.isVisible();
            node.setInputVisibility(components[2], visible);
            d3.event.stopPropagation();
            view.updateGraphVisibility();
          });
      }
      if (d.outputs.length != 0) {
        const x = d.getOutputX();
        const y = d.getNodeHeight(view.state.showTypes) + DEFAULT_NODE_BUBBLE_RADIUS;
        g.append('circle')
          .classed("filledBubbleStyle", function (c) {
            return d.areAnyOutputsVisible() == 2;
          })
          .classed("halFilledBubbleStyle", function (c) {
            return d.areAnyOutputsVisible() == 1;
          })
          .classed("bubbleStyle", function (c) {
            return d.areAnyOutputsVisible() == 0;
          })
          .attr("id", "ob," + d.id)
          .attr("r", DEFAULT_NODE_BUBBLE_RADIUS)
          .attr("transform", function (d) {
            return "translate(" + x + "," + y + ")";
          })
          .on("click", function (d) {
            d.setOutputVisibility(d.areAnyOutputsVisible() == 0);
            d3.event.stopPropagation();
            view.updateGraphVisibility();
          });
      }
    }

    newGs.each(function (d) {
      appendInputAndOutputBubbles(d3.select(this), d);
    });

    newGs.each(function (d) {
      d3.select(this).append("text")
        .classed("label", true)
        .attr("text-anchor", "right")
        .attr("dx", 5)
        .attr("dy", 5)
        .append('tspan')
        .text(function (l) {
          return d.getDisplayLabel();
        })
        .append("title")
        .text(function (l) {
          return d.getTitle();
        });
      if (d.nodeLabel.type != undefined) {
        d3.select(this).append("text")
          .classed("label", true)
          .classed("type", true)
          .attr("text-anchor", "right")
          .attr("dx", 5)
          .attr("dy", d.labelbbox.height + 5)
          .append('tspan')
          .text(function (l) {
            return d.getDisplayType();
          })
          .append("title")
          .text(function (l) {
            return d.getType();
          });
      }
    });

    const newAndOldNodes = newGs.merge(selNodes);

    newAndOldNodes.select<SVGTextElement>('.type').each(function (d) {
      this.setAttribute('visibility', view.state.showTypes ? 'visible' : 'hidden');
    });

    newAndOldNodes
      .classed("selected", function (n) {
        if (state.selection.isSelected(n)) return true;
        return false;
      })
      .attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; })
      .select('rect')
      .attr('height', function (d) { return d.getNodeHeight(view.state.showTypes); });

    view.visibleBubbles = d3.selectAll('circle');

    view.updateInputAndOutputBubbles();

    graph.maxGraphX = graph.maxGraphNodeX;
    newAndOldEdges.attr("d", function (edge) {
      return edge.generatePath(graph, view.state.showTypes);
    });
  }

  getSvgViewDimensions() {
    return [this.container.clientWidth, this.container.clientHeight];
  }

  getSvgExtent(): [[number, number], [number, number]] {
    return [[0, 0], [this.container.clientWidth, this.container.clientHeight]];
  }

  minScale() {
    const dimensions = this.getSvgViewDimensions();
    const minXScale = dimensions[0] / (2 * this.graph.width);
    const minYScale = dimensions[1] / (2 * this.graph.height);
    const minScale = Math.min(minXScale, minYScale);
    this.panZoom.scaleExtent([minScale, 40]);
    return minScale;
  }

  onresize() {
    const trans = d3.zoomTransform(this.svg.node());
    const ctrans = this.panZoom.constrain()(trans, this.getSvgExtent(), this.panZoom.translateExtent());
    this.panZoom.transform(this.svg, ctrans);
  }

  toggleTypes() {
    const view = this;
    view.state.showTypes = !view.state.showTypes;
    const element = document.getElementById('toggle-types');
    element.classList.toggle('button-input-toggled', view.state.showTypes);
    view.updateGraphVisibility();
  }

  viewSelection() {
    const view = this;
    let minX;
    let maxX;
    let minY;
    let maxY;
    let hasSelection = false;
    view.visibleNodes.selectAll<SVGGElement, GNode>("g").each(function (n) {
      if (view.state.selection.isSelected(n)) {
        hasSelection = true;
        minX = minX ? Math.min(minX, n.x) : n.x;
        maxX = maxX ? Math.max(maxX, n.x + n.getTotalNodeWidth()) :
          n.x + n.getTotalNodeWidth();
        minY = minY ? Math.min(minY, n.y) : n.y;
        maxY = maxY ? Math.max(maxY, n.y + n.getNodeHeight(view.state.showTypes)) :
          n.y + n.getNodeHeight(view.state.showTypes);
      }
    });
    if (hasSelection) {
      view.viewGraphRegion(minX - NODE_INPUT_WIDTH, minY - 60,
        maxX + NODE_INPUT_WIDTH, maxY + 60);
    }
  }

  viewGraphRegion(minX, minY, maxX, maxY) {
    const [width, height] = this.getSvgViewDimensions();
    const dx = maxX - minX;
    const dy = maxY - minY;
    const x = (minX + maxX) / 2;
    const y = (minY + maxY) / 2;
    const scale = Math.min(width / (1.1 * dx), height / (1.1 * dy));
    this.svg
      .transition().duration(300).call(this.panZoom.translateTo, x, y)
      .transition().duration(300).call(this.panZoom.scaleTo, scale)
      .transition().duration(300).call(this.panZoom.translateTo, x, y);
  }

  viewWholeGraph() {
    this.panZoom.scaleTo(this.svg, 0);
    this.panZoom.translateTo(this.svg,
      this.graph.minGraphX + this.graph.width / 2,
      this.graph.minGraphY + this.graph.height / 2);
  }
}
