<!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="import" href="/tracing/base/event.html">
<link rel="import" href="/tracing/base/settings.html">
<link rel="import" href="/tracing/base/task.html">
<link rel="import" href="/tracing/core/filter.html">
<link rel="import" href="/tracing/model/event.html">
<link rel="import" href="/tracing/model/event_set.html">
<link rel="import" href="/tracing/model/x_marker_annotation.html">
<link rel="import" href="/tracing/ui/base/hotkey_controller.html">
<link rel="import" href="/tracing/ui/base/mouse_mode_selector.html">
<link rel="import" href="/tracing/ui/base/timing_tool.html">
<link rel="import" href="/tracing/ui/base/ui.html">
<link rel="import" href="/tracing/ui/timeline_display_transform_animations.html">
<link rel="import" href="/tracing/ui/timeline_viewport.html">
<link rel="import" href="/tracing/ui/tracks/drawing_container.html">
<link rel="import" href="/tracing/ui/tracks/model_track.html">
<link rel="import" href="/tracing/ui/tracks/ruler_track.html">
<link rel="import" href="/tracing/value/unit.html">

<!--
  Interactive visualizaiton of Model objects based loosely on gantt charts.
  Each thread in the Model 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
-->
<polymer-element name='tr-ui-timeline-track-view'>
  <template>
    <style>
    :host {
      -webkit-box-orient: vertical;
      display: -webkit-box;
      position: relative;
    }

    :host ::content * {
      -webkit-user-select: none;
      cursor: default;
    }

    #drag_box {
      background-color: rgba(0, 0, 255, 0.25);
      border: 1px solid rgb(0, 0, 96);
      font-size: 75%;
      position: fixed;
    }

    #hint_text {
      position: absolute;
      bottom: 6px;
      right: 6px;
      font-size: 8pt;
    }
    </style>
    <content></content>

    <div id='drag_box'></div>
    <div id='hint_text'></div>

    <tv-ui-b-hotkey-controller id='hotkey_controller'>
    </tv-ui-b-hotkey-controller>
  </template>

  <script>
  'use strict';

  Polymer({
    ready: function() {
      this.displayTransform_ = new tr.ui.TimelineDisplayTransform();
      this.model_ = undefined;

      this.timelineView_ = undefined;

      this.viewport_ = new tr.ui.TimelineViewport(this);
      this.viewportDisplayTransformAtMouseDown_ = undefined;
      this.brushingStateController_ = undefined;

      this.rulerTrackContainer_ =
          new tr.ui.tracks.DrawingContainer(this.viewport_);
      this.appendChild(this.rulerTrackContainer_);
      this.rulerTrackContainer_.invalidate();

      this.rulerTrack_ = new tr.ui.tracks.RulerTrack(this.viewport_);
      this.rulerTrackContainer_.appendChild(this.rulerTrack_);

      this.upperModelTrack_ = new tr.ui.tracks.ModelTrack(this.viewport_);
      this.upperModelTrack_.upperMode = true;
      this.rulerTrackContainer_.appendChild(this.upperModelTrack_);

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

      this.viewport_.modelTrackContainer = this.modelTrackContainer_;

      this.modelTrack_ = new tr.ui.tracks.ModelTrack(this.viewport_);
      this.modelTrackContainer_.appendChild(this.modelTrack_);

      this.timingTool_ = new tr.ui.b.TimingTool(this.viewport_, this);

      this.initMouseModeSelector();

      this.hideDragBox_();

      this.initHintText_();

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

      this.onDblClick_ = this.onDblClick_.bind(this);
      this.addEventListener('dblclick', this.onDblClick_);

      this.onMouseWheel_ = this.onMouseWheel_.bind(this);
      this.addEventListener('mousewheel', this.onMouseWheel_);

      this.onMouseDown_ = this.onMouseDown_.bind(this);
      this.addEventListener('mousedown', this.onMouseDown_);

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

      this.onTouchStart_ = this.onTouchStart_.bind(this);
      this.addEventListener('touchstart', this.onTouchStart_);

      this.onTouchMove_ = this.onTouchMove_.bind(this);
      this.addEventListener('touchmove', this.onTouchMove_);

      this.onTouchEnd_ = this.onTouchEnd_.bind(this);
      this.addEventListener('touchend', this.onTouchEnd_);


      this.addHotKeys_();

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

      this.lastTouchViewPositions_ = [];

      this.alert_ = undefined;

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

    initMouseModeSelector: function() {
      this.mouseModeSelector_ = document.createElement(
          'tr-ui-b-mouse-mode-selector');
      this.mouseModeSelector_.targetElement = 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 = tr.ui.b.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_.setModifierForAlternateMode(
          m.SELECTION, tr.ui.b.MODIFIER.SHIFT);
      this.mouseModeSelector_.setModifierForAlternateMode(
          m.PANSCAN, tr.ui.b.MODIFIER.SPACE);
    },

    get brushingStateController() {
      return this.brushingStateController_;
    },

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

    set timelineView(view) {
      this.timelineView_ = view;
    },

    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();

      this.viewport_.detach();
    },

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

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

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

      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));
    },

    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;
      this.displayTransform_.set(this.viewport_.currentDisplayTransform);
      this.displayTransform_.xSetWorldBounds(
          min - boost, min + range + boost, w);
      this.viewport_.setDisplayTransformImmediately(this.displayTransform_);
    },

    /**
     * @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;
    },

    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_();
    },

    addHotKeys_: function() {
      this.addKeyDownHotKeys_();
      this.addKeyPressHotKeys_();
    },

    addKeyPressHotKeys_: function() {
      var addBinding = function(dict) {
        dict.eventType = 'keypress';
        dict.useCapture = false;
        dict.thisArg = this;
        var binding = new tr.ui.b.HotKey(dict);
        this.$.hotkey_controller.addHotKey(binding);
      }.bind(this);

      addBinding({
        keyCodes: ['w'.charCodeAt(0), ','.charCodeAt(0)],
        callback: function(e) {
          this.zoomBy_(1.5, true);
          e.stopPropagation();
        }
      });

      addBinding({
        keyCodes: ['s'.charCodeAt(0), 'o'.charCodeAt(0)],
        callback: function(e) {
          this.zoomBy_(1 / 1.5, true);
          e.stopPropagation();
        }
      });

      addBinding({
        keyCode: 'g'.charCodeAt(0),
        callback: function(e) {
          this.onGridToggle_(true);
          e.stopPropagation();
        }
      });

      addBinding({
        keyCode: 'G'.charCodeAt(0),
        callback: function(e) {
          this.onGridToggle_(false);
          e.stopPropagation();
        }
      });

      addBinding({
        keyCodes: ['W'.charCodeAt(0), '<'.charCodeAt(0)],
        callback: function(e) {
          this.zoomBy_(10, true);
          e.stopPropagation();
        }
      });

      addBinding({
        keyCodes: ['S'.charCodeAt(0), 'O'.charCodeAt(0)],
        callback: function(e) {
          this.zoomBy_(1 / 10, true);
          e.stopPropagation();
        }
      });

      addBinding({
        keyCode: 'a'.charCodeAt(0),
        callback: function(e) {
          this.queueSmoothPan_(this.viewWidth_ * 0.3, 0);
          e.stopPropagation();
        }
      });

      addBinding({
        keyCodes: ['d'.charCodeAt(0), 'e'.charCodeAt(0)],
        callback: function(e) {
          this.queueSmoothPan_(this.viewWidth_ * -0.3, 0);
          e.stopPropagation();
        }
      });

      addBinding({
        keyCode: 'A'.charCodeAt(0),
        callback: function(e) {
          this.queueSmoothPan_(viewWidth * 0.5, 0);
          e.stopPropagation();
        }
      });

      addBinding({
        keyCode: 'D'.charCodeAt(0),
        callback: function(e) {
          this.queueSmoothPan_(viewWidth * -0.5, 0);
          e.stopPropagation();
        }
      });

      addBinding({
        keyCode: '0'.charCodeAt(0),
        callback: function(e) {
          this.setInitialViewport_();
          e.stopPropagation();
        }
      });

      addBinding({
        keyCode: 'f'.charCodeAt(0),
        callback: function(e) {
          this.zoomToSelection();
          e.stopPropagation();
        }
      });

      addBinding({
        keyCode: 'm'.charCodeAt(0),
        callback: function(e) {
          this.setCurrentSelectionAsInterestRange_();
          e.stopPropagation();
        }
      });

      addBinding({
        keyCode: 'h'.charCodeAt(0),
        callback: function(e) {
          this.toggleHighDetails_();
          e.stopPropagation();
        }
      });
    },

    get viewWidth_() {
      return this.modelTrackContainer_.canvas.clientWidth;
    },

    addKeyDownHotKeys_: function() {
      var addBinding = function(dict) {
        dict.eventType = 'keydown';
        dict.useCapture = false;
        dict.thisArg = this;
        var binding = new tr.ui.b.HotKey(dict);
        this.$.hotkey_controller.addHotKey(binding);
      }.bind(this);

      addBinding({
        keyCode: 37, // Left arrow.
        callback: function(e) {
          var curSel = this.brushingStateController_.selection;
          var sel = this.viewport.getShiftedSelection(curSel, -1);

          if (sel) {
            this.brushingStateController.changeSelectionFromTimeline(sel);
            this.panToSelection();
          } else {
            this.queueSmoothPan_(this.viewWidth_ * 0.3, 0);
          }
          e.preventDefault();
          e.stopPropagation();
        }
      });

      addBinding({
        keyCode: 39, // Right arrow.
        callback: function(e) {
          var curSel = this.brushingStateController_.selection;
          var sel = this.viewport.getShiftedSelection(curSel, 1);
          if (sel) {
            this.brushingStateController.changeSelectionFromTimeline(sel);
            this.panToSelection();
          } else {
            this.queueSmoothPan_(-this.viewWidth_ * 0.3, 0);
          }
          e.preventDefault();
          e.stopPropagation();
        }
      });
    },

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

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

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

      this.brushingStateController.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 !==
          tr.ui.b.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;
      tr.ui.b.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 = tr.model.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 tr.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 tr.ui.b.UIState(loc,
            this.viewport_.currentDisplayTransform.scaleX);
        this.timelineView_.setFindCtlText(
            state.toUserFriendlyString(this.viewport_));
      }.bind(this),
      undefined, // Mouse up handler.
      function onKeyUpDuringDrag() {
        if (this.dragBeginEvent_) {
          this.setDragBoxPosition_(this.dragBoxXStart_, this.dragBoxYStart_,
              this.dragBoxXEnd_, this.dragBoxYEnd_);
        }
      }.bind(this));
    },

    queueSmoothPan_: function(viewDeltaX, deltaY) {
      var deltaX = this.viewport_.currentDisplayTransform.xViewVectorToWorld(
          viewDeltaX);
      var animation = new tr.ui.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 pixelRatio = window.devicePixelRatio || 1;

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

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

      var bounds = this.brushingStateController.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 tr.ui.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.brushingStateController.selectionOfInterest.length)
        return;

      var bounds = this.brushingStateController.selectionOfInterest.bounds;
      var worldCenter = bounds.center;
      var viewWidth = this.viewWidth_;

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

      this.displayTransform_.set(dt);
      this.displayTransform_.xPanWorldBoundsIntoView(
          bounds.min,
          bounds.max,
          viewWidth);
      var deltaX = this.displayTransform_.panX - dt.panX;
      var animation = new tr.ui.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 tr.ui.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 tr.model.XMarkerAnnotation(worldCenter);
      this.model.addAnnotation(this.xNavStringMarker_);
    },

    setCurrentSelectionAsInterestRange_: function() {
      var selectionBounds = this.brushingStateController_.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.$.drag_box.style.left = '-1000px';
      this.$.drag_box.style.top = '-1000px';
      this.$.drag_box.style.width = 0;
      this.$.drag_box.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('tr-ui-heading')).width;
      var trackTitleWidth = parseInt(headingWidth);
      clipRect.left = clipRect.left + trackTitleWidth;

      var intersectRect_ = function(r1, r2) {
        if (r2.left > r1.right || r2.right < r1.left ||
            r2.top > r1.bottom || r2.bottom < r1.top)
          return false;

        var results = {};
        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;
      };

      // TODO(dsinclair): intersectRect_ can return false (which should actually
      // be undefined) but we use finalDragBox without checking the return value
      // which could potentially blowup. Fix this .....
      var finalDragBox = intersectRect_(clipRect, dragRect);

      this.$.drag_box.style.left = finalDragBox.left + 'px';
      this.$.drag_box.style.width = finalDragBox.width + 'px';
      this.$.drag_box.style.top = finalDragBox.top + 'px';
      this.$.drag_box.style.height = finalDragBox.height + 'px';
      this.$.drag_box.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.$.drag_box.textContent =
          tr.v.Unit.byName.timeDurationInMs.format(hiWX - loWX);

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

    onGridToggle_: function(left) {
      var selection = this.brushingStateController_.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() {
      this.$.hotkey_controller.childRequestsGeneralFocus(this);
    },

    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.viewWidth_;

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

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

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

      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_ = undefined;

      // 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 tr.model.EventSet();
      if (eDown.appendSelection) {
        var previousSelection = this.brushingStateController_.selection;
        if (previousSelection !== undefined)
          selection.addEventSet(previousSelection);
      }
      this.modelTrack_.addIntersectingEventsInRangeToSelection(
          loVX, hiVX, loY, hiY, selection);

      // Activate the new selection.
      this.brushingStateController_.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.viewWidth_;
      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);

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

    initHintText_: function() {
      this.$.hint_text.style.display = 'none';

      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.$.hint_text.textContent = text;
      this.$.hint_text.style.display = '';
    },

    hideHintText_: function() {
      this.pendingHintTextClearTimeout_ = undefined;
      this.$.hint_text.style.display = 'none';
    }
  });
  </script>
</polymer-element>
