<!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="/core/draw_helpers.html">
<link rel="import" href="/core/timeline_interest_range.html">
<link rel="import" href="/core/timeline_display_transform.html">
<link rel="import" href="/base/events.html">
<link rel="import" href="/base/ui/animation.html">
<link rel="import" href="/base/ui/animation_controller.html">
<link rel="import" href="/base/ui/dom_helpers.html">

<script>
'use strict';

/**
 * @fileoverview Code for the viewport.
 */
tr.exportTo('tr.c', function() {
  var TimelineDisplayTransform = tr.c.TimelineDisplayTransform;
  var TimelineInterestRange = tr.c.TimelineInterestRange;

  /**
   * ContainerToTrackObj is a class to handle building and accessing a map
   * between an EventContainer's stableId and its handling track.
   *
   * @constructor
   */
  function ContainerToTrackObj() {
    this.stableIdToTrackMap_ = {};
  }

  ContainerToTrackObj.prototype = {
    addContainer: function(container, track) {
      if (!track)
        throw new Error('Must provide a track.');
      this.stableIdToTrackMap_[container.stableId] = track;
    },

    clearMap: function() {
      this.stableIdToTrackMap_ = {};
    },

    getTrackByStableId: function(stableId) {
      return this.stableIdToTrackMap_[stableId];
    }
  };

  /**
   * The TimelineViewport manages the transform used for navigating
   * within the timeline. It is a simple transform:
   *   x' = (x+pan) * scale
   *
   * The timeline code tries to avoid directly accessing this transform,
   * instead using this class to do conversion between world and viewspace,
   * as well as the math for centering the viewport in various interesting
   * ways.
   *
   * @constructor
   * @extends {tr.b.EventTarget}
   */
  function TimelineViewport(parentEl) {
    this.parentEl_ = parentEl;
    this.modelTrackContainer_ = undefined;
    this.currentDisplayTransform_ = new TimelineDisplayTransform();
    this.initAnimationController_();

    // Flow events
    this.showFlowEvents_ = false;

    // Highlights.
    this.highlightVSync_ = false;

    // High details.
    this.highDetails_ = false;

    // Grid system.
    this.gridTimebase_ = 0;
    this.gridStep_ = 1000 / 60;
    this.gridEnabled_ = false;

    // Init logic.
    this.hasCalledSetupFunction_ = false;

    this.onResize_ = this.onResize_.bind(this);
    this.onModelTrackControllerScroll_ =
        this.onModelTrackControllerScroll_.bind(this);

    // The following code uses an interval to detect when the parent element
    // is attached to the document. That is a trigger to run the setup function
    // and install a resize listener.
    this.checkForAttachInterval_ = setInterval(
        this.checkForAttach_.bind(this), 250);

    this.majorMarkPositions = [];
    this.interestRange_ = new TimelineInterestRange(this);

    this.eventToTrackMap_ = {};
    this.containerToTrackObj = new ContainerToTrackObj();
  }

  TimelineViewport.prototype = {
    __proto__: tr.b.EventTarget.prototype,

    /**
     * Allows initialization of the viewport when the viewport's parent element
     * has been attached to the document and given a size.
     * @param {Function} fn Function to call when the viewport can be safely
     * initialized.
     */
    setWhenPossible: function(fn) {
      this.pendingSetFunction_ = fn;
    },

    /**
     * @return {boolean} Whether the current timeline is attached to the
     * document.
     */
    get isAttachedToDocumentOrInTestMode() {
      // Allow not providing a parent element, used by tests.
      if (this.parentEl_ === undefined)
        return;
      return tr.b.ui.isElementAttachedToDocument(this.parentEl_);
    },

    onResize_: function() {
      this.dispatchChangeEvent();
    },

    /**
     * Checks whether the parentNode is attached to the document.
     * When it is, it installs the iframe-based resize detection hook
     * and then runs the pendingSetFunction_, if present.
     */
    checkForAttach_: function() {
      if (!this.isAttachedToDocumentOrInTestMode || this.clientWidth == 0)
        return;

      if (!this.iframe_) {
        this.iframe_ = document.createElement('iframe');
        this.iframe_.style.cssText =
            'position:absolute;width:100%;height:0;border:0;visibility:hidden;';
        this.parentEl_.appendChild(this.iframe_);

        this.iframe_.contentWindow.addEventListener('resize', this.onResize_);
      }

      var curSize = this.parentEl_.clientWidth + 'x' +
          this.parentEl_.clientHeight;
      if (this.pendingSetFunction_) {
        this.lastSize_ = curSize;
        try {
          this.pendingSetFunction_();
        } catch (ex) {
          console.log('While running setWhenPossible:',
              ex.message ? ex.message + '\n' + ex.stack : ex.stack);
        }
        this.pendingSetFunction_ = undefined;
      }

      window.clearInterval(this.checkForAttachInterval_);
      this.checkForAttachInterval_ = undefined;
    },

    /**
     * Fires the change event on this viewport. Used to notify listeners
     * to redraw when the underlying model has been mutated.
     */
    dispatchChangeEvent: function() {
      tr.b.dispatchSimpleEvent(this, 'change');
    },

    detach: function() {
      if (this.checkForAttachInterval_) {
        window.clearInterval(this.checkForAttachInterval_);
        this.checkForAttachInterval_ = undefined;
      }
      if (this.iframe_) {
        this.iframe_.removeEventListener('resize', this.onResize_);
        this.parentEl_.removeChild(this.iframe_);
      }
    },

    initAnimationController_: function() {
      this.dtAnimationController_ = new tr.b.ui.AnimationController();
      this.dtAnimationController_.addEventListener(
          'didtick', function(e) {
            this.onCurentDisplayTransformChange_(e.oldTargetState);
          }.bind(this));

      var that = this;
      this.dtAnimationController_.target = {
        get panX() {
          return that.currentDisplayTransform_.panX;
        },

        set panX(panX) {
          that.currentDisplayTransform_.panX = panX;
        },

        get panY() {
          return that.currentDisplayTransform_.panY;
        },

        set panY(panY) {
          that.currentDisplayTransform_.panY = panY;
        },

        get scaleX() {
          return that.currentDisplayTransform_.scaleX;
        },

        set scaleX(scaleX) {
          that.currentDisplayTransform_.scaleX = scaleX;
        },

        cloneAnimationState: function() {
          return that.currentDisplayTransform_.clone();
        },

        xPanWorldPosToViewPos: function(xWorld, xView) {
          that.currentDisplayTransform_.xPanWorldPosToViewPos(
              xWorld, xView, that.modelTrackContainer_.canvas.clientWidth);
        }
      };
    },

    get currentDisplayTransform() {
      return this.currentDisplayTransform_;
    },

    setDisplayTransformImmediately: function(displayTransform) {
      this.dtAnimationController_.cancelActiveAnimation();

      var oldDisplayTransform =
          this.dtAnimationController_.target.cloneAnimationState();
      this.currentDisplayTransform_.set(displayTransform);
      this.onCurentDisplayTransformChange_(oldDisplayTransform);
    },

    queueDisplayTransformAnimation: function(animation) {
      if (!(animation instanceof tr.b.ui.Animation))
        throw new Error('animation must be instanceof tr.b.ui.Animation');
      this.dtAnimationController_.queueAnimation(animation);
    },

    onCurentDisplayTransformChange_: function(oldDisplayTransform) {
      // Ensure panY stays clamped in the track container's scroll range.
      if (this.modelTrackContainer_) {
        this.currentDisplayTransform.panY = tr.b.clamp(
            this.currentDisplayTransform.panY,
            0,
            this.modelTrackContainer_.scrollHeight -
                this.modelTrackContainer_.clientHeight);
      }

      var changed = !this.currentDisplayTransform.equals(oldDisplayTransform);
      var yChanged = this.currentDisplayTransform.panY !==
          oldDisplayTransform.panY;
      if (yChanged)
        this.modelTrackContainer_.scrollTop = this.currentDisplayTransform.panY;
      if (changed)
        this.dispatchChangeEvent();
    },

    onModelTrackControllerScroll_: function(e) {
      if (this.dtAnimationController_.activeAnimation &&
          this.dtAnimationController_.activeAnimation.affectsPanY)
        this.dtAnimationController_.cancelActiveAnimation();
      var panY = this.modelTrackContainer_.scrollTop;
      this.currentDisplayTransform_.panY = panY;
    },

    get modelTrackContainer() {
      return this.modelTrackContainer_;
    },

    set modelTrackContainer(m) {
      if (this.modelTrackContainer_)
        this.modelTrackContainer_.removeEventListener('scroll',
            this.onModelTrackControllerScroll_);

      this.modelTrackContainer_ = m;
      this.modelTrackContainer_.addEventListener('scroll',
          this.onModelTrackControllerScroll_);
    },

    get showFlowEvents() {
      return this.showFlowEvents_;
    },

    set showFlowEvents(showFlowEvents) {
      this.showFlowEvents_ = showFlowEvents;
      this.dispatchChangeEvent();
    },

    get highlightVSync() {
      return this.highlightVSync_;
    },

    set highlightVSync(highlightVSync) {
      this.highlightVSync_ = highlightVSync;
      this.dispatchChangeEvent();
    },

    get highDetails() {
      return this.highDetails_;
    },

    set highDetails(highDetails) {
      this.highDetails_ = highDetails;
      this.dispatchChangeEvent();
    },

    get gridEnabled() {
      return this.gridEnabled_;
    },

    set gridEnabled(enabled) {
      if (this.gridEnabled_ == enabled)
        return;

      this.gridEnabled_ = enabled && true;
      this.dispatchChangeEvent();
    },

    get gridTimebase() {
      return this.gridTimebase_;
    },

    set gridTimebase(timebase) {
      if (this.gridTimebase_ == timebase)
        return;
      this.gridTimebase_ = timebase;
      this.dispatchChangeEvent();
    },

    get gridStep() {
      return this.gridStep_;
    },

    get interestRange() {
      return this.interestRange_;
    },

    drawMajorMarkLines: function(ctx) {
      // Apply subpixel translate to get crisp lines.
      // http://www.mobtowers.com/html5-canvas-crisp-lines-every-time/
      ctx.save();
      ctx.translate((Math.round(ctx.lineWidth) % 2) / 2, 0);

      ctx.beginPath();
      for (var idx in this.majorMarkPositions) {
        var x = Math.floor(this.majorMarkPositions[idx]);
        tr.c.drawLine(ctx, x, 0, x, ctx.canvas.height);
      }
      ctx.strokeStyle = '#ddd';
      ctx.stroke();

      ctx.restore();
    },

    drawGridLines: function(ctx, viewLWorld, viewRWorld) {
      if (!this.gridEnabled)
        return;

      var dt = this.currentDisplayTransform;
      var x = this.gridTimebase;

      // Apply subpixel translate to get crisp lines.
      // http://www.mobtowers.com/html5-canvas-crisp-lines-every-time/
      ctx.save();
      ctx.translate((Math.round(ctx.lineWidth) % 2) / 2, 0);

      ctx.beginPath();
      while (x < viewRWorld) {
        if (x >= viewLWorld) {
          // Do conversion to viewspace here rather than on
          // x to avoid precision issues.
          var vx = Math.floor(dt.xWorldToView(x));
          tr.c.drawLine(ctx, vx, 0, vx, ctx.canvas.height);
        }

        x += this.gridStep;
      }
      ctx.strokeStyle = 'rgba(255, 0, 0, 0.25)';
      ctx.stroke();

      ctx.restore();
    },

    rebuildEventToTrackMap: function() {
      this.eventToTrackMap_ = undefined;

      var eventToTrackMap = {};
      eventToTrackMap.addEvent = function(event, track) {
        if (!track)
          throw new Error('Must provide a track.');
        this[event.guid] = track;
      };
      this.modelTrackContainer_.addEventsToTrackMap(eventToTrackMap);
      this.eventToTrackMap_ = eventToTrackMap;
    },

    rebuildContainerToTrackMap: function() {
      this.containerToTrackObj.clearMap();
      this.modelTrackContainer_.addContainersToTrackMap(
          this.containerToTrackObj);
    },

    trackForEvent: function(event) {
      return this.eventToTrackMap_[event.guid];
    }
  };

  return {
    ContainerToTrackObj: ContainerToTrackObj,
    TimelineViewport: TimelineViewport
  };
});
</script>
