  <!-- The <comp-page-sk> custom element declaration.

    Displays a comparison grid that allows to compare digests against each other.

    Attributes:
      None

    Events:
      None

    Methods:
      pageSelected - Called by the router when view is visible.

      pageDeselected - Called by the router when the view is no longer visible.

  -->

<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="bower_components/paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="bower_components/iron-icons/iron-icons.html">
<link rel="import" href="bower_components/iron-icons/notification-icons.html">
<link rel="import" href="bower_components/paper-button/paper-button.html">
<link rel="import" href="bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="bower_components/paper-listbox/paper-listbox.html">
<link rel="import" href="bower_components/paper-item/paper-item.html">
<link rel="import" href="bower_components/paper-dialog/paper-dialog.html">

<link rel="import" href="../common/imp/paramset.html">

<link rel="import" href="digest-details-sk.html">
<link rel="import" href="activity-sk.html">
<link rel="import" href="grid-sk.html">
<link rel="import" href="search-controls-sk.html">
<link rel="import" href="select-popup-sk.html">
<link rel="import" href="zoom-dialog-sk.html">
<link rel="import" href="sort-control-sk.html">
<link rel="import" href="shared-styles.html">

<dom-module id="comp-page-sk">
  <template>
    <style include="iron-flex iron-flex-alignment"></style>
    <style include="shared-styles">
      #heading {
        margin: 0;
      }

      #heading > span {
        font-weight: bold;
        margin-right: 1.5em;
        vertical-align: middle;
      }

      .headingContainer {
        padding-bottom: 2em;
      }

      .name {
        color: #7570B3;
      }

      .pos {
        color: #1B9E77;
      }

      .neg {
        color: #E7298A;
      }

      .unt {
        color: #A6761D;
      }

      .gridContainer {
        margin: 0 5em 3em 2em;
        overflow-x: auto;
      }

      .compDiffContainer {
        width: 50em;
      }

      .modButtonContainer {
        margin-bottom: 7em;
        width: 10em;
      }

      .diffMetricLabel {
        font-weight: bold;
        margin-left: 20em;
      }

      paper-dropdown-menu.diffMetricSelect {
        width: 8em;
        --paper-input-container-underline: {
            display: none;
        };
      }

      .moreColumns {
        vertical-align: middle;
      }

      .contentWrapper {
        padding: 0.5em;
      }

      #columnSortControl, #rowSortControl {
        width: 10em;
      }

      #rowSortControl {
        margin-top: 2em;
      }
    </style>
    <activity-sk id="activityCompare" busy="{{_hideAll}}"></activity-sk>
    <div class="vertical layout contentWrapper">
      <div class="horizontal layout center headingContainer">
        <div id="heading" hidden$="[[!_data.summary]]">
          <span class="name">Name: [[_data.summary.name]]</span>
          <span class="pos">Pos: [[_data.summary.pos]]</span>
          <span class="neg">Neg: [[_data.summary.neg]]</span>
          <span class="unt">Unt: [[_data.summary.untriaged]]</span>
        </div>

        <div>
          <!-- Note:The values of the dropdown need to match the metric ids on the backend -->
          <span class="diffMetricLabel">Diff Metric:</span>
          <paper-dropdown-menu label="Diff metric" class="diffMetricSelect" no-label-float>
            <paper-listbox id="diffMetric" class="dropdown-content" selected="{{_diffMetric}}" attr-for-selected="value">
              <paper-item value="combined">Combined</paper-item>
              <paper-item value="percent">Percent</paper-item>
            </paper-listbox>
          </paper-dropdown-menu>
        </div>
      </div>

      <div id="mainContent" class="horizontal layout wrap">
        <!-- left column -->
        <div class="vertical layout leftColumn">
          <div class="vertical layout modButtonContainer">
          <select-popup-sk id="paramsSelect"></select-popup-sk>

          </div>
          <search-controls-sk id="rowSearchControls" orientation="vertical"></search-controls-sk>
          <sort-control-sk id="rowSortControl" selection="{{_rowSorting}}" disabled="[[_hideAll]]"></sort-control-sk>
        </div>

        <!-- main column with grid -->
        <div class="vertical layout gridContainer">
          <div class="horizontal layout">
            <search-controls-sk id="colSearchControls" orientation="horizontal"></search-controls-sk>
            <sort-control-sk id="columnSortControl" selection="{{_colSorting}}" disabled="[[_hideAll]]"></sort-control-sk>
          </div>

          <div class="horizontal layout center">
            <div class="layout vertical center">
              <grid-sk id="gridCompare"></grid-sk>
              <paper-button  id="moreRowsButton" hidden$="[[_noMoreRows(_data)]]">
                <iron-icon icon="icons:expand-more"></iron-icon>
              </paper-button>
            </div>
            <div class="moreColumns">
              <paper-button id="moreColumnsButton" hidden$="[[_noMoreColumns(_data)]]">
                <iron-icon icon="icons:chevron-right"></iron-icon>
              </paper-button>
            </div>
          </div>
        </div>
        <div class="vertical layout compDiffContainer">
          <activity-sk id="activityCompDiff"></activity-sk>
          <digest-details-sk id="digestDetails"
               mode="detail"
               details="[[_digestDetails.digest]]"
               commits="[[_digestDetails.commits]]">
          </digest-details-sk>

          <digest-details-sk
               id="compDetails"
               mode="diff"
               details="[[_diffData.left]]"
               right="[[_diffData.right]]"
               diff="[[_diffData.diff]]"
               embedded>
          </digest-details-sk>
        </div>
      </div>
    </div>

    <!-- zoom dialog -->
    <zoom-dialog-sk></zoom-dialog-sk>
  </template>
  <script>
    (function() {
      // The current state of the page.
      var defaultQuery = {
        rowQuery: null,
        columnQuery: null,
        match: gold.DEFAULT_MATCH_CONFIGS,
        sortRows: "",
        rowsDir: "",
        sortColumns: "",
        columnsDir: "",
        metric: ""
      };

      // Default values for the row and column queries.
      var defaultRowQuery = sk.object.shallowCopy(gold.defaultSearchState);
      defaultRowQuery.limit = 10;
      var defaultColumnQuery = sk.object.shallowCopy(gold.defaultSearchState);
      defaultColumnQuery.pos = true;
      defaultColumnQuery.neg = true;
      defaultColumnQuery.unt = false;
      defaultColumnQuery.limit = 10;

      // Sort options for the row and column query.
      var SORT_FIELD_N_IMAGES = "count";
      var SORT_FIELD_DIFF = "diff";

      var rowSortOptions = [
          {field: SORT_FIELD_N_IMAGES, label: "#images"},
          {field: SORT_FIELD_DIFF, label: "Diff"}
        ];
      var colSortOptions = [ {field: SORT_FIELD_DIFF, label: "Diff"} ];
      var defaultRowSorting = {dir: gold.SORT_DESC, field: SORT_FIELD_DIFF};
      var defaultColSorting = {dir: gold.SORT_ASC, field: SORT_FIELD_DIFF};

      // ids fo the different diff metrics.
      var METRIC_COMBINED = "combined";
      var METRIC_PERCENT = "percent";

      Polymer({
        is: "comp-page-sk",

      behaviors: [gold.ZoomTargetBehavior, gold.PageStateBehavior],

        properties: {
          _data: {
            type: Object,
            value: null
          },
          _syncParams: {
            type: Boolean,
          },
          _diffMetric: {
              type: String
          }
        },

        ready: function() {
          this.listen(this.$.paramsSelect, 'changed-selection', '_handleMatchChanged');
          this.listen(this.$.gridCompare, 'diff-click', '_handleGridClick');
          this.listen(this.$.gridCompare, 'diff-dblclick', '_handleGridDblClick');
          this.listen(this.$.compDetails, 'zoom-clicked', "_handleZoomClicked");
          this.listen(this.$.rowSearchControls, 'state-change', '_handleRowQueryChange');
          this.listen(this.$.colSearchControls, 'state-change', '_handleColumnQueryChange');
          this.listen(this.$.moreColumnsButton, 'click', '_handleMoreColumns');
          this.listen(this.$.moreRowsButton, 'click', '_handleMoreRows');
          this.listen(this.$.rowSortControl, 'sort-changed', '_load');
          this.listen(this.$.columnSortControl, 'sort-changed', '_load');
          this.listen(this.$.diffMetric, 'iron-select', '_load');
          this.listen(this.$.digestDetails, 'triage', '_handleTriage');
          this.listen(this.$.compDetails, 'triage', '_handleTriage');
          this.$.rowSortControl.setItems(rowSortOptions);
          this.$.columnSortControl.setItems(colSortOptions);
          this._setDefaultState(gold.defaultSearchState, true);
        },

        pageSelected: function(ctx) {
          this._query = sk.object.shallowCopy(defaultQuery);
          this._query.match = gold.DEFAULT_MATCH_CONFIGS.slice()

          // Use the _state variable to as the row query and reflect the URL parameters.
          this._initState(ctx, this._getDefaultStateWithCorpus(defaultRowQuery));

          this._query.columnQuery = this._getDefaultStateWithCorpus(defaultColumnQuery);
          this._query.columnQuery.head = this._state.head;
          this._query.columnQuery.include = this._state.include;
          this._query.columnQuery.query = '';
          this._query.columnQuery = this._addCorpus(this._query.columnQuery);

          this.set("_colSorting", sk.object.shallowCopy(defaultColSorting));
          this.set("_rowSorting", sk.object.shallowCopy(defaultRowSorting));
          this.set("_diffMetric", METRIC_COMBINED);
          this._load();
        },

        pageDeselected: function() {},

        // _reset clears the detail views.
        _reset: function() {
          this.set('_diffData', {});
          this.set('_digestDetails', {});
        },

        _load: function() {
          this._reset();
          sk.get("/json/paramset").then(JSON.parse).then(function (json) {
            this.$.rowSearchControls.setParamSet(json);
            this.$.rowSearchControls.setState(this._state);

            this.$.colSearchControls.setParamSet(json);
            this.$.colSearchControls.setState(this._query.columnQuery);
            this.$.paramsSelect.setParamSet(json);
            this.$.paramsSelect.setSelection(this._query.match);
          }.bind(this)).catch(sk.errorMessage);

          // Update the query object.
          this._query.sortRows = this._rowSorting.field;
          this._query.rowsDir = this._rowSorting.dir;
          this._query.sortColumns = this._colSorting.field,
          this._query.columnsDir = this._colSorting.dir;
          this._query.metric = this._diffMetric;
          this._query.rowQuery = sk.object.shallowCopy(this._state);

          var activity = this.$.activityCompare;
          activity.startSpinner("Loading...");
          this.set("_data", null);
          sk.post("/json/cmp", JSON.stringify(this._query)).then(JSON.parse).then(function (json) {
            activity.stopSpinner();

            // If there is only one test set the summary. Otherwise inject it
            // into the individual rows.
            if (Object.keys(json.summaries).length === 1) {
              json.summary = json.summaries[json.grid.rows[0].test];
              json.summary.name = json.grid.rows[0].test;
            } else {
              // Inject the summaries into every test.
              for(var i=0; i < json.grid.rows.length; i++) {
                json.grid.rows[i].summary = json.summaries[json.grid.rows[i].test];
              }
            }

            this.set("_data", json);
            this.$.gridCompare.setValue(json.grid);
          }.bind(this)).catch(function(e) {
            activity.stopSpinner();
            sk.errorMessage(e);
          });
        },

        _handleGridClick: function(ev) {
          this.$.compDetails.clear();
          this.$.digestDetails.clear();
          if (ev.detail.colDigest) {
            var url = "/json/diff" +  gold.diffQuery(ev.detail.test, ev.detail.rowDigest, ev.detail.colDigest);
            this.$.gridCompare.clearSelection();
            gold.loadWithActivity(this, url, this.$.activityCompDiff, function(json) {
              this.set('_diffData', json);
              this.$.gridCompare.selectCell(ev.detail.rowIndex, ev.detail.columnIndex);
            }.bind(this));
          } else {
            var url = "/json/details" + gold.detailQuery(ev.detail.test, ev.detail.rowDigest);
            this.$.gridCompare.clearSelection();
            gold.loadWithActivity(this, url, this.$.activityCompDiff, function(json) {
              this.set('_digestDetails', json);
              this.$.gridCompare.selectRow(ev.detail.rowIndex);
            }.bind(this));
          }
        },

        _handleGridDblClick: function(ev) {
          if (ev.detail.colDigest) {
            var zoomDetail = {
              leftImgUrl: gold.imgHref(ev.detail.rowDigest),
              rightImgUrl: gold.imgHref(ev.detail.colDigest),
              middleImgUrl: gold.diffImgHref(ev.detail.rowDigest, ev.detail.colDigest),
              llabel: "Row",
              rlabel: "Column"
            };
            $$$('zoom-dialog-sk', this).open(zoomDetail);
          }
        },

        _handleTriage: function(ev) {
          ev.stopPropagation();
          sk.post('/json/triage', JSON.stringify(ev.detail)).catch(sk.errorMessage);
        },

        _handleMatchChanged: function(ev) {
          this._query.match = ev.detail;
          this._load();
        },

        _handleRowQueryChange: function(ev) {
          // Reload the page with the new  state in the query parameters.
          this._redirectToState(ev.detail);
        },

        _handleColumnQueryChange: function(ev) {
          this._query.columnQuery = this._addCorpus(ev.detail);
          this._load();
        },

        // copy the query string from the row query to the column query.
        _copyQueryStr: function() {
          var newState = sk.object.shallowCopy(this.$.colSearchControls.state);
          newState.query = this._state.query;
          this.$.colSearchControls.setState(this._state, true);
        },

        _handleMoreRows: function() {
          this._state.limit += 10;
          this._load();
        },

        _handleMoreColumns: function() {
          if (this._data) {
            this._query.columnQuery.limit += 10;
            this._load();
          }
        },

        _noMoreRows: function(data) {
          return data && (data.grid.rows.length >= data.grid.rowTotal);
        },

        _noMoreColumns: function(data) {
          if (data) {
            for(var i=0; i < data.grid.rows.length; i++) {
              if (data.grid.rows[i].values.length >= data.grid.columnsTotal) {
                return true;
              }
            }
            return false;
          }
          return true;
        }
      });

    })();

  </script>
</dom-module>
