const { TouchBarScrubber } = require("electron");

// Default range: 0 to 300s, shared between both views
var RANGE_LEFT_INIT = 0;
var RANGE_RIGHT_INIT = 300;

// Global timeline start
var g_StartingSec = undefined;

function ShouldShowDebugInfo() {
  if (g_cb_debug_info.checked) return true;
  else return false;
}

function GetHistoryHistogram() {
  return HistoryHistogram;
}

function RenderHistogramForImageData(ctx, key) {
  let PAD = 1,   // To make up for the extra stroke width
      PAD2 = 2;  // To preserve some space at both ends of the histogram

  let cumDensity0 = 0, cumDensity1 = 0;

  //      Left normalized index  Left value  Right normalized index, Right value
  let threshEntry = [[undefined, undefined], [undefined, undefined]];
  const x = 0, y = 0, w = HISTOGRAM_W, h = HISTOGRAM_H;
  let hist = GetHistoryHistogram()[key];
  if (hist == undefined) return;

  let buckets = hist[2];
  let dw = w * 1.0 / buckets.length;
  let maxCount = 0, totalCount = 0;
  for (let i = 0; i < buckets.length; i++) {
    if (maxCount < buckets[i]) {
      maxCount = buckets[i];
    }
    totalCount += buckets[i];
  }
  ctx.fillStyle = '#FFF';
  ctx.fillRect(x, y, w, h);

  ctx.strokeStyle = '#AAA';
  ctx.fillStyle = '#000';
  ctx.lineWidth = 1;
  ctx.strokeRect(x + PAD, y + PAD, w - 2 * PAD, h - 2 * PAD);
  for (let i = 0; i < buckets.length; i++) {
    const bucketsLen = buckets.length;
    if (buckets[i] > 0) {
      let dx0 = x + PAD2 + (w - 2 * PAD2) * 1.0 * i / buckets.length,
          dx1 = x + PAD2 + (w - 2 * PAD2) * 1.0 * (i + 1) / buckets.length,
          dy0 = y + h - h * 1.0 * buckets[i] / maxCount, dy1 = y + h;
      let delta_density = buckets[i] / totalCount;
      cumDensity0 = cumDensity1;
      cumDensity1 += delta_density;

      // Write thresholds
      if (cumDensity0 < HISTOGRAM_LEFT_TAIL_WIDTH &&
          cumDensity1 >= HISTOGRAM_LEFT_TAIL_WIDTH) {
        threshEntry[0][0] = i / buckets.length;
        threshEntry[0][1] = hist[0] + (hist[1] - hist[0]) / bucketsLen * i;
      }
      if (cumDensity0 < 1 - HISTOGRAM_RIGHT_TAIL_WIDTH &&
          cumDensity1 >= 1 - HISTOGRAM_RIGHT_TAIL_WIDTH) {
        threshEntry[1][0] = (i - 1) / buckets.length;
        threshEntry[1][1] =
            hist[0] + (hist[1] - hist[0]) / bucketsLen * (i - 1);
      }

      ctx.fillRect(dx0, dy0, dx1 - dx0, dy1 - dy0);
    }
  }

  // Mark the threshold regions
  ctx.fillStyle = 'rgba(0,255,0,0.1)';
  let dx = x + PAD2;
  dw = (w - 2 * PAD2) * 1.0 * threshEntry[0][0];
  ctx.fillRect(dx, y, dw, h);

  ctx.fillStyle = 'rgba(255,0,0,0.1)';
  ctx.beginPath();
  dx = x + PAD2 + (w - 2 * PAD2) * 1.0 * threshEntry[1][0];
  dw = (w - 2 * PAD2) * 1.0 * (1 - threshEntry[1][0]);
  ctx.fillRect(dx, y, dw, h);

  IsCanvasDirty = true;
  return [ctx.getImageData(x, y, w, h), threshEntry];
}

function RenderHistogram(ctx, key, xMid, yMid) {
  if (GetHistoryHistogram()[key] == undefined) {
    return;
  }
  if (IpmiVizHistogramImageData[key] == undefined) {
    return;
  }
  let hist = GetHistoryHistogram()[key];
  ctx.putImageData(
      IpmiVizHistogramImageData[key], xMid - HISTOGRAM_W / 2,
      yMid - HISTOGRAM_H / 2);

  let ub = '';  // Upper bound label
  ctx.textAlign = 'left';
  ctx.fillStyle = '#000';
  if (hist[1] > 1000) {
    ub = (hist[1] / 1000.0).toFixed(1) + 'ms';
  } else {
    ub = hist[1].toFixed(1) + 'us';
  }
  ctx.fillText(ub, xMid + HISTOGRAM_W / 2, yMid);

  let lb = '';  // Lower bound label
  if (hist[0] > 1000) {
    lb = (hist[0] / 1000.0).toFixed(1) + 'ms';
  } else {
    lb = hist[0].toFixed(1) + 'us';
  }
  ctx.textAlign = 'right';
  ctx.textBaseline = 'middle';
  ctx.fillText(lb, xMid - HISTOGRAM_W / 2, yMid);
}

// A TimelineView contains data that has already gone through
// the Layout step and is ready for showing
class TimelineView {
  constructor() {
    this.Intervals = [];
    this.Titles = [];  // { "header":true|false, "title":string, "intervals_idxes":[int] } 
    this.Heights = [];  // Visual height for each line
    this.HeaderCollapsed = {};
    this.TitleProperties = []; // [Visual height, Is Header]
    this.LowerBoundTime = RANGE_LEFT_INIT;
    this.UpperBoundTime = RANGE_RIGHT_INIT;
    this.LowerBoundTimeTarget = this.LowerBoundTime;
    this.UpperBoundTimeTarget = this.UpperBoundTime;
    this.LastTimeLowerBound = 0;
    this.LastTimeUpperBound = 0;
    this.IsCanvasDirty = true;
    this.IsHighlightDirty = true;
    this.IsAnimating = false;
    this.IpmiVizHistogramImageData = {};
    this.IpmiVizHistHighlighted = {};
    this.HighlightedRequests = [];
    this.Canvas = undefined;
    this.TitleDispLengthLimit = 32;  // display this many chars for title
    this.IsTimeDistributionEnabled = false;
    this.AccentColor = '#000';
    this.CurrentFileName = '';
    this.VisualLineStartIdx = 0;

    // For connecting to the data model
    this.GroupBy = [];
    this.GroupByStr = '';

    // For keyboard navigation
    this.CurrDeltaX = 0;
    this.CurrDeltaZoom = 0;
    this.CurrShiftFlag = false;
    this.MouseState = {
      hovered: true,
      pressed: false,
      x: 0,
      y: 0,
      hoveredVisibleLineIndex: -999,
      hoveredSide: undefined,  // 'left', 'right', 'scroll', 'timeline'
      drag_begin_title_start_idx: undefined,
      drag_begin_y: undefined,
      IsDraggingScrollBar: function() {
        return (this.drag_begin_y != undefined);
      },
      EndDragScrollBar: function() {
        this.drag_begin_y = undefined;
        this.drag_begin_title_start_idx = undefined;
      },
      IsHoveredOverHorizontalScrollbar: function() {
        if (this.hoveredSide == "top_horizontal_scrollbar") return true;
        else if (this.hoveredSide == "bottom_horizontal_scrollbar") return true;
        else return false;
      }
    };
    this.ScrollBarState = {
      y0: undefined,
      y1: undefined,
    };
    this.HighlightedRegion = {t0: -999, t1: -999};

    // The linked view will move and zoom with this view
    this.linked_views = [];
  }

  // Performs layout operation, move overlapping intervals to different
  // lines
  LayoutForOverlappingIntervals() {
    this.Heights = [];
    const MAX_STACK = 10; // Stack level limit: 10, arbitrarily chosen
    
    for (let i=0; i<this.Titles.length; i++) {
      let last_x = {};
      let ymax = 0;

      const title_data = this.Titles[i];

      const intervals_idxes = title_data.intervals_idxes;

      // TODO: What happens if there are > 1
      if (title_data.header == false) {
        const line = this.Intervals[intervals_idxes[0]];

        for (let j=0; j<line.length; j++) {
          const entry = line[j];
          let y = 0;
          for (; y<MAX_STACK; y++) {
            if (!(y in last_x)) { break; }
            if (last_x[y] <= entry[0]) {
              break;
            }
          }
          
          const end_time = entry[1];
          if (end_time != undefined && !isNaN(end_time)) {
            last_x[y] = end_time;
          } else {
            last_x[y] = entry[0];
          }
          entry[4] = y;
          ymax = Math.max(y, ymax);
        }
      } else if (intervals_idxes.length == 0) {
        // Don't do anything, set height to 1
      }
      this.Heights.push(ymax+1);
    }
  }

  TotalVisualHeight() {
    let ret = 0;
    this.Heights.forEach((h) => {
      ret += h;
    })
    return ret;
  }

