<!DOCTYPE html>
<!--
Copyright (c) 2015 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="/tracing/base/statistics.html">
<link rel="import" href="/tracing/ui/base/bar_chart.html">
<link rel="import" href="/tracing/value/ui/scalar_span.html">

<polymer-element name="tr-v-ui-histogram-span">
  <template>
    <style>
      :host {
        display: flex;
        flex-direction: column;
      }

      #stats {
        display: flex;
        flex-direction: row;
        flex: 0 0 auto;
        font-weight: bold;
      }

      #nnans {
        color: red;
      }
      #table {
        flex: 1 1 auto;
      }
    </style>
    <div id="stats">
      <span id="nsamples"></span>&nbsp;samples,&nbsp;
      <span id="hadnans"><span id="nnans"></span> non-numeric samples,&nbsp;
      </span>
      average=<tr-v-ui-scalar-span id="average"></tr-v-ui-scalar-span>
    </div>
    <div id="container"></div>
  </template>
  <script>
  'use strict';

  Polymer({
    created: function() {
      this.histogram_ = undefined;
      this.chart_ = new tr.ui.b.BarChart();
      this.chart_.width = 400;
      this.chart_.height = 200;
      this.mouseDownBin_ = undefined;
      this.brushedBins_ = [];
      this.chart_.addEventListener('item-mousedown',
          this.onMouseDown_.bind(this));
      this.chart_.addEventListener('item-mousemove',
          this.onMouseMove_.bind(this));
      this.chart_.addEventListener('item-mouseup',
          this.onMouseUp_.bind(this));
    },

    ready: function() {
      this.$.container.appendChild(this.chart_);
    },

    get brushedBins() {
      return this.brushedBins_;
    },

    updateBrushedRange_: function(currentX) {
      this.brushedBins_ = [this.histogram_.getBinForValue(currentX)];
      var r = new tr.b.Range();
      r.addValue(this.mouseDownX_);
      r.addValue(currentX);

      // Collect bins:
      var centralMin = Number.MAX_VALUE;
      var centralMax = -Number.MAX_VALUE;
      this.histogram_.centralBins.forEach(function(bin) {
        centralMin = Math.min(centralMin, bin.range.min);
        centralMax = Math.max(centralMax, bin.range.max);
        if ((bin.range.max > r.min) &&
            (bin.range.min < r.max) &&
            (this.brushedBins_.indexOf(bin) < 0))
          this.brushedBins_.push(bin);
      }, this);
      if ((this.histogram_.underflowBin.max > r.min) &&
          (this.brushedBins_.indexOf(this.histogram_.underflowBin) < 0)) {
        this.brushedBins_.push(this.histogram_.underflowBin);
      }
      if ((this.histogram_.overflowBin.min < r.max) &&
          (this.brushedBins_.indexOf(this.histogram_.overflowBin) < 0)) {
        this.brushedBins_.push(this.histogram_.overflowBin);
      }
      this.brushedBins_.sort(function(a, b) {
        return a.range.min - b.range.min;
      });

      // Prevent Infinity:
      var minBin = this.histogram_.getBinForValue(r.min);
      var maxBin = this.histogram_.getBinForValue(r.max);
      var binWidth = this.histogram_.centralBins[0].range.range;
      r.min = minBin ? Math.max(centralMin - binWidth, minBin.range.min) :
        centralMin - binWidth;
      r.max = maxBin ? Math.min(centralMax + binWidth, maxBin.range.max) :
        centralMax + binWidth;

      this.chart_.brushedRange = r;

      this.dispatchEvent(new tr.b.Event('brushed-bins-changed'));
    },

    onMouseDown_: function(chartEvent) {
      chartEvent.stopPropagation();
      if (!this.histogram_)
        return;
      this.mouseDownX_ = chartEvent.x;
      this.updateBrushedRange_(chartEvent.x);
    },

    onMouseMove_: function(chartEvent) {
      chartEvent.stopPropagation();
      if (!this.histogram_)
        return;
      this.updateBrushedRange_(chartEvent.x);
    },

    onMouseUp_: function(chartEvent) {
      chartEvent.stopPropagation();
      if (!this.histogram_)
        return;
      this.updateBrushedRange_(chartEvent.x);
      this.mouseDownX_ = undefined;
    },

    get histogram() {
      return this.histogram_;
    },

    set histogram(histogram) {
      this.histogram_ = histogram;
      this.updateContents_();
    },

    set isYLogScale(logScale) {
      this.chart_.isYLogScale = logScale;
    },

    updateContents_: function() {
      this.$.container.style.display = this.histogram_ ? '' : 'none';
      if (!this.histogram_) {
        this.$.nsamples.textContent = 0;
        this.$.average.setValueAndUnit(undefined, undefined);
        return;
      }

      this.$.nsamples.textContent = this.histogram_.numValues;
      this.$.average.setValueAndUnit(this.histogram_.average,
                                     this.histogram_.unit);
      if (this.histogram_.numNans > 0) {
        this.$.hadnans.style.display = '';
        this.$.nnans.textContent = this.histogram_.numNans;
      } else {
        this.$.hadnans.style.display = 'none';
      }

      var maximumBinValue = tr.b.Statistics.max(this.histogram_.allBins,
                                                function(bin) {
                                                  return bin.count;
                                                });
      var chartData = [];
      var binWidth = this.histogram_.centralBins[0].range.range;
      this.histogram_.allBins.forEach(function(bin) {
        var x = bin.range.min;
        if (x === -Number.MAX_VALUE) {
          if (!bin.count)
            return;
          x = bin.range.max - binWidth;
        }
        chartData.push({x: x,
                        y: bin.count});
      });
      chartData.sort(function(x, y) {
        return x.x - y.x;
      });
      this.$.container.style.display = chartData.length ? '' : 'none';
      this.chart_.data = chartData;
      this.brushedBins_ = [];
      this.chart_.brushedRange = new tr.b.Range();
    }
  });
  </script>
</polymer-element>
