// Copyright 2017 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"

function $(id) {
  return document.getElementById(id);
}

let components = [];

function createViews() {
  components.push(new CallTreeView());
  components.push(new TimelineView());
  components.push(new HelpView());
  components.push(new SummaryView());
  components.push(new ModeBarView());

  main.setMode("summary");
}

function emptyState() {
  return {
    file : null,
    mode : "none",
    currentCodeId : null,
    start : 0,
    end : Infinity,
    timeLine : {
      width : 100,
      height : 100
    },
    callTree : {
      attribution : "js-exclude-bc",
      categories : "code-type",
      sort : "time"
    }
  };
}

function setCallTreeState(state, callTreeState) {
  state = Object.assign({}, state);
  state.callTree = callTreeState;
  return state;
}

let main = {
  currentState : emptyState(),

  setMode(mode) {
    if (mode != main.currentState.mode) {

      function setCallTreeModifiers(attribution, categories, sort) {
        let callTreeState = Object.assign({}, main.currentState.callTree);
        callTreeState.attribution = attribution;
        callTreeState.categories = categories;
        callTreeState.sort = sort;
        return callTreeState;
      }

      let state = Object.assign({}, main.currentState);

      switch (mode) {
        case "bottom-up":
          state.callTree =
              setCallTreeModifiers("js-exclude-bc", "code-type", "time");
          break;
        case "top-down":
          state.callTree =
              setCallTreeModifiers("js-exclude-bc", "none", "time");
          break;
        case "function-list":
          state.callTree =
              setCallTreeModifiers("js-exclude-bc", "code-type", "own-time");
          break;
      }

      state.mode = mode;

      main.currentState = state;
      main.delayRender();
    }
  },

  setCallTreeAttribution(attribution) {
    if (attribution != main.currentState.attribution) {
      let callTreeState = Object.assign({}, main.currentState.callTree);
      callTreeState.attribution = attribution;
      main.currentState = setCallTreeState(main.currentState,  callTreeState);
      main.delayRender();
    }
  },

  setCallTreeSort(sort) {
    if (sort != main.currentState.sort) {
      let callTreeState = Object.assign({}, main.currentState.callTree);
      callTreeState.sort = sort;
      main.currentState = setCallTreeState(main.currentState,  callTreeState);
      main.delayRender();
    }
  },

  setCallTreeCategories(categories) {
    if (categories != main.currentState.categories) {
      let callTreeState = Object.assign({}, main.currentState.callTree);
      callTreeState.categories = categories;
      main.currentState = setCallTreeState(main.currentState,  callTreeState);
      main.delayRender();
    }
  },

  setViewInterval(start, end) {
    if (start != main.currentState.start ||
        end != main.currentState.end) {
      main.currentState = Object.assign({}, main.currentState);
      main.currentState.start = start;
      main.currentState.end = end;
      main.delayRender();
    }
  },

  setTimeLineDimensions(width, height) {
    if (width != main.currentState.timeLine.width ||
        height != main.currentState.timeLine.height) {
      let timeLine = Object.assign({}, main.currentState.timeLine);
      timeLine.width = width;
      timeLine.height = height;
      main.currentState = Object.assign({}, main.currentState);
      main.currentState.timeLine = timeLine;
      main.delayRender();
    }
  },

  setFile(file) {
    if (file != main.currentState.file) {
      main.currentState = Object.assign({}, main.currentState);
      main.currentState.file = file;
      main.delayRender();
    }
  },

  setCurrentCode(codeId) {
    if (codeId != main.currentState.currentCodeId) {
      main.currentState = Object.assign({}, main.currentState);
      main.currentState.currentCodeId = codeId;
      main.delayRender();
    }
  },

  onResize() {
    main.setTimeLineDimensions(
      Math.round(window.innerWidth - 20),
      Math.round(window.innerHeight / 5));
  },

  onLoad() {
    function loadHandler(evt) {
      let f = evt.target.files[0];
      if (f) {
        let reader = new FileReader();
        reader.onload = function(event) {
          let profData = JSON.parse(event.target.result);
          main.setViewInterval(0, Infinity);
          main.setFile(profData);
        };
        reader.onerror = function(event) {
          console.error(
              "File could not be read! Code " + event.target.error.code);
        };
        reader.readAsText(f);
      } else {
        main.setFile(null);
      }
    }
    $("fileinput").addEventListener(
        "change", loadHandler, false);
    createViews();
    main.onResize();
  },

  delayRender()  {
    Promise.resolve().then(() => {
      for (let c of components) {
        c.render(main.currentState);
      }
    });
  }
};