  // Returns [Index, Offset]
  VisualLineIndexToDataLineIndex(x) {
    if (this.Heights.length < 1) return undefined;
    let lb = 0, ub = this.Heights[0]-1;
    for (let i=0; i<this.Heights.length; i++) {
      ub = lb + this.Heights[i] - 1;
      if (lb <= x && ub >= x) {
        return [i, x-lb];
      }
      lb = ub+1;
    }
    return -999;
  }

  IsEmpty() {
    return (this.Intervals.length < 1);
  }

  GetTitleWidthLimit() {
    if (this.IsTimeDistributionEnabled == true) {
      return 32;
    } else {
      return 64;
    }
  }

  ToLines(t, limit) {
    let ret = [];
    for (let i = 0; i < t.length; i += limit) {
      let j = Math.min(i + limit, t.length);
      ret.push(t.substr(i, j));
    }
    return ret;
  }

  Zoom(dz, mid = undefined, iter = 1) {
    if (this.CurrShiftFlag) dz *= 2;
    if (dz != 0) {
      if (mid == undefined) {
        mid = (this.LowerBoundTime + this.UpperBoundTime) / 2;
      }
      this.LowerBoundTime = mid - (mid - this.LowerBoundTime) * (1 - dz);
      this.UpperBoundTime = mid + (this.UpperBoundTime - mid) * (1 - dz);
      this.IsCanvasDirty = true;
      this.IsAnimating = false;
    }

    if (iter > 0) {
      this.linked_views.forEach(function(v) {
        v.Zoom(dz, mid, iter - 1);
      });
    }
  }

  BeginZoomAnimation(dz, mid = undefined, iter = 1) {
    if (mid == undefined) {
      mid = (this.LowerBoundTime + this.UpperBoundTime) / 2;
    }
    this.LowerBoundTimeTarget = mid - (mid - this.LowerBoundTime) * (1 - dz);
    this.UpperBoundTimeTarget = mid + (this.UpperBoundTime - mid) * (1 - dz);
    this.IsCanvasDirty = true;
    this.IsAnimating = true;

    if (iter > 0) {
      this.linked_views.forEach(function(v) {
        v.BeginZoomAnimation(dz, mid, iter - 1);
      });
    }
  }

  BeginPanScreenAnimaton(delta_screens, iter = 1) {
    let deltat = (this.UpperBoundTime - this.LowerBoundTime) * delta_screens;
    this.BeginSetBoundaryAnimation(
        this.LowerBoundTime + deltat, this.UpperBoundTime + deltat);

    if (iter > 0) {
      this.linked_views.forEach(function(v) {
        v.BeginPanScreenAnimaton(delta_screens, iter - 1);
      });
    }
  }

  BeginSetBoundaryAnimation(lt, rt, iter = 1) {
    this.IsAnimating = true;
    this.LowerBoundTimeTarget = lt;
    this.UpperBoundTimeTarget = rt;

    if (iter > 0) {
      this.linked_views.forEach(function(v) {
        v.BeginSetBoundaryAnimation(lt, rt, iter - 1);
      });
    }
  }

  BeginWarpToRequestAnimation(req, iter = 1) {
    let mid_new = (req[0] + req[1]) / 2;
    let mid = (this.LowerBoundTime + this.UpperBoundTime) / 2;
    let lt = this.LowerBoundTime + (mid_new - mid);
    let rt = this.UpperBoundTime + (mid_new - mid);
    this.BeginSetBoundaryAnimation(lt, rt, 0);

    this.linked_views.forEach(function(v) {
      v.BeginSetBoundaryAnimation(lt, rt, 0);
    });
  }

  UpdateAnimation() {
    const EPS = 1e-3;
    if (Math.abs(this.LowerBoundTime - this.LowerBoundTimeTarget) < EPS &&
        Math.abs(this.UpperBoundTime - this.UpperBoundTimeTarget) < EPS) {
      this.LowerBoundTime = this.LowerBoundTimeTarget;
      this.UpperBoundTime = this.UpperBoundTimeTarget;
      this.IsAnimating = false;
    }
    if (this.IsAnimating) {
      let t = 0.80;
      this.LowerBoundTime =
          this.LowerBoundTime * t + this.LowerBoundTimeTarget * (1 - t);
      this.UpperBoundTime =
          this.UpperBoundTime * t + this.UpperBoundTimeTarget * (1 - t);
      this.IsCanvasDirty = true;
    }
  }

  IsHighlighted() {
    return (
        this.HighlightedRegion.t0 != -999 && this.HighlightedRegion.t1 != -999);
  }

  RenderHistogram(ctx, key, xMid, yMid) {
    if (GetHistoryHistogram()[key] == undefined) {
      return;
    }
    if (this.IpmiVizHistogramImageData[key] == undefined) {
      return;
    }
    let hist = GetHistoryHistogram()[key];
    ctx.putImageData(
        this.IpmiVizHistogramImageData[key], xMid - HISTOGRAM_W / 2,
        yMid - HISTOGRAM_H / 2);

    let ub = '';  // Upper bound label
    ctx.textAlign = 'left';
    ctx.fillStyle = '#000';
    if (hist[1] > 1000) {
      ub = (hist[1] / 1000.0).toFixed(1) + 'ms';
    } else {
      ub = hist[1].toFixed(1) + 'us';
    }
    ctx.fillText(ub, xMid + HISTOGRAM_W / 2, yMid);

    let lb = '';  // Lower bound label
    if (hist[0] > 1000) {
      lb = (hist[0] / 1000.0).toFixed(1) + 'ms';
    } else {
      lb = hist[0].toFixed(1) + 'us';
    }
    ctx.textAlign = 'right';
    ctx.textBaseline = 'middle';
    ctx.fillText(lb, xMid - HISTOGRAM_W / 2, yMid);
  }

  IsMouseOverTimeline() {
    return this.MouseState.x > LEFT_MARGIN;
  }

  MouseXToTimestamp(x) {
    let ret = (x - LEFT_MARGIN) / (RIGHT_MARGIN - LEFT_MARGIN) *
            (this.UpperBoundTime - this.LowerBoundTime) +
        this.LowerBoundTime;
    ret = Math.max(ret, this.LowerBoundTime);
    ret = Math.min(ret, this.UpperBoundTime);
    return ret;
  }

  Unhighlight() {
    this.HighlightedRegion.t0 = -999;
    this.HighlightedRegion.t1 = -999;
  }

  OnMouseMove() {
    // Drag gestures
    if (this.MouseState.pressed == true) {
      const h = this.MouseState.hoveredSide;
      if (h == 'timeline') {
        // Update highlighted area
        this.HighlightedRegion.t1 =
          this.MouseXToTimestamp(this.MouseState.x);
      }
    }

    const PAD = 2;
    if (this.MouseState.x < LEFT_MARGIN)
      this.MouseState.hovered = false;
    else if (this.MouseState.x > RIGHT_MARGIN)
      this.MouseState.hovered = false;
    else
      this.MouseState.hovered = true;

    this.IsCanvasDirty = true;
    let lineIndex =
        Math.floor((this.MouseState.y - YBEGIN + TEXT_Y0) / LINE_SPACING);

    if (this.MouseState.x <= 0 ||
        this.MouseState.x >= RIGHT_MARGIN) {
      lineIndex = undefined;
    }

    const old_hoveredSide = this.MouseState.hoveredSide;

    // Left/right overflow markers or time axis drag
    this.MouseState.hoveredVisibleLineIndex = -999;
    if (this.MouseState.hoveredSide != "scrollbar" &&
        this.MouseState.pressed == false) {
      if (lineIndex != undefined) {
        this.MouseState.hoveredVisibleLineIndex = lineIndex;

        let should_hide_cursor = false;  // Should we hide the vertical cursor for linked views?

        if (this.MouseState.x <= PAD + LINE_SPACING / 2 + LEFT_MARGIN &&
            this.MouseState.x >= PAD + LEFT_MARGIN) {
          this.MouseState.hoveredSide = 'left';
          this.IsCanvasDirty = true;
        } else if (
            this.MouseState.x <= RIGHT_MARGIN - PAD &&
            this.MouseState.x >= RIGHT_MARGIN - PAD - LINE_SPACING / 2) {
          this.MouseState.hoveredSide = 'right';
          this.IsCanvasDirty = true;
        } else if (this.MouseState.x >= PAD + LEFT_MARGIN &&
                   this.MouseState.y <= TOP_HORIZONTAL_SCROLLBAR_HEIGHT &&
                   this.MouseState.y >  0) {
          this.MouseState.hoveredVisibleLineIndex = undefined;
          this.MouseState.hoveredSide = 'top_horizontal_scrollbar';
        } else if (this.MouseState.x >= PAD + LEFT_MARGIN &&
                   this.MouseState.y >= this.Canvas.height - BOTTOM_HORIZONTAL_SCROLLBAR_HEIGHT &&
                   this.MouseState.y <= this.Canvas.height) {
          this.MouseState.hoveredVisibleLineIndex = undefined;
          this.MouseState.hoveredSide = 'bottom_horizontal_scrollbar';
        } else {
          this.MouseState.hoveredSide = undefined;
        }
      }
    }

    // During a dragging session
    if (this.MouseState.pressed == true) {

      if (this.MouseState.hoveredSide == "top_horizontal_scrollbar" ||
          this.MouseState.hoveredSide == "bottom_horizontal_scrollbar") {
        const sec_per_px = (this.MouseState.begin_UpperBoundTime - this.MouseState.begin_LowerBoundTime) / (RIGHT_MARGIN - LEFT_MARGIN);
        const pan_secs = (this.MouseState.x - this.MouseState.begin_drag_x) * sec_per_px;

        const new_lb = this.MouseState.begin_LowerBoundTime - pan_secs;
        const new_ub = this.MouseState.begin_UpperBoundTime - pan_secs;
        this.LowerBoundTime = new_lb;
        this.UpperBoundTime = new_ub;

        // Sync to all other views
        this.linked_views.forEach((v) => {
          v.LowerBoundTime = new_lb; v.UpperBoundTime = new_ub;
        })
      }

      const tvh = this.TotalVisualHeight();
      if (this.MouseState.hoveredSide == 'scrollbar') {
        const diff_y = this.MouseState.y - this.MouseState.drag_begin_y;
        const diff_title_idx = tvh * diff_y / this.Canvas.height;
        let new_title_start_idx = this.MouseState.drag_begin_title_start_idx + parseInt(diff_title_idx);
        if (new_title_start_idx < 0) { new_title_start_idx = 0; }
        else if (new_title_start_idx >= tvh) {
          new_title_start_idx = tvh - 1;
        }
        this.VisualLineStartIdx = new_title_start_idx;
      }
    }
  }

