<!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/base/units/time_duration.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_viewport.html">
<link rel="import" href="/tracing/ui/timeline_display_transform_animations.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">

<!--
  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.b.u.TimeDuration.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>
