// 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.

'use strict';

/**
 * @fileoverview 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
 *
 */
base.requireStylesheet('timeline_track_view');
base.require('event_target');
base.require('measuring_stick');
base.require('filter');
base.require('selection');
base.require('timeline_viewport');
base.require('tracks.model_track');
base.require('tracks.ruler_track');
base.require('ui');

base.exportTo('tracing', function() {

  var Selection = tracing.Selection;
  var Viewport = tracing.TimelineViewport;

  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 Model 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 = tracing.ui.define('div');

  TimelineTrackView.prototype = {
    __proto__: HTMLDivElement.prototype,

    model_: null,

    decorate: function() {
      this.classList.add('timeline-track-view');

      this.categoryFilter_ = new tracing.CategoryFilter();

      this.viewport_ = new Viewport(this);

      // Add the viewport track.
      this.rulerTrack_ = new tracing.tracks.RulerTrack();
      this.rulerTrack_.viewport = this.viewport_;
      this.appendChild(this.rulerTrack_);

      this.modelTrackContainer_ = document.createElement('div');
      this.modelTrackContainer_.className = 'model-track-container';
      this.appendChild(this.modelTrackContainer_);

      this.modelTrack_ = new tracing.tracks.ModelTrack();
      this.modelTrackContainer_.appendChild(this.modelTrack_);

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

      this.bindEventListener_(document, 'keypress', this.onKeypress_, this);
      this.bindEventListener_(document, 'keydown', this.onKeydown_, this);
      this.bindEventListener_(document, 'keyup', this.onKeyup_, this);
      this.bindEventListener_(document, 'mousemove', this.onMouseMove_, this);
      this.bindEventListener_(document, 'mouseup', this.onMouseUp_, this);

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

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

      this.selection_ = new Selection();
    },

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

    detach: function() {
      this.modelTrack_.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 categoryFilter() {
      return this.categoryFilter_;
    },

    set categoryFilter(filter) {
      this.categoryFilter_ = filter;
      this.modelTrack_.categoryFilter = filter;
    },

    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.modelTrack_.viewport = this.viewport_;
      this.modelTrack_.categoryFilter = this.categoryFilter;
      this.rulerTrack_.headingWidth = this.modelTrack_.headingWidth;

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

    get numVisibleTracks() {
      return this.modelTrack_.numVisibleTracks;
    },

    setInitialViewport_: function() {
      var w = this.firstCanvas.width;
      var boost =
          (this.model_.bounds.max - this.model_.bounds.min) * 0.15;
      this.viewport_.xSetWorldBounds(this.model_.bounds.min - boost,
                                    this.model_.bounds.max + boost,
                                    w);
    },

    /**
     * @param {Filter} filter The filter to use for finding matches.
     * @param {Selection} selection The selection to add matches to.
     * @return {Array} An array of objects that match the provided
     * TitleFilter.
     */
    addAllObjectsMatchingFilterToSelection: function(filter, selection) {
      this.modelTrack_.addAllObjectsMatchingFilterToSelection(filter,
                                                              selection);
    },

    /**
     * @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 keybaord input.
     */
    set focusElement(value) {
      this.focusElement_ = value;
    },

    get listenToKeys_() {
      if (!this.viewport_.isAttachedToDocument_)
        return false;
      if (this.activeElement instanceof tracing.FindControl)
        return false;
      if (!this.focusElement_)
        return true;
      if (this.focusElement.tabIndex >= 0)
        return document.activeElement == this.focusElement;
      return true;
    },

    onKeypress_: function(e) {
      var vp = this.viewport_;
      if (!this.firstCanvas)
        return;
      if (!this.listenToKeys_)
        return;
      if (document.activeElement.nodeName == 'INPUT')
        return;
      var viewWidth = this.firstCanvas.clientWidth;
      var curMouseV, curCenterW;
      switch (e.keyCode) {
        case 119:  // w
        case 44:   // ,
          this.zoomBy_(1.5);
          break;
        case 115:  // s
        case 111:  // o
          this.zoomBy_(1 / 1.5);
          break;
        case 103:  // g
          this.onGridToggle_(true);
          break;
        case 71:  // G
          this.onGridToggle_(false);
          break;
        case 87:  // W
        case 60:  // <
          this.zoomBy_(10);
          break;
        case 83:  // S
        case 79:  // O
          this.zoomBy_(1 / 10);
          break;
        case 97:  // a
          vp.panX += vp.xViewVectorToWorld(viewWidth * 0.1);
          break;
        case 100:  // d
        case 101:  // e
          vp.panX -= vp.xViewVectorToWorld(viewWidth * 0.1);
          break;
        case 65:  // A
          vp.panX += vp.xViewVectorToWorld(viewWidth * 0.5);
          break;
        case 68:  // D
          vp.panX -= vp.xViewVectorToWorld(viewWidth * 0.5);
          break;
        case 48:  // 0
        case 122: // z
          this.setInitialViewport_();
          break;
        case 102:  // f
          this.zoomToSelection_();
          break;
      }
    },

    onMouseWheel_: function(e) {
      if (e.altKey) {
        var delta = e.wheelDeltaY / 120;
        var zoomScale = Math.pow(1.5, delta);
        this.zoomBy_(zoomScale);
        e.preventDefault();
      }
    },

    // Not all keys send a keypress.
    onKeydown_: function(e) {
      if (!this.listenToKeys_)
        return;
      var sel;
      var vp = this.viewport_;
      var viewWidth = this.firstCanvas.clientWidth;
      switch (e.keyCode) {
        case 37:   // left arrow
          sel = this.selection.getShiftedSelection(-1);
          if (sel) {
            this.setSelectionAndMakeVisible(sel);
            e.preventDefault();
          } else {
            if (!this.firstCanvas)
              return;
            vp.panX += vp.xViewVectorToWorld(viewWidth * 0.1);
          }
          break;
        case 39:   // right arrow
          sel = this.selection.getShiftedSelection(1);
          if (sel) {
            this.setSelectionAndMakeVisible(sel);
            e.preventDefault();
          } else {
            if (!this.firstCanvas)
              return;
            vp.panX -= vp.xViewVectorToWorld(viewWidth * 0.1);
          }
          break;
        case 9:    // TAB
          if (this.focusElement.tabIndex == -1) {
            if (e.shiftKey)
              this.selectPrevious_(e);
            else
              this.selectNext_(e);
            e.preventDefault();
          }
          break;
      }
      if (e.shiftKey && this.dragBeginEvent_) {
          var vertical = e.shiftKey;
          if (this.dragBeginEvent_) {
            this.setDragBoxPosition_(this.dragBoxXStart_, this.dragBoxYStart_,
                               this.dragBoxXEnd_, this.dragBoxYEnd_, vertical);
          }
      }
    },

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

    /**
     * Zoom in or out on the timeline by the given scale factor.
     * @param {integer} scale The scale factor to apply.  If <1, zooms out.
     */
    zoomBy_: function(scale) {
      if (!this.firstCanvas)
        return;
      var vp = this.viewport_;
      var viewWidth = this.firstCanvas.clientWidth;
      var pixelRatio = window.devicePixelRatio || 1;
      var curMouseV = this.lastMouseViewPos_.x * pixelRatio;
      var curCenterW = vp.xViewToWorld(curMouseV);
      vp.scaleX = vp.scaleX * scale;
      vp.xPanWorldPosToViewPos(curCenterW, curMouseV, viewWidth);
    },

    /**
     * Zoom into the current selection.
     */
    zoomToSelection_: function() {
      if (!this.selection)
        return;
      var bounds = this.selection.bounds;
      var worldCenter = bounds.min + (bounds.max - bounds.min) * 0.5;
      var worldBounds = (bounds.max - bounds.min) * 0.5;
      var boost = worldBounds * 0.15;
      this.viewport_.xSetWorldBounds(worldCenter - worldBounds - boost,
                                    worldCenter + worldBounds + boost,
                                    this.firstCanvas.width);
    },

    get keyHelp() {
      var mod = navigator.platform.indexOf('Mac') == 0 ? 'cmd' : 'ctrl';
      var help = 'Qwerty Controls\n' +
          ' w/s           : Zoom in/out    (with shift: go faster)\n' +
          ' a/d           : Pan left/right\n\n' +
          'Dvorak Controls\n' +
          ' ,/o           : Zoom in/out     (with shift: go faster)\n' +
          ' a/e           : Pan left/right\n\n' +
          'Mouse Controls\n' +
          ' drag          : Select slices   (with ' + mod +
                                                        ': zoom to slices)\n' +
          ' drag + shift  : Select all slices vertically\n\n';

      if (this.focusElement.tabIndex) {
        help +=
          ' <-            : Select previous event on current timeline\n' +
          ' ->            : Select next event on current timeline\n';
      } else {
        help += 'General Navigation\n' +
          ' g/General     : Shows grid at the start/end of the selected' +
                                                                  ' task\n' +
          ' <-,^TAB       : Select previous event on current timeline\n' +
          ' ->, TAB       : Select next event on current timeline\n';
      }
      help +=
          '\n' +
          'Alt + Scroll to zoom in/out\n' +
          'Dbl-click to zoom in; Shift dbl-click to zoom out\n' +
          'f to zoom into selection\n' +
          'z to reset zoom and pan to initial view\n';
      return help;
    },

    get selection() {
      return this.selection_;
    },

    set selection(selection) {
      if (!(selection instanceof Selection))
        throw new Error('Expected Selection');

      // Clear old selection.
      var i;
      for (i = 0; i < this.selection_.length; i++)
        this.selection_[i].selected = false;

      this.selection_ = selection;

      base.dispatchSimpleEvent(this, 'selectionChange');
      for (i = 0; i < this.selection_.length; i++)
        this.selection_[i].selected = true;
      this.viewport_.dispatchChangeEvent(); // Triggers a redraw.
    },

    setSelectionAndMakeVisible: function(selection, zoomAllowed) {
      if (!(selection instanceof Selection))
        throw new Error('Expected Selection');
      this.selection = selection;
      var bounds = this.selection.bounds;
      var size = this.viewport_.xWorldVectorToView(bounds.max - bounds.min);
      if (zoomAllowed && size < 50) {
        var worldCenter = bounds.min + (bounds.max - bounds.min) * 0.5;
        var worldBounds = (bounds.max - bounds.min) * 5;
        this.viewport_.xSetWorldBounds(worldCenter - worldBounds * 0.5,
                                      worldCenter + worldBounds * 0.5,
                                      this.firstCanvas.width);
        return;
      }

      this.viewport_.xPanWorldBoundsIntoView(bounds.min, bounds.max,
                                            this.firstCanvas.width);
    },

    get firstCanvas() {
      if (this.rulerTrack_)
        return this.rulerTrack_.firstCanvas;
      if (this.modelTrack_)
        return this.modelTrack_.firstCanvas;
      return undefined;
    },

    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, vertical) {
      var loY;
      var hiY;
      var loX = Math.min(xStart, xEnd);
      var hiX = Math.max(xStart, xEnd);
      var modelTrackRect = this.modelTrack_.getBoundingClientRect();

      if (vertical) {
        loY = modelTrackRect.top;
        hiY = modelTrackRect.bottom;
      } else {
        loY = Math.min(yStart, yEnd);
        hiY = Math.max(yStart, yEnd);
      }

      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 trackTitleWidth = parseInt(this.modelTrack_.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';

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

      var roundedDuration = Math.round((hiWX - loWX) * 100) / 100;
      this.dragBox_.textContent = roundedDuration + 'ms';

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

    onGridToggle_: function(left) {
      var tb;
      if (left)
        tb = this.selection_.bounds.min;
      else
        tb = this.selection_.bounds.max;

      // Shift the timebase left until its just left of model_.bounds.min.
      var numInterfvalsSinceStart = Math.ceil((tb - this.model_.bounds.min) /
          this.viewport_.gridStep_);
      this.viewport_.gridTimebase = tb -
          (numInterfvalsSinceStart + 1) * this.viewport_.gridStep_;
      this.viewport_.gridEnabled = true;
    },

    isChildOfThis_: function(el) {
      if (el == this)
        return;

      var isChildOfThis = false;
      var cur = el;
      while (cur.parentNode) {
        if (cur == this)
          return true;
        cur = cur.parentNode;
      }
      return false;
    },

    onMouseDown_: function(e) {
      if (e.button !== 0)
        return;

      if (e.shiftKey) {
        this.rulerTrack_.placeAndBeginDraggingMarker(e.clientX);
        return;
      }

      var canv = this.firstCanvas;
      var rect = this.modelTrack_.getBoundingClientRect();
      var canvRect = this.firstCanvas.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;

      var pos = {
        x: e.clientX - canv.offsetLeft,
        y: e.clientY - canv.offsetTop
      };

      var wX = this.viewport_.xViewToWorld(pos.x);

      this.dragBeginEvent_ = e;
      e.preventDefault();
      if (document.activeElement)
        document.activeElement.blur();
      if (this.focusElement.tabIndex >= 0)
        this.focusElement.focus();
    },

    onMouseMove_: function(e) {
      if (!this.firstCanvas)
        return;
      var canv = this.firstCanvas;
      var pos = {
        x: e.clientX - canv.offsetLeft,
        y: e.clientY - canv.offsetTop
      };

      // Remember position. Used during keyboard zooming.
      this.lastMouseViewPos_ = pos;

      // Update the drag box
      if (this.dragBeginEvent_) {
        this.dragBoxXStart_ = this.dragBeginEvent_.clientX;
        this.dragBoxXEnd_ = e.clientX;
        this.dragBoxYStart_ = this.dragBeginEvent_.clientY;
        this.dragBoxYEnd_ = e.clientY;
        var vertical = e.shiftKey;
        this.setDragBoxPosition_(this.dragBoxXStart_, this.dragBoxYStart_,
                                this.dragBoxXEnd_, this.dragBoxYEnd_, vertical);
      }
    },

    onMouseUp_: function(e) {
      var i;
      if (this.dragBeginEvent_) {
        // Stop the dragging.
        this.hideDragBox_();
        var eDown = this.dragBeginEvent_;
        this.dragBeginEvent_ = null;

        // Figure out extents of the drag.
        var loY;
        var hiY;
        var loX = Math.min(eDown.clientX, e.clientX);
        var hiX = Math.max(eDown.clientX, e.clientX);
        var tracksContainer = this.modelTrackContainer_.getBoundingClientRect();
        var topBoundary = tracksContainer.height;
        var vertical = e.shiftKey;
        if (vertical) {
          var modelTrackRect = this.modelTrack_.getBoundingClientRect();
          loY = modelTrackRect.top;
          hiY = modelTrackRect.bottom;
        } else {
          loY = Math.min(eDown.clientY, e.clientY);
          hiY = Math.max(eDown.clientY, e.clientY);
        }

        // Convert to worldspace.
        var canv = this.firstCanvas;
        var loVX = loX - canv.offsetLeft;
        var hiVX = hiX - canv.offsetLeft;

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

        // Activate the new selection, and zoom if ctrl key held down.
        this.selection = selection;
        if ((base.isMac && e.metaKey) || (!base.isMac && e.ctrlKey)) {
          this.zoomToSelection_();
        }
      }
    },

    onDblClick_: function(e) {
      var modelTrackContainerRect =
                              this.modelTrackContainer_.getBoundingClientRect();
      var clipBounds = {
        left: modelTrackContainerRect.left,
        right: modelTrackContainerRect.right,
      };
      var trackTitleWidth = parseInt(this.modelTrack_.headingWidth);
      clipBounds.left = clipBounds.left + trackTitleWidth;

      if (e.clientX < clipBounds.left || e.clientX > clipBounds.right)
        return;

      var canv = this.firstCanvas;

      var scale = 4;
      if (e.shiftKey)
        scale = 1 / scale;
      this.zoomBy_(scale);
      e.preventDefault();
    }
  };

  /**
   * The Model being viewed by the timeline
   * @type {Model}
   */
  base.defineProperty(TimelineTrackView, 'model', base.PropertyKind.JS);

  return {
    TimelineTrackView: TimelineTrackView
  };
});
