<!--
Copyright (C) 2015 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../behaviors/keyboard-shortcut-behavior.html">
<link rel="import" href="../behaviors/rest-client-behavior.html">
<link rel="import" href="gr-ajax.html">

<dom-module id="gr-file-list">
  <template>
    <style>
      :host {
        display: block;
      }
      .tableContainer {
        overflow-x: auto;
      }
      table {
        border-collapse: collapse;
        width: 100%;
      }
      table a {
        display: block;
      }
      td {
        padding: 2px 0;
        white-space: nowrap;
      }
      th {
        text-align: left;
      }
      .positionIndicator {
        padding-left: .25em;
        visibility: hidden;
      }
      tr[selected] {
        background-color: #ebf5fb;
      }
      tr[selected] .positionIndicator {
        visibility: visible;
      }
      .status {
        width: 20px;
      }
      .drafts {
        color: #C62828;
        font-weight: bold;
      }
    </style>
    <gr-ajax id="filesXHR"
        url="[[_computeFilesURL(changeNum, patchNum)]]"
        on-response="_handleResponse"></gr-ajax>
    <gr-ajax id="draftsXHR"
        url="[[_computeDraftsURL(changeNum, patchNum)]]"
        last-response="{{_drafts}}"></gr-ajax>
    </gr-ajax>
    <div class="tableContainer">
      <table>
        <tr>
          <th></th>
          <th></th>
          <th>Path</th>
          <th>Comments</th>
          <th>Stats</th>
        </tr>
        <template is="dom-repeat" items="{{files}}" as="file">
          <tr class="fileRow" selected$="[[_computeFileSelected(index, selectedIndex)]]">
            <td class="positionIndicator">&#x25b6;</td>
            <td class="status">[[file.status]]</td>
            <td class="path">
              <a class="file"
                 href$="[[_computeDiffURL(changeNum, patchNum, file.__path)]]">[[file.__path]]</a>
            </td>
            <td>
              <span class="drafts">[[_computeDraftsString(_drafts, file.__path)]]</span>
              <span class="comments">[[_computeCommentsString(comments, patchNum, file.__path)]]</span>
            </td>
            <td>
              +<span>[[file.lines_inserted]]</span> lines,
              -<span>[[file.lines_deleted]]</span> lines
            </td>
          </tr>
        </template>
      </table>
    </div>
  </template>
  <script>
  (function() {
    'use strict';

    Polymer({
      is: 'gr-file-list',

      properties: {
        patchNum: String,
        changeNum: String,
        comments: Object,
        files: Array,
        selectedIndex: {
          type: Number,
          notify: true,
        },
        keyEventTarget: {
          type: Object,
          value: function() { return document.body; },
        },

        _drafts: Object,
      },

      behaviors: [
        Gerrit.KeyboardShortcutBehavior,
        Gerrit.RESTClientBehavior,
      ],

      reload: function() {
        if (!this.changeNum || !this.patchNum) {
          return Promise.resolve();
        }
        return Promise.all([
          this.$.filesXHR.generateRequest().completes,
          app.accountReady.then(function() {
            if (!app.loggedIn) { return; }
            this.$.draftsXHR.generateRequest();
          }.bind(this)),
        ]);
      },

      _computeFilesURL: function(changeNum, patchNum) {
        return this.changeBaseURL(changeNum, patchNum) + '/files';
      },

      _computeCommentsString: function(comments, patchNum, path) {
        var patchComments = (comments[path] || []).filter(function(c) {
          return c.patch_set == patchNum;
        });
        var num = patchComments.length;
        if (num == 0) { return ''; }
        if (num == 1) { return '1 comment'; }
        if (num > 1) { return num + ' comments'; };
      },

      _computeDraftsURL: function(changeNum, patchNum) {
        return this.changeBaseURL(changeNum, patchNum) + '/drafts';
      },

      _computeDraftsString: function(drafts, path) {
        var num = (drafts[path] || []).length;
        if (num == 0) { return ''; }
        if (num == 1) { return '1 draft'; }
        if (num > 1) { return num + ' drafts'; };
      },

      _handleResponse: function(e, req) {
        var result = e.detail.response;
        var paths = Object.keys(result).sort();
        var files = [];
        for (var i = 0; i < paths.length; i++) {
          var info = result[paths[i]];
          info.__path = paths[i];
          info.lines_inserted = info.lines_inserted || 0;
          info.lines_deleted = info.lines_deleted || 0;
          files.push(info)
        }
        this.files = files;
      },

      _handleKey: function(e) {
        if (this.shouldSupressKeyboardShortcut(e)) { return; }

        switch(e.keyCode) {
          case 74:  // 'j'
            e.preventDefault();
            this.selectedIndex =
                Math.min(this.files.length - 1, this.selectedIndex + 1);
            break;
          case 75:  // 'k'
            e.preventDefault();
            this.selectedIndex = Math.max(0, this.selectedIndex - 1);
            break;
          case 219:  // '['
            e.preventDefault();
            this._openSelectedFile(this.files.length - 1);
            break;
          case 221:  // ']'
            e.preventDefault();
            this._openSelectedFile(0);
            break;
          case 13:  // <enter>
          case 79:  // 'o'
            e.preventDefault();
            this._openSelectedFile();
            break;
        }
      },

      _openSelectedFile: function(opt_index) {
        if (opt_index != null) {
          this.selectedIndex = opt_index;
        }
        page(this._computeDiffURL(this.changeNum, this.patchNum,
            this.files[this.selectedIndex].__path));
      },

      _computeFileSelected: function(index, selectedIndex) {
        return index == selectedIndex;
      },

      _computeDiffURL: function(changeNum, patchNum, path) {
        return '/c/' + changeNum + '/' + patchNum + '/' + path;
      },
    });
  })();
  </script>
</dom-module>