  OnMouseLeave() {
    // When dragging the scroll bar, allow mouse to temporarily leave the element since we only
    // care about delta Y
    if (this.MouseState.hoveredSide == 'scrollbar') {
      
    } else {
      this.MouseState.hovered = false;
      this.MouseState.hoveredSide = undefined;
      this.IsCanvasDirty = true;
      this.MouseState.hoveredVisibleLineIndex = undefined;
      this.MouseState.y = undefined;
      this.MouseState.x = undefined;
    }
  }

  // Assume event.button is zero (left mouse button)
  OnMouseDown(iter = 1) {
    // If hovering over an overflowing triangle, warp to the nearest overflowed
    //     request on that line
    if (this.MouseState.hoveredVisibleLineIndex >= 0 &&
        this.MouseState.hoveredVisibleLineIndex < this.Intervals.length &&
        this.MouseState.hoveredSide != undefined) {
      const x = this.VisualLineIndexToDataLineIndex(this.MouseState.hoveredVisibleLineIndex);
      if (x == undefined) return;
      const line = this.Intervals[x[0]];
      if (this.MouseState.hoveredSide == 'left') {
        for (let i = line.length - 1; i >= 0; i--) {
          if (line[i][1] <= this.LowerBoundTime) {
            this.BeginWarpToRequestAnimation(line[i]);
            // TODO: pass timeline X to linked view
            break;
          }
        }
      } else if (this.MouseState.hoveredSide == 'right') {
        for (let i = 0; i < line.length; i++) {
          if (line[i][0] >= this.UpperBoundTime) {
            // TODO: pass timeline X to linked view
            this.BeginWarpToRequestAnimation(line[i]);
            break;
          }
        }
      }
    }

    let tx = this.MouseXToTimestamp(this.MouseState.x);
    let t0 = Math.min(this.HighlightedRegion.t0, this.HighlightedRegion.t1),
        t1 = Math.max(this.HighlightedRegion.t0, this.HighlightedRegion.t1);
    if (this.MouseState.x > LEFT_MARGIN) {

      // If clicking on the horizontal scroll bar, start panning the viewport
      if (this.MouseState.hoveredSide == "top_horizontal_scrollbar" ||
          this.MouseState.hoveredSide == "bottom_horizontal_scrollbar") {
        this.MouseState.pressed = true;
        this.MouseState.begin_drag_x = this.MouseState.x;
        this.MouseState.begin_LowerBoundTime = this.LowerBoundTime;
        this.MouseState.begin_UpperBoundTime = this.UpperBoundTime;
      } else if (tx >= t0 && tx <= t1) {
        // If clicking inside highlighted area, zoom around the area
        this.BeginSetBoundaryAnimation(t0, t1);
        this.Unhighlight();
        this.IsCanvasDirty = true;

        this.linked_views.forEach(function(v) {
          v.BeginSetBoundaryAnimation(t0, t1, 0);
          v.Unhighlight();
          v.IsCanvasDirty = false;
        });
      } else {  // If in the timeline area, start a new dragging action
        this.MouseState.hoveredSide = 'timeline';
        this.MouseState.pressed = true;
        this.HighlightedRegion.t0 = this.MouseXToTimestamp(this.MouseState.x);
        this.HighlightedRegion.t1 = this.HighlightedRegion.t0;
        this.IsCanvasDirty = true;
      }
    } else if (this.MouseState.x < SCROLL_BAR_WIDTH) {  // Todo: draagging the scroll bar
      const THRESH = 4;
      if (this.MouseState.y >= this.ScrollBarState.y0 - THRESH &&
          this.MouseState.y <= this.ScrollBarState.y1 + THRESH) {
        this.MouseState.pressed = true;
        this.MouseState.drag_begin_y = this.MouseState.y;
        this.MouseState.drag_begin_title_start_idx = this.VisualLineStartIdx;
        this.MouseState.hoveredSide = 'scrollbar';
      }
    }

    // Collapse or expand a "header"
    if (this.MouseState.x < LEFT_MARGIN &&
        this.MouseState.hoveredVisibleLineIndex != undefined) {
      const x = this.VisualLineIndexToDataLineIndex(this.VisualLineStartIdx + this.MouseState.hoveredVisibleLineIndex);
      if (x != undefined) {
        const tidx = x[0];
        if (this.Titles[tidx] != undefined && this.Titles[tidx].header == true) {

          // Currently, only DBus pane supports column headers, so we can hard-code the DBus re-group function (rather than to figure out which pane we're in)
          this.HeaderCollapsed[this.Titles[tidx].title] = !(this.HeaderCollapsed[this.Titles[tidx].title]);
          OnGroupByConditionChanged_DBus();
        }
      }
    }
  }

  // Assume event.button == 0 (left mouse button)
  OnMouseUp() {
    this.MouseState.EndDragScrollBar();
    this.MouseState.pressed = false;
    this.IsCanvasDirty = true;
    this.UnhighlightIfEmpty();
    this.IsHighlightDirty = true;
    this.MouseState.hoveredSide = undefined;
  }

  UnhighlightIfEmpty() {
    if (this.HighlightedRegion.t0 == this.HighlightedRegion.t1) {
      this.Unhighlight();
      this.IsCanvasDirty = true;
      return true;
    } else
      return false;
  }

  OnMouseWheel(event) {
    event.preventDefault();
    const v = this;

    let is_mouse_on_horizontal_scrollbar = false;
    if (this.MouseState.y > 0 && this.MouseState.y < TOP_HORIZONTAL_SCROLLBAR_HEIGHT)
      is_mouse_on_horizontal_scrollbar = true;
    if (this.MouseState.y > this.Canvas.height - BOTTOM_HORIZONTAL_SCROLLBAR_HEIGHT &&
        this.MouseState.y < this.Canvas.height)
      is_mouse_on_horizontal_scrollbar = true;

    if (/*v.IsMouseOverTimeline()*/ is_mouse_on_horizontal_scrollbar) {
      let dz = 0;
      if (event.deltaY > 0) {  // Scroll down, zoom out
        dz = -0.3;
      } else if (event.deltaY < 0) {  // Scroll up, zoom in
        dz = 0.3;
      }
      v.Zoom(dz, v.MouseXToTimestamp(v.MouseState.x));
    } else {
      if (event.deltaY > 0) {
        v.ScrollY(1);
      } else if (event.deltaY < 0) {
        v.ScrollY(-1);
      }
    }
  }

  ScrollY(delta) {
    this.VisualLineStartIdx += delta;
    if (this.VisualLineStartIdx < 0) {
      this.VisualLineStartIdx = 0;
    } else if (this.VisualLineStartIdx >= this.TotalVisualHeight()) {
      this.VisualLineStartIdx = this.TotalVisualHeight() - 1;
    }
  }