let bucketDescriptors =
    [ { kinds : [ "JSOPT" ],
        color : "#00ff00",
        backgroundColor : "#c0ffc0",
        text : "JS Optimized" },
      { kinds : [ "JSUNOPT", "BC" ],
        color : "#ffb000",
        backgroundColor : "#ffe0c0",
        text : "JS Unoptimized" },
      { kinds : [ "IC" ],
        color : "#ffff00",
        backgroundColor : "#ffffc0",
        text : "IC" },
      { kinds : [ "STUB", "BUILTIN", "REGEXP" ],
        color : "#ffb0b0",
        backgroundColor : "#fff0f0",
        text : "Other generated" },
      { kinds : [ "CPP", "LIB" ],
        color : "#0000ff",
        backgroundColor : "#c0c0ff",
        text : "C++" },
      { kinds : [ "CPPEXT" ],
        color : "#8080ff",
        backgroundColor : "#e0e0ff",
        text : "C++/external" },
      { kinds : [ "CPPPARSE" ],
        color : "#b890f7",
        backgroundColor : "#ebdeff",
        text : "C++/Parser" },
      { kinds : [ "CPPCOMPBC" ],
        color : "#52b0ce",
        backgroundColor : "#a5c8d4",
        text : "C++/Bytecode compiler" },
      { kinds : [ "CPPCOMP" ],
        color : "#00ffff",
        backgroundColor : "#c0ffff",
        text : "C++/Compiler" },
      { kinds : [ "CPPGC" ],
        color : "#ff00ff",
        backgroundColor : "#ffc0ff",
        text : "C++/GC" },
      { kinds : [ "UNKNOWN" ],
        color : "#f0f0f0",
        backgroundColor : "#e0e0e0",
        text : "Unknown" }
    ];

let kindToBucketDescriptor = {}
for (let i = 0; i < bucketDescriptors.length; i++) {
  let bucket = bucketDescriptors[i];
  for (let j = 0; j < bucket.kinds.length; j++) {
    kindToBucketDescriptor[bucket.kinds[j]] = bucket;
  }
}

function bucketFromKind(kind) {
  for (let i = 0; i < bucketDescriptors.length; i++) {
    let bucket = bucketDescriptors[i];
    for (let j = 0; j < bucket.kinds.length; j++) {
      if (bucket.kinds[j] === kind) {
        return bucket;
      }
    }
  }
  return null;
}

function codeTypeToText(type) {
  switch (type) {
    case "UNKNOWN":
      return "Unknown";
    case "CPPPARSE":
      return "C++ (parser)";
    case "CPPCOMPBC":
      return "C++ (bytecode compiler)";
    case "CPPCOMP":
      return "C++ (compiler)";
    case "CPPGC":
      return "C++";
    case "CPPEXT":
      return "C++ External";
    case "CPP":
      return "C++";
    case "LIB":
      return "Library";
    case "IC":
      return "IC";
    case "BC":
      return "Bytecode";
    case "STUB":
      return "Stub";
    case "BUILTIN":
      return "Builtin";
    case "REGEXP":
      return "RegExp";
    case "JSOPT":
      return "JS opt";
    case "JSUNOPT":
      return "JS unopt";
  }
  console.error("Unknown type: " + type);
}

function createTypeDiv(type) {
  if (type === "CAT") {
    return document.createTextNode("");
  }
  let div = document.createElement("div");
  div.classList.add("code-type-chip");

  let span = document.createElement("span");
  span.classList.add("code-type-chip");
  span.textContent = codeTypeToText(type);
  div.appendChild(span);

  span = document.createElement("span");
  span.classList.add("code-type-chip-space");
  div.appendChild(span);

  return div;
}

function isBytecodeHandler(kind) {
  return kind === "BytecodeHandler";
}

function filterFromFilterId(id) {
  switch (id) {
    case "full-tree":
      return (type, kind) => true;
    case "js-funs":
      return (type, kind) => type !== 'CODE';
    case "js-exclude-bc":
      return (type, kind) =>
          type !== 'CODE' || !isBytecodeHandler(kind);
  }
}

function createTableExpander(indent) {
  let div = document.createElement("div");
  div.style.width = (indent + 0.5) + "em";
  div.style.display = "inline-block";
  div.style.textAlign = "right";
  return div;
}

function createFunctionNode(name, codeId) {
  if (codeId == -1) {
    return document.createTextNode(name);
  }
  let nameElement = document.createElement("span");
  nameElement.classList.add("codeid-link")
  nameElement.onclick = function() {
    main.setCurrentCode(codeId);
  };
  nameElement.appendChild(document.createTextNode(name));
  return nameElement;
}

class CallTreeView {
  constructor() {
    this.element = $("calltree");
    this.treeElement = $("calltree-table");
    this.selectAttribution = $("calltree-attribution");
    this.selectCategories = $("calltree-categories");
    this.selectSort = $("calltree-sort");

    this.selectAttribution.onchange = () => {
      main.setCallTreeAttribution(this.selectAttribution.value);
    };

    this.selectCategories.onchange = () => {
      main.setCallTreeCategories(this.selectCategories.value);
    };

    this.selectSort.onchange = () => {
      main.setCallTreeSort(this.selectSort.value);
    };

    this.currentState = null;
  }

