// 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.

"use strict";

class GraphView extends View {
  constructor (d3, id, nodes, edges, broker) {
    super(id, broker);
    var graph = this;

    var svg = this.divElement.append("svg").attr('version','1.1').attr("width", "100%");
    graph.svg = svg;

    graph.nodes = nodes || [];
    graph.edges = edges || [];

    graph.minGraphX = 0;
    graph.maxGraphX = 1;
    graph.minGraphY = 0;
    graph.maxGraphY = 1;

    graph.state = {
      selection: null,
      mouseDownNode: null,
      justDragged: false,
      justScaleTransGraph: false,
      lastKeyDown: -1,
      showTypes: false
    };

    var selectionHandler = {
      clear: function() {
        broker.clear(selectionHandler);
      },
      select: function(items, selected) {
        var ranges = [];
        for (var d of items) {
          if (selected) {
            d.classList.add("selected");
          } else {
            d.classList.remove("selected");
          }
          var data = d.__data__;
          ranges.push([data.pos, data.pos + 1, data.id]);
        }
        broker.select(selectionHandler, ranges, selected);
      },
      selectionDifference: function(span1, inclusive1, span2, inclusive2) {
        // Should not be called
      },
      brokeredSelect: function(ranges, selected) {
        var test = [].entries().next();
        var selection = graph.nodes
          .filter(function(n) {
            var pos = n.pos;
            for (var range of ranges) {
              var start = range[0];
              var end = range[1];
              var id = range[2];
              if (end != undefined) {
                if (pos >= start && pos < end) {
                  return true;
                }
              } else if (start != undefined) {
                if (pos === start) {
                  return true;
                }
              } else {
                if (n.id === id) {
                  return true;
                }
              }
            }
            return false;
          });
        var newlySelected = new Set();
        selection.forEach(function(n) {
          newlySelected.add(n);
          if (!n.visible) {
            n.visible = true;
          }
        });
        graph.updateGraphVisibility();
        graph.visibleNodes.each(function(n) {
          if (newlySelected.has(n)) {
            graph.state.selection.select(this, selected);
          }
        });
        graph.updateGraphVisibility();
        graph.viewSelection();
      },
      brokeredClear: function() {
        graph.state.selection.clear();
      }
    };
    broker.addSelectionHandler(selectionHandler);

    graph.state.selection = new Selection(selectionHandler);

    var 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");
    graph.visibleEdges = this.graphElement.append("g").selectAll("g");
    graph.visibleNodes = this.graphElement.append("g").selectAll("g");

    graph.drag = d3.behavior.drag()
      .origin(function(d){
        return {x: d.x, y: d.y};
      })
      .on("drag", function(args){
        graph.state.justDragged = true;
        graph.dragmove.call(graph, args);
      })

    d3.select("#upload").on("click", function(){
      document.getElementById("hidden-file-upload").click();
    });

    d3.select("#layout").on("click", function(){
      graph.updateGraphVisibility();
      graph.layoutGraph();
      graph.updateGraphVisibility();
      graph.viewWholeGraph();
    });

    d3.select("#show-all").on("click", function(){
      graph.nodes.filter(function(n) { n.visible = true; })
      graph.edges.filter(function(e) { e.visible = true; })
      graph.updateGraphVisibility();
      graph.viewWholeGraph();
    });

    d3.select("#hide-unselected").on("click", function() {
      var unselected = graph.visibleNodes.filter(function(n) {
        return !this.classList.contains("selected");
      });
      unselected.each(function(n) {
        n.visible = false;
      });
      graph.updateGraphVisibility();
    });

    d3.select("#hide-selected").on("click", function() {
      var selected = graph.visibleNodes.filter(function(n) {
        return this.classList.contains("selected");
      });
      selected.each(function(n) {
        n.visible = false;
      });
      graph.state.selection.clear();
      graph.updateGraphVisibility();
    });

    d3.select("#zoom-selection").on("click", function() {
      graph.viewSelection();
    });

    d3.select("#toggle-types").on("click", function() {
      graph.toggleTypes();
    });

    d3.select("#search-input").on("keydown", function() {
      if (d3.event.keyCode == 13) {
        graph.state.selection.clear();
        var reg = new RegExp(this.value);
        var filterFunction = function(n) {
          return (reg.exec(n.getDisplayLabel()) != null ||
                  (graph.state.showTypes && reg.exec(n.getDisplayType())) ||
                  reg.exec(n.opcode) != null);
        };
        if (d3.event.ctrlKey) {
          graph.nodes.forEach(function(n, i) {
            if (filterFunction(n)) {
              n.visible = true;
            }
          });
          graph.updateGraphVisibility();
        }
        var selected = graph.visibleNodes.each(function(n) {
          if (filterFunction(n)) {
            graph.state.selection.select(this, true);
          }
        });
        graph.connectVisibleSelectedNodes();
        graph.updateGraphVisibility();
        this.blur();
        graph.viewSelection();
      }
      d3.event.stopPropagation();
    });

    // listen for key events
    d3.select(window).on("keydown", function(e){
      graph.svgKeyDown.call(graph);
    })
      .on("keyup", function(){
        graph.svgKeyUp.call(graph);
      });
    svg.on("mousedown", function(d){graph.svgMouseDown.call(graph, d);});
    svg.on("mouseup", function(d){graph.svgMouseUp.call(graph, d);});

    graph.dragSvg = d3.behavior.zoom()
      .on("zoom", function(){
        if (d3.event.sourceEvent.shiftKey){
          return false;
        } else{
          graph.zoomed.call(graph);
        }
        return true;
      })
      .on("zoomstart", function(){
        if (!d3.event.sourceEvent.shiftKey) d3.select('body').style("cursor", "move");
      })
      .on("zoomend", function(){
        d3.select('body').style("cursor", "auto");
      });

    svg.call(graph.dragSvg).on("dblclick.zoom", null);
  }

