<!DOCTYPE html>
<!--
Copyright (c) 2014 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/ui.html">
<link rel="import" href="/base/ui/color_scheme.html">
<link rel="import" href="/base/ui/d3.html">

<style>
  * /deep/ .chart-base #title {
    font-size: 16pt;
  }

  * /deep/ .chart-base {
    font-size: 12pt;
    -webkit-user-select: none;
    cursor: default;
  }

  * /deep/ .chart-base .axis path,
  * /deep/ .chart-base .axis line {
    fill: none;
    shape-rendering: crispEdges;
    stroke: #000;
  }
</style>

<template id="chart-base-template">
  <svg> <!-- svg tag is dropped by ChartBase.decorate. -->
    <g xmlns="http://www.w3.org/2000/svg" id="chart-area">
      <g class="x axis"></g>
      <g class="y axis"></g>
      <text id="title"></text>
    </g>
  </svg>
</template>

<script>
'use strict';

tr.exportTo('tr.b.ui', function() {
  var THIS_DOC = document.currentScript.ownerDocument;

  var svgNS = 'http://www.w3.org/2000/svg';
  var highlightIdBoost = tr.b.ui.getColorPaletteHighlightIdBoost();

  function getColorOfKey(key, selected) {
    var id = tr.b.ui.getColorIdForGeneralPurposeString(key);
    if (selected)
      id += highlightIdBoost;
    return tr.b.ui.getColorPalette()[id];
  }

  /**
   * A virtual base class for basic charts that provides X and Y axes, if
   * needed, a title, and legend.
   *
   * @constructor
   */
  var ChartBase = tr.b.ui.define('svg', undefined, svgNS);

  ChartBase.prototype = {
    __proto__: HTMLUnknownElement.prototype,

    decorate: function() {
      this.classList.add('chart-base');
      this.chartTitle_ = undefined;
      this.data_ = undefined;
      this.seriesKeys_ = undefined;
      this.width_ = 400;
      this.height_ = 300;

      // This should use tr.b.instantiateTemplate. However, creating
      // svg-namespaced elements inside a template isn't possible. Thus, this
      // hack.
      var template = THIS_DOC.querySelector('#chart-base-template');
      var svgEl = template.content.querySelector('svg');
      for (var i = 0; i < svgEl.children.length; i++)
        this.appendChild(svgEl.children[i].cloneNode(true));

      // svg likes to take over width & height properties for some reason. This
      // works around it.
      Object.defineProperty(
          this, 'width', {
            get: function() {
              return this.width_;
            },
            set: function(width) {
              this.width_ = width;
              this.updateContents_();
            }
          });
      Object.defineProperty(
          this, 'height', {
            get: function() {
              return this.height_;
            },
            set: function(height) {
              this.height_ = height;
              this.updateContents_();
            }
          });
    },

    get chartTitle() {
      return chartTitle_;
    },

    set chartTitle(chartTitle) {
      this.chartTitle_ = chartTitle;
      this.updateContents_();
    },

    get chartAreaElement() {
      return this.querySelector('#chart-area');
    },

    get data() {
      return this.data_;
    },

    setSize: function(size) {
      this.width_ = size.width;
      this.height_ = size.height;
      this.updateContents_();
    },

    get margin() {
      var margin = {top: 20, right: 20, bottom: 30, left: 50};
      if (this.chartTitle_)
        margin.top += 20;
      return margin;
    },

    get chartAreaSize() {
      var margin = this.margin;
      return {
        width: this.width_ - margin.left - margin.right,
        height: this.height_ - margin.top - margin.bottom
      };
    },

    getLegendKeys_: function() {
      throw new Error('Not implemented');
    },

    updateScales_: function(width, height) {
      throw new Error('Not implemented');
    },

    updateContents_: function() {
      var margin = this.margin;
      var width = this.chartAreaSize.width;
      var height = this.chartAreaSize.height;

      var thisSel = d3.select(this);
      thisSel.attr('width', this.width_);
      thisSel.attr('height', this.height_);

      var chartAreaSel = d3.select(this.chartAreaElement);
      chartAreaSel.attr(
          'transform',
          'translate(' + margin.left + ',' + margin.top + ')');

      this.updateScales_(width, height);

      // Axes.
      if (this.xScale_ && this.yScale_) {
        var xAxisRenderer = d3.svg.axis()
            .scale(this.xScale_)
            .orient('bottom');

        var yAxisRenderer = d3.svg.axis()
            .scale(this.yScale_)
            .orient('left');

        chartAreaSel.select('.x.axis')
            .attr('transform', 'translate(0,' + height + ')')
            .call(xAxisRenderer);

        chartAreaSel.select('.y.axis')
            .call(yAxisRenderer);
      }

      // Title.
      var titleSel = chartAreaSel.select('#title');
      if (this.chartTitle_) {
        titleSel.attr('transform', 'translate(' + width * 0.5 + ',-5)')
            .style('display', undefined)
            .style('text-anchor', 'middle')
            .attr('class', 'title')
            .attr('width', width)
            .text(this.chartTitle_);
      } else {
        titleSel.style('display', 'none');
      }

      // Basics
      this.updateLegend_();
    },

    updateLegend_: function() {
      var keys = this.getLegendKeys_();
      if (keys === undefined)
        return;

      var chartAreaSel = d3.select(this.chartAreaElement);
      var chartAreaSize = this.chartAreaSize;

      var legendEntriesSel = chartAreaSel.selectAll('.legend')
          .data(keys.slice().reverse());

      legendEntriesSel.enter()
          .append('g')
          .attr('class', 'legend')
          .attr('transform', function(d, i) {
            return 'translate(0,' + i * 20 + ')';
          }).append('text').text(function(key) {
            return key;
          });
      legendEntriesSel.exit().remove();

      legendEntriesSel.attr('x', chartAreaSize.width - 18)
          .attr('width', 18)
          .attr('height', 18)
          .style('fill', function(key) {
            var selected = this.currentHighlightedLegendKey === key;
            return getColorOfKey(key, selected);
          }.bind(this));

      legendEntriesSel.selectAll('text')
        .attr('x', chartAreaSize.width - 24)
        .attr('y', 9)
        .attr('dy', '.35em')
        .style('text-anchor', 'end')
        .text(function(d) { return d; });
    },

    get highlightedLegendKey() {
      return this.highlightedLegendKey_;
    },

    set highlightedLegendKey(highlightedLegendKey) {
      this.highlightedLegendKey_ = highlightedLegendKey;
      this.updateHighlight_();
    },

    get currentHighlightedLegendKey() {
      if (this.tempHighlightedLegendKey_)
        return this.tempHighlightedLegendKey_;
      return this.highlightedLegendKey_;
    },

    pushTempHighlightedLegendKey: function(key) {
      if (this.tempHighlightedLegendKey_)
        throw new Error('push cannot nest');
      this.tempHighlightedLegendKey_ = key;
      this.updateHighlight_();
    },

    popTempHighlightedLegendKey: function(key) {
      if (this.tempHighlightedLegendKey_ != key)
        throw new Error('pop cannot happen');
      this.tempHighlightedLegendKey_ = undefined;
      this.updateHighlight_();
    },

    updateHighlight_: function() {
      // Update label colors.
      var chartAreaSel = d3.select(this.chartAreaElement);
      var legendEntriesSel = chartAreaSel.selectAll('.legend');

      var that = this;
      legendEntriesSel.each(function(key) {
        var highlighted = key == that.currentHighlightedLegendKey;
        var color = getColorOfKey(key, highlighted);
        this.style.fill = color;
        if (highlighted)
          this.style.fontWeight = 'bold';
        else
          this.style.fontWeight = '';
      });
    }
  };

  return {
    getColorOfKey: getColorOfKey,
    ChartBase: ChartBase
  };
});
</script>