  sortFromId(id) {
    switch (id) {
      case "time":
        return (c1, c2) => {
          if (c1.ticks < c2.ticks) return 1;
          else if (c1.ticks > c2.ticks) return -1;
          return c2.ownTicks - c1.ownTicks;
        }
      case "own-time":
        return (c1, c2) => {
          if (c1.ownTicks < c2.ownTicks) return 1;
          else if (c1.ownTicks > c2.ownTicks) return -1;
          return c2.ticks - c1.ticks;
        }
      case "category-time":
        return (c1, c2) => {
          if (c1.type === c2.type) return c2.ticks - c1.ticks;
          if (c1.type < c2.type) return 1;
          return -1;
        };
      case "category-own-time":
        return (c1, c2) => {
          if (c1.type === c2.type) return c2.ownTicks - c1.ownTicks;
          if (c1.type < c2.type) return 1;
          return -1;
        };
    }
  }

  expandTree(tree, indent) {
    let that = this;
    let index = 0;
    let id = "R/";
    let row = tree.row;
    let expander = tree.expander;

    if (row) {
      index = row.rowIndex;
      id = row.id;

      // Make sure we collapse the children when the row is clicked
      // again.
      expander.textContent = "\u25BE";
      let expandHandler = expander.onclick;
      expander.onclick = () => {
        that.collapseRow(tree, expander, expandHandler);
      }
    }

    // Collect the children, and sort them by ticks.
    let children = [];
    let filter =
        filterFromFilterId(this.currentState.callTree.attribution);
    for (let childId in tree.children) {
      let child = tree.children[childId];
      if (child.ticks > 0) {
        children.push(child);
        if (child.delayedExpansion) {
          expandTreeNode(this.currentState.file, child, filter);
        }
      }
    }
    children.sort(this.sortFromId(this.currentState.callTree.sort));

    for (let i = 0; i < children.length; i++) {
      let node = children[i];
      let row = this.rows.insertRow(index);
      row.id = id + i + "/";

      if (node.type != "CAT") {
        row.style.backgroundColor = bucketFromKind(node.type).backgroundColor;
      }

      // Inclusive time % cell.
      let c = row.insertCell();
      c.textContent = (node.ticks * 100 / this.tickCount).toFixed(2) + "%";
      c.style.textAlign = "right";
      // Percent-of-parent cell.
      c = row.insertCell();
      c.textContent = (node.ticks * 100 / tree.ticks).toFixed(2) + "%";
      c.style.textAlign = "right";
      // Exclusive time % cell.
      if (this.currentState.mode !== "bottom-up") {
        c = row.insertCell(-1);
        c.textContent = (node.ownTicks * 100 / this.tickCount).toFixed(2) + "%";
        c.style.textAlign = "right";
      }

      // Create the name cell.
      let nameCell = row.insertCell();
      let expander = createTableExpander(indent + 1);
      nameCell.appendChild(expander);
      nameCell.appendChild(createTypeDiv(node.type));
      nameCell.appendChild(createFunctionNode(node.name, node.codeId));

      // Inclusive ticks cell.
      c = row.insertCell();
      c.textContent = node.ticks;
      c.style.textAlign = "right";
      if (this.currentState.mode !== "bottom-up") {
        // Exclusive ticks cell.
        c = row.insertCell(-1);
        c.textContent = node.ownTicks;
        c.style.textAlign = "right";
      }
      if (node.children.length > 0) {
        expander.textContent = "\u25B8";
        expander.onclick = () => { that.expandTree(node, indent + 1); };
      }

      node.row = row;
      node.expander = expander;

      index++;
    }
  }

  collapseRow(tree, expander, expandHandler) {
    let row = tree.row;
    let id = row.id;
    let index = row.rowIndex;
    while (row.rowIndex < this.rows.rows.length &&
        this.rows.rows[index].id.startsWith(id)) {
      this.rows.deleteRow(index);
    }

    expander.textContent = "\u25B8";
    expander.onclick = expandHandler;
  }

