<!--
  The <search-page2-sk> custom element declaration.

  Shows the results of a search request.
  It sends the query string as a JSON request to the
  search entpoint ('/json/search') and renders the result.

  It assumes to the be part of a client site routed system
  of views and therefore offers the 'pageSelected' and 'pageUnselected'
  functions. These need to be called whenever the page goes
  in and out of view.

  Attributes:
    None

  Methods:
    pageSelected(ctx) - Called by the router when the view becomes visible.
          ctx is the context provided in the route dispatch of page.js.

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

  Events:
    None

  Mailboxes:
    None
-->

<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/iron-icons/iron-icons.html">
<link rel="import" href="bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="bower_components/paper-button/paper-button.html">
<link rel="import" href="bower_components/paper-menu-button/paper-menu-button.html">
<link rel="import" href="bower_components/paper-toggle-button/paper-toggle-button.html">

<link rel="import" href="activity-sk.html">
<link rel=import href="detail-list2-sk.html">
<link rel=import href="digest-details-sk.html">
<link rel=import href="search-controls-sk.html">
<link rel=import href="trybot-controls-sk.html">
<link rel="import" href="../common/imp/triage-sk.html">

<dom-module id="search-page2-sk">
  <template>
    <style include="iron-flex iron-flex-alignment"></style>
    <style include="shared-styles">
      digest-details-sk {
        display: block;
        box-shadow: 3px 3px 6px 1px rgba(133,133,133,1);
        margin-top: 1em;
        margin-bottom: 1em;
        margin-left: 0;
        margin-right: 0;
        padding-left: 1em;
        padding-top: 1em;
        padding-bottom: 1em;
        padding-right: 0;
      }

      digest-details-sk[data-focus] {
        box-shadow: 3px 3px 6px 5px #FF7F00;
      }

      #missing {
        padding-top: 2em;
      }

      .searchPageWrapper {
        padding-left: 1em;
        padding-top: 1em;
        margin-left:1em;
        margin-right: 3em;
      }

      #triggerSearchButton {
        font-size: 18px;
      }

      .helpIconContainer {
        padding-left: 3em;
      }

      paper-button {
        min-width: 2em;
        margin: 5px;
        background: #eee;
      }

      .actionMenu {
        max-width: 10em;
        margin-left: 10em;
      }

      .actionButton {
        color: green;
      };

      #closestButton[raised] > iron-icon {
        color: #bbb;
      }

      #closestButton[raised] {
        background: #fff;
      }

      #closestButton:hover,
      #closestButton[raised]:hover {
        background: #ddd;
      }

      .searchResponse {
        padding: 1em;
        margin: 1em 1em 1em 0;
        border: 1px solid #555555;
      }
    </style>

    <div class="searchPageWrapper layout vertical">
      <activity-sk id="activityBar" busy="{{_hideAll}}"></activity-sk>
      <div class="layout horizontal">
          <search-controls-sk id="searchControls" beta></search-controls-sk>
          <div>
            <paper-button id="triggerSearchButton" raised disabled="[[_hideAll]]">Search</paper-button>
          </div>

          <paper-menu-button close-on-activate no-animations class="actionMenu">
            <paper-button class="dropdown-trigger actionButton" raised>Actions</paper-button>
            <paper-menu class="dropdown-content">
              <paper-item id="actionTestView">Switch To Test View</paper-item>
              <paper-item id="actionBulkTriage">Bulk Triage</paper-item>
              <paper-item id="actionExport">Export</paper-item>
              <paper-item id="actionLegacySearch">Legacy Search</paper-item>
              <paper-item id="actionHelpDialog">Help</paper-item>
            </paper-menu>
          </paper-menu-button>
      </div>

      <div class="searchResponse" hidden$="[[_noResult(_allData)]]">
        Displaying: [[_allData.size]] of [[_allData.digests.length]] images starting at [[_allData.offset]]<br>
        UniqueTests Visible: [[_uniqueTests.length]] <br>
        UniqueTests Total: [[_uniqueTestsAll.length]]<br>
      </div>
      <trybot-controls-sk id="trybotControls"></trybot-controls-sk>

      <div hidden$="[[_hideAll]]">
        <div id="missing" hidden$="[[_nonEmptyResult(data)]]">
          No digests match your query.
        </div>
        <div hidden$="[[_emptyResult(data)]]">
           <detail-list2-sk id="detailList" data="[[data]]">
          </detail-list2-sk>
        </div>
      </div>
    </div>
    <paper-dialog id="bulkDialog" with-backdrop>
      <h2>Bulk Triage</h2>
      <p>Assign the status to all images on this page at once.</p>
      <div class="layout horizontal">
        <triage-sk value="{{_bulkStatus}}" id="triageControls"></triage-sk>
        <paper-button id="closestButton" on-tap="_handleClosestButton" title="Assign status of closest image">
          <iron-icon icon="icons:view-agenda"></iron-icon>
        </paper-button>
      </div>
      <div hidden$="[[_noMore(_allData)]]">
        <paper-toggle-button checked="{{_triageAll}}">Triage all [[_getBulkTriageCount(_allData.digests, _bulkStatus)]].</paper-toggle-button>
      </div>
      <div class="buttons">
        <paper-button raise dialog-dismiss>Cancel</paper-button>
        <paper-button raise dialog-dismiss on-tap="_doBulkTriage" disabled="[[!_bulkStatus]]">Triage</paper-button>
      </div>
    </paper-dialog>

  </template>
  <script>
    Polymer({
      is: "search-page2-sk",

      behaviors: [gold.PageStateBehavior],

      properties: {
        data: {
          type: Object,
          value: function() { return {}; }
        },
        _bulkStatus: {
          type: String,
          value: "",
          observer: "_handleBulkStatusChanged"
        },
        _triageAll: {
          type: Boolean,
          value: false
        }
      },

      ready: function() {
        this.listen(this.$.searchControls, 'state-change', '_handleStateChange');
        this.listen(this.$.triggerSearchButton, 'tap', '_handleSearchButton');
        this.listen(this.$.actionTestView, 'tap', '_handleSwitchToByTest');
        this.listen(this.$.actionBulkTriage, 'tap', '_handleBulkButton');
        this.listen(this.$.actionExport, 'tap', '_handleExport');
        this.listen(this.$.actionLegacySearch, 'tap', '_handleLegacySearchButton');
        this.listen(this.$.actionHelpDialog, 'tap', '_openHelpDialog');
        this._setDefaultState(gold.defaultSearchState, false);
      },

      pageSelected: function(ctx) {
        this.set('data', {});
        this.set('_allData', {});
        this.$.detailList.startUse();

        // Initialize the state and set values of the controls.
        this._initState(ctx, this._getDefaultStateWithCorpus());
        this.$.searchControls.setState(this._state);

        // _loadParamset will also trigger loading the data.
        this._loadParamset();
      },

      pageDeselected: function() {
        this.$.detailList.endUse();
      },

      _handleSearchButton: function(ev) {
        // Reload the page with the current state of the controls.
        this._redirectToState(this.$.searchControls.state);
      },

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

      _handleSwitchToByTest: function() {
        this._redirectToState({}, "/list");
      },

      _openHelpDialog: function(ev) {
        this.$.detailList.openHelpDialog();
      },

      _handleBulkButton: function(ev) {
        this.set("_bulkStatus", "");
        this.set("_triageAll", false);
        this.$.bulkDialog.open();
      },

      _handleExport: function(ev) {
        var url = this._getRedirectURL({}, "/json/export");
        window.open(url, "_blank");
      },

      _handleLegacySearchButton: function(ev) {
        this._redirectToState({}, "/legacysearch");
      },

      _handleClosestButton: function(ev) {
        this.set("_bulkStatus", '=');
      },

      _handleBulkStatusChanged: function(newVal) {
        if (newVal === '=') {
          Polymer.dom(this.$.closestButton).removeAttribute('raised');
        } else {
          Polymer.dom(this.$.closestButton).setAttribute('raised', '');
        }
      },

      // _statusClosest returns label based on whether the digest is closest to
      // a positive or negative image.
      _statusClosest:function(digest) {
         if (digest.closestRef === gold.REF_NEG) {
           return gold.NEGATIVE;
        }
        return gold.POSITIVE;
      },

      // _getBulkTriageCount returns the number of digests that will be triaged
      // in a bulk triage operation.
      _getBulkTriageCount: function(digests, bulkStatus) {
        if (bulkStatus !== '=') {
          return digests.length;
        }

        // If we compare to the closest we only show the number of digests
        // that actually have a reference image.
        var count = 0;
        for(var i=0; i < digests.length; i++) {
          if (digests[i].closestRef !== '') {
            count++;
          }
        }
        return count;
      },

      _doBulkTriage: function(ev) {
        var targetStatus = this.$.triageControls.value;
        var digests = (this._triageAll) ? this._allData.digests : this.data.digests;
        var triageList = [];
        if (targetStatus === '=') {
          for(var i=0; i < digests.length; i++) {
            if (digests[i].closestRef !== '') {
              var status = this._statusClosest(digests[i]);
              triageList.push([digests[i].test, digests[i].digest, status]);
            }
          }
        } else {
          for(var i=0; i < digests.length; i++) {
            triageList.push([digests[i].test, digests[i].digest, targetStatus]);
          }
        }
        var query = new gold.TriageQuery(triageList);
        query.setIssue(sk.robust_get(this._issue, ["id"]));
        this.$.activityBar.startSpinner("Triaging ...");
        sk.post('/json/triage', JSON.stringify(query)).then(function() {
          this.$.activityBar.stopSpinner();
        }.bind(this)).catch(function(e) {
          this.$.activityBar.stopSpinner();
          sk.errorMessage(e);
        }.bind(this));
      },

      _load: function() {
        var q = window.location.search;
        sk.get("/json/search" + q).then(JSON.parse).then(function (json) {
          // Split out the digests that are being displayed and keep a copy
          // of all digests that matched the query.
          var displayData = sk.object.shallowCopy(json);
          displayData.digests = displayData.digests.slice(json.offset, json.offset+json.size);
          this.set('_allData', json);

          this.set('_uniqueTestsAll', this._getUniqueTests(json.digests));
          this.set('_uniqueTests', this._getUniqueTests(displayData.digests));

          this.set('data', displayData);
          this.set('_issue', json.issue);
          this.$.trybotControls.setIssue(json.issue);
          this.$.activityBar.stopSpinner();
        }.bind(this)).catch(function(e) {
          this.$.activityBar.stopSpinner();
          sk.errorMessage(e);
        }.bind(this));
      },

      _getUniqueTests: function(digests) {
        var unique = {};
        for(var i=0; i < digests.length; i++) {
          unique[digests[i].test] = true;
        }
        return Object.keys(unique);
      },

      _loadParamset: function() {
        this.$.activityBar.startSpinner("Loading ...");

        // If we already have a paramset then trigger load right away.
        // TODO(stephana): Improve this so that we load the paramset with the
        // data.
        var loadTriggered = false;
        if (this._paramSet) {
          this._load();
          loadTriggered = true;
        }

        sk.get("/json/paramset").then(JSON.parse).then(function (json) {
          this.$.searchControls.setParamSet(json);
          this._paramSet = json;
          if (!loadTriggered) {
            this._load();
          }
        }.bind(this)).catch(sk.errorMessage);
      },

      _entryId: function(item) {
        // Make sure it's a valid selector.
        return (item.test + '_' + item.digest).replace(/[^_A-Za-z0-9]/g, '_');
      },

      // Returns true if there was a query and result is not empty.
      _nonEmptyResult: function(data) {
        return !data.digests || data.digests.length > 0;
      },

      // Returns true if there was a query and the result is empty.
      _emptyResult: function(data) {
        return !data.digests || data.digests.length === 0;
      },

      _noResult: function(data) {
        return !data.digests;
      },

      _noMore: function(allData) {
        return (allData.digests && allData.digests.length <= allData.size);
      }
    });
  </script>
</dom-module>
