<!DOCTYPE html>
<!--
Copyright (c) 2015 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="/base/base.html">

<script>
'use strict';

tr.exportTo('tr.model', function() {
  /**
   * YComponent is a class that handles storing the stableId and the percentage
   * offset in the y direction of all tracks within a specific viewX and viewY
   * coordinate.
   * @constructor
   */
  function YComponent(stableId, yPercentOffset) {
    this.stableId = stableId;
    this.yPercentOffset = yPercentOffset;
  }

  YComponent.prototype = {
    toDict: function() {
      return {
        stableId: this.stableId,
        yPercentOffset: this.yPercentOffset
      };
    }
  };

  /**
   * Location is a class that represents a spatial location on the timeline
   * that is specified by percent offsets within tracks rather than specific
   * points.
   *
   * @constructor
   */
  function Location(xWorld, yComponents) {
    this.xWorld_ = xWorld;
    this.yComponents_ = yComponents;
  };

  /**
   * Returns a new Location given by x and y coordinates with respect to
   * the timeline's drawing canvas.
   */
  Location.fromViewCoordinates = function(viewport, viewX, viewY) {
    var dt = viewport.currentDisplayTransform;
    var xWorld = dt.xViewToWorld(viewX);
    var yComponents = [];

    // Since we're given coordinates within the timeline canvas, we need to
    // convert them to document coordinates to get the element.
    var elem = document.elementFromPoint(
          viewX + viewport.modelTrackContainer.canvas.offsetLeft,
          viewY + viewport.modelTrackContainer.canvas.offsetTop);
    // Build yComponents by calculating percentage offset with respect to
    // each parent track.
    while (elem instanceof tr.ui.tracks.Track) {
      if (elem.eventContainer) {
        var boundRect = elem.getBoundingClientRect();
        var yPercentOffset = (viewY - boundRect.top) / boundRect.height;
        yComponents.push(
            new YComponent(elem.eventContainer.stableId, yPercentOffset));
      }
      elem = elem.parentElement;
    }

    if (yComponents.length == 0)
      return;
    return new Location(xWorld, yComponents);
  }

  Location.fromStableIdAndTimestamp = function(viewport, stableId, ts) {
    var xWorld = ts;
    var yComponents = [];

    // The y components' percentage offsets will be calculated with respect to
    // the boundingRect's top of containing track.
    var containerToTrack = viewport.containerToTrackMap;
    var elem = containerToTrack.getTrackByStableId(stableId);
    if (!elem)
      return;

    var firstY = elem.getBoundingClientRect().top;
    while (elem instanceof tr.ui.tracks.Track) {
      if (elem.eventContainer) {
        var boundRect = elem.getBoundingClientRect();
        var yPercentOffset = (firstY - boundRect.top) / boundRect.height;
        yComponents.push(
            new YComponent(elem.eventContainer.stableId, yPercentOffset));
      }
      elem = elem.parentElement;
    }

    if (yComponents.length == 0)
      return;
    return new Location(xWorld, yComponents);
  }

  Location.prototype = {

    get xWorld() {
      return this.xWorld_;
    },

    /**
     * Returns the first valid containing track based on the
     * internal yComponents.
     */
    getContainingTrack: function(viewport) {
      var containerToTrack = viewport.containerToTrackMap;
      for (var i in this.yComponents_) {
        var yComponent = this.yComponents_[i];
        var track = containerToTrack.getTrackByStableId(yComponent.stableId);
        if (track !== undefined)
          return track;
      }
    },

    /**
     * Calculates and returns x and y coordinates of the current location with
     * respect to the timeline's canvas.
     */
    toViewCoordinates: function(viewport) {
      var dt = viewport.currentDisplayTransform;
      var containerToTrack = viewport.containerToTrackMap;
      var viewX = dt.xWorldToView(this.xWorld_);

      var viewY = -1;
      for (var index in this.yComponents_) {
        var yComponent = this.yComponents_[index];
        var track = containerToTrack.getTrackByStableId(yComponent.stableId);
        if (track !== undefined) {
          var boundRect = track.getBoundingClientRect();
          viewY = yComponent.yPercentOffset * boundRect.height + boundRect.top;
          break;
        }
      }

      return {
        viewX: viewX,
        viewY: viewY
      };
    },

    toDict: function() {
      return {
        xWorld: this.xWorld_,
        yComponents: this.yComponents_
      };
    }
  };

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