  fillSelects(mode, calltree) {
    function addOptions(e, values, current) {
      while (e.options.length > 0) {
        e.remove(0);
      }
      for (let i = 0; i < values.length; i++) {
        let option = document.createElement("option");
        option.value = values[i].value;
        option.textContent = values[i].text;
        e.appendChild(option);
      }
      e.value = current;
    }

    let attributions = [
        { value : "js-exclude-bc",
          text : "Attribute bytecode handlers to caller" },
        { value : "full-tree",
          text : "Count each code object separately" },
        { value : "js-funs",
          text : "Attribute non-functions to JS functions"  }
    ];

    switch (mode) {
      case "bottom-up":
        addOptions(this.selectAttribution, attributions, calltree.attribution);
        addOptions(this.selectCategories, [
            { value : "code-type", text : "Code type" },
            { value : "none", text : "None" }
        ], calltree.categories);
        addOptions(this.selectSort, [
            { value : "time", text : "Time (including children)" },
            { value : "category-time", text : "Code category, time" },
        ], calltree.sort);
        return;
      case "top-down":
        addOptions(this.selectAttribution, attributions, calltree.attribution);
        addOptions(this.selectCategories, [
            { value : "none", text : "None" },
            { value : "rt-entry", text : "Runtime entries" }
        ], calltree.categories);
        addOptions(this.selectSort, [
            { value : "time", text : "Time (including children)" },
            { value : "own-time", text : "Own time" },
            { value : "category-time", text : "Code category, time" },
            { value : "category-own-time", text : "Code category, own time"}
        ], calltree.sort);
        return;
      case "function-list":
        addOptions(this.selectAttribution, attributions, calltree.attribution);
        addOptions(this.selectCategories, [
            { value : "code-type", text : "Code type" },
            { value : "none", text : "None" }
        ], calltree.categories);
        addOptions(this.selectSort, [
            { value : "own-time", text : "Own time" },
            { value : "time", text : "Time (including children)" },
            { value : "category-own-time", text : "Code category, own time"},
            { value : "category-time", text : "Code category, time" },
        ], calltree.sort);
        return;
    }
    console.error("Unexpected mode");
  }

  static isCallTreeMode(mode) {
    switch (mode) {
      case "bottom-up":
      case "top-down":
      case "function-list":
        return true;
      default:
        return false;
    }
  }

  render(newState) {
    let oldState = this.currentState;
    if (!newState.file || !CallTreeView.isCallTreeMode(newState.mode)) {
      this.element.style.display = "none";
      this.currentState = null;
      return;
    }

    this.currentState = newState;
    if (oldState) {
      if (newState.file === oldState.file &&
          newState.start === oldState.start &&
          newState.end === oldState.end &&
          newState.mode === oldState.mode &&
          newState.callTree.attribution === oldState.callTree.attribution &&
          newState.callTree.categories === oldState.callTree.categories &&
          newState.callTree.sort === oldState.callTree.sort) {
        // No change => just return.
        return;
      }
    }

    this.element.style.display = "inherit";

    let mode = this.currentState.mode;
    if (!oldState || mode !== oldState.mode) {
      // Technically, we should also call this if attribution, categories or
      // sort change, but the selection is already highlighted by the combobox
      // itself, so we do need to do anything here.
      this.fillSelects(newState.mode, newState.callTree);
    }

    let ownTimeClass = (mode === "bottom-up") ? "numeric-hidden" : "numeric";
    let ownTimeTh = $(this.treeElement.id + "-own-time-header");
    ownTimeTh.classList = ownTimeClass;
    let ownTicksTh = $(this.treeElement.id + "-own-ticks-header");
    ownTicksTh.classList = ownTimeClass;

    // Build the tree.
    let stackProcessor;
    let filter = filterFromFilterId(this.currentState.callTree.attribution);
    if (mode === "top-down") {
      if (this.currentState.callTree.categories === "rt-entry") {
        stackProcessor =
            new RuntimeCallTreeProcessor();
      } else {
        stackProcessor =
            new PlainCallTreeProcessor(filter, false);
      }
    } else if (mode === "function-list") {
      stackProcessor = new FunctionListTree(
          filter, this.currentState.callTree.categories === "code-type");

    } else {
      console.assert(mode === "bottom-up");
      if (this.currentState.callTree.categories == "none") {
        stackProcessor =
            new PlainCallTreeProcessor(filter, true);
      } else {
        console.assert(this.currentState.callTree.categories === "code-type");
        stackProcessor =
            new CategorizedCallTreeProcessor(filter, true);
      }
    }
    this.tickCount =
        generateTree(this.currentState.file,
                     this.currentState.start,
                     this.currentState.end,
                     stackProcessor);
    // TODO(jarin) Handle the case when tick count is negative.

    this.tree = stackProcessor.tree;

    // Remove old content of the table, replace with new one.
    let oldRows = this.treeElement.getElementsByTagName("tbody");
    let newRows = document.createElement("tbody");
    this.rows = newRows;

    // Populate the table.
    this.expandTree(this.tree, 0);

    // Swap in the new rows.
    this.treeElement.replaceChild(newRows, oldRows[0]);
  }
}

