<!--
  The common.js file must be included before this file.

  This in an HTML Import-able file that contains the definition
  of the following elements:

    <query-sk>

  To use this file import it:

    <link href="/res/imp/query.html" rel="import" />

  Usage:

    <query-sk></query-sk>

  Properties:
    currentquery - The current URL query formatted selections.

    showparams - A list of keys for params that should always be shown.

    hideparams - A list of keys for params that should never be shown.

    matches - A URL for reporting the number of items that match
       the currentquery. If not the empty string then a request
       will be made to:

          matches + '?' + currentquery

       The response must have the form of:

       {
         "matches": NNNN,
       }

    noclear - Don't display the clear selections button.

    feedback - If set shows the current selections as string values.

  Methods:
    setParamSet(set) - Set the params to be displayed.

    clearSelections() - Clear all selections.

    setSelections(sel) - Set the current selections. Must be called after
      setParamSet.

  Events:
    'query-change'
      The 'sk-query' element will produce 'query-change' events when the query
      parameters chosen have changed. The event contains the current
      selections formatted as a URL query, found in e.detail.
-->
<link rel="import" href="/res/imp/bower_components/paper-input/paper-input.html">
<link rel="import" href="/res/common/imp/toggle.html">
<link rel="stylesheet" href="/res/common/css/md.css" type="text/css" media="all" />
<link rel="import" href="/res/imp/bower_components/iron-flex-layout/iron-flex-layout-classes.html">

<style type="text/css" media="screen">
  #moreContainer.hide {
    display: none;
  }
</style>

<dom-module id="query-sk">
  <style include="iron-flex iron-flex-alignment">

    #moreContainer.hide {
      display: none;
    }

    select {
      border: solid 1px lightgray;
      padding: 0.2em;
    }

    option {
      padding: 0.2em;
    }

    .node {
      margin: 0.5em;
    }

    .topControls {
      min-width: 40em;
    }

    .currSelection {
      padding-left: 2em;
      min-width: 40em;
    }

  </style>
  <template>
      <div class="horizontal layout">
        <div class="vertical layout topControls">
          <div>
            <button id="clear">Clear selections</button>
            <span id="count"></span>
          </div>
          <div>
            <paper-input id="fast" label="Filter"></paper-input>
          </div>
        </div>
        <div hidden$="{{!feedback}}" class="currSelection">
          <pre>{{_splitAmp(currentquery)}}</pre>
        </div>
      </div>
      <div id=inputsContainer class="horizontal layout wrap">
  			<template is="dom-repeat" items="[[_primary]]" as="sel">
  				<div class="node">
  					<h4>[[sel.name]]</h4>
  					<select size=9 data-name$="[[sel.name]]" multiple=true initial-count=1000>
  						<template is="dom-repeat" items="[[sel.values]]" as="o">
  							<option label$="[[o]]">[[o]]</option>
  						</template>
  					</select>
  				</div>
  			</template>
      </div>
    <toggle-display-sk id=toggle classname=hide>More...</toggle-display-sk>
      <div id=moreContainer class="horizontal layout wrap hide">
  			<template is="dom-repeat" items="[[_secondary]]" as="sel">
  				<div class="node">
  					<h4>[[sel.name]]</h4>
  					<select size=9 data-name$="[[sel.name]]" multiple=true>
  						<template is="dom-repeat" items="[[sel.values]]" as="o" initial-count=1000>
  							<option label$="[[o]]">[[o]]</option>
  						</template>
  					</select>
  				</div>
  			</template>
      </div>
  </template>