  // This function is called in Render to draw a line of Intervals.
  // It is made into its own function for brevity in Render().
  // It depends on too much context so it doesn't look very clean though
  do_RenderIntervals(ctx, intervals_j, j, dy0, dy1, 
    data_line_idx, visual_line_offset_within_data_line,
    isAggregateSelection,
    vars) {
    // To reduce the number of draw calls while preserve the accuracy in
    // the visual presentation, combine rectangles that are within 1 pixel
    // into one
    let last_dx_begin = LEFT_MARGIN;
    let last_dx_end = LEFT_MARGIN; 

    for (let i = 0; i < intervals_j.length; i++) {
      let lb = intervals_j[i][0], ub = intervals_j[i][1];
      const yoffset = intervals_j[i][4];
      if (yoffset != visual_line_offset_within_data_line)
        continue;
      if (lb > ub)
        continue;  // Unmatched (only enter & no exit timestamp)

      let isHighlighted = false;
      let durationUsec =
          (intervals_j[i][1] - intervals_j[i][0]) * 1000000;
      let lbub = [lb, ub];
      if (this.IsHighlighted()) {
        if (IsIntersected(lbub, vars.highlightedInterval)) {
          vars.numIntersected++;
          isHighlighted = true;
          vars.currHighlightedReqs.push(intervals_j[i][2]);
        }
      }

      if (ub < this.LowerBoundTime) {
        vars.numOverflowEntriesToTheLeft++;
        continue;
      }
      if (lb > this.UpperBoundTime) {
        vars.numOverflowEntriesToTheRight++;
        continue;
      }
      // Failed request
      if (ub == undefined && lb < this.UpperBoundTime) {
        vars.numOverflowEntriesToTheLeft++;
        continue;
      }

      let dx0 = MapXCoord(
              lb, LEFT_MARGIN, RIGHT_MARGIN, this.LowerBoundTime,
              this.UpperBoundTime),
          dx1 = MapXCoord(
              ub, LEFT_MARGIN, RIGHT_MARGIN, this.LowerBoundTime,
              this.UpperBoundTime);

      dx0 = Math.max(dx0, LEFT_MARGIN);
      dx1 = Math.min(dx1, RIGHT_MARGIN);
      let dw = Math.max(0, dx1 - dx0);

      if (isHighlighted) {
        ctx.fillStyle = 'rgba(128,128,255,0.5)';
        ctx.fillRect(dx0, dy0, dw, dy1 - dy0);
      }

      let isCurrentReqHovered = false;
      // Intersect with mouse using pixel coordinates

      // When the mouse position is within 4 pixels distance from an entry, consider
      // the mouse to be over that entry and show the information popup
      const X_TOLERANCE = 4;

      if (vars.theHoveredReq == undefined &&
          IsIntersectedPixelCoords(
              [dx0 - X_TOLERANCE, dx0 + dw + X_TOLERANCE],
              [this.MouseState.x, this.MouseState.x]) &&
          IsIntersectedPixelCoords(
              [dy0, dy1], [this.MouseState.y, this.MouseState.y])) {
        ctx.fillStyle = 'rgba(255,255,0,0.5)';
        ctx.fillRect(dx0, dy0, dw, dy1 - dy0);
        vars.theHoveredReq = intervals_j[i][2];
        vars.theHoveredInterval = intervals_j[i];
        isCurrentReqHovered = true;
      }

      ctx.lineWidth = 0.5;


      // If this request is taking too long/is quick enough, use red/green
      let entry = HistogramThresholds[this.Titles[data_line_idx].title];

      let isError = false;
      if (intervals_j[i][3] == 'error') {
        isError = true;
      }

      if (entry != undefined) {
        if (entry[0][1] != undefined && durationUsec < entry[0][1]) {
          ctx.strokeStyle = '#0F0';
        } else if (
            entry[1][1] != undefined && durationUsec > entry[1][1]) {
          ctx.strokeStyle = '#A00';
        } else {
          ctx.strokeStyle = '#000';
        }
      } else {
        ctx.strokeStyle = '#000';
      }

      const duration = intervals_j[i][1] - intervals_j[i][0];
      if (!isNaN(duration)) {
        if (isError) {
          ctx.fillStyle = 'rgba(192, 128, 128, 0.8)';
          ctx.fillRect(dx0, dy0, dw, dy1 - dy0);
          ctx.strokeStyle = 'rgba(192, 128, 128, 1)';
        } else {
          ctx.fillStyle = undefined;
          ctx.strokeStyle = '#000';
        }

        // This keeps track of the current "cluster" of requests
        // that might visually overlap (i.e less than 1 pixel wide).
        // This can greatly reduce overdraw and keep render time under
        // a reasonable bound.
        if (!ShouldShowDebugInfo()) {
          if (dx0+dw - last_dx_begin > 1 ||
              i == intervals_j.length - 1) {
            ctx.strokeRect(last_dx_begin, dy0, 
              /*dx0+dw-last_dx_begin*/
              last_dx_end - last_dx_begin, // At least 1 pixel wide
              dy1-dy0);
            last_dx_begin = dx0;
          }
        } else {
          ctx.strokeRect(dx0, dy0, dw, dy1 - dy0);
        }
        last_dx_end = dx0 + dw;
        this.numVisibleRequests++;
      } else {
        // This entry has only a beginning and not an end
        // perhaps the original method call did not return
        if (isCurrentReqHovered) {
          ctx.fillStyle = 'rgba(192, 192, 0, 0.8)';
        } else {
          ctx.fillStyle = 'rgba(255, 128, 128, 0.8)';
        }
        ctx.beginPath();
        ctx.arc(dx0, (dy0 + dy1) / 2, HISTOGRAM_H * 0.17, 0, 2 * Math.PI);
        ctx.fill();
      }


      // Affects whether this req will be reflected in the aggregate info
      //     section
      if ((isAggregateSelection == false) ||
          (isAggregateSelection == true && isHighlighted == true)) {
        if (!isNaN(duration)) {
          vars.numVisibleRequestsCurrLine++;
          vars.totalSecsCurrLine += duration;
        } else {
          vars.numFailedRequestsCurrLine++;
        }

        // If a histogram exists for Titles[j], process the highlighted
        //     histogram buckets
        if (GetHistoryHistogram()[this.Titles[data_line_idx].title] != undefined) {
          let histogramEntry = GetHistoryHistogram()[this.Titles[data_line_idx].title];
          let bucketInterval = (histogramEntry[1] - histogramEntry[0]) /
              histogramEntry[2].length;
          let bucketIndex =
              Math.floor(
                  (durationUsec - histogramEntry[0]) / bucketInterval) /
              histogramEntry[2].length;

          if (this.IpmiVizHistHighlighted[this.Titles[data_line_idx].title] == undefined) {
            this.IpmiVizHistHighlighted[this.Titles[data_line_idx].title] = new Set();
          }
          let entry = this.IpmiVizHistHighlighted[this.Titles[data_line_idx].title];
          entry.add(bucketIndex);
        }
      }
    }  // end for (i=0 to interval_j.length-1)
    
    if (!ShouldShowDebugInfo()) {
      ctx.strokeRect(last_dx_begin, dy0, 
        /*dx0+dw-last_dx_begin*/
        last_dx_end - last_dx_begin, // At least 1 pixel wide
        dy1-dy0);
    }
  }