class TimelineView {
  constructor() {
    this.element = $("timeline");
    this.canvas = $("timeline-canvas");
    this.legend = $("timeline-legend");
    this.currentCode = $("timeline-currentCode");

    this.canvas.onmousedown = this.onMouseDown.bind(this);
    this.canvas.onmouseup = this.onMouseUp.bind(this);
    this.canvas.onmousemove = this.onMouseMove.bind(this);

    this.selectionStart = null;
    this.selectionEnd = null;
    this.selecting = false;

    this.fontSize = 12;
    this.imageOffset = Math.round(this.fontSize * 1.2);
    this.functionTimelineHeight = 24;
    this.functionTimelineTickHeight = 16;

    this.currentState = null;
  }

  onMouseDown(e) {
    this.selectionStart =
        e.clientX - this.canvas.getBoundingClientRect().left;
    this.selectionEnd = this.selectionStart + 1;
    this.selecting = true;
  }

  onMouseMove(e) {
    if (this.selecting) {
      this.selectionEnd =
          e.clientX - this.canvas.getBoundingClientRect().left;
      this.drawSelection();
    }
  }

  onMouseUp(e) {
    if (this.selectionStart !== null) {
      let x = e.clientX - this.canvas.getBoundingClientRect().left;
      if (Math.abs(x - this.selectionStart) < 10) {
        this.selectionStart = null;
        this.selectionEnd = null;
        let ctx = this.canvas.getContext("2d");
        ctx.drawImage(this.buffer, 0, this.imageOffset);
      } else {
        this.selectionEnd = x;
        this.drawSelection();
      }
      let file = this.currentState.file;
      if (file) {
        let start = this.selectionStart === null ? 0 : this.selectionStart;
        let end = this.selectionEnd === null ? Infinity : this.selectionEnd;
        let firstTime = file.ticks[0].tm;
        let lastTime = file.ticks[file.ticks.length - 1].tm;

        let width = this.buffer.width;

        start = (start / width) * (lastTime - firstTime) + firstTime;
        end = (end / width) * (lastTime - firstTime) + firstTime;

        if (end < start) {
          let temp = start;
          start = end;
          end = temp;
        }

        main.setViewInterval(start, end);
      }
    }
    this.selecting = false;
  }