  static get selectedClass() {
    return "selected";
  }
  static get rectClass() {
    return "nodeStyle";
  }
  static get activeEditId() {
    return "active-editing";
  }
  static get nodeRadius() {
    return 50;
  }

  getNodeHeight(graph) {
    if (this.state.showTypes) {
      return DEFAULT_NODE_HEIGHT + TYPE_HEIGHT;
    } else {
      return DEFAULT_NODE_HEIGHT;
    }
  }

  getEdgeFrontier(nodes, inEdges, edgeFilter) {
    let frontier = new Set();
    nodes.forEach(function(element) {
      var edges = inEdges ? element.__data__.inputs : element.__data__.outputs;
      var edgeNumber = 0;
      edges.forEach(function(edge) {
        if (edgeFilter == undefined || edgeFilter(edge, edgeNumber)) {
          frontier.add(edge);
        }
        ++edgeNumber;
      });
    });
    return frontier;
  }

  getNodeFrontier(nodes, inEdges, edgeFilter) {
    let graph = this;
    var frontier = new Set();
    var newState = true;
    var edgeFrontier = graph.getEdgeFrontier(nodes, inEdges, edgeFilter);
    // Control key toggles edges rather than just turning them on
    if (d3.event.ctrlKey) {
      edgeFrontier.forEach(function(edge) {
        if (edge.visible) {
          newState = false;
        }
      });
    }
    edgeFrontier.forEach(function(edge) {
      edge.visible = newState;
      if (newState) {
        var node = inEdges ? edge.source : edge.target;
        node.visible = true;
        frontier.add(node);
      }
    });
    graph.updateGraphVisibility();
    if (newState) {
      return graph.visibleNodes.filter(function(n) {
        return frontier.has(n);
      });
    } else {
      return undefined;
    }
  }

  dragmove(d) {
    var graph = this;
    d.x += d3.event.dx;
    d.y += d3.event.dy;
    graph.updateGraphVisibility();
  }

  initializeContent(data, rememberedSelection) {
    this.createGraph(data, rememberedSelection);
    if (rememberedSelection != null) {
      this.attachSelection(rememberedSelection);
      this.connectVisibleSelectedNodes();
    }
    this.updateGraphVisibility();
  }

  deleteContent() {
    if (this.visibleNodes) {
      this.nodes = [];
      this.edges = [];
      this.nodeMap = [];
      this.updateGraphVisibility();
    }
  };

