<!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';

tv.exportTo('tv.c', 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 tv.c.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.containerToTrackObj;
    var elem = containerToTrack.getTrackByStableId(stableId);
    if (!elem)
      return;

    var firstY = elem.getBoundingClientRect().top;
    while (elem instanceof tv.c.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.containerToTrackObj;
      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.containerToTrackObj;
      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>
