// 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 locations = [];
        for (var d of items) {
          if (selected) {
            d.classList.add("selected");
          } else {
            d.classList.remove("selected");
          }
          var data = d.__data__;
          locations.push({ pos_start: data.pos, pos_end: data.pos + 1, node_id: data.id});
        }
        broker.select(selectionHandler, locations, selected);
      },
      selectionDifference: function(span1, inclusive1, span2, inclusive2) {
        // Should not be called
      },
      brokeredSelect: function(locations, selected) {
        var test = [].entries().next();
        var selection = graph.nodes
          .filter(function(n) {
            var pos = n.pos;
            for (var location of locations) {
              var start = location.pos_start;
              var end = location.pos_end;
              var id = location.node_id;
              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", partial(this.uploadAction, graph));
    d3.select("#layout").on("click", partial(this.layoutAction, graph));
    d3.select("#show-all").on("click", partial(this.showAllAction, graph));
    d3.select("#hide-dead").on("click", partial(this.hideDeadAction, graph));
    d3.select("#hide-unselected").on("click", partial(this.hideUnselectedAction, graph));
    d3.select("#hide-selected").on("click", partial(this.hideSelectedAction, graph));
    d3.select("#zoom-selection").on("click", partial(this.zoomSelectionAction, graph));
    d3.select("#toggle-types").on("click", partial(this.toggleTypesAction, graph));
    d3.select("#search-input").on("keydown", partial(this.searchInputAction, graph));

    // 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(d) {
    if (this.state.showTypes) {
      return d.normalheight + d.labelbbox.height;
    } else {
      return d.normalheight;
    }
  }

  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.viewSelection();
    }
    this.updateGraphVisibility();
  }

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

  measureText(text) {
    var textMeasure = document.getElementById('text-measure');
    textMeasure.textContent = text;
    return {
      width: textMeasure.getBBox().width,
      height: textMeasure.getBBox().height,
    };
  }

  createGraph(data, initiallyVisibileIds) {
    var g = this;
    g.nodes = data.nodes;
    g.nodeMap = [];
    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();
      n.labelbbox = g.measureText(n.displayLabel);
      n.typebbox = g.measureText(n.getDisplayType());
      var innerwidth = Math.max(n.labelbbox.width, n.typebbox.width);
      n.width = Math.alignUp(innerwidth + NODE_INPUT_WIDTH * 2,
                             NODE_INPUT_WIDTH);
      var innerheight = Math.max(n.labelbbox.height, n.typebbox.height);
      n.normalheight = innerheight + 20;
    });
    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(from) + DEFAULT_NODE_BUBBLE_RADIUS;
        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 (state.justDragged) {
      // dragged, not clicked
      redetermineGraphBoundingBox(graph);
      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();
  }

  uploadAction(graph) {
    document.getElementById("hidden-file-upload").click();
  }

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

  showAllAction(graph) {
    graph.nodes.filter(function(n) { n.visible = true; })
    graph.edges.filter(function(e) { e.visible = true; })
    graph.updateGraphVisibility();
    graph.viewWholeGraph();
  }

  hideDeadAction(graph) {
    graph.nodes.filter(function(n) { if (!n.isLive()) n.visible = false; })
    graph.updateGraphVisibility();
  }

  hideUnselectedAction(graph) {
    var unselected = graph.visibleNodes.filter(function(n) {
      return !this.classList.contains("selected");
    });
    unselected.each(function(n) {
      n.visible = false;
    });
    graph.updateGraphVisibility();
  }

  hideSelectedAction(graph) {
    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();
  }

  zoomSelectionAction(graph) {
    graph.viewSelection();
  }

  toggleTypesAction(graph) {
    graph.toggleTypes();
  }

  searchInputAction(graph) {
    if (d3.event.keyCode == 13) {
      graph.state.selection.clear();
      var query = this.value;
      window.sessionStorage.setItem("lastSearch", query);

      var reg = new RegExp(query);
      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();
  }

  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 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) => { return index == (d3.event.keyCode - 97); },
          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;
    }
    case 82:
      // 'r'
      if (!d3.event.ctrlKey) {
        this.layoutAction(this);
      } else {
        eventHandled = false;
      }
      break;
    case 191:
      // '/'
      document.getElementById("search-input").focus();
      document.getElementById("search-input").select();
      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(d); });

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

    newGs.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(); })
      .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(d);
      })

    function appendInputAndOutputBubbles(g, d) {
      for (var i = 0; i < d.inputs.length; ++i) {
        var x = d.getInputX(i);
        var y = -DEFAULT_NODE_BUBBLE_RADIUS;
        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(d) + DEFAULT_NODE_BUBBLE_RADIUS;
        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", 5)
        .append('tspan')
        .text(function(l) {
          return d.getDisplayLabel();
        })
        .append("title")
        .text(function(l) {
          return d.getTitle();
        })
      if (d.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();
          })
      }
    });

    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 + graph.getNodeHeight(n)) :
          n.y + graph.getNodeHeight(n);
      }
    });
    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);
  }
}