  // For the header:
  do_RenderHeader(ctx, header, j, dy0, dy1, 
    data_line_idx, visual_line_offset_within_data_line,
    isAggregateSelection,
    vars) {

    const dy = (dy0+dy1) / 2;
    ctx.fillStyle = "rgba(192,192,255, 1)";

    ctx.strokeStyle = "rgba(192,192,255, 1)"

    const title_text = header.title + " (" + header.intervals_idxes.length + ")";
    let skip_render = false;

    ctx.save();

    if (this.HeaderCollapsed[header.title] == false) {  // Expanded
      const x0 = LEFT_MARGIN - LINE_HEIGHT;
      ctx.fillRect(0, dy-LINE_HEIGHT/2, x0, LINE_HEIGHT);

      ctx.beginPath();
      ctx.moveTo(x0, dy0);
      ctx.lineTo(x0, dy1);
      ctx.lineTo(x0 + LINE_HEIGHT, dy1);
      ctx.fill();
      ctx.closePath();

      ctx.beginPath();
      ctx.lineWidth = 1.5;
      ctx.moveTo(0, dy1);
      ctx.lineTo(RIGHT_MARGIN, dy1);
      ctx.stroke();
      ctx.closePath();

      ctx.fillStyle = '#003';
      ctx.textBaseline = 'center';
      ctx.textAlign = 'right';
      ctx.fillText(title_text, LEFT_MARGIN - LINE_HEIGHT, dy);

      // Don't draw the timelines so visual clutter is reduced
      skip_render = true;
    } else {
      const x0 = LEFT_MARGIN - LINE_HEIGHT / 2;
      ctx.fillRect(0, dy-LINE_HEIGHT/2, x0, LINE_HEIGHT);
      
      ctx.beginPath();
      ctx.lineWidth = 1.5;
      ctx.moveTo(x0, dy0);
      ctx.lineTo(x0 + LINE_HEIGHT/2, dy);
      ctx.lineTo(x0, dy1);
      ctx.closePath();
      ctx.fill();

      /*
      ctx.beginPath();
      ctx.moveTo(0, dy);
      ctx.lineTo(RIGHT_MARGIN, dy);
      ctx.stroke();
      ctx.closePath();
      */

      ctx.fillStyle = '#003';
      ctx.textBaseline = 'center';
      ctx.textAlign = 'right';
      ctx.fillText(title_text, LEFT_MARGIN - LINE_HEIGHT, dy);
    }

    ctx.fillStyle = "rgba(160,120,255,0.8)";

    ctx.restore();

    // Draw the merged intervals
    // Similar to drawing the actual messages in do_Render(), but no collision detection against the mouse, and no hovering tooltip processing involved
    const merged_intervals = header.merged_intervals;
    let dxx0 = undefined, dxx1 = undefined;
    for (let i=0; i<merged_intervals.length; i++) {
      const lb = merged_intervals[i][0], ub = merged_intervals[i][1], weight = merged_intervals[i][2];
      let duration = ub-lb;
      let duration_usec = duration * 1000000;
      const lbub = [lb, ub];
      
      let isHighlighted = false;
      if (this.IsHighlighted()) {
        if (IsIntersected(lbub, vars.highlightedInterval)) {
          vars.numIntersected += weight;
          isHighlighted = true;
        }
      }

      if (ub < this.LowerBoundTime) continue;
      if (lb > this.UpperBoundTime) continue;

      // Render only if collapsed
      if (!skip_render) {
        let dx0 = MapXCoord(
          lb, LEFT_MARGIN, RIGHT_MARGIN, this.LowerBoundTime,
          this.UpperBoundTime),
            dx1 = MapXCoord(
          ub, LEFT_MARGIN, RIGHT_MARGIN, this.LowerBoundTime,
          this.UpperBoundTime);
        dx0 = Math.max(dx0, LEFT_MARGIN);
        dx1 = Math.min(dx1, RIGHT_MARGIN);
        let dw = Math.max(1, dx1 - dx0);  // At least 1 pixel wide during rendering

        // Draw this interval
        //ctx.fillRect(dx0, dy0, dw, dy1-dy0);
        if (dxx0 == undefined || dxx1 == undefined) {
          dxx0 = dx0;
        }

        const MERGE_THRESH = 0.5;  // Pixels

        let should_draw = true;
        if (dxx1 == undefined || dx0 < dxx1 + MERGE_THRESH) should_draw = false;
        if (i == merged_intervals.length - 1) {
          should_draw = true;
          dxx1 = dx1 + MERGE_THRESH;
        }

        if (should_draw) {
          //console.log(dxx0 + ", " + dy0 + ", " + (dx1-dxx0) + ", " + LINE_HEIGHT);
          ctx.fillRect(dxx0, dy0, dxx1-dxx0, LINE_HEIGHT);
          dxx0 = undefined; dxx1 = undefined;
        } else {
          // merge
          dxx1 = dx1 + MERGE_THRESH;
        }
      }

      if ((isAggregateSelection == false) ||
          (isAggregateSelection == true && isHighlighted == true)) {
        vars.totalSecsCurrLine += duration;
        vars.numVisibleRequestsCurrLine += weight;
      }
    }
  }