  createGraph(data, initiallyVisibileIds) {
    var g = this;
    g.nodes = data.nodes;
    g.nodeMap = [];
    var textMeasure = document.getElementById('text-measure');
    g.nodes.forEach(function(n, i){
      n.__proto__ = Node;
      n.visible = false;
      n.x = 0;
      n.y = 0;
      n.rank = MAX_RANK_SENTINEL;
      n.inputs = [];
      n.outputs = [];
      n.rpo = -1;
      n.outputApproach = MINIMUM_NODE_OUTPUT_APPROACH;
      n.cfg = n.control;
      g.nodeMap[n.id] = n;
      n.displayLabel = n.getDisplayLabel();
      textMeasure.textContent = n.getDisplayLabel();
      var width = textMeasure.getComputedTextLength();
      textMeasure.textContent = n.getDisplayType();
      width = Math.max(width, textMeasure.getComputedTextLength());
      n.width = Math.alignUp(width + NODE_INPUT_WIDTH * 2,
                             NODE_INPUT_WIDTH);
    });
    g.edges = [];
    data.edges.forEach(function(e, i){
      var t = g.nodeMap[e.target];
      var s = g.nodeMap[e.source];
      var newEdge = new Edge(t, e.index, s, e.type);
      t.inputs.push(newEdge);
      s.outputs.push(newEdge);
      g.edges.push(newEdge);
      if (e.type == 'control') {
        s.cfg = true;
      }
    });
    g.nodes.forEach(function(n, i) {
      n.visible = isNodeInitiallyVisible(n);
      if (initiallyVisibileIds != undefined) {
        if (initiallyVisibileIds.has(n.id)) {
          n.visible = true;
        }
      }
    });
    g.fitGraphViewToWindow();
    g.updateGraphVisibility();
    g.layoutGraph();
    g.updateGraphVisibility();
    g.viewWholeGraph();
  }

  connectVisibleSelectedNodes() {
    var graph = this;
    graph.state.selection.selection.forEach(function(element) {
      var edgeNumber = 0;
      element.__data__.inputs.forEach(function(edge) {
        if (edge.source.visible && edge.target.visible) {
          edge.visible = true;
        }
      });
      element.__data__.outputs.forEach(function(edge) {
        if (edge.source.visible && edge.target.visible) {
          edge.visible = true;
        }
      });
    });
  }

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

  attachSelection(s) {
    var graph = this;
    if (s.size != 0) {
      this.visibleNodes.each(function(n) {
        if (s.has(this.__data__.id)) {
          graph.state.selection.select(this, true);
        }
      });
    }
  }

  detachSelection() {
    var selection = this.state.selection.detachSelection();
    var s = new Set();
    for (var i of selection) {
      s.add(i.__data__.id);
    };
    return s;
  }

  pathMouseDown(path, d) {
    d3.event.stopPropagation();
    this.state.selection.clear();
    this.state.selection.add(path);
  };

  nodeMouseDown(node, d) {
    d3.event.stopPropagation();
    this.state.mouseDownNode = d;
  }

  nodeMouseUp(d3node, d) {
    var graph = this,
    state = graph.state,
    consts = graph.consts;

    var mouseDownNode = state.mouseDownNode;

    if (!mouseDownNode) return;

    if (mouseDownNode !== d){
      // we're in a different node: create new edge for mousedown edge and add to graph
      var newEdge = {source: mouseDownNode, target: d};
      var filtRes = graph.visibleEdges.filter(function(d){
        if (d.source === newEdge.target && d.target === newEdge.source){
          graph.edges.splice(graph.edges.indexOf(d), 1);
        }
        return d.source === newEdge.source && d.target === newEdge.target;
      });
      if (!filtRes[0].length){
        graph.edges.push(newEdge);
        graph.updateGraphVisibility();
      }
    } else{
      // we're in the same node
      if (state.justDragged) {
        // dragged, not clicked
        state.justDragged = false;
      } else{
        // clicked, not dragged
        var extend = d3.event.shiftKey;
        var selection = graph.state.selection;
        if (!extend) {
          selection.clear();
        }
        selection.select(d3node[0][0], true);
      }
    }
  }

  selectSourcePositions(start, end, selected) {
    var graph = this;
    var map = [];
    var sel = graph.nodes.filter(function(n) {
      var pos = (n.pos === undefined)
        ? -1
        : n.getFunctionRelativeSourcePosition(graph);
      if (pos >= start && pos < end) {
        map[n.id] = true;
        n.visible = true;
      }
    });
    graph.updateGraphVisibility();
    graph.visibleNodes.filter(function(n) { return map[n.id]; })
      .each(function(n) {
        var selection = graph.state.selection;
        selection.select(d3.select(this), selected);
      });
  }