  drawSelection() {
    let ctx = this.canvas.getContext("2d");

    // Draw the timeline image.
    ctx.drawImage(this.buffer, 0, this.imageOffset);

    // Draw the current interval highlight.
    let left;
    let right;
    if (this.selectionStart !== null && this.selectionEnd !== null) {
      ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
      left = Math.min(this.selectionStart, this.selectionEnd);
      right = Math.max(this.selectionStart, this.selectionEnd);
      let height = this.buffer.height - this.functionTimelineHeight;
      ctx.fillRect(0, this.imageOffset, left, height);
      ctx.fillRect(right, this.imageOffset, this.buffer.width - right, height);
    } else {
      left = 0;
      right = this.buffer.width;
    }

    // Draw the scale text.
    let file = this.currentState.file;
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, this.canvas.width, this.imageOffset);
    if (file && file.ticks.length > 0) {
      let firstTime = file.ticks[0].tm;
      let lastTime = file.ticks[file.ticks.length - 1].tm;

      let leftTime =
          firstTime + left / this.canvas.width * (lastTime - firstTime);
      let rightTime =
          firstTime + right / this.canvas.width * (lastTime - firstTime);

      let leftText = (leftTime / 1000000).toFixed(3) + "s";
      let rightText = (rightTime / 1000000).toFixed(3) + "s";

      ctx.textBaseline = 'top';
      ctx.font = this.fontSize + "px Arial";
      ctx.fillStyle = "black";

      let leftWidth = ctx.measureText(leftText).width;
      let rightWidth = ctx.measureText(rightText).width;

      let leftStart = left - leftWidth / 2;
      let rightStart = right - rightWidth / 2;

      if (leftStart < 0) leftStart = 0;
      if (rightStart + rightWidth > this.canvas.width) {
        rightStart = this.canvas.width - rightWidth;
      }
      if (leftStart + leftWidth > rightStart) {
        if (leftStart > this.canvas.width - (rightStart - rightWidth)) {
          rightStart = leftStart + leftWidth;

        } else {
          leftStart = rightStart - leftWidth;
        }
      }

      ctx.fillText(leftText, leftStart, 0);
      ctx.fillText(rightText, rightStart, 0);
    }
  }

  render(newState) {
    let oldState = this.currentState;

    if (!newState.file) {
      this.element.style.display = "none";
      return;
    }

    this.currentState = newState;
    if (oldState) {
      if (newState.timeLine.width === oldState.timeLine.width &&
          newState.timeLine.height === oldState.timeLine.height &&
          newState.file === oldState.file &&
          newState.currentCodeId === oldState.currentCodeId &&
          newState.start === oldState.start &&
          newState.end === oldState.end) {
        // No change, nothing to do.
        return;
      }
    }

    this.element.style.display = "inherit";

    // Make sure the canvas has the right dimensions.
    let width = this.currentState.timeLine.width;
    let height = this.currentState.timeLine.height;
    this.canvas.width = width;
    this.canvas.height  = height;

    // Make space for the selection text.
    height -= this.imageOffset;

    let file = this.currentState.file;
    if (!file) return;

    let currentCodeId = this.currentState.currentCodeId;

    let firstTime = file.ticks[0].tm;
    let lastTime = file.ticks[file.ticks.length - 1].tm;
    let start = Math.max(this.currentState.start, firstTime);
    let end = Math.min(this.currentState.end, lastTime);

    this.selectionStart = (start - firstTime) / (lastTime - firstTime) * width;
    this.selectionEnd = (end - firstTime) / (lastTime - firstTime) * width;

    let tickCount = file.ticks.length;

    let minBucketPixels = 10;
    let minBucketSamples = 30;
    let bucketCount = Math.min(width / minBucketPixels,
                               tickCount / minBucketSamples);

    let stackProcessor = new CategorySampler(file, bucketCount);
    generateTree(file, 0, Infinity, stackProcessor);
    let codeIdProcessor = new FunctionTimelineProcessor(
      currentCodeId,
      filterFromFilterId(this.currentState.callTree.attribution));
    generateTree(file, 0, Infinity, codeIdProcessor);

    let buffer = document.createElement("canvas");

    buffer.width = width;
    buffer.height = height;

    // Calculate the bar heights for each bucket.
    let graphHeight = height - this.functionTimelineHeight;
    let buckets = stackProcessor.buckets;
    let bucketsGraph = [];
    for (let i = 0; i < buckets.length; i++) {
      let sum = 0;
      let bucketData = [];
      let total = buckets[i].total;
      for (let j = 0; j < bucketDescriptors.length; j++) {
        let desc = bucketDescriptors[j];
        for (let k = 0; k < desc.kinds.length; k++) {
          sum += buckets[i][desc.kinds[k]];
        }
        bucketData.push(Math.round(graphHeight * sum / total));
      }
      bucketsGraph.push(bucketData);
    }

    // Draw the category graph into the buffer.
    let bucketWidth = width / bucketsGraph.length;
    let ctx = buffer.getContext('2d');
    for (let i = 0; i < bucketsGraph.length - 1; i++) {
      let bucketData = bucketsGraph[i];
      let nextBucketData = bucketsGraph[i + 1];
      for (let j = 0; j < bucketData.length; j++) {
        let x1 = Math.round(i * bucketWidth);
        let x2 = Math.round((i + 1) * bucketWidth);
        ctx.beginPath();
        ctx.moveTo(x1, j && bucketData[j - 1]);
        ctx.lineTo(x2, j && nextBucketData[j - 1]);
        ctx.lineTo(x2, nextBucketData[j]);
        ctx.lineTo(x1, bucketData[j]);
        ctx.closePath();
        ctx.fillStyle = bucketDescriptors[j].color;
        ctx.fill();
      }
    }

    // Draw the function ticks.
    let functionTimelineYOffset = graphHeight;
    let functionTimelineTickHeight = this.functionTimelineTickHeight;
    let functionTimelineHalfHeight =
        Math.round(functionTimelineTickHeight / 2);
    let timestampScaler = width / (lastTime - firstTime);
    let timestampToX = (t) => Math.round((t - firstTime) * timestampScaler);
    ctx.fillStyle = "white";
    ctx.fillRect(
      0,
      functionTimelineYOffset,
      buffer.width,
      this.functionTimelineHeight);
    for (let i = 0; i < codeIdProcessor.blocks.length; i++) {
      let block = codeIdProcessor.blocks[i];
      let bucket = kindToBucketDescriptor[block.kind];
      ctx.fillStyle = bucket.color;
      ctx.fillRect(
        timestampToX(block.start),
        functionTimelineYOffset,
        Math.max(1, Math.round((block.end - block.start) * timestampScaler)),
        block.topOfStack ?
            functionTimelineTickHeight : functionTimelineHalfHeight);
    }
    ctx.strokeStyle = "black";
    ctx.lineWidth = "1";
    ctx.beginPath();
    ctx.moveTo(0, functionTimelineYOffset + 0.5);
    ctx.lineTo(buffer.width, functionTimelineYOffset + 0.5);
    ctx.stroke();
    ctx.strokeStyle = "rgba(0,0,0,0.2)";
    ctx.lineWidth = "1";
    ctx.beginPath();
    ctx.moveTo(0, functionTimelineYOffset + functionTimelineHalfHeight - 0.5);
    ctx.lineTo(buffer.width,
        functionTimelineYOffset + functionTimelineHalfHeight - 0.5);
    ctx.stroke();

    // Draw marks for optimizations and deoptimizations in the function
    // timeline.
    if (currentCodeId && currentCodeId >= 0 &&
        file.code[currentCodeId].func) {
      let y = Math.round(functionTimelineYOffset + functionTimelineTickHeight +
          (this.functionTimelineHeight - functionTimelineTickHeight) / 2);
      let func = file.functions[file.code[currentCodeId].func];
      for (let i = 0; i < func.codes.length; i++) {
        let code = file.code[func.codes[i]];
        if (code.kind === "Opt") {
          if (code.deopt) {
            // Draw deoptimization mark.
            let x = timestampToX(code.deopt.tm);
            ctx.lineWidth = 0.7;
            ctx.strokeStyle = "red";
            ctx.beginPath();
            ctx.moveTo(x - 3, y - 3);
            ctx.lineTo(x + 3, y + 3);
            ctx.stroke();
            ctx.beginPath();
            ctx.moveTo(x - 3, y + 3);
            ctx.lineTo(x + 3, y - 3);
            ctx.stroke();
          }
          // Draw optimization mark.
          let x = timestampToX(code.tm);
          ctx.lineWidth = 0.7;
          ctx.strokeStyle = "blue";
          ctx.beginPath();
          ctx.moveTo(x - 3, y - 3);
          ctx.lineTo(x, y);
          ctx.stroke();
          ctx.beginPath();
          ctx.moveTo(x - 3, y + 3);
          ctx.lineTo(x, y);
          ctx.stroke();
        } else {
          // Draw code creation mark.
          let x = Math.round(timestampToX(code.tm));
          ctx.beginPath();
          ctx.fillStyle = "black";
          ctx.arc(x, y, 3, 0, 2 * Math.PI);
          ctx.fill();
        }
      }
    }

    // Remember stuff for later.
    this.buffer = buffer;

    // Draw the buffer.
    this.drawSelection();

    // (Re-)Populate the graph legend.
    while (this.legend.cells.length > 0) {
      this.legend.deleteCell(0);
    }
    let cell = this.legend.insertCell(-1);
    cell.textContent = "Legend: ";
    cell.style.padding = "1ex";
    for (let i = 0; i < bucketDescriptors.length; i++) {
      let cell = this.legend.insertCell(-1);
      cell.style.padding = "1ex";
      let desc = bucketDescriptors[i];
      let div = document.createElement("div");
      div.style.display = "inline-block";
      div.style.width = "0.6em";
      div.style.height = "1.2ex";
      div.style.backgroundColor = desc.color;
      div.style.borderStyle = "solid";
      div.style.borderWidth = "1px";
      div.style.borderColor = "Black";
      cell.appendChild(div);
      cell.appendChild(document.createTextNode(" " + desc.text));
    }

    while (this.currentCode.firstChild) {
      this.currentCode.removeChild(this.currentCode.firstChild);
    }
    if (currentCodeId) {
      let currentCode = file.code[currentCodeId];
      this.currentCode.appendChild(document.createTextNode(currentCode.name));
    } else {
      this.currentCode.appendChild(document.createTextNode("<none>"));
    }
  }
}