  Render(ctx) {
    // Wait for initialization
    if (this.Canvas == undefined) return;

    // Update
    let toFixedPrecision = 2;
    const extent = this.UpperBoundTime - this.LowerBoundTime;
    {
      if (extent < 0.1) {
        toFixedPrecision = 4;
      } else if (extent < 1) {
        toFixedPrecision = 3;
      }
    }

    let dx = this.CurrDeltaX;
    if (dx != 0) {
      if (this.CurrShiftFlag) dx *= 5;
      this.LowerBoundTime += dx * extent;
      this.UpperBoundTime += dx * extent;
      this.IsCanvasDirty = true;
    }

    // Hovered interval for display
    let theHoveredReq = undefined;
    let theHoveredInterval = undefined;
    let currHighlightedReqs = [];

    let dz = this.CurrDeltaZoom;
    this.Zoom(dz);
    this.UpdateAnimation();

    this.LastTimeLowerBound = this.LowerBoundTime;
    this.LastTimeUpperBound = this.UpperBoundTime;

    if (this.IsCanvasDirty) {
      this.IsCanvasDirty = false;
      // Shorthand for HighlightedRegion.t{0,1}
      let t0 = undefined, t1 = undefined;

      // Highlight
      let highlightedInterval = [];
      let numIntersected =
          0;  // How many requests intersect with highlighted area
      if (this.IsHighlighted()) {
        t0 = Math.min(this.HighlightedRegion.t0, this.HighlightedRegion.t1);
        t1 = Math.max(this.HighlightedRegion.t0, this.HighlightedRegion.t1);
        highlightedInterval = [t0, t1];
      }
      this.IpmiVizHistHighlighted = {};

      const width = this.Canvas.width;
      const height = this.Canvas.height;

      ctx.globalCompositeOperation = 'source-over';
      ctx.clearRect(0, 0, width, height);
      ctx.strokeStyle = '#000';
      ctx.fillStyle = '#000';
      ctx.lineWidth = 1;

      ctx.font = '12px Monospace';

      // Highlight current line
      if (this.MouseState.hoveredVisibleLineIndex != undefined) {
        const hv_lidx = this.MouseState.hoveredVisibleLineIndex + this.VisualLineStartIdx;
        if (hv_lidx >= 0 &&
            hv_lidx < this.Titles.length) {
          ctx.fillStyle = 'rgba(32,32,32,0.2)';
          let dy = YBEGIN + LINE_SPACING * this.MouseState.hoveredVisibleLineIndex -
              LINE_SPACING / 2;
          ctx.fillRect(0, dy, RIGHT_MARGIN, LINE_SPACING);
        }
      }

      // Draw highlighted background over time labels when the mouse is hovering over
      // the time axis
      ctx.fillStyle = "#FF9";
      if (this.MouseState.hoveredSide == "top_horizontal_scrollbar") {
        ctx.fillRect(LEFT_MARGIN, 0, RIGHT_MARGIN-LEFT_MARGIN, TOP_HORIZONTAL_SCROLLBAR_HEIGHT);
      } else if (this.MouseState.hoveredSide == "bottom_horizontal_scrollbar") {
        ctx.fillRect(LEFT_MARGIN, height-BOTTOM_HORIZONTAL_SCROLLBAR_HEIGHT, RIGHT_MARGIN-LEFT_MARGIN, BOTTOM_HORIZONTAL_SCROLLBAR_HEIGHT);
      }

      ctx.fillStyle = '#000';
      // Time marks at the beginning & end of the visible range
      ctx.textBaseline = 'bottom';
      ctx.textAlign = 'left';
      ctx.fillText(
          '' + this.LowerBoundTime.toFixed(toFixedPrecision) + 's',
          LEFT_MARGIN + 3, height);
      ctx.textAlign = 'end';
      ctx.fillText(
          '' + this.UpperBoundTime.toFixed(toFixedPrecision) + 's',
          RIGHT_MARGIN - 3, height);

      ctx.textBaseline = 'top';
      ctx.textAlign = 'left';
      ctx.fillText(
          '' + this.LowerBoundTime.toFixed(toFixedPrecision) + 's',
          LEFT_MARGIN + 3, TEXT_Y0);
      ctx.textAlign = 'right';
      ctx.fillText(
          '' + this.UpperBoundTime.toFixed(toFixedPrecision) + 's',
          RIGHT_MARGIN - 3, TEXT_Y0);

      let y = YBEGIN;
      let numVisibleRequests = 0;

      ctx.beginPath();
      ctx.moveTo(LEFT_MARGIN, 0);
      ctx.lineTo(LEFT_MARGIN, height);
      ctx.stroke();

      ctx.beginPath();
      ctx.moveTo(RIGHT_MARGIN, 0);
      ctx.lineTo(RIGHT_MARGIN, height);
      ctx.stroke();

      // Column Titles
      ctx.fillStyle = '#000';
      let columnTitle = '(All requests)';
      if (this.GroupByStr.length > 0) {
        columnTitle = this.GroupByStr;
      }
      ctx.textAlign = 'right';
      ctx.textBaseline = 'top';
      // Split into lines
      {
        let lines = this.ToLines(columnTitle, this.TitleDispLengthLimit)
        for (let i = 0; i < lines.length; i++) {
          ctx.fillText(lines[i], LEFT_MARGIN - 3, 3 + i * LINE_HEIGHT);
        }
      }

      if (this.IsTimeDistributionEnabled) {
        // "Histogram" title
        ctx.fillStyle = '#000';
        ctx.textBaseline = 'top';
        ctx.textAlign = 'center';
        ctx.fillText('Time Distribution', HISTOGRAM_X, TEXT_Y0);

        ctx.textAlign = 'right'
        ctx.fillText('In dataset /', HISTOGRAM_X, TEXT_Y0 + LINE_SPACING - 2);

        ctx.fillStyle = '#00F';

        ctx.textAlign = 'left'
        if (this.IsHighlighted()) {
          ctx.fillText(
              ' In selection', HISTOGRAM_X, TEXT_Y0 + LINE_SPACING - 2);
        }
        else {
          ctx.fillText(' In viewport', HISTOGRAM_X, TEXT_Y0 + LINE_SPACING - 2);
        }
      }

      ctx.fillStyle = '#000';

      // Time Axis Breaks
      const breakWidths = [
        86400,  10800,  3600,    1800,    1200,   600,   300,   120,
        60,     30,     10,      5,       2,      1,     0.5,   0.2,
        0.1,    0.05,   0.02,    0.01,    0.005,  0.002, 0.001, 0.0005,
        0.0002, 0.0001, 0.00005, 0.00002, 0.00001
      ];
      const BreakDrawLimit = 1000;  // Only draw up to this many grid lines

      let bidx = 0;
      while (bidx < breakWidths.length &&
             breakWidths[bidx] > this.UpperBoundTime - this.LowerBoundTime) {
        bidx++;
      }
      let breakWidth = breakWidths[bidx + 1];
      if (bidx < breakWidths.length) {
        let t2 = 0;  // Cannot name as "t0" otherwise clash
        bidx = 0;
        while (bidx < breakWidths.length) {
          while (t2 + breakWidths[bidx] < this.LowerBoundTime) {
            t2 += breakWidths[bidx];
          }
          if (t2 + breakWidths[bidx] >= this.LowerBoundTime &&
              t2 + breakWidths[bidx] <= this.UpperBoundTime) {
            break;
          }
          bidx++;
        }
        let draw_count = 0;
        if (bidx < breakWidths.length) {
          for (; t2 < this.UpperBoundTime; t2 += breakWidth) {
            if (t2 > this.LowerBoundTime) {
              ctx.beginPath();
              let dx = MapXCoord(
                  t2, LEFT_MARGIN, RIGHT_MARGIN, this.LowerBoundTime,
                  this.UpperBoundTime);
              ctx.strokeStyle = '#C0C0C0';
              ctx.moveTo(dx, 0);
              ctx.lineTo(dx, height);
              ctx.stroke();
              ctx.closePath();
              ctx.fillStyle = '#C0C0C0';

              ctx.textAlign = 'left';
              ctx.textBaseline = 'bottom';
              let label2 = t2.toFixed(toFixedPrecision) + 's';
              let w = ctx.measureText(label2).width;
              if (dx + w > RIGHT_MARGIN) ctx.textAlign = 'right';
              ctx.fillText(label2, dx, height);

              ctx.textBaseline = 'top';
              ctx.fillText(label2, dx, TEXT_Y0);

              draw_count++;
              if (draw_count > BreakDrawLimit) break;
            }
          }
        }
      }

      // Whether we aggregate selected requests or visible requests
      let isAggregateSelection = false;
      if (this.IsHighlighted()) isAggregateSelection = true;
      let numVisibleRequestsPerLine = {}; // DataLineIndex -> Count
      let numFailedRequestsPerLine = {};
      let totalSecondsPerLine = {};

      // Range of Titles that were displayed
      let title_start_idx = this.VisualLineStartIdx, title_end_idx = title_start_idx;

      const tvh = this.TotalVisualHeight();

      // This is used to handle Intervals that have overlapping entries
      let last_data_line_idx = -999;//this.VisualLineIndexToDataLineIndex(this.VisualLineStartIdx);

      // 'j' iterates over the "visual rows" that need to be displayed.
      // A "visual row" might be one of:
      // 1. a "header" line
      // 2. an actual row of data (in the Intervals variable)
      for (let j = this.VisualLineStartIdx; j < tvh; j++) {
        const tmp = this.VisualLineIndexToDataLineIndex(j);
        if (tmp == undefined) break;
        const data_line_idx = tmp[0];
        const visual_line_offset_within_data_line = tmp[1];
       
        const is_different_data_line = (data_line_idx != last_data_line_idx);
        last_data_line_idx = data_line_idx;

        if (is_different_data_line && data_line_idx != -999) { // Only draw line title and histogram per data line index not visual line index
          ctx.textBaseline = 'middle';
          ctx.textAlign = 'right';
          let desc_width = 0;
          if (NetFnCmdToDescription[this.Titles[data_line_idx].title] != undefined) {
            let desc = ' (' + NetFnCmdToDescription[this.Titles[data_line_idx].title] + ')';
            desc_width = ctx.measureText(desc).width;
            ctx.fillStyle = '#888';  // Grey
            ctx.fillText(desc, LEFT_MARGIN - 3, y);
          }


          // Plot histogram
          if (this.IsTimeDistributionEnabled == true) {
            const t = this.Titles[data_line_idx].title;
            if (GetHistoryHistogram()[t] != undefined) {
              if (this.IpmiVizHistogramImageData[t] == undefined) {
                let tmp = RenderHistogramForImageData(ctx, t);
                this.IpmiVizHistogramImageData[t] = tmp[0];
                HistogramThresholds[t] = tmp[1];
              }
              this.RenderHistogram(ctx, t, HISTOGRAM_X, y);
              ctx.textAlignment = 'right';
            } else {
            }
          }

          // If is HEADER: do not draw here, darw in do_RenderHeader()
          if (this.Titles[data_line_idx].header == false) {
            ctx.textAlignment = 'right';
            ctx.textBaseline = 'middle';
            ctx.fillStyle = '#000000';  // Revert to Black
            ctx.strokeStyle = '#000000';
            let tj_draw = this.Titles[data_line_idx].title;
            const title_disp_length_limit = this.GetTitleWidthLimit();
            if (tj_draw != undefined && tj_draw.length > title_disp_length_limit) {
              tj_draw = tj_draw.substr(0, title_disp_length_limit) + '...'
            }
            ctx.fillText(tj_draw, LEFT_MARGIN - 3 - desc_width, y);
          }
        } else if (is_different_data_line && data_line_idx == -999) {
          continue;
        }

        let numOverflowEntriesToTheLeft = 0;  // #entries below the lower bound
        let numOverflowEntriesToTheRight =
            0;                               // #entries beyond the upper bound
        let numVisibleRequestsCurrLine = 0;  // #entries visible
        let totalSecsCurrLine = 0;           // Total duration in seconds
        let numFailedRequestsCurrLine = 0;

        const intervals_idxes = this.Titles[data_line_idx].intervals_idxes;
        
        let intervals_j = undefined;
        if (intervals_idxes.length == 1) {
          intervals_j = this.Intervals[intervals_idxes[0]];
        }

        // Draw the contents in the set of intervals
        // The drawing method depends on whether this data line is a header or not
        
        // Save the context for reference for the rendering routines
        let vars = {
          "theHoveredReq": theHoveredReq,
          "theHoveredInterval": theHoveredInterval,
          "numIntersected": numIntersected,
          "numOverflowEntriesToTheLeft": numOverflowEntriesToTheLeft,
          "numOverflowEntriesToTheRight": numOverflowEntriesToTheRight,
          "currHighlightedReqs": currHighlightedReqs,
          "totalSecondsPerLine": totalSecondsPerLine,
          "highlightedInterval": highlightedInterval,
          "numVisibleRequestsCurrLine": numVisibleRequestsCurrLine,
          "totalSecsCurrLine": totalSecsCurrLine,
        }  // Emulate a reference

        let dy0 = y - LINE_HEIGHT / 2, dy1 = y + LINE_HEIGHT / 2;
        if (this.Titles[data_line_idx].header == false) {
          if (intervals_j != undefined) {
            this.do_RenderIntervals(ctx, intervals_j, j, dy0, dy1,
              data_line_idx, visual_line_offset_within_data_line, isAggregateSelection, vars);
          }
        } else {
          this.do_RenderHeader(ctx, this.Titles[data_line_idx],
            j, dy0, dy1,
            data_line_idx, visual_line_offset_within_data_line, isAggregateSelection, vars);
        }

        // Update the context variables with updated values
        theHoveredReq = vars.theHoveredReq;
        theHoveredInterval = vars.theHoveredInterval;
        numIntersected = vars.numIntersected;
        numOverflowEntriesToTheLeft = vars.numOverflowEntriesToTheLeft;
        numOverflowEntriesToTheRight = vars.numOverflowEntriesToTheRight;
        currHighlightedReqs = vars.currHighlightedReqs;
        totalSecondsPerLine = vars.totalSecondsPerLine;
        highlightedInterval = vars.highlightedInterval;
        numVisibleRequestsCurrLine = vars.numVisibleRequestsCurrLine;
        totalSecsCurrLine = vars.totalSecsCurrLine;

        // Triangle markers for entries outside of the viewport
        {
          const PAD = 2, H = LINE_SPACING;
          if (this.MouseState.hoveredVisibleLineIndex + this.VisualLineStartIdx == data_line_idx &&
              this.MouseState.hoveredSide == 'left') {
            ctx.fillStyle = '#0000FF';
          } else {
            ctx.fillStyle = 'rgba(128,128,0,0.5)';
          }
          if (numOverflowEntriesToTheLeft > 0) {
            ctx.beginPath();
            ctx.moveTo(LEFT_MARGIN + PAD + H / 2, y - H / 2);
            ctx.lineTo(LEFT_MARGIN + PAD, y);
            ctx.lineTo(LEFT_MARGIN + PAD + H / 2, y + H / 2);
            ctx.closePath();
            ctx.fill();
            ctx.textAlign = 'left';
            ctx.textBaseline = 'center';
            ctx.fillText(
                '+' + numOverflowEntriesToTheLeft,
                LEFT_MARGIN + 2 * PAD + H / 2, y);
          }

          if (this.MouseState.hoveredVisibleLineIndex + this.VisualLineStartIdx == j &&
              this.MouseState.hoveredSide == 'right') {
            ctx.fillStyle = '#0000FF';
          } else {
            ctx.fillStyle = 'rgba(128,128,0,0.5)';
          }
          if (numOverflowEntriesToTheRight > 0) {
            ctx.beginPath();
            ctx.moveTo(RIGHT_MARGIN - PAD - H / 2, y - H / 2);
            ctx.lineTo(RIGHT_MARGIN - PAD, y);
            ctx.lineTo(RIGHT_MARGIN - PAD - H / 2, y + H / 2);
            ctx.closePath();
            ctx.fill();
            ctx.textAlign = 'right';
            ctx.fillText(
                '+' + numOverflowEntriesToTheRight,
                RIGHT_MARGIN - 2 * PAD - H / 2, y);
          }
        }
        y = y + LINE_SPACING;

        numVisibleRequestsPerLine[data_line_idx] = numVisibleRequestsCurrLine;
        numFailedRequestsPerLine[data_line_idx] = numFailedRequestsCurrLine;
        totalSecondsPerLine[data_line_idx] = totalSecsCurrLine;

        title_end_idx = j;
        if (y > height) break;
      }

      {
        let nbreaks = this.TotalVisualHeight();
        // Draw a scroll bar on the left
        if (!(title_start_idx == 0 && title_end_idx == nbreaks - 1)) {

          const y0 = title_start_idx * height / nbreaks;
          const y1 = (1 + title_end_idx) * height / nbreaks;

          let highlighted = false;
          const THRESH = 8;
          if (this.MouseState.IsDraggingScrollBar()) {
            highlighted = true;
          }
          this.ScrollBarState.highlighted = highlighted;

          // If not dragging, let title_start_idx drive y0 and y1, else let the
          // user's input drive y0 and y1 and title_start_idx
          if (!this.MouseState.IsDraggingScrollBar()) {
            this.ScrollBarState.y0 = y0;
            this.ScrollBarState.y1 = y1;
          }

          if (highlighted) {
            ctx.fillStyle = "#FF3";
          } else {
            ctx.fillStyle = this.AccentColor;
          }
          ctx.fillRect(0, y0, SCROLL_BAR_WIDTH, y1 - y0);

        } else {
          this.ScrollBarState.y0 = undefined;
          this.ScrollBarState.y1 = undefined;
          this.ScrollBarState.highlighted = false;
        }
      }

      // Draw highlighted sections for the histograms
      if (this.IsTimeDistributionEnabled) {
        y = YBEGIN;
        for (let j = this.TitleStartIdx; j < this.Intervals.length; j++) {
          if (this.IpmiVizHistHighlighted[this.Titles[data_line_idx].title] != undefined) {
            let entry = HistogramThresholds[this.Titles[data_line_idx].title];
            const theSet =
                Array.from(this.IpmiVizHistHighlighted[this.Titles[data_line_idx].title]);
            for (let i = 0; i < theSet.length; i++) {
              bidx = theSet[i];
              if (entry != undefined) {
                if (bidx < entry[0][0]) {
                  if (bidx < 0) {
                    bidx = 0;
                  }
                  ctx.fillStyle = 'rgba(0, 255, 0, 0.3)';
                } else if (bidx > entry[1][0]) {
                  if (bidx > 1) {
                    bidx = 1;
                  }
                  ctx.fillStyle = 'rgba(255,0,0,0.3)';
                } else {
                  ctx.fillStyle = 'rgba(0,0,255,0.3)';
                }
              } else {
                ctx.fillStyle = 'rgba(0,0,255,0.3)';
              }
              const dx = HISTOGRAM_X - HISTOGRAM_W / 2 + HISTOGRAM_W * bidx;

              const r = HISTOGRAM_H * 0.17;
              ctx.beginPath();
              ctx.ellipse(dx, y, r, r, 0, 0, 3.14159 * 2);
              ctx.fill();
            }
          }
          y += LINE_SPACING;
        }
      }

      // Render number of visible requests versus totals
      ctx.textAlign = 'left';
      ctx.textBaseline = 'top';
      let totalOccs = 0, totalSecs = 0;
      if (this.IsHighlighted()) {
        ctx.fillStyle = '#00F';
        ctx.fillText('# / time', 3, TEXT_Y0);
        ctx.fillText('in selection', 3, TEXT_Y0 + LINE_SPACING - 2);
      } else {
        ctx.fillStyle = '#000';
        ctx.fillText('# / time', 3, TEXT_Y0);
        ctx.fillText('in viewport', 3, TEXT_Y0 + LINE_SPACING - 2);
      }

      let timeDesc = '';
      ctx.textBaseline = 'middle';
      last_data_line_idx = -999;

      for (let j = this.VisualLineStartIdx, i = 0;
               j < tvh && (YBEGIN + i*LINE_SPACING)<height; j++, i++) {
        const x = this.VisualLineIndexToDataLineIndex(j);
        if (x == undefined) break;
        const data_line_idx = x[0];
        if (data_line_idx == undefined) break;
        if (data_line_idx != last_data_line_idx) {
          let y1 = YBEGIN + LINE_SPACING * (i);
          let totalSeconds = totalSecondsPerLine[data_line_idx];
          if (totalSeconds < 1) {
            timeDesc = (totalSeconds * 1000.0).toFixed(toFixedPrecision) + 'ms';
          } else {
            timeDesc = totalSeconds.toFixed(toFixedPrecision) + 's';
          }

          const n0 = numVisibleRequestsPerLine[data_line_idx];
          const n1 = numFailedRequestsPerLine[data_line_idx];
          let txt = '';
          if (n1 > 0) {
            txt = '' + n0 + '+' + n1 + ' / ' + timeDesc;
          } else {
            txt = '' + n0 + ' / ' + timeDesc;
          }

          const tw = ctx.measureText(txt).width;
          const PAD = 8;

          ctx.fillStyle = '#000';
          ctx.fillText(txt, 3, y1);
          totalOccs += numVisibleRequestsPerLine[data_line_idx];
          totalSecs += totalSeconds;
        }
        last_data_line_idx = data_line_idx;
      }

      // This does not get displayed correctly, so disabling for now
      //timeDesc = '';
      //if (totalSecs < 1) {
      //  timeDesc = '' + (totalSecs * 1000).toFixed(toFixedPrecision) + 'ms';
      //} else {
      //  timeDesc = '' + totalSecs.toFixed(toFixedPrecision) + 's';
      //}

      //ctx.fillText('Sum:', 3, y + 2 * LINE_SPACING);
      //ctx.fillText('' + totalOccs + ' / ' + timeDesc, 3, y + 3 * LINE_SPACING);

      // Update highlighted requests
      if (this.IsHighlightDirty) {
        this.HighlightedRequests = currHighlightedReqs;
        this.IsHighlightDirty = false;

        // Todo: This callback will be different for the DBus pane
        OnHighlightedChanged(HighlightedRequests);
      }

      // Render highlight statistics
      if (this.IsHighlighted()) {
        ctx.fillStyle = 'rgba(128,128,255,0.5)';
        let x0 = MapXCoord(
            t0, LEFT_MARGIN, RIGHT_MARGIN, this.LowerBoundTime,
            this.UpperBoundTime);
        let x1 = MapXCoord(
            t1, LEFT_MARGIN, RIGHT_MARGIN, this.LowerBoundTime,
            this.UpperBoundTime);
        ctx.fillRect(x0, 0, x1 - x0, height);

        let label0 = '' + t0.toFixed(toFixedPrecision) + 's';
        let label1 = '' + t1.toFixed(toFixedPrecision) + 's';
        let width0 = ctx.measureText(label0).width;
        let width1 = ctx.measureText(label1).width;
        let dispWidth = x1 - x0;
        // Draw time marks outside or inside?
        ctx.fillStyle = '#0000FF';
        ctx.textBaseline = 'top';
        if (dispWidth > width0 + width1) {
          ctx.textAlign = 'left';
          ctx.fillText(label0, x0, LINE_SPACING + TEXT_Y0);
          ctx.textAlign = 'right';
          ctx.fillText(label1, x1, LINE_SPACING + TEXT_Y0);
        } else {
          ctx.textAlign = 'right';
          ctx.fillText(label0, x0, LINE_SPACING + TEXT_Y0);
          ctx.textAlign = 'left';
          ctx.fillText(label1, x1, LINE_SPACING + TEXT_Y0);
        }

        // This was calculated earlier
        ctx.textAlign = 'center';
        label1 = 'Duration: ' + (t1 - t0).toFixed(toFixedPrecision) + 's';
        ctx.fillText(label1, (x0 + x1) / 2, height - LINE_SPACING * 2);
      }

      // Hovering cursor
      // Only draw when the mouse is not over any hotizontal scroll bar
      let should_hide_cursor = false;

      if (this.MouseState.hoveredSide == "top_horizontal_scrollbar" ||
          this.MouseState.hoveredSide == "bottom_horizontal_scrollbar") {
        should_hide_cursor = true;
      }
      this.linked_views.forEach((v) => {
        if (v.MouseState.hoveredSide == "top_horizontal_scrollbar" ||
            v.MouseState.hoveredSide == "bottom_horizontal_scrollbar") {
          should_hide_cursor = true;
        }
      })

      if (this.MouseState.hovered == true &&
          this.MouseState.hoveredSide == undefined &&
          should_hide_cursor == false) {
        ctx.beginPath();
        ctx.strokeStyle = '#0000FF';
        ctx.lineWidth = 1;
        if (this.IsHighlighted()) {
          ctx.moveTo(this.MouseState.x, 0);
          ctx.lineTo(this.MouseState.x, height);
        } else {
          ctx.moveTo(this.MouseState.x, LINE_SPACING * 2);
          ctx.lineTo(this.MouseState.x, height - LINE_SPACING * 2);
        }
        ctx.stroke();

        if (this.IsHighlighted() == false) {
          let dispWidth = this.MouseState.x - LEFT_MARGIN;
          let label = '' +
              this.MouseXToTimestamp(this.MouseState.x)
                  .toFixed(toFixedPrecision) +
              's';
          let width0 = ctx.measureText(label).width;
          ctx.fillStyle = '#0000FF';
          ctx.textBaseline = 'bottom';
          ctx.textAlign = 'center';
          ctx.fillText(label, this.MouseState.x, height - LINE_SPACING);
          ctx.textBaseline = 'top';
          ctx.fillText(label, this.MouseState.x, LINE_SPACING + TEXT_Y0);
        }
      }

      // Tooltip box next to hovered entry
      if (theHoveredReq !== undefined) {
        this.RenderToolTip(
            ctx, theHoveredReq, theHoveredInterval, toFixedPrecision, height);
      }
    }  // End IsCanvasDirty
  }
};

