<!DOCTYPE html>
<!--
Copyright (c) 2012 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="stylesheet" href="/base/ui/common.css">
<link rel="stylesheet" href="/core/timeline_track_view.css">

<link rel="import" href="/base/events.html">
<link rel="import" href="/base/properties.html">
<link rel="import" href="/base/settings.html">
<link rel="import" href="/base/task.html">
<link rel="import" href="/base/ui.html">
<link rel="import" href="/base/ui/mouse_mode_selector.html">
<link rel="import" href="/core/filter.html">
<link rel="import" href="/core/selection.html">
<link rel="import" href="/core/timeline_viewport.html">
<link rel="import" href="/core/timeline_display_transform_animations.html">
<link rel="import" href="/core/timing_tool.html">
<link rel="import" href="/core/trace_model/event.html">
<link rel="import" href="/core/trace_model/x_marker_annotation.html">
<link rel="import" href="/core/tracks/drawing_container.html">
<link rel="import" href="/core/tracks/trace_model_track.html">
<link rel="import" href="/core/tracks/ruler_track.html">

<script>
'use strict';

/**
 * @fileoverview Interactive visualizaiton of TraceModel objects
 * based loosely on gantt charts. Each thread in the TraceModel is given a
 * set of Tracks, one per subrow in the thread. The TimelineTrackView class
 * acts as a controller, creating the individual tracks, while Tracks
 * do actual drawing.
 *
 * Visually, the TimelineTrackView produces (prettier) visualizations like the
 * following:
 *    Thread1:  AAAAAAAAAA         AAAAA
 *                  BBBB              BB
 *    Thread2:     CCCCCC                 CCCCC
 *
 */