class ModeBarView {
  constructor() {
    let modeBar = this.element = $("mode-bar");

    function addMode(id, text, active) {
      let div = document.createElement("div");
      div.classList = "mode-button" + (active ? " active-mode-button" : "");
      div.id = "mode-" + id;
      div.textContent = text;
      div.onclick = () => {
        if (main.currentState.mode === id) return;
        let old = $("mode-" + main.currentState.mode);
        old.classList = "mode-button";
        div.classList = "mode-button active-mode-button";
        main.setMode(id);
      };
      modeBar.appendChild(div);
    }

    addMode("summary", "Summary", true);
    addMode("bottom-up", "Bottom up");
    addMode("top-down", "Top down");
    addMode("function-list", "Functions");
  }

  render(newState) {
    if (!newState.file) {
      this.element.style.display = "none";
      return;
    }

    this.element.style.display = "inherit";
  }
}

class SummaryView {
  constructor() {
    this.element = $("summary");
    this.currentState = null;
  }

  render(newState) {
    let oldState = this.currentState;

    if (!newState.file || newState.mode !== "summary") {
      this.element.style.display = "none";
      this.currentState = null;
      return;
    }

    this.currentState = newState;
    if (oldState) {
      if (newState.file === oldState.file &&
          newState.start === oldState.start &&
          newState.end === oldState.end) {
        // No change, nothing to do.
        return;
      }
    }

    this.element.style.display = "inherit";

    while (this.element.firstChild) {
      this.element.removeChild(this.element.firstChild);
    }

    let stats = computeOptimizationStats(
        this.currentState.file, newState.start, newState.end);

    let table = document.createElement("table");
    let rows = document.createElement("tbody");

    function addRow(text, number, indent) {
      let row = rows.insertRow(-1);
      let textCell = row.insertCell(-1);
      textCell.textContent = text;
      let numberCell = row.insertCell(-1);
      numberCell.textContent = number;
      if (indent) {
        textCell.style.textIndent = indent + "em";
        numberCell.style.textIndent = indent + "em";
      }
      return row;
    }

    function makeCollapsible(row, expander) {
      expander.textContent = "\u25BE";
      let expandHandler = expander.onclick;
      expander.onclick = () => {
        let id = row.id;
        let index = row.rowIndex + 1;
        while (index < rows.rows.length &&
          rows.rows[index].id.startsWith(id)) {
          rows.deleteRow(index);
        }
        expander.textContent = "\u25B8";
        expander.onclick = expandHandler;
      }
    }

    function expandDeoptInstances(row, expander, instances, indent, kind) {
      let index = row.rowIndex;
      for (let i = 0; i < instances.length; i++) {
        let childRow = rows.insertRow(index + 1);
        childRow.id = row.id + i + "/";

        let deopt = instances[i].deopt;

        let textCell = childRow.insertCell(-1);
        textCell.appendChild(document.createTextNode(deopt.posText));
        textCell.style.textIndent = indent + "em";
        let reasonCell = childRow.insertCell(-1);
        reasonCell.appendChild(
            document.createTextNode("Reason: " + deopt.reason));
        reasonCell.style.textIndent = indent + "em";
      }
      makeCollapsible(row, expander);
    }

    function expandDeoptFunctionList(row, expander, list, indent, kind) {
      let index = row.rowIndex;
      for (let i = 0; i < list.length; i++) {
        let childRow = rows.insertRow(index + 1);
        childRow.id = row.id + i + "/";

        let textCell = childRow.insertCell(-1);
        let expander = createTableExpander(indent);
        textCell.appendChild(expander);
        textCell.appendChild(
            createFunctionNode(list[i].f.name, list[i].f.codes[0]));

        let numberCell = childRow.insertCell(-1);
        numberCell.textContent = list[i].instances.length;
        numberCell.style.textIndent = indent + "em";

        expander.textContent = "\u25B8";
        expander.onclick = () => {
          expandDeoptInstances(
              childRow, expander, list[i].instances, indent + 1);
        };
      }
      makeCollapsible(row, expander);
    }

    function expandOptimizedFunctionList(row, expander, list, indent, kind) {
      let index = row.rowIndex;
      for (let i = 0; i < list.length; i++) {
        let childRow = rows.insertRow(index + 1);
        childRow.id = row.id + i + "/";

        let textCell = childRow.insertCell(-1);
        textCell.appendChild(
            createFunctionNode(list[i].f.name, list[i].f.codes[0]));
        textCell.style.textIndent = indent + "em";

        let numberCell = childRow.insertCell(-1);
        numberCell.textContent = list[i].instances.length;
        numberCell.style.textIndent = indent + "em";
      }
      makeCollapsible(row, expander);
    }

    function addExpandableRow(text, list, indent, kind) {
      let row = rows.insertRow(-1);

      row.id = "opt-table/" + kind + "/";

      let textCell = row.insertCell(-1);
      let expander = createTableExpander(indent);
      textCell.appendChild(expander);
      textCell.appendChild(document.createTextNode(text));

      let numberCell = row.insertCell(-1);
      numberCell.textContent = list.count;
      if (indent) {
        numberCell.style.textIndent = indent + "em";
      }

      if (list.count > 0) {
        expander.textContent = "\u25B8";
        if (kind === "opt") {
          expander.onclick = () => {
            expandOptimizedFunctionList(
                row, expander, list.functions, indent + 1, kind);
          };
        } else {
          expander.onclick = () => {
            expandDeoptFunctionList(
                row, expander, list.functions, indent + 1, kind);
          };
        }
      }
      return row;
    }

    addRow("Total function count:", stats.functionCount);
    addRow("Optimized function count:", stats.optimizedFunctionCount, 1);
    addRow("Deoptimized function count:", stats.deoptimizedFunctionCount, 2);

    addExpandableRow("Optimization count:", stats.optimizations, 0, "opt");
    let deoptCount = stats.eagerDeoptimizations.count +
        stats.softDeoptimizations.count + stats.lazyDeoptimizations.count;
    addRow("Deoptimization count:", deoptCount);
    addExpandableRow("Eager:", stats.eagerDeoptimizations, 1, "eager");
    addExpandableRow("Lazy:", stats.lazyDeoptimizations, 1, "lazy");
    addExpandableRow("Soft:", stats.softDeoptimizations, 1, "soft");

    table.appendChild(rows);
    this.element.appendChild(table);
  }
}

class HelpView {
  constructor() {
    this.element = $("help");
  }

  render(newState) {
    this.element.style.display = newState.file ? "none" : "inherit";
  }
}