  selectAllNodes(inEdges, filter) {
    var graph = this;
    if (!d3.event.shiftKey) {
      graph.state.selection.clear();
    }
    graph.state.selection.select(graph.visibleNodes[0], true);
    graph.updateGraphVisibility();
  }

  svgMouseDown() {
    this.state.graphMouseDown = true;
  }

  svgMouseUp() {
    var graph = this,
    state = graph.state;
    if (state.justScaleTransGraph) {
      // Dragged
      state.justScaleTransGraph = false;
    } else {
      // Clicked
      if (state.mouseDownNode == null) {
        graph.state.selection.clear();
      }
    }
    state.mouseDownNode = null;
    state.graphMouseDown = false;
  }

  svgKeyDown() {
    var state = this.state;
    var graph = this;

    // Don't handle key press repetition
    if(state.lastKeyDown !== -1) return;

    var showSelectionFrontierNodes = function(inEdges, filter, select) {
      var frontier = graph.getNodeFrontier(state.selection.selection, inEdges, filter);
      if (frontier != undefined) {
        if (select) {
          if (!d3.event.shiftKey) {
            state.selection.clear();
          }
          state.selection.select(frontier[0], true);
        }
        graph.updateGraphVisibility();
      }
      allowRepetition = false;
    }

    var allowRepetition = true;
    var 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, index) => { return index == (d3.event.keyCode - 49); },
          false);
      break;
    case 67:
      // 'c'
      showSelectionFrontierNodes(true,
          (edge, index) => { return edge.type == 'control'; },
          false);
      break;
    case 69:
      // 'e'
      showSelectionFrontierNodes(true,
          (edge, index) => { return edge.type == 'effect'; },
          false);
      break;
    case 79:
      // 'o'
      showSelectionFrontierNodes(false, undefined, false);
      break;
    case 73:
      // 'i'
      showSelectionFrontierNodes(true, undefined, false);
      break;
    case 65:
      // 'a'
      graph.selectAllNodes();
      allowRepetition = false;
      break;
    case 38:
    case 40: {
      showSelectionFrontierNodes(d3.event.keyCode == 38, undefined, true);
      break;
    }
    default:
      eventHandled = false;
      break;
    }
    if (eventHandled) {
      d3.event.preventDefault();
    }
    if (!allowRepetition) {
      state.lastKeyDown = d3.event.keyCode;
    }
  }

  svgKeyUp() {
    this.state.lastKeyDown = -1
  };

  layoutEdges() {
    var graph = this;
    graph.maxGraphX = graph.maxGraphNodeX;
    this.visibleEdges.attr("d", function(edge){
      return edge.generatePath(graph);
    });
  }

  layoutGraph() {
    layoutNodeGraph(this);
  }

  // call to propagate changes to graph
  updateGraphVisibility() {

    var graph = this,
    state = graph.state;

    var filteredEdges = graph.edges.filter(function(e) { return e.isVisible(); });
    var visibleEdges = graph.visibleEdges.data(filteredEdges, function(edge) {
      return edge.stringID();
    });

    // add new paths
    visibleEdges.enter()
      .append('path')
      .style('marker-end','url(#end-arrow)')
      .classed('hidden', function(e) {
        return !e.isVisible();
      })
      .attr("id", function(edge){ return "e," + edge.stringID(); })
      .on("mousedown", function(d){
        graph.pathMouseDown.call(graph, d3.select(this), d);
      })

    // Set the correct styles on all of the paths
    visibleEdges.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" : "";
    });

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

    graph.visibleEdges = visibleEdges;

    // update existing nodes
    var filteredNodes = graph.nodes.filter(function(n) { return n.visible; });
    graph.visibleNodes = graph.visibleNodes.data(filteredNodes, function(d) {
      return d.id;
    });
    graph.visibleNodes.attr("transform", function(n){
      return "translate(" + n.x + "," + n.y + ")";
    }).select('rect').
      attr(HEIGHT, function(d) { return graph.getNodeHeight(); });

    // add new nodes
    var newGs = graph.visibleNodes.enter()
      .append("g");

    newGs.classed("control", function(n) { return n.isControl(); })
      .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(); })
      .attr("transform", function(d){ return "translate(" + d.x + "," + d.y + ")";})
      .on("mousedown", function(d){
        graph.nodeMouseDown.call(graph, d3.select(this), d);
      })
      .on("mouseup", function(d){
        graph.nodeMouseUp.call(graph, d3.select(this), d);
      })
      .call(graph.drag);

    newGs.append("rect")
      .attr("rx", 10)
      .attr("ry", 10)
      .attr(WIDTH, function(d) { return d.getTotalNodeWidth(); })
      .attr(HEIGHT, function(d) { return graph.getNodeHeight(); })

    function appendInputAndOutputBubbles(g, d) {
      for (var i = 0; i < d.inputs.length; ++i) {
        var x = d.getInputX(i);
        var y = -DEFAULT_NODE_BUBBLE_RADIUS / 2 - 4;
        var s = 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("mousedown", function(d){
            var components = this.id.split(',');
            var node = graph.nodeMap[components[3]];
            var edge = node.inputs[components[2]];
            var visible = !edge.isVisible();
            node.setInputVisibility(components[2], visible);
            d3.event.stopPropagation();
            graph.updateGraphVisibility();
          });
      }
      if (d.outputs.length != 0) {
        var x = d.getOutputX();
        var y = graph.getNodeHeight() + DEFAULT_NODE_BUBBLE_RADIUS / 2 + 4;
        var s = 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("mousedown", function(d) {
            d.setOutputVisibility(d.areAnyOutputsVisible() == 0);
            d3.event.stopPropagation();
            graph.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", DEFAULT_NODE_HEIGHT / 2 + 5)
        .append('tspan')
        .text(function(l) {
          return d.getDisplayLabel();
        })
        .append("title")
        .text(function(l) {
          return d.getLabel();
        })
      if (d.type != undefined) {
        d3.select(this).append("text")
          .classed("label", true)
          .classed("type", true)
          .attr("text-anchor","right")
          .attr("dx", "5")
          .attr("dy", DEFAULT_NODE_HEIGHT / 2 + TYPE_HEIGHT + 5)
          .append('tspan')
          .text(function(l) {
            return d.getDisplayType();
          })
          .append("title")
          .text(function(l) {
            return d.getType();
          })
      }
    });

    graph.visibleNodes.select('.type').each(function (d) {
      this.setAttribute('visibility', graph.state.showTypes ? 'visible' : 'hidden');
    });

    // remove old nodes
    graph.visibleNodes.exit().remove();

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

    graph.updateInputAndOutputBubbles();

    graph.layoutEdges();

    graph.svg.style.height = '100%';
  }

  getVisibleTranslation(translate, scale) {
    var graph = this;
    var height = (graph.maxGraphY - graph.minGraphY + 2 * GRAPH_MARGIN) * scale;
    var width = (graph.maxGraphX - graph.minGraphX + 2 * GRAPH_MARGIN) * scale;

    var dimensions = this.getSvgViewDimensions();

    var baseY = translate[1];
    var minY = (graph.minGraphY - GRAPH_MARGIN) * scale;
    var maxY = (graph.maxGraphY + GRAPH_MARGIN) * scale;

    var adjustY = 0;
    var adjustYCandidate = 0;
    if ((maxY + baseY) < dimensions[1]) {
      adjustYCandidate = dimensions[1] - (maxY + baseY);
      if ((minY + baseY + adjustYCandidate) > 0) {
        adjustY = (dimensions[1] / 2) - (maxY - (height / 2)) - baseY;
      } else {
        adjustY = adjustYCandidate;
      }
    } else if (-baseY < minY) {
      adjustYCandidate = -(baseY + minY);
      if ((maxY + baseY + adjustYCandidate) < dimensions[1]) {
        adjustY = (dimensions[1] / 2) - (maxY - (height / 2)) - baseY;
      } else {
        adjustY = adjustYCandidate;
      }
    }
    translate[1] += adjustY;

    var baseX = translate[0];
    var minX = (graph.minGraphX - GRAPH_MARGIN) * scale;
    var maxX = (graph.maxGraphX + GRAPH_MARGIN) * scale;

    var adjustX = 0;
    var adjustXCandidate = 0;
    if ((maxX + baseX) < dimensions[0]) {
      adjustXCandidate = dimensions[0] - (maxX + baseX);
      if ((minX + baseX + adjustXCandidate) > 0) {
        adjustX = (dimensions[0] / 2) - (maxX - (width / 2)) - baseX;
      } else {
        adjustX = adjustXCandidate;
      }
    } else if (-baseX < minX) {
      adjustXCandidate = -(baseX + minX);
      if ((maxX + baseX + adjustXCandidate) < dimensions[0]) {
        adjustX = (dimensions[0] / 2) - (maxX - (width / 2)) - baseX;
      } else {
        adjustX = adjustXCandidate;
      }
    }
    translate[0] += adjustX;
    return translate;
  }

  translateClipped(translate, scale, transition) {
    var graph = this;
    var graphNode = this.graphElement[0][0];
    var translate = this.getVisibleTranslation(translate, scale);
    if (transition) {
      graphNode.classList.add('visible-transition');
      clearTimeout(graph.transitionTimout);
      graph.transitionTimout = setTimeout(function(){
        graphNode.classList.remove('visible-transition');
      }, 1000);
    }
    var translateString = "translate(" + translate[0] + "px," + translate[1] + "px) scale(" + scale + ")";
    graphNode.style.transform = translateString;
    graph.dragSvg.translate(translate);
    graph.dragSvg.scale(scale);
  }

  zoomed(){
    this.state.justScaleTransGraph = true;
    var scale =  this.dragSvg.scale();
    this.translateClipped(d3.event.translate, scale);
  }


  getSvgViewDimensions() {
    var canvasWidth = this.parentNode.clientWidth;
    var documentElement = document.documentElement;
    var canvasHeight = documentElement.clientHeight;
    return [canvasWidth, canvasHeight];
  }


  minScale() {
    var graph = this;
    var dimensions = this.getSvgViewDimensions();
    var width = graph.maxGraphX - graph.minGraphX;
    var height = graph.maxGraphY - graph.minGraphY;
    var minScale = dimensions[0] / (width + GRAPH_MARGIN * 2);
    var minScaleYCandidate = dimensions[1] / (height + GRAPH_MARGIN * 2);
    if (minScaleYCandidate < minScale) {
      minScale = minScaleYCandidate;
    }
    this.dragSvg.scaleExtent([minScale, 1.5]);
    return minScale;
  }

  fitGraphViewToWindow() {
    this.svg.attr("height", document.documentElement.clientHeight + "px");
    this.translateClipped(this.dragSvg.translate(), this.dragSvg.scale());
  }

  toggleTypes() {
    var graph = this;
    graph.state.showTypes = !graph.state.showTypes;
    var element = document.getElementById('toggle-types');
    if (graph.state.showTypes) {
      element.classList.add('button-input-toggled');
    } else {
      element.classList.remove('button-input-toggled');
    }
    graph.updateGraphVisibility();
  }

  viewSelection() {
    var graph = this;
    var minX, maxX, minY, maxY;
    var hasSelection = false;
    graph.visibleNodes.each(function(n) {
      if (this.classList.contains("selected")) {
        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 + DEFAULT_NODE_HEIGHT) :
          n.y + DEFAULT_NODE_HEIGHT;
      }
    });
    if (hasSelection) {
      graph.viewGraphRegion(minX - NODE_INPUT_WIDTH, minY - 60,
                            maxX + NODE_INPUT_WIDTH, maxY + 60,
                            true);
    }
  }

  viewGraphRegion(minX, minY, maxX, maxY, transition) {
    var graph = this;
    var dimensions = this.getSvgViewDimensions();
    var width = maxX - minX;
    var height = maxY - minY;
    var scale = Math.min(dimensions[0] / width, dimensions[1] / height);
    scale = Math.min(1.5, scale);
    scale = Math.max(graph.minScale(), scale);
    var translation = [-minX*scale, -minY*scale];
    translation = graph.getVisibleTranslation(translation, scale);
    graph.translateClipped(translation, scale, transition);
  }

  viewWholeGraph() {
    var graph = this;
    var minScale = graph.minScale();
    var translation = [0, 0];
    translation = graph.getVisibleTranslation(translation, minScale);
    graph.translateClipped(translation, minScale);
  }
}
