<!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="/base/base.html">
<link rel="import" href="/base/iteration_helpers.html">
<link rel="import" href="/base/statistics.html">
<link rel="import" href="/core/analysis/analysis_link.html">
<link rel="import" href="/core/analysis/multi_event_summary.html">
<link rel="import" href="/core/analysis/table_builder.html">
<link rel="import" href="/core/analysis/time_span.html">

</script>
<polymer-element name='tv-c-a-multi-event-summary-table'>
  <template>
    <style>
    :host {
      display: flex;
    }
    #table {
      flex: 1 1 auto;
      align-self: stretch;
    }
    </style>
    <tracing-analysis-nested-table id="table">
    </tracing-analysis-nested-table>
    </div>
  </template>
  <script>
  'use strict';

  Polymer({
    ready: function() {
      this.showTotals_ = false;
      this.eventsHaveDuration_ = true;
      this.eventsHaveSubRows_ = true;
      this.eventsByTitle_ = undefined;
    },

    updateTableColumns_: function(rows) {
      var hasCpuData = false;
      var hasAlerts = false;
      rows.forEach(function(row) {
        if (row.cpuDuration !== undefined)
          hasCpuData = true;
        if (row.cpuSelfTime !== undefined)
          hasCpuData = true;
        if (row.numAlerts)
          hasAlerts = true;
      });


      var columns = [];

      columns.push({
        title: 'Name',
        value: function(row) {
          if (row.title === 'Totals')
            return 'Totals';

          var linkEl = document.createElement('tv-c-analysis-link');
          linkEl.setSelectionAndContent(function() {
            return new tv.c.Selection(row.events);
          }, row.title);
          return linkEl;
        },
        width: '350px',
        cmp: function(rowA, rowB) {
          return rowA.title.localeCompare(rowB.title);
        }
      });
      if (this.eventsHaveDuration_) {
        columns.push({
          title: 'Wall Duration (ms)',
          value: function(row) {
            return tv.c.analysis.createTimeSpan(row.duration);
          },
          width: '<upated further down>',
          cmp: function(rowA, rowB) {
            return rowA.duration - rowB.duration;
          }
        });
      }

      if (this.eventsHaveDuration_ && hasCpuData) {
        columns.push({
          title: 'CPU Duration (ms)',
          value: function(row) {
            return tv.c.analysis.createTimeSpan(row.cpuDuration);
          },
          width: '<upated further down>',
          cmp: function(rowA, rowB) {
            return rowA.cpuDuration - rowB.cpuDuration;
          }
        });
      }

      if (this.eventsHaveSubRows_ && this.eventsHaveDuration_) {
        columns.push({
          title: 'Self time (ms)',
          value: function(row) {
            return tv.c.analysis.createTimeSpan(row.selfTime);
          },
          width: '<upated further down>',
          cmp: function(rowA, rowB) {
            return rowA.selfTime - rowB.selfTime;
          }
        });
      }

      if (this.eventsHaveSubRows_ && this.eventsHaveDuration_ && hasCpuData) {
        columns.push({
          title: 'CPU Self Time (ms)',
          value: function(row) {
            return tv.c.analysis.createTimeSpan(row.cpuSelfTime);
          },
          width: '<upated further down>',
          cmp: function(rowA, rowB) {
            return rowA.cpuSelfTime - rowB.cpuSelfTime;
          }
        });
      }
      columns.push({
        title: 'Occurrences',
        value: function(row) {
          return row.numEvents;
        },
        width: '<upated further down>',
        cmp: function(rowA, rowB) {
          return rowA.numEvents - rowB.numEvents;
        }
      });

      var alertsColumnIndex;
      if (hasAlerts) {
        columns.push({
          title: 'Num Alerts',
          value: function(row) {
            return row.numAlerts;
          },
          width: '<upated further down>',
          cmp: function(rowA, rowB) {
            return rowA.numAlerts - rowB.numAlerts;
          }
        });
        alertsColumnIndex = columns.length - 1;
      }
      var colWidthPercentage;
      if (columns.length == 1)
        colWidthPercentage = '100%';
      else
        colWidthPercentage = (100 / (columns.length - 1)).toFixed(3) + '%';

      for (var i = 1; i < columns.length; i++)
        columns[i].width = colWidthPercentage;

      this.$.table.tableColumns = columns;

      if (hasAlerts) {
        this.$.table.sortColumnIndex = alertsColumnIndex;
        this.$.table.sortDescending = true;
      }
    },

    configure: function(config) {
      if (config.eventsByTitle === undefined)
        throw new Error('Required: eventsByTitle');

      if (config.showTotals !== undefined)
        this.showTotals_ = config.showTotals;
      else
        this.showTotals_ = true;

      if (config.eventsHaveDuration !== undefined)
        this.eventsHaveDuration_ = config.eventsHaveDuration;
      else
        this.eventsHaveDuration_ = true;

      if (config.eventsHaveSubRows !== undefined)
        this.eventsHaveSubRows_ = config.eventsHaveSubRows;
      else
        this.eventsHaveSubRows_ = true;

      this.eventsByTitle_ = config.eventsByTitle;
      this.updateContents_();
    },

    get showTotals() {
      return this.showTotals_;
    },

    set showTotals(showTotals) {
      this.showTotals_ = showTotals;
      this.updateContents_();
    },

    get eventsHaveDuration() {
      return this.eventsHaveDuration_;
    },

    set eventsHaveDuration(eventsHaveDuration) {
      this.eventsHaveDuration_ = eventsHaveDuration;
      this.updateContents_();
    },

    get eventsHaveSubRows() {
      return this.eventsHaveSubRows_;
    },

    set eventsHaveSubRows(eventsHaveSubRows) {
      this.eventsHaveSubRows_ = eventsHaveSubRows;
      this.updateContents_();
    },

    get eventsByTitle() {
      return this.eventsByTitle_;
    },

    set eventsByTitle(eventsByTitle) {
      this.eventsByTitle_ = eventsByTitle;
      this.updateContents_();
    },

    get selectionBounds() {
      return this.selectionBounds_;
    },

    set selectionBounds(selectionBounds) {
      this.selectionBounds_ = selectionBounds;
      this.updateContents_();
    },

    updateContents_: function() {
      var eventsByTitle;
      if (this.eventsByTitle_ !== undefined)
        eventsByTitle = this.eventsByTitle_;
      else
        eventsByTitle = [];

      var allEvents = [];
      var rows = [];
      tv.b.iterItems(
          eventsByTitle,
          function(title, eventsOfSingleTitle) {
            allEvents.push.apply(allEvents, eventsOfSingleTitle);
            var row = new tv.c.analysis.MultiEventSummary(title,
                                                          eventsOfSingleTitle);
            rows.push(row);
          });

      this.updateTableColumns_(rows);
      this.$.table.tableRows = rows;

      var footerRows = [];

      if (this.showTotals_) {
        footerRows.push(
            new tv.c.analysis.MultiEventSummary('Totals', allEvents));
      }
      // TODO(selection bounds).

      // TODO(sorting)

      this.$.table.footerRows = footerRows;
      this.$.table.rebuild();
    }
  });
  </script>
</polymer-element>