</dom-module>
<script>
  (function () {
    Polymer({
      is: 'query-sk',

      properties: {
        currentquery: {
          type: String,
          value: "",
        },
        matches: {
          type: String,
          value: '/query/0/-1/',
          reflectToAttribute: true
        },
        noclear: {
          type: Boolean,
          value: false,
          reflectToAttribute: true
        },
        showparams: {
          type: Array,
          value: function() {
            return [
              'name',
              'bench_type',
              'os',
              'source_type',
              'scale',
              'extra_config',
              'config',
              'arch',
              'sub_result'
            ];
          },
          reflectToAttribute: true
        },
        hideparams: {
          type: Array,
          value: function() { return []; }
        },
        feedback: {
          type: Boolean,
          value: false,
          notify: true
        }
      },

      ready: function() {
        // Both _primary and _secondary are arrays of objects that look like:
        //
        //  {
        //    name: "config",
        //    values: ["565", "8888", "gpu"]
        //  }
        //
        // Where _primary contains selections that are in the showparams, and
        // _secondary contains all the other selections.
        this._primary = [];
        this._secondary = [];

        this.$.inputsContainer.addEventListener('change', this._fireChange.bind(this));
        this.$.moreContainer.addEventListener('change', this._fireChange.bind(this));
        this.$.clear.addEventListener('click', this.clearSelections.bind(this));
        if (this.noclear) {
          this.$.clear.style.display = 'none';
        }
        this.$.fast.addEventListener('input', function (e) {
          this.$.toggle.open();
          this._fastFilter();
        }.bind(this));
      },

      _splitAmp: sk.query.splitAmp,

      _fastFilter: function() {
        var filters = this.$.fast.value.trim().toLowerCase().split(/\s+/);
        // Create a closure that returns true if the given label
        // matches the filter.
        var matches = function(s) {
          s = s.toLowerCase();
          for (var i = 0; i < filters.length; i++) {
            if (s.indexOf(filters[i]) >= 0) {
              return true;
            }
          }
          return false;
        };
        $$('option', this).forEach(function (ele) {
          ele.hidden = !matches(ele.getAttribute('label'));
        });
      },

      _fireChange: function() {
        var q = this._selectionsAsQuery();

        // Only fire if we see a real change in the state.
        if (q != this.currentquery) {
          this.currentquery = q;
          this.dispatchEvent(new CustomEvent('query-change', { detail: q, bubbles: true }));
          var countEle = this.$.count;
          if (this.matches) {
            sk.get(this.matches + "?" + q).then(JSON.parse).then(function (json) {
              countEle.innerHTML = json['matches'] + ' lines selected<br />';
            });
          }
        }
      },

      // _selectionsAsQuery bundles up the current set of selections as a URL query
      // suitable for passing to the /query/ endpoint.
      //
      _selectionsAsQuery: function () {
        var sel = [];
        $$('option', this).forEach(function (option) {
          if (!option.selected) {
            return;
          }
          var key = option.parentElement.dataset.name;
          sel.push(encodeURIComponent(key) + '=' + encodeURIComponent(option.value));
        });
        return sel.join('&');
      },

      clearSelections: function() {
        $$('option', this).forEach(function (elem) {
          elem.selected = false;
        });
        this.$.fast.value = '';
        this._fastFilter();
        this._fireChange();
        this.$.count.textContent = '';
      },

      // Selects all the values in paramset.
      //
      // The argument is a URL query encoded paramset.
      setSelections: function (paramset) {
        paramset = sk.query.toParamSet(paramset);
        this.clearSelections();
        $$('option', this).forEach(function (sel) {
          var params = paramset[sel.parentElement.dataset.name];
          if (params) {
            sel.selected = params.indexOf(sel.value) !== -1;
          }
        });
        this._fireChange();
      },

      // When paramset is changed we rebuild _primary and _secondary.
      //
      // The paramset is an object that maps selection names
      // to a list of selection values, not necessarily in alphabetical
      // order.
      setParamSet: function (paramset) {
        var keylist = Object.keys(paramset).sort();
        this.splice('_primary', 0, this._primary.length);
        this.splice('_secondary', 0, this._secondary.length);
        for (var i = 0; i < keylist.length; i++) {
          var key = keylist[i];
          if ((this.hideparams.length > 0) && (this.hideparams.indexOf(key) != -1)) {
            continue;
          }

          var sel = {
            name: key,
            values: paramset[key].sort()
          };
          if (this.showparams.length == 0 || this.showparams.indexOf(key) != -1) {
            this.push('_primary', sel);
          } else {
            this.push('_secondary', sel);
          }
        }
        this.$.toggle.hidden = (this._secondary.length == 0);
      }
    });
  })();
</script>
