<!-- The <paramset-sk> custom element declaration.

  The paramset-sk element displays a paramset and generates events
  as the params and labels are clicked.

  Attributes:
    clickable - If true then keys and values look like they are clickable
      i.e. via color, text-decoration, and cursor. If clickable is false
      then this element won't generate the events listed below, and the
      keys and values are not styled to look clickable. Setting both
      clickable and clickable-values is unsupported.

    clickable-values - If true then only the values are clickable. Setting
      both clickable and clickable-values is unsupported.

  Events:
    paramset-key-click - Generated when the key for a paramset is clicked.
      The name of the key will be sent in e.detail.key. The value of
      e.detail.ctrl is true if the control key was pressed when clicking.

       {
         key: "arch",
         ctrl: false,
       }

    paramset-key-value-click - Generated when one value for a paramset is clicked.
      The name of the key will be sent in e.detail.key, the value in
      e.detail.value. The value of e.detail.ctrl is true if the control key
      was pressed when clicking.

       {
         key: "arch",
         value: "x86",
         ctrl: false,
       }

  Methods:
    setParamSets([p1, p2, ...], [title1, title2, ...]) - p1 and p2 are param sets.
      title1 and title2 are strings to use as the title of the columns.
      The titles are optional and no title will be displayed if they are not supplied.

    setHighlight(params) - Highlights all the values that match the given params.

    clearHighlight() - Removes any highlighting.

  Styles:
    --paramset-highlight-color - Sets the color of the values when highlighted.

    --paramset-clickable-color - Sets the color of the keys and values when
        they are clickable.
-->
<dom-module id="paramset-sk">
  <style type="text/css" media="screen">
      td,
      th {
        padding: 0.1em;
      }

      th {
        text-align: left;
      }

      div {
        display: inline-block;
        padding: 0.2em;
      }

      .clickable th,
      .clickable div {
        cursor: pointer;
        color: var(--paramset-clickable-color, #1f78b4);
      }

      .clickable th:hover,
      .clickable div:hover {
        text-decoration: underline;
      }

      .clickable-values div {
        cursor: pointer;
        color: var(--paramset-clickable-color, #1f78b4);
      }

      .clickable-values div.highlight {
        color: var(--paramset-highlight-color, #FF7F00);
        animation-duration: 100ms;
        animation-name: flash;
        animation-timing-function: linear;
      }

      .clickable-values div:hover {
        text-decoration: underline;
      }

      :host {
        display: block;
      }

      .clickable .highlight,
      .highlight {
        color: var(--paramset-highlight-color, #FF7F00);
        animation-duration: 200ms;
        animation-name: flash;
        animation-timing-function: ease-in-out;
      }

      @keyframes flash {
        from {
          background-color: white;
        }
        to {
          background-color: #FDBF6F;
        }
      }

      tr:nth-child(even) {
        background-color: #eee;
      }
    </style>
  <template>
    <table id="table" class$="{{_computeClass(clickable,clickableValues)}}">
      <tbody><tr>
        <th></th>
        <template is="dom-repeat" items="{{_titles}}" as="t">
          <th>{{t}}</th>
        </template>
      </tr>
      <template is="dom-repeat" items="{{_sortedKeys}}" as="key">
        <tr>
          <th data-key$="{{key}}">{{key}}</th>
          <template is="dom-repeat" items="{{_paramsets}}" as="paramset">
            <td>
              <template is="dom-repeat" items="{{_computeItems(paramset, key)}}" as="value">
                <div data-key$="{{key}}" data-value$="{{value}}">{{value}}</div>
              </template>
            </td>
          </template>
        </tr>
      </template>
    </tbody></table>
  </template>
  <script>
    Polymer({
      is: 'paramset-sk',

      properties: {
        clickable: {
          type: Boolean,
          value: false,
          reflectToAttribute: true,
        },
        clickableValues: {
          type: Boolean,
          value: false,
          reflectToAttribute: true,
        },
      },

      ready: function () {
        this._titles = [];
        this._paramsets = [];
        this._sortedKeys = [];
        this.$.table.addEventListener('click', this._clickHandler.bind(this));
      },

      setParamSets: function (paramsets, titles) {
        this._paramsets = paramsets;
        // Fix up titles if missing.
        if (!titles) {
          titles = [];
          for (var i = paramsets.length - 1; i >= 0; i--) {
            titles.push('');
          }
        }
        this._titles = titles;
        // Compute a rolled up set of all parameter keys across all paramsets.
        var allKeys = {};
        paramsets.forEach(function (p) {
          var keys = Object.keys(p);
          keys.forEach(function (key) {
            allKeys[key] = true;
          });
        });
        this._sortedKeys = Object.keys(allKeys);
        this._sortedKeys.sort();
      },

      setHighlight: function (params) {
        $$('div', this).forEach(function (ele) {
          var key = ele.dataset.key;
          ele.classList.toggle('highlight', key && params[key] == ele.dataset.value);
        });
      },

      clearHighlight: function () {
        $$('div', this).forEach(function (ele) {
          ele.classList.remove('highlight');
        });
      },

      _clickHandler: function (e) {
        if (!this.clickable && !this.clickableValues) {
          return;
        }
        var t = e.target;
        if (!t.dataset.key) {
          return;
        }
        if (t.nodeName == 'TH') {
          if (!this.clickable) {
            return;
          }
          var detail = {
            key: t.dataset.key,
            ctrl: e.ctrlKey
          };
          this.dispatchEvent(new CustomEvent('paramset-key-click', {
            detail: detail,
            bubbles: true
          }));
        } else if (t.nodeName == 'DIV') {
          var detail = {
            key: t.dataset.key,
            value: t.dataset.value,
            ctrl: e.ctrlKey
          };
          this.dispatchEvent(new CustomEvent('paramset-key-value-click', {
            detail: detail,
            bubbles: true
          }));
        }
      },

      _computeClass: function (clickable, clickableValues) {
        if (clickableValues) {
          return 'clickable-values';
        } else if (clickable) {
          return 'clickable';
        } else {
          return '';
        }
      },

      _computeItems: function (paramset, key) {
        return paramset[key];
      }
    });
  </script>
</dom-module>
