<!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="/model/counter_series.html">
<link rel="import" href="/model/event_container.html">
<link rel="import" href="/base/guid.html">
<link rel="import" href="/base/range.html">

<script>
'use strict';

/**
 * @fileoverview Provides the Counter class.
 */
tr.exportTo('tr.model', function() {

  /**
   * Stores all the samples for a given counter.
   * @constructor
   */
  function Counter(parent, id, category, name) {
    tr.model.EventContainer.call(this);
    this.guid_ = tr.b.GUID.allocate();

    this.parent_ = parent;
    this.id_ = id;
    this.category_ = category || '';
    this.name_ = name;

    this.series_ = [];
    this.totals = [];
    this.bounds = new tr.b.Range();
  }

  Counter.prototype = {
    __proto__: tr.model.EventContainer.prototype,

    get guid() {
      return this.guid_;
    },

    get parent() {
      return this.parent_;
    },

    get id() {
      return this.id_;
    },

    get category() {
      return this.category_;
    },

    get name() {
      return this.name_;
    },

    iterateAllEventsInThisContainer: function(eventTypePredicate,
                                              callback, opt_this) {
    },

    iterateAllChildEventContainers: function(callback, opt_this) {
      for (var i = 0; i < this.series_.length; i++)
        callback.call(opt_this, this.series_[i]);
    },

    set timestamps(arg) {
      throw new Error('Bad counter API. No cookie.');
    },

    set seriesNames(arg) {
      throw new Error('Bad counter API. No cookie.');
    },

    set seriesColors(arg) {
      throw new Error('Bad counter API. No cookie.');
    },

    set samples(arg) {
      throw new Error('Bad counter API. No cookie.');
    },

    addSeries: function(series) {
      series.counter = this;
      series.seriesIndex = this.series_.length;
      this.series_.push(series);
      return series;
    },

    getSeries: function(idx) {
      return this.series_[idx];
    },

    get series() {
      return this.series_;
    },

    get numSeries() {
      return this.series_.length;
    },

    get numSamples() {
      if (this.series_.length === 0)
        return 0;
      return this.series_[0].length;
    },

    get timestamps() {
      if (this.series_.length === 0)
        return [];
      return this.series_[0].timestamps;
    },

    /**
     * Obtains min, max, avg, values, start, and end for different series for
     * a given counter
     *     getSampleStatistics([0,1])
     * The statistics objects that this returns are an array of objects, one
     * object for each series for the counter in the form:
     * {min: minVal, max: maxVal, avg: avgVal, start: startVal, end: endVal}
     *
     * @param {Array.<Number>} Indices to summarize.
     * @return {Object} An array of statistics. Each element in the array
     * has data for one of the series in the selected counter.
     */
    getSampleStatistics: function(sampleIndices) {
      sampleIndices.sort();

      var ret = [];
      this.series_.forEach(function(series) {
        ret.push(series.getStatistics(sampleIndices));
      });
      return ret;
    },

    /**
     * Shifts all the timestamps inside this counter forward by the amount
     * specified.
     */
    shiftTimestampsForward: function(amount) {
      for (var i = 0; i < this.series_.length; ++i)
        this.series_[i].shiftTimestampsForward(amount);
    },

    /**
     * Updates the bounds for this counter based on the samples it contains.
     */
    updateBounds: function() {
      this.totals = [];
      this.maxTotal = 0;
      this.bounds.reset();

      if (this.series_.length === 0)
        return;

      var firstSeries = this.series_[0];
      var lastSeries = this.series_[this.series_.length - 1];

      this.bounds.addValue(firstSeries.getTimestamp(0));
      this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length - 1));

      var numSeries = this.numSeries;
      this.maxTotal = -Infinity;

      // Sum the samples at each timestamp.
      // Note, this assumes that all series have all timestamps.
      for (var i = 0; i < firstSeries.length; ++i) {
        var total = 0;
        this.series_.forEach(function(series) {
          total += series.getSample(i).value;
          this.totals.push(total);
        }.bind(this));

        this.maxTotal = Math.max(total, this.maxTotal);
      }
    }
  };

  /**
   * Comparison between counters that orders by parent.compareTo, then name.
   */
  Counter.compare = function(x, y) {
    var tmp = x.parent.compareTo(y);
    if (tmp != 0)
      return tmp;
    var tmp = x.name.localeCompare(y.name);
    if (tmp == 0)
      return x.tid - y.tid;
    return tmp;
  };

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