1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5
6/**
7 * Maintains the stats table.
8 * @param {SsrcInfoManager} ssrcInfoManager The source of the ssrc info.
9 */
10var StatsTable = (function(ssrcInfoManager) {
11  'use strict';
12
13  /**
14   * @param {SsrcInfoManager} ssrcInfoManager The source of the ssrc info.
15   * @constructor
16   */
17  function StatsTable(ssrcInfoManager) {
18    /**
19     * @type {SsrcInfoManager}
20     * @private
21     */
22    this.ssrcInfoManager_ = ssrcInfoManager;
23  }
24
25  StatsTable.prototype = {
26    /**
27     * Adds |report| to the stats table of |peerConnectionElement|.
28     *
29     * @param {!Element} peerConnectionElement The root element.
30     * @param {!Object} report The object containing stats, which is the object
31     *     containing timestamp and values, which is an array of strings, whose
32     *     even index entry is the name of the stat, and the odd index entry is
33     *     the value.
34     */
35    addStatsReport: function(peerConnectionElement, report) {
36      var statsTable = this.ensureStatsTable_(peerConnectionElement, report);
37
38      if (report.stats) {
39        this.addStatsToTable_(statsTable,
40                              report.stats.timestamp, report.stats.values);
41      }
42    },
43
44    /**
45     * Ensure the DIV container for the stats tables is created as a child of
46     * |peerConnectionElement|.
47     *
48     * @param {!Element} peerConnectionElement The root element.
49     * @return {!Element} The stats table container.
50     * @private
51     */
52    ensureStatsTableContainer_: function(peerConnectionElement) {
53      var containerId = peerConnectionElement.id + '-table-container';
54      var container = $(containerId);
55      if (!container) {
56        container = document.createElement('div');
57        container.id = containerId;
58        container.className = 'stats-table-container';
59        var head = document.createElement('div');
60        head.textContent = 'Stats Tables';
61        container.appendChild(head);
62        peerConnectionElement.appendChild(container);
63      }
64      return container;
65    },
66
67    /**
68     * Ensure the stats table for track specified by |report| of PeerConnection
69     * |peerConnectionElement| is created.
70     *
71     * @param {!Element} peerConnectionElement The root element.
72     * @param {!Object} report The object containing stats, which is the object
73     *     containing timestamp and values, which is an array of strings, whose
74     *     even index entry is the name of the stat, and the odd index entry is
75     *     the value.
76     * @return {!Element} The stats table element.
77     * @private
78     */
79     ensureStatsTable_: function(peerConnectionElement, report) {
80      var tableId = peerConnectionElement.id + '-table-' + report.id;
81      var table = $(tableId);
82      if (!table) {
83        var container = this.ensureStatsTableContainer_(peerConnectionElement);
84        var details = document.createElement('details');
85        container.appendChild(details);
86
87        var summary = document.createElement('summary');
88        summary.textContent = report.id;
89        details.appendChild(summary);
90
91        table = document.createElement('table');
92        details.appendChild(table);
93        table.id = tableId;
94        table.border = 1;
95
96        table.innerHTML = '<tr><th colspan=2></th></tr>';
97        table.rows[0].cells[0].textContent = 'Statistics ' + report.id;
98        if (report.type == 'ssrc') {
99            table.insertRow(1);
100            table.rows[1].innerHTML = '<td colspan=2></td>';
101            this.ssrcInfoManager_.populateSsrcInfo(
102                table.rows[1].cells[0], GetSsrcFromReport(report));
103        }
104      }
105      return table;
106    },
107
108    /**
109     * Update |statsTable| with |time| and |statsData|.
110     *
111     * @param {!Element} statsTable Which table to update.
112     * @param {number} time The number of miliseconds since epoch.
113     * @param {Array.<string>} statsData An array of stats name and value pairs.
114     * @private
115     */
116    addStatsToTable_: function(statsTable, time, statsData) {
117      var date = new Date(time);
118      this.updateStatsTableRow_(statsTable, 'timestamp', date.toLocaleString());
119      for (var i = 0; i < statsData.length - 1; i = i + 2) {
120        this.updateStatsTableRow_(statsTable, statsData[i], statsData[i + 1]);
121      }
122    },
123
124    /**
125     * Update the value column of the stats row of |rowName| to |value|.
126     * A new row is created is this is the first report of this stats.
127     *
128     * @param {!Element} statsTable Which table to update.
129     * @param {string} rowName The name of the row to update.
130     * @param {string} value The new value to set.
131     * @private
132     */
133    updateStatsTableRow_: function(statsTable, rowName, value) {
134      var trId = statsTable.id + '-' + rowName;
135      var trElement = $(trId);
136      if (!trElement) {
137        trElement = document.createElement('tr');
138        trElement.id = trId;
139        statsTable.firstChild.appendChild(trElement);
140        trElement.innerHTML = '<td>' + rowName + '</td><td></td>';
141      }
142      trElement.cells[1].textContent = value;
143
144      // Highlights the table for the active connection.
145      if (rowName == 'googActiveConnection' && value == 'true')
146        statsTable.parentElement.classList.add('stats-table-active-connection');
147    }
148  };
149
150  return StatsTable;
151})();
152