<!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="stylesheet" href="/core/tracks/rect_track.css">

<link rel="import" href="/model/proxy_selectable_item.html">
<link rel="import" href="/core/tracks/heading_track.html">
<link rel="import" href="/core/fast_rect_renderer.html">
<link rel="import" href="/core/draw_helpers.html">
<link rel="import" href="/base/sorted_array_utils.html">
<link rel="import" href="/base/ui.html">

<script>
'use strict';

tr.exportTo('tr.c.tracks', function() {

  /**
   * A track that displays an array of Rect objects.
   * @constructor
   * @extends {HeadingTrack}
   */
  var RectTrack = tr.b.ui.define(
      'rect-track', tr.c.tracks.HeadingTrack);

  RectTrack.prototype = {

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

    decorate: function(viewport) {
      tr.c.tracks.HeadingTrack.prototype.decorate.call(this, viewport);
      this.classList.add('rect-track');
      this.asyncStyle_ = false;
      this.rects_ = null;
    },

    get asyncStyle() {
      return this.asyncStyle_;
    },

    set asyncStyle(v) {
      this.asyncStyle_ = !!v;
    },

    get rects() {
      return this.rects_;
    },

    set rects(rects) {
      this.rects_ = rects || [];
      this.invalidateDrawingContainer();
    },

    get height() {
      return window.getComputedStyle(this).height;
    },

    set height(height) {
      this.style.height = height;
      this.invalidateDrawingContainer();
    },

    get hasVisibleContent() {
      return this.rects_.length > 0;
    },

    draw: function(type, viewLWorld, viewRWorld) {
      switch (type) {
        case tr.c.tracks.DrawType.GENERAL_EVENT:
          this.drawRects_(viewLWorld, viewRWorld);
          break;
      }
    },

    drawRects_: function(viewLWorld, viewRWorld) {
      var ctx = this.context();

      ctx.save();
      var bounds = this.getBoundingClientRect();
      tr.c.drawSlices(
          ctx,
          this.viewport.currentDisplayTransform,
          viewLWorld,
          viewRWorld,
          bounds.height,
          this.rects_,
          this.asyncStyle_);
      ctx.restore();

      if (bounds.height <= 6)
        return;

      var fontSize, yOffset;
      if (bounds.height < 15) {
        fontSize = 6;
        yOffset = 1.0;
      } else {
        fontSize = 10;
        yOffset = 2.5;
      }
      tr.c.drawLabels(
          ctx,
          this.viewport.currentDisplayTransform,
          viewLWorld,
          viewRWorld,
          this.rects_,
          this.asyncStyle_,
          fontSize,
          yOffset);
    },

    addEventsToTrackMap: function(eventToTrackMap) {
      if (this.rects_ === undefined || this.rects_ === null)
        return;

      this.rects_.forEach(function(rect) {
        rect.addToTrackMap(eventToTrackMap, this);
      }, this);
    },

    addIntersectingEventsInRangeToSelectionInWorldSpace: function(
        loWX, hiWX, viewPixWidthWorld, selection) {
      function onRect(rect) {
        rect.addToSelection(selection);
      }
      onRect = onRect.bind(this);
      tr.b.iterateOverIntersectingIntervals(this.rects_,
          function(x) { return x.start; },
          function(x) { return x.duration; },
          loWX, hiWX,
          onRect);
    },

    /**
     * Add the item to the left or right of the provided event, if any, to the
     * selection.
     * @param {rect} The current rect.
     * @param {Number} offset Number of rects away from the event 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) {
      var index = tr.b.findFirstIndexInArray(this.rects_, function(rect) {
        return rect.modelItem === event;
      });
      if (index === -1)
        return false;

      var newIndex = index + offset;
      if (newIndex < 0 || newIndex >= this.rects_.length)
        return false;

      this.rects_[newIndex].addToSelection(selection);
      return true;
    },

    addAllEventsMatchingFilterToSelection: function(filter, selection) {
      for (var i = 0; i < this.rects_.length; ++i) {
        // TODO(petrcermak): Rather than unpacking the proxy item here,
        // we should probably add an addToSelectionIfMatching(selection, filter)
        // method to SelectableItem (#900).
        var modelItem = this.rects_[i].modelItem;
        if (!modelItem)
          continue;
        if (filter.matchSlice(modelItem))
          selection.push(modelItem);
      }
    },

    addClosestEventToSelection: function(worldX, worldMaxDist, loY, hiY,
                                         selection) {
      var rect = tr.b.findClosestIntervalInSortedIntervals(
          this.rects_,
          function(x) { return x.start; },
          function(x) { return x.end; },
          worldX,
          worldMaxDist);

      if (!rect)
        return;

      rect.addToSelection(selection);
    }
  };

  /**
   * A filled rectangle with a title.
   *
   * @constructor
   * @extends {ProxySelectableItem}
   */
  function Rect(modelItem, title, colorId, start, duration) {
    tr.model.ProxySelectableItem.call(this, modelItem);
    this.title = title;
    this.colorId = colorId;
    this.start = start;
    this.duration = duration;
    this.end = start + duration;
  };

  Rect.prototype = {
    __proto__: tr.model.ProxySelectableItem.prototype
  };

  return {
    RectTrack: RectTrack,
    Rect: Rect
  };
});
</script>