// The extended classes have their own way of drawing popups for hovered entries
class IPMITimelineView extends TimelineView {
  RenderToolTip(
      ctx, theHoveredReq, theHoveredInterval, toFixedPrecision, height) {
    if (theHoveredReq == undefined) {
      return;
    }
    const PAD = 2, DELTA_Y = 14;

    let labels = [];
    let netFn = theHoveredReq[0];
    let cmd = theHoveredReq[1];
    let t0 = theHoveredInterval[0];
    let t1 = theHoveredInterval[1];

    labels.push('Netfn and CMD : (' + netFn + ', ' + cmd + ')');
    let key = netFn + ', ' + cmd;

    if (NetFnCmdToDescription[key] != undefined) {
      labels.push('Description   : ' + NetFnCmdToDescription[key]);
    }

    if (theHoveredReq.offset != undefined) {
      labels.push('Offset      : ' + theHoveredReq.offset);
    }

    let req = theHoveredReq[4];
    labels.push('Request Data  : ' + req.length + ' bytes');
    if (req.length > 0) {
      labels.push('Hex   : ' + ToHexString(req, '', ' '));
      labels.push('ASCII : ' + ToASCIIString(req));
    }
    let resp = theHoveredReq[5];
    labels.push('Response Data : ' + theHoveredReq[5].length + ' bytes');
    if (resp.length > 0) {
      labels.push('Hex   : ' + ToHexString(resp, '', ' '));
      labels.push('ASCII : ' + ToASCIIString(resp));
    }
    labels.push('Start         : ' + t0.toFixed(toFixedPrecision) + 's');
    labels.push('End           : ' + t1.toFixed(toFixedPrecision) + 's');
    labels.push('Duration      : ' + ((t1 - t0) * 1000).toFixed(3) + 'ms');


    let w = 1, h = LINE_SPACING * labels.length + 2 * PAD;
    for (let i = 0; i < labels.length; i++) {
      w = Math.max(w, ctx.measureText(labels[i]).width);
    }
    let dy = this.MouseState.y + DELTA_Y;
    if (dy + h > height) {
      dy = height - h;
    }
    let dx = this.MouseState.x;
    if (RIGHT_MARGIN - dx < w) dx -= (w + 2 * PAD);

    ctx.fillStyle = 'rgba(0,0,0,0.5)';
    ctx.fillRect(dx, dy, w + 2 * PAD, h);

    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';
    ctx.fillStyle = '#FFFFFF';
    for (let i = 0; i < labels.length; i++) {
      ctx.fillText(
          labels[i], dx + PAD, dy + PAD + i * LINE_SPACING + LINE_SPACING / 2);
    }
  }
};

