<!DOCTYPE html>
<!--
Copyright (c) 2013 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/tracks/heading_track.html">
<link rel="import" href="/base/ui.html">

<script>
'use strict';

tr.exportTo('tr.c.tracks', function() {
  /**
   * A track that displays traces as stacked bars.
   * @constructor
   * @extends {HeadingTrack}
   */
  var StackedBarsTrack = tr.b.ui.define(
      'stacked-bars-track', tr.c.tracks.HeadingTrack);

  StackedBarsTrack.prototype = {

    __proto__: tr.c.tracks.HeadingTrack.prototype,

    decorate: function(viewport) {
      tr.c.tracks.HeadingTrack.prototype.decorate.call(this, viewport);
      this.classList.add('stacked-bars-track');
      this.objectInstance_ = null;
    },

    addEventsToTrackMap: function(eventToTrackMap) {
      var objectSnapshots = this.objectInstance_.snapshots;
      objectSnapshots.forEach(function(obj) {
        eventToTrackMap.addEvent(obj, this);
      }, this);
    },

    /**
     * Used to hit-test clicks in the graph.
     */
    addIntersectingEventsInRangeToSelectionInWorldSpace: function(
        loWX, hiWX, viewPixWidthWorld, selection) {
      function onSnapshot(snapshot) {
        selection.push(snapshot);
      }

      var snapshots = this.objectInstance_.snapshots;
      var maxBounds = this.objectInstance_.parent.model.bounds.max;

      tr.b.iterateOverIntersectingIntervals(
          snapshots,
          function(x) { return x.ts; },
          function(x, i) {
            if (i == snapshots.length - 1) {
              if (snapshots.length == 1)
                return maxBounds;

              return snapshots[i].ts - snapshots[i - 1].ts;
            }

            return snapshots[i + 1].ts - snapshots[i].ts;
          },
          loWX, hiWX,
          onSnapshot);
    },

    /**
     * Add the item to the left or right of the provided item, if any, to the
     * selection.
     * @param {slice} The current slice.
     * @param {Number} offset Number of slices away from the object to look.
     * @param {Selection} selection The selection to add an event to,
     * if found.
     * @return {boolean} Whether an event was found.
     * @private
     */
    addEventNearToProvidedEventToSelection: function(event, offset, selection) {
      if (!(event instanceof tr.model.ObjectSnapshot))
        throw new Error('Unrecognized event');
      var objectSnapshots = this.objectInstance_.snapshots;
      var index = objectSnapshots.indexOf(event);
      var newIndex = index + offset;
      if (newIndex >= 0 && newIndex < objectSnapshots.length) {
        selection.push(objectSnapshots[newIndex]);
        return true;
      }
      return false;
    },

    addAllEventsMatchingFilterToSelection: function(filter, selection) {
    },

    addClosestEventToSelection: function(worldX, worldMaxDist, loY, hiY,
                                         selection) {
      var snapshot = tr.b.findClosestElementInSortedArray(
          this.objectInstance_.snapshots,
          function(x) { return x.ts; },
          worldX,
          worldMaxDist);

      if (!snapshot)
        return;

      selection.push(snapshot);
    }
  };

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