tv.exportTo('tv.c', function() {
  var Selection = tv.c.Selection;
  var SelectionState = tv.c.trace_model.SelectionState;
  var Viewport = tv.c.TimelineViewport;

  var tempDisplayTransform = new tv.c.TimelineDisplayTransform();

  function intersectRect_(r1, r2) {
    var results = new Object;
    if (r2.left > r1.right || r2.right < r1.left ||
        r2.top > r1.bottom || r2.bottom < r1.top) {
      return false;
    }
    results.left = Math.max(r1.left, r2.left);
    results.top = Math.max(r1.top, r2.top);
    results.right = Math.min(r1.right, r2.right);
    results.bottom = Math.min(r1.bottom, r2.bottom);
    results.width = (results.right - results.left);
    results.height = (results.bottom - results.top);
    return results;
  }

  /**
   * Renders a TraceModel into a div element, making one
   * Track for each subrow in each thread of the model, managing
   * overall track layout, and handling user interaction with the
   * viewport.
   *
   * @constructor
   * @extends {HTMLDivElement}
   */
  var TimelineTrackView = tv.b.ui.define('div');

  TimelineTrackView.prototype = {
    __proto__: HTMLDivElement.prototype,

    model_: null,

    decorate: function(timelineView) {

      this.classList.add('timeline-track-view');

      this.timelineView_ = timelineView;

      this.viewport_ = new Viewport(this);
      this.viewportDisplayTransformAtMouseDown_ = null;
      this.selectionController_ = undefined;

      this.rulerTrackContainer_ =
          new tv.c.tracks.DrawingContainer(this.viewport_);
      this.appendChild(this.rulerTrackContainer_);
      this.rulerTrackContainer_.invalidate();

      this.rulerTrack_ = new tv.c.tracks.RulerTrack(this.viewport_);
      this.rulerTrackContainer_.appendChild(this.rulerTrack_);

      this.upperModelTrack_ = new tv.c.tracks.TraceModelTrack(this.viewport_);
      this.upperModelTrack_.upperMode = true;
      this.rulerTrackContainer_.appendChild(this.upperModelTrack_);

      this.modelTrackContainer_ =
          new tv.c.tracks.DrawingContainer(this.viewport_);
      this.appendChild(this.modelTrackContainer_);
      this.modelTrackContainer_.style.display = 'block';
      this.modelTrackContainer_.invalidate();

      this.viewport_.modelTrackContainer = this.modelTrackContainer_;

      this.modelTrack_ = new tv.c.tracks.TraceModelTrack(this.viewport_);
      this.modelTrackContainer_.appendChild(this.modelTrack_);

      this.timingTool_ = new tv.c.TimingTool(this.viewport_,
                                                this);

      this.initMouseModeSelector();

      this.dragBox_ = this.ownerDocument.createElement('div');
      this.dragBox_.className = 'drag-box';
      this.appendChild(this.dragBox_);
      this.hideDragBox_();

      this.initHintText_();

      this.onSelectionChanged_ = this.onSelectionChanged_.bind(this);

      this.bindEventListener_(document, 'keypress', this.onKeypress_, this);
      this.bindEventListener_(document, 'keydown', this.onKeydown_, this);
      this.bindEventListener_(document, 'keyup', this.onKeyup_, this);

      this.bindEventListener_(this, 'dblclick', this.onDblClick_, this);
      this.bindEventListener_(this, 'mousewheel', this.onMouseWheel_, this);
      this.bindEventListener_(this, 'mousedown', this.onMouseDown_, this);

      this.addEventListener('mousemove', this.onMouseMove_);

      this.addEventListener('touchstart', this.onTouchStart_);
      this.addEventListener('touchmove', this.onTouchMove_);
      this.addEventListener('touchend', this.onTouchEnd_);

      this.mouseViewPosAtMouseDown_ = {x: 0, y: 0};
      this.lastMouseViewPos_ = {x: 0, y: 0};

      this.lastTouchViewPositions_ = [];

      this.alert_ = undefined;

      this.isPanningAndScanning_ = false;
      this.isZooming_ = false;
    },

    /**
     * Wraps the standard addEventListener but automatically binds the provided
     * func to the provided target, tracking the resulting closure. When detach
     * is called, these listeners will be automatically removed.
     */
    bindEventListener_: function(object, event, func, target) {
      if (!this.boundListeners_)
        this.boundListeners_ = [];
      var boundFunc = func.bind(target);
      this.boundListeners_.push({object: object,
        event: event,
        boundFunc: boundFunc});
      object.addEventListener(event, boundFunc);
    },

    initMouseModeSelector: function() {
      this.mouseModeSelector_ = new tv.b.ui.MouseModeSelector(this);
      this.appendChild(this.mouseModeSelector_);

      this.mouseModeSelector_.addEventListener('beginpan',
          this.onBeginPanScan_.bind(this));
      this.mouseModeSelector_.addEventListener('updatepan',
          this.onUpdatePanScan_.bind(this));
      this.mouseModeSelector_.addEventListener('endpan',
          this.onEndPanScan_.bind(this));

      this.mouseModeSelector_.addEventListener('beginselection',
          this.onBeginSelection_.bind(this));
      this.mouseModeSelector_.addEventListener('updateselection',
          this.onUpdateSelection_.bind(this));
      this.mouseModeSelector_.addEventListener('endselection',
          this.onEndSelection_.bind(this));

      this.mouseModeSelector_.addEventListener('beginzoom',
          this.onBeginZoom_.bind(this));
      this.mouseModeSelector_.addEventListener('updatezoom',
          this.onUpdateZoom_.bind(this));
      this.mouseModeSelector_.addEventListener('endzoom',
          this.onEndZoom_.bind(this));

      this.mouseModeSelector_.addEventListener('entertiming',
          this.timingTool_.onEnterTiming.bind(this.timingTool_));
      this.mouseModeSelector_.addEventListener('begintiming',
          this.timingTool_.onBeginTiming.bind(this.timingTool_));
      this.mouseModeSelector_.addEventListener('updatetiming',
          this.timingTool_.onUpdateTiming.bind(this.timingTool_));
      this.mouseModeSelector_.addEventListener('endtiming',
          this.timingTool_.onEndTiming.bind(this.timingTool_));
      this.mouseModeSelector_.addEventListener('exittiming',
          this.timingTool_.onExitTiming.bind(this.timingTool_));

      var m = tv.b.ui.MOUSE_SELECTOR_MODE;
      this.mouseModeSelector_.supportedModeMask =
          m.SELECTION | m.PANSCAN | m.ZOOM | m.TIMING;
      this.mouseModeSelector_.settingsKey =
          'timelineTrackView.mouseModeSelector';
      this.mouseModeSelector_.setKeyCodeForMode(m.PANSCAN, '2'.charCodeAt(0));
      this.mouseModeSelector_.setKeyCodeForMode(m.SELECTION, '1'.charCodeAt(0));
      this.mouseModeSelector_.setKeyCodeForMode(m.ZOOM, '3'.charCodeAt(0));
      this.mouseModeSelector_.setKeyCodeForMode(m.TIMING, '4'.charCodeAt(0));

      this.mouseModeSelector_.setKeyCodeCondition(function() {
        // Return false when FindControl is active so that MouseMode keyboard
        // shortcuts are ignored.
        return this.listenToKeys_;
      }.bind(this));

      this.mouseModeSelector_.setModifierForAlternateMode(
          m.SELECTION, tv.b.ui.MODIFIER.SHIFT);
      this.mouseModeSelector_.setModifierForAlternateMode(
          m.PANSCAN, tv.b.ui.MODIFIER.SPACE);
      this.mouseModeSelector_.setModifierForAlternateMode(
          m.ZOOM, tv.b.ui.MODIFIER.CMD_OR_CTRL);
    },

    get selectionController() {
      return this.selectionController_;
    },

    set selectionController(selectionController) {
      if (this.selectionController_) {
        this.selectionController_.removeEventListener('change',
                                                      this.onSelectionChanged_);
      }
      this.selectionController_ = selectionController;
      if (this.selectionController_) {
        this.selectionController_.addEventListener('change',
                                                   this.onSelectionChanged_);
      }
    },

    onSelectionChanged_: function() {
      this.showHintText_('Press \'m\' to mark current selection');
      this.viewport_.dispatchChangeEvent();
    },

    set selection(selection) {
      throw new Error('DO NOT CALL THIS');
    },

    set highlight(highlight) {
      throw new Error('DO NOT CALL THIS');
    },

    detach: function() {
      this.modelTrack_.detach();
      this.upperModelTrack_.detach();

      for (var i = 0; i < this.boundListeners_.length; i++) {
        var binding = this.boundListeners_[i];
        binding.object.removeEventListener(binding.event, binding.boundFunc);
      }
      this.boundListeners_ = undefined;
      this.viewport_.detach();
    },

    get viewport() {
      return this.viewport_;
    },

    get model() {
      return this.model_;
    },

    set model(model) {
      if (!model)
        throw new Error('Model cannot be null');

      var modelInstanceChanged = this.model_ !== model;
      this.model_ = model;
      this.modelTrack_.model = model;
      this.upperModelTrack_.model = model;

      // Set up a reasonable viewport.
      if (modelInstanceChanged)
        this.viewport_.setWhenPossible(this.setInitialViewport_.bind(this));

      tv.b.setPropertyAndDispatchChange(this, 'model', model);
    },

    get hasVisibleContent() {
      return this.modelTrack_.hasVisibleContent ||
          this.upperModelTrack_.hasVisibleContent;
    },

    setInitialViewport_: function() {
      // We need the canvas size to be up-to-date at this point. We maybe in
      // here before the raf fires, so the size may have not been updated since
      // the canvas was resized.
      this.modelTrackContainer_.updateCanvasSizeIfNeeded_();
      var w = this.modelTrackContainer_.canvas.width;

      var min;
      var range;

      if (this.model_.bounds.isEmpty) {
        min = 0;
        range = 1000;
      } else if (this.model_.bounds.range === 0) {
        min = this.model_.bounds.min;
        range = 1000;
      } else {
        min = this.model_.bounds.min;
        range = this.model_.bounds.range;
      }

      var boost = range * 0.15;
      tempDisplayTransform.set(this.viewport_.currentDisplayTransform);
      tempDisplayTransform.xSetWorldBounds(min - boost,
                                           min + range + boost,
                                           w);
      this.viewport_.setDisplayTransformImmediately(tempDisplayTransform);
    },

    /**
     * @param {Filter} filter The filter to use for finding matches.
     * @param {Selection} selection The selection to add matches to.
     * @return {Task} which performs the filtering.
     */
    addAllEventsMatchingFilterToSelectionAsTask: function(filter, selection) {
      var modelTrack = this.modelTrack_;
      var firstT = modelTrack.addAllEventsMatchingFilterToSelectionAsTask(
          filter, selection);
      var lastT = firstT.after(function() {
        this.upperModelTrack_.addAllEventsMatchingFilterToSelection(
          filter, selection);

      }, this);
      return firstT;
    },

    /**
     * @return {Element} The element whose focused state determines
     * whether to respond to keyboard inputs.
     * Defaults to the parent element.
     */
    get focusElement() {
      if (this.focusElement_)
        return this.focusElement_;
      return this.parentElement;
    },

    /**
     * Sets the element whose focus state will determine whether
     * to respond to keyboard input.
     */
    set focusElement(value) {
      this.focusElement_ = value;
    },

    get listenToKeys_() {
      if (!this.viewport_.isAttachedToDocumentOrInTestMode)
        return false;
      if (document.activeElement instanceof TracingFindControl)
        return false;
      if (document.activeElement instanceof TracingScriptingControl)
        return false;
      if (!this.focusElement_)
        return true;
      if (this.focusElement.tabIndex >= 0) {
        if (document.activeElement == this.focusElement)
          return true;
        return tv.b.ui.elementIsChildOf(document.activeElement,
                                        this.focusElement);
      }
      return true;
    },

    onMouseMove_: function(e) {

      // Zooming requires the delta since the last mousemove so we need to avoid
      // tracking it when the zoom interaction is active.
      if (this.isZooming_)
        return;

      this.storeLastMousePos_(e);
    },

    onTouchStart_: function(e) {
      this.storeLastTouchPositions_(e);
      this.focusElements_();
    },

    onTouchMove_: function(e) {
      e.preventDefault();
      this.onUpdateTransformForTouch_(e);
    },

    onTouchEnd_: function(e) {
      this.storeLastTouchPositions_(e);
      this.focusElements_();
    },

    onKeypress_: function(e) {
      var vp = this.viewport_;
      if (!this.listenToKeys_)
        return;
      if (document.activeElement.nodeName == 'INPUT')
        return;
      var viewWidth = this.modelTrackContainer_.canvas.clientWidth;
      var curMouseV, curCenterW;
      switch (e.keyCode) {

        case 119:  // w
        case 44:   // ,
          this.zoomBy_(1.5, true);
          break;
        case 115:  // s
        case 111:  // o
          this.zoomBy_(1 / 1.5, true);
          break;
        case 103:  // g
          this.onGridToggle_(true);
          break;
        case 71:  // G
          this.onGridToggle_(false);
          break;
        case 87:  // W
        case 60:  // <
          this.zoomBy_(10, true);
          break;
        case 83:  // S
        case 79:  // O
          this.zoomBy_(1 / 10, true);
          break;
        case 97:  // a
          this.queueSmoothPan_(viewWidth * 0.3, 0);
          break;
        case 100:  // d
        case 101:  // e
          this.queueSmoothPan_(viewWidth * -0.3, 0);
          break;
        case 65:  // A
          this.queueSmoothPan_(viewWidth * 0.5, 0);
          break;
        case 68:  // D
          this.queueSmoothPan_(viewWidth * -0.5, 0);
          break;
        case 48:  // 0
          this.setInitialViewport_();
          break;
        case 102:  // f
          this.zoomToSelection();
          break;
        case 'm'.charCodeAt(0):
          this.setCurrentSelectionAsInterestRange_();
          break;
        case 104:  // h
          this.toggleHighDetails_();
          break;
      }
    },

    // Not all keys send a keypress.
    onKeydown_: function(e) {
      if (!this.listenToKeys_)
        return;
      var sel;
      var vp = this.viewport_;
      var viewWidth = this.modelTrackContainer_.canvas.clientWidth;

      switch (e.keyCode) {
        case 37:   // left arrow
          sel = this.selectionController_.selection.getShiftedSelection(
              this.viewport, -1);

          if (sel) {
            this.selectionController.changeSelectionFromTimeline(sel);
            this.panToSelection();
            e.preventDefault();
          } else {
            this.queueSmoothPan_(viewWidth * 0.3, 0);
          }
          break;
        case 39:   // right arrow
          sel = this.selectionController_.selection.getShiftedSelection(
              this.viewport, 1);
          if (sel) {
            this.selectionController.changeSelectionFromTimeline(sel);
            this.panToSelection();
            e.preventDefault();
          } else {
            this.queueSmoothPan_(-viewWidth * 0.3, 0);
          }
          break;
        case 9:    // TAB
          if (this.focusElement.tabIndex == -1) {
            if (e.shiftKey)
              this.selectPrevious_(e);
            else
              this.selectNext_(e);
            e.preventDefault();
          }
          break;
      }
    },

    onKeyup_: function(e) {
      if (!this.listenToKeys_)
        return;
      if (!e.shiftKey) {
        if (this.dragBeginEvent_) {
          this.setDragBoxPosition_(this.dragBoxXStart_, this.dragBoxYStart_,
              this.dragBoxXEnd_, this.dragBoxYEnd_);
        }
      }

    },

    onDblClick_: function(e) {
      if (this.mouseModeSelector_.mode !==
          tv.b.ui.MOUSE_SELECTOR_MODE.SELECTION)
        return;

      var curSelection = this.selectionController_.selection;
      if (!curSelection.length || !curSelection[0].title)
        return;

      var selection = new Selection();
      var filter = new tv.c.ExactTitleFilter(curSelection[0].title);
      this.modelTrack_.addAllEventsMatchingFilterToSelection(filter,
                                                              selection);

      this.selectionController.changeSelectionFromTimeline(selection);
    },

    onMouseWheel_: function(e) {
      if (!e.altKey)
        return;

      var delta = e.wheelDelta / 120;
      var zoomScale = Math.pow(1.5, delta);
      this.zoomBy_(zoomScale);
      e.preventDefault();
    },

    onMouseDown_: function(e) {
      if (this.mouseModeSelector_.mode !==
          tv.b.ui.MOUSE_SELECTOR_MODE.SELECTION)
        return;
      // Mouse down must start on ruler track for crosshair guide lines to draw.
      if (e.target !== this.rulerTrack_)
        return;

      // Make sure we don't start a selection drag event here.
      this.dragBeginEvent_ = undefined;

      // Remove nav string marker if it exists, since we're clearing the
      // find control box.
      if (this.xNavStringMarker_) {
        this.model.removeAnnotation(this.xNavStringMarker_);
        this.xNavStringMarker_ = undefined;
      }

      var dt = this.viewport_.currentDisplayTransform;
      tv.b.ui.trackMouseMovesUntilMouseUp(function(e) { // Mouse move handler.
        // If mouse event is on ruler, don't do anything.
        if (e.target === this.rulerTrack_)
          return;

        var relativePosition = this.extractRelativeMousePosition_(e);
        var loc = tv.c.Location.fromViewCoordinates(
            this.viewport_, relativePosition.x, relativePosition.y);
        // Not all points on the timeline represents a valid location.
        // ex. process header tracks, letter dot tracks.
        if (!loc)
          return;

        if (this.guideLineAnnotation_ === undefined) {
          this.guideLineAnnotation_ =
              new tv.c.trace_model.XMarkerAnnotation(loc.xWorld);
          this.model.addAnnotation(this.guideLineAnnotation_);
        } else {
          this.guideLineAnnotation_.timestamp = loc.xWorld;
          this.modelTrackContainer_.invalidate();
        }

        // Set the findcontrol's text to nav string of current state.
        var state = new tv.c.UIState(loc,
            this.viewport_.currentDisplayTransform.scaleX);
        this.timelineView_.setFindCtlText(
            state.toUserFriendlyString(this.viewport_));
      }.bind(this));
    },

    queueSmoothPan_: function(viewDeltaX, deltaY) {
      var deltaX = this.viewport_.currentDisplayTransform.xViewVectorToWorld(
          viewDeltaX);
      var animation = new tv.c.TimelineDisplayTransformPanAnimation(
          deltaX, deltaY);
      this.viewport_.queueDisplayTransformAnimation(animation);
    },

    /**
     * Zoom in or out on the timeline by the given scale factor.
     * @param {Number} scale The scale factor to apply.  If <1, zooms out.
     * @param {boolean} Whether to change the zoom level smoothly.
     */
    zoomBy_: function(scale, smooth) {
      if (scale <= 0) {
        return;
      }

      smooth = !!smooth;
      var vp = this.viewport_;
      var viewWidth = this.modelTrackContainer_.canvas.clientWidth;
      var pixelRatio = window.devicePixelRatio || 1;

      var goalFocalPointXView = this.lastMouseViewPos_.x * pixelRatio;
      var goalFocalPointXWorld = vp.currentDisplayTransform.xViewToWorld(
          goalFocalPointXView);
      if (smooth) {
        var animation = new tv.c.TimelineDisplayTransformZoomToAnimation(
            goalFocalPointXWorld, goalFocalPointXView,
            vp.currentDisplayTransform.panY,
            scale);
        vp.queueDisplayTransformAnimation(animation);
      } else {
        tempDisplayTransform.set(vp.currentDisplayTransform);
        tempDisplayTransform.scaleX = tempDisplayTransform.scaleX * scale;
        tempDisplayTransform.xPanWorldPosToViewPos(
            goalFocalPointXWorld, goalFocalPointXView, viewWidth);
        vp.setDisplayTransformImmediately(tempDisplayTransform);
      }
    },

    /**
     * Zoom into the current selection.
     */
    zoomToSelection: function() {
      if (!this.selectionController.selectionOfInterest.length)
        return;

      var bounds = this.selectionController.selectionOfInterest.bounds;
      if (!bounds.range)
        return;

      var worldCenter = bounds.center;
      var viewCenter = this.modelTrackContainer_.canvas.width / 2;
      var adjustedWorldRange = bounds.range * 1.25;
      var newScale = this.modelTrackContainer_.canvas.width /
          adjustedWorldRange;
      var zoomInRatio = newScale /
          this.viewport_.currentDisplayTransform.scaleX;

      var animation = new tv.c.TimelineDisplayTransformZoomToAnimation(
          worldCenter, viewCenter,
          this.viewport_.currentDisplayTransform.panY,
          zoomInRatio);
      this.viewport_.queueDisplayTransformAnimation(animation);
    },

    /**
     * Pan the view so the current selection becomes visible.
     */
    panToSelection: function() {
      if (!this.selectionController.selectionOfInterest.length)
        return;

      var bounds = this.selectionController.selectionOfInterest.bounds;
      var worldCenter = bounds.center;
      var viewWidth = this.modelTrackContainer_.canvas.width;

      var dt = this.viewport_.currentDisplayTransform;
      if (false && !bounds.range) {
        if (dt.xWorldToView(bounds.center) < 0 ||
            dt.xWorldToView(bounds.center) > viewWidth) {
          tempDisplayTransform.set(dt);
          tempDisplayTransform.xPanWorldPosToViewPos(
              worldCenter, 'center', viewWidth);
          var deltaX = tempDisplayTransform.panX - dt.panX;
          var animation = new tv.c.TimelineDisplayTransformPanAnimation(
              deltaX, 0);
          this.viewport_.queueDisplayTransformAnimation(animation);
        }
        return;
      }

      tempDisplayTransform.set(dt);
      tempDisplayTransform.xPanWorldBoundsIntoView(
          bounds.min,
          bounds.max,
          viewWidth);
      var deltaX = tempDisplayTransform.panX - dt.panX;
      var animation = new tv.c.TimelineDisplayTransformPanAnimation(
          deltaX, 0);
      this.viewport_.queueDisplayTransformAnimation(animation);
    },

    navToPosition: function(uiState, showNavLine) {
      var location = uiState.location;
      var scaleX = uiState.scaleX;
      var track = location.getContainingTrack(this.viewport_);

      var worldCenter = location.xWorld;
      var viewCenter = this.modelTrackContainer_.canvas.width / 5;
      var zoomInRatio = scaleX /
          this.viewport_.currentDisplayTransform.scaleX;

      // Vertically scroll so track is in view.
      track.scrollIntoViewIfNeeded();

      // Perform zoom and panX animation.
      var animation = new tv.c.TimelineDisplayTransformZoomToAnimation(
          worldCenter, viewCenter,
          this.viewport_.currentDisplayTransform.panY,
          zoomInRatio);
      this.viewport_.queueDisplayTransformAnimation(animation);

      if (!showNavLine)
        return;
      // Add an X Marker Annotation at the specified timestamp.
      if (this.xNavStringMarker_)
        this.model.removeAnnotation(this.xNavStringMarker_);
      this.xNavStringMarker_ =
          new tv.c.trace_model.XMarkerAnnotation(worldCenter);
      this.model.addAnnotation(this.xNavStringMarker_);
    },

    setCurrentSelectionAsInterestRange_: function() {
      var selectionBounds = this.selectionController_.selection.bounds;
      if (selectionBounds.empty) {
        this.viewport_.interestRange.reset();
        return;
      }

      if (this.viewport_.interestRange.min == selectionBounds.min &&
          this.viewport_.interestRange.max == selectionBounds.max)
        this.viewport_.interestRange.reset();
      else
        this.viewport_.interestRange.set(selectionBounds);
    },

    toggleHighDetails_: function() {
      this.viewport_.highDetails = !this.viewport_.highDetails;
    },

    hideDragBox_: function() {
      this.dragBox_.style.left = '-1000px';
      this.dragBox_.style.top = '-1000px';
      this.dragBox_.style.width = 0;
      this.dragBox_.style.height = 0;
    },

    setDragBoxPosition_: function(xStart, yStart, xEnd, yEnd) {
      var loY = Math.min(yStart, yEnd);
      var hiY = Math.max(yStart, yEnd);
      var loX = Math.min(xStart, xEnd);
      var hiX = Math.max(xStart, xEnd);
      var modelTrackRect = this.modelTrack_.getBoundingClientRect();
      var dragRect = {left: loX, top: loY, width: hiX - loX, height: hiY - loY};

      dragRect.right = dragRect.left + dragRect.width;
      dragRect.bottom = dragRect.top + dragRect.height;

      var modelTrackContainerRect =
          this.modelTrackContainer_.getBoundingClientRect();
      var clipRect = {
        left: modelTrackContainerRect.left,
        top: modelTrackContainerRect.top,
        right: modelTrackContainerRect.right,
        bottom: modelTrackContainerRect.bottom
      };

      var headingWidth = window.getComputedStyle(
          this.querySelector('heading')).width;
      var trackTitleWidth = parseInt(headingWidth);
      clipRect.left = clipRect.left + trackTitleWidth;

      var finalDragBox = intersectRect_(clipRect, dragRect);

      this.dragBox_.style.left = finalDragBox.left + 'px';
      this.dragBox_.style.width = finalDragBox.width + 'px';
      this.dragBox_.style.top = finalDragBox.top + 'px';
      this.dragBox_.style.height = finalDragBox.height + 'px';
      this.dragBox_.style.whiteSpace = 'nowrap';

      var pixelRatio = window.devicePixelRatio || 1;
      var canv = this.modelTrackContainer_.canvas;
      var dt = this.viewport_.currentDisplayTransform;
      var loWX = dt.xViewToWorld(
          (loX - canv.offsetLeft) * pixelRatio);
      var hiWX = dt.xViewToWorld(
          (hiX - canv.offsetLeft) * pixelRatio);

      this.dragBox_.textContent = tv.c.analysis.tsString((hiWX - loWX));

      var e = new tv.b.Event('selectionChanging');
      e.loWX = loWX;
      e.hiWX = hiWX;
      this.dispatchEvent(e);
    },

    onGridToggle_: function(left) {
      var selection = this.selectionController_.selection;
      var tb = left ? selection.bounds.min : selection.bounds.max;

      // Toggle the grid off if the grid is on, the marker position is the same
      // and the same element is selected (same timebase).
      if (this.viewport_.gridEnabled &&
          this.viewport_.gridSide === left &&
          this.viewport_.gridInitialTimebase === tb) {
        this.viewport_.gridside = undefined;
        this.viewport_.gridEnabled = false;
        this.viewport_.gridInitialTimebase = undefined;
        return;
      }

      // Shift the timebase left until its just left of model_.bounds.min.
      var numIntervalsSinceStart = Math.ceil((tb - this.model_.bounds.min) /
          this.viewport_.gridStep_);

      this.viewport_.gridEnabled = true;
      this.viewport_.gridSide = left;
      this.viewport_.gridInitialTimebase = tb;
      this.viewport_.gridTimebase = tb -
          (numIntervalsSinceStart + 1) * this.viewport_.gridStep_;
    },

    storeLastMousePos_: function(e) {
      this.lastMouseViewPos_ = this.extractRelativeMousePosition_(e);
    },

    storeLastTouchPositions_: function(e) {
      this.lastTouchViewPositions_ = this.extractRelativeTouchPositions_(e);
    },

    extractRelativeMousePosition_: function(e) {
      var canv = this.modelTrackContainer_.canvas;
      return {
        x: e.clientX - canv.offsetLeft,
        y: e.clientY - canv.offsetTop
      };
    },

    extractRelativeTouchPositions_: function(e) {
      var canv = this.modelTrackContainer_.canvas;

      var touches = [];
      for (var i = 0; i < e.touches.length; ++i) {
        touches.push({
          x: e.touches[i].clientX - canv.offsetLeft,
          y: e.touches[i].clientY - canv.offsetTop
        });
      }
      return touches;
    },

    storeInitialMouseDownPos_: function(e) {

      var position = this.extractRelativeMousePosition_(e);

      this.mouseViewPosAtMouseDown_.x = position.x;
      this.mouseViewPosAtMouseDown_.y = position.y;
    },

    focusElements_: function() {
      if (document.activeElement)
        document.activeElement.blur();
      if (this.focusElement.tabIndex >= 0)
        this.focusElement.focus();
    },

    storeInitialInteractionPositionsAndFocus_: function(e) {

      this.storeInitialMouseDownPos_(e);
      this.storeLastMousePos_(e);

      this.focusElements_();
    },

    onBeginPanScan_: function(e) {
      var vp = this.viewport_;
      this.viewportDisplayTransformAtMouseDown_ =
          vp.currentDisplayTransform.clone();
      this.isPanningAndScanning_ = true;

      this.storeInitialInteractionPositionsAndFocus_(e);
      e.preventDefault();
    },

    onUpdatePanScan_: function(e) {
      if (!this.isPanningAndScanning_)
        return;

      var viewWidth = this.modelTrackContainer_.canvas.clientWidth;

      var pixelRatio = window.devicePixelRatio || 1;
      var xDeltaView = pixelRatio * (this.lastMouseViewPos_.x -
          this.mouseViewPosAtMouseDown_.x);

      var yDelta = this.lastMouseViewPos_.y -
          this.mouseViewPosAtMouseDown_.y;

      tempDisplayTransform.set(this.viewportDisplayTransformAtMouseDown_);
      tempDisplayTransform.incrementPanXInViewUnits(xDeltaView);
      tempDisplayTransform.panY -= yDelta;
      this.viewport_.setDisplayTransformImmediately(tempDisplayTransform);

      e.preventDefault();
      e.stopPropagation();

      this.storeLastMousePos_(e);
    },

    onEndPanScan_: function(e) {
      this.isPanningAndScanning_ = false;

      this.storeLastMousePos_(e);

      if (!e.isClick)
        e.preventDefault();
    },

    onBeginSelection_: function(e) {
      var canv = this.modelTrackContainer_.canvas;
      var rect = this.modelTrack_.getBoundingClientRect();
      var canvRect = canv.getBoundingClientRect();

      var inside = rect &&
          e.clientX >= rect.left &&
          e.clientX < rect.right &&
          e.clientY >= rect.top &&
          e.clientY < rect.bottom &&
          e.clientX >= canvRect.left &&
          e.clientX < canvRect.right;

      if (!inside)
        return;

      this.dragBeginEvent_ = e;

      this.storeInitialInteractionPositionsAndFocus_(e);
      e.preventDefault();
    },

    onUpdateSelection_: function(e) {
      if (!this.dragBeginEvent_)
        return;

      // Update the drag box
      this.dragBoxXStart_ = this.dragBeginEvent_.clientX;
      this.dragBoxXEnd_ = e.clientX;
      this.dragBoxYStart_ = this.dragBeginEvent_.clientY;
      this.dragBoxYEnd_ = e.clientY;
      this.setDragBoxPosition_(this.dragBoxXStart_, this.dragBoxYStart_,
          this.dragBoxXEnd_, this.dragBoxYEnd_);

    },

    onEndSelection_: function(e) {
      e.preventDefault();

      if (!this.dragBeginEvent_)
        return;

      // Stop the dragging.
      this.hideDragBox_();
      var eDown = this.dragBeginEvent_;
      this.dragBeginEvent_ = null;

      // Figure out extents of the drag.
      var loY = Math.min(eDown.clientY, e.clientY);
      var hiY = Math.max(eDown.clientY, e.clientY);
      var loX = Math.min(eDown.clientX, e.clientX);
      var hiX = Math.max(eDown.clientX, e.clientX);

      // Convert to worldspace.
      var canv = this.modelTrackContainer_.canvas;
      var worldOffset = canv.getBoundingClientRect().left;
      var loVX = loX - worldOffset;
      var hiVX = hiX - worldOffset;

      // Figure out what has been selected.
      var selection = new Selection();
      this.modelTrack_.addIntersectingEventsInRangeToSelection(
          loVX, hiVX, loY, hiY, selection);

      // Activate the new selection.
      this.selectionController_.changeSelectionFromTimeline(selection);
    },

    onBeginZoom_: function(e) {
      this.isZooming_ = true;

      this.storeInitialInteractionPositionsAndFocus_(e);
      e.preventDefault();
    },

    onUpdateZoom_: function(e) {
      if (!this.isZooming_)
        return;
      var newPosition = this.extractRelativeMousePosition_(e);

      var zoomScaleValue = 1 + (this.lastMouseViewPos_.y -
          newPosition.y) * 0.01;

      this.zoomBy_(zoomScaleValue, false);
      this.storeLastMousePos_(e);
    },

    onEndZoom_: function(e) {
      this.isZooming_ = false;

      if (!e.isClick)
        e.preventDefault();
    },

    computeTouchCenter_: function(positions) {
      var xSum = 0;
      var ySum = 0;
      for (var i = 0; i < positions.length; ++i) {
        xSum += positions[i].x;
        ySum += positions[i].y;
      }
      return {
        x: xSum / positions.length,
        y: ySum / positions.length
      };
    },

    computeTouchSpan_: function(positions) {
      var xMin = Number.MAX_VALUE;
      var yMin = Number.MAX_VALUE;
      var xMax = Number.MIN_VALUE;
      var yMax = Number.MIN_VALUE;
      for (var i = 0; i < positions.length; ++i) {
        xMin = Math.min(xMin, positions[i].x);
        yMin = Math.min(yMin, positions[i].y);
        xMax = Math.max(xMax, positions[i].x);
        yMax = Math.max(yMax, positions[i].y);
      }
      return Math.sqrt((xMin - xMax) * (xMin - xMax) +
          (yMin - yMax) * (yMin - yMax));
    },

    onUpdateTransformForTouch_: function(e) {
      var newPositions = this.extractRelativeTouchPositions_(e);
      var currentPositions = this.lastTouchViewPositions_;

      var newCenter = this.computeTouchCenter_(newPositions);
      var currentCenter = this.computeTouchCenter_(currentPositions);

      var newSpan = this.computeTouchSpan_(newPositions);
      var currentSpan = this.computeTouchSpan_(currentPositions);

      var vp = this.viewport_;
      var viewWidth = this.modelTrackContainer_.canvas.clientWidth;
      var pixelRatio = window.devicePixelRatio || 1;

      var xDelta = pixelRatio * (newCenter.x - currentCenter.x);
      var yDelta = newCenter.y - currentCenter.y;
      var zoomScaleValue = currentSpan > 10 ? newSpan / currentSpan : 1;

      var viewFocus = pixelRatio * newCenter.x;
      var worldFocus = vp.currentDisplayTransform.xViewToWorld(viewFocus);

      tempDisplayTransform.set(vp.currentDisplayTransform);
      tempDisplayTransform.scaleX *= zoomScaleValue;
      tempDisplayTransform.xPanWorldPosToViewPos(
          worldFocus, viewFocus, viewWidth);
      tempDisplayTransform.incrementPanXInViewUnits(xDelta);
      tempDisplayTransform.panY -= yDelta;
      vp.setDisplayTransformImmediately(tempDisplayTransform);
      this.storeLastTouchPositions_(e);
    },

    initHintText_: function() {
      this.hintTextBox_ = this.ownerDocument.createElement('div');
      this.hintTextBox_.className = 'hint-text';
      this.hintTextBox_.style.display = 'none';
      this.appendChild(this.hintTextBox_);

      this.pendingHintTextClearTimeout_ = undefined;
    },

    showHintText_: function(text) {
      if (this.pendingHintTextClearTimeout_) {
        window.clearTimeout(this.pendingHintTextClearTimeout_);
        this.pendingHintTextClearTimeout_ = undefined;
      }
      this.pendingHintTextClearTimeout_ = setTimeout(
          this.hideHintText_.bind(this), 1000);
      this.hintTextBox_.textContent = text;
      this.hintTextBox_.style.display = '';
    },

    hideHintText_: function() {
      this.pendingHintTextClearTimeout_ = undefined;
      this.hintTextBox_.style.display = 'none';
    }
  };

  return {
    TimelineTrackView: TimelineTrackView
  };
});
</script>