class DBusTimelineView extends TimelineView {
  RenderToolTip(
      ctx, theHoveredReq, theHoveredInterval, toFixedPrecision, height) {
    if (theHoveredReq == undefined) {
      return;
    }
    const PAD = 2, DELTA_Y = 14;

    let labels = [];
    let msg_type = theHoveredReq[0];
    let serial = theHoveredReq[2];
    let sender = theHoveredReq[3];
    let destination = theHoveredReq[4];
    let path = theHoveredReq[5];
    let iface = theHoveredReq[6];
    let member = theHoveredReq[7];

    let t0 = theHoveredInterval[0];
    let t1 = theHoveredInterval[1];

    labels.push('Message type: ' + msg_type);
    labels.push('Serial      : ' + serial);
    labels.push('Sender      : ' + sender);
    labels.push('Destination : ' + destination);
    labels.push('Path        : ' + path);
    labels.push('Interface   : ' + iface);
    labels.push('Member      : ' + member);

    let w = 1, h = LINE_SPACING * labels.length + 2 * PAD;
    for (let i = 0; i < labels.length; i++) {
      w = Math.max(w, ctx.measureText(labels[i]).width);
    }
    let dy = this.MouseState.y + DELTA_Y;
    if (dy + h > height) {
      dy = height - h;
    }
    let dx = this.MouseState.x;
    if (RIGHT_MARGIN - dx < w) dx -= (w + 2 * PAD);

    ctx.fillStyle = 'rgba(0,0,0,0.5)';
    ctx.fillRect(dx, dy, w + 2 * PAD, h);

    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';
    ctx.fillStyle = '#FFFFFF';
    for (let i = 0; i < labels.length; i++) {
      ctx.fillText(
          labels[i], dx + PAD, dy + PAD + i * LINE_SPACING + LINE_SPACING / 2);
    }
  }
};

class BoostASIOHandlerTimelineView extends TimelineView {
  RenderToolTip(
      ctx, theHoveredReq, theHoveredInterval, toFixedPrecision, height) {
    if (theHoveredReq == undefined) {
      return;
    }
    const PAD = 2, DELTA_Y = 14;

    let labels = [];
    let create_time = theHoveredReq[2];
    let enter_time = theHoveredReq[3];
    let exit_time = theHoveredReq[4];
    let desc = theHoveredReq[5];

    let t0 = theHoveredInterval[0];
    let t1 = theHoveredInterval[1];

    labels.push('Creation time: ' + create_time);
    labels.push('Entry time   : ' + enter_time);
    labels.push('Exit time    : ' + exit_time);
    labels.push('Creation->Entry : ' + (enter_time - create_time));
    labels.push('Entry->Exit     : ' + (exit_time - enter_time));
    labels.push('Description  : ' + desc);

    let w = 1, h = LINE_SPACING * labels.length + 2 * PAD;
    for (let i = 0; i < labels.length; i++) {
      w = Math.max(w, ctx.measureText(labels[i]).width);
    }
    let dy = this.MouseState.y + DELTA_Y;
    if (dy + h > height) {
      dy = height - h;
    }
    let dx = this.MouseState.x;
    if (RIGHT_MARGIN - dx < w) dx -= (w + 2 * PAD);

    ctx.fillStyle = 'rgba(0,0,0,0.5)';
    ctx.fillRect(dx, dy, w + 2 * PAD, h);

    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';
    ctx.fillStyle = '#FFFFFF';
    for (let i = 0; i < labels.length; i++) {
      ctx.fillText(
          labels[i], dx + PAD, dy + PAD + i * LINE_SPACING + LINE_SPACING / 2);
    }
  }
}
