<link rel="import" href="/libs/vendor/polymer/polymer/polymer.html">
<link rel="import" href="/libs/vendor/polymer/paper-icon-button/paper-icon-button.html">
<link rel="import" href="/libs/vendor/polymer/paper-dialog/paper-dialog.html">
<link rel="import" href="/libs/vendor/polymer/paper-dialog/paper-dialog-transition.html">
<link rel="import" href="/libs/vendor/polymer/paper-fab/paper-fab.html">
<link rel="import" href="/libs/vendor/polymer/core-collapse/core-collapse.html">
<link rel="import" href="/libs/ui-components/data-grid/grid/row/renderer.html">
<link rel="import" href="/libs/ui-components/data-grid/grid/cell/renderer.html">
<link rel="import" href="/libs/ui-components/data-grid/grid/column/renderer.html">

<polymer-element name="p2b-grid" attributes="summary dataSource defaultSortKey defaultSortAscending">
  <template>
    <link rel="stylesheet" href="/libs/css/common-style.css">
    <link rel="stylesheet" href="component.css">
    <div id="templates"></div>
    <core-collapse id="searchTools">
      <div class="result-count">Showing {{ dataSourceResult.length }} items</div>
      <div>
        <content select="[grid-search]"></content>
      </div>
      <div>
        <content select="[grid-filter]"></content>
      </div>
    </core-collapse>
    <table id="table" summary="{{ summary }}" cellpadding="0" cellpadding="0" border="0"  style="visibility:hidden" >
      <thead>
        <tr>
          <th is="p2b-grid-column-renderer" gridState="{{ gridState }}" data="{{ col.columnData }}" repeat="{{ col in columns }}" template></th>
          <th style="width:40px">&nbsp;<span class="screen-reader">More info</span>
            <paper-fab class="search-fab" focused icon="search" on-tap="{{ toggleSearchTools }}"></paper-fab>
          </th>
        </tr>
      </thead>
      <tbody>
        <!-- quirk: Shadow Dom breaks parent-child relationships in HTML, this causes issues with
         elements like table. Ideally we could have had <grid><grid-row><grid-cell> but we can't do
         that yet since the tr and td rendered by <grid-row> <grid-cell> will be in shadow Dom and isolated.
         Chromium bug: https://code.google.com/p/chromium/issues/detail?id=374315
         W3C Spec bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=15616
         -->
        <tr is="p2b-grid-row-renderer" repeat="{{ item in dataSourceResult }}" template>
          <td is="p2b-grid-cell-renderer" data="{{ col.columnData }}" repeat="{{ col in columns }}" template>
            <template ref="{{ col.cellTemplateId }}" bind></template>
          </td>
          <td class="info-column">
            <paper-icon-button on-tap="{{ showMoreInfo }}" class="more-icon" icon="more-vert" title="more info"></paper-icon-button
            >
          </td>
        </tr>
      </tbody>
    </table>

    <!-- Dialog that displays all columns and their values when more info icon activated -->
    <paper-dialog id="dialog" heading="Details" transition="paper-dialog-transition-bottom">
      <template id="moreInfoTemplate" bind>
        <div class="more-dialog-content">
          <template repeat="{{ item in selectedItems }}">
            <template repeat="{{ col in columns }}">
              <h3 class="heading">{{ col.columnData.label }}</h3>
              <div class="details"><template ref="{{ col.cellTemplateId }}" bind></template></div>
            </template>
          </template>
        </div>
      </template>
      <paper-button label="Close" dismissive></paper-button>
    </paper-dialog>

  </template>
  <script>
    /*
     * Reusable grid that can host search, filters and supports sortable columns and custom cell renderer
     * @example usage:

           <p2b-grid defaultSortKey="firstName"
            defaultSortAscending
            dataSource="{{ myContactsDataSource }}"
            summary="Displays your contacts in a tabular format">

            <!-- Search contacts-->
            <p2b-grid-search label="Search Contacts"></p2b-grid-search>

            <!-- Filter for circles -->
            <p2b-grid-filter-select multiple key="circle" label="Circles">
              <p2b-grid-filter-select-item checked label="Close Friends" value="close"></p2b-grid-filter-select-item>
              <p2b-grid-filter-select-item label="Colleagues" value="far"></p2b-grid-filter-select-item>
            </p2b-grid-filter-select>

            <!-- Toggle to allow filtering by online mode-->
            <p2b-grid-filter-toggle key="online" label="Show online only" checked></p2b-grid-filter-toggle>

            <!-- Columns, sorting and cell templates -->
            <p2b-grid-column sortable label="First Name" key="firstName" />
              <template>{{ item.firstName }}</template>
            </p2b-grid-column>

            <p2b-grid-column sortable label="Last Name" key="lastName" />
              <template>
                <span style="text-transform:uppercase;">
                  {{ item.lastName }}
                </span>
              </template>
            </p2b-grid-column>

            <p2b-grid-column label="Circle" key="circle"/>
              <template>
                <img src="images\circls\{{ item.circle }}.jpg" alt="in {{ item.circle }} circle"><img>
              </template>
            </p2b-grid-column>

          </p2b-grid>

     * DataSource attribute expects an object that has a fetch(search, sort, filters) method. Please see
     * documentation on DataSource property for details.
     */
    Polymer('p2b-grid', {
      /*
       * DataSource is an object that has a fetch(search, sort, filters) method where
       * search{key<string>} is current search keyword
       * sort{key<string>, ascending<bool>} current sort key and direction
       * filter{map{key<string>, values<Array>}} Map of filter keys to currently selected filter values
       * search, sort and filters are provided by the grid control whenever they are changed by the user.
       * DataSource is called automatically by the grid when user interacts with the component
       * Grid does some batching of user actions and only calls fetch when needed in a requestAnimationFrame
       * Keys provided for sort and filters correspond to keys set in the markup when constructing the grid.
       * DataSource.fetch() is expected to return an array of filtered sorted results of the items.
       */
      dataSource: null,

      /*
       * Summary for the grid.
       * @type {string}
       */
      summary: '',

      /*
       * Initial sort key
       * @type {string}
       */
      defaultSortKey: '',

      /*
       * Initial sort direction
       * @type {string}
       */
      defaultSortAscending: false,

      showMoreInfo: function(e) {
        var item = e.target.templateInstance.model.item;
        this.selectedItems = [item];
        this.$.dialog.opened = true;
      },

      ready: function() {

        // private property fields
        this.columns = [];
        this.shouldRefetchData = true;
        this.dataSource = null;
        this.cachedDataSourceResult = [];
        this.gridState = {
          sort: {
            key: '',
            ascending: false
          },
          search: {
            keyword: ''
          },
          filters: {}
        },

        // set the default sort and direction on the state object
        this.gridState.sort.key = this.defaultSortKey;
        this.gridState.sort.ascending = this.defaultSortAscending;

        this.initTemplates(); // loads cell templates
        this.initGridStateDependents(); //  initialize filters and search
        this.initGridStateObserver(); // observe changes to grid state by filters

      },

      /*
       * Called by Polymer when DOM is read.
       * @private
       */
      domReady: function() {
        this.adjustFlexWidths();
        this.$.table.style.visibility = 'visible';
      },

      /*
       * Called by Polymer when dataSource attribute changes.
       * @private
       */
      dataSourceChanged: function() {
        this.refresh();
      },

      /*
       * Sets up an object observer to get any mutations on the grid state object.
       * Filters or sortable columns can change the state and we like to refresh
       * when changes happens.
       * @private
       */
      initGridStateObserver: function() {
        var self = this;
        for (key in this.gridState) {
          var observer = new ObjectObserver(this.gridState[key])
          observer.open(function() {
            // refresh the grid on any mutations
            self.refresh();
          });
        }
      },

      /*
       * Copies the cell templates as defined by the user for each column into
       * the grid so that we can reference them in a loop.
       * quirk: Need to reference them by Id so a new Id is generated for each one
       * Ids are scoped in the shadow DOM so no collisions.
       * @private
       */
      initTemplates: function() {
        var self = this;
        var columnNodes = this.querySelectorAll('[grid-column]');
        var totalFlex = 0;
        for (var i = 0; i < columnNodes.length; i++) {
          var col = columnNodes[i];
          var cellTemplate = col.querySelector('template');
          this.originalContext = cellTemplate.model;
          var cellTemplateId = "userProvidedCellTemplate" + i;
          cellTemplate.id = cellTemplateId;
          this.$.templates.appendChild(cellTemplate);
          totalFlex += col.flex;
          col.origFlex = col.flex;
          this.columns.push({
            cellTemplateId: cellTemplateId,
            columnData: col
          });
        }

        // add up the total value of flex attribute on each column and add it to data
        this.columns.forEach(function(c) {
          c.columnData.totalFlex = totalFlex;
        });

        // readjust the widths on resize
        var previousTableWidth = self.$.table.offsetWidth;
        onResizeHandler = function() {
          var newWidth = self.$.table.offsetWidth;
          if (newWidth != previousTableWidth && newWidth > 0) {
            self.adjustFlexWidths();
          }
          previousTableWidth = newWidth;
        };

        // quirks: since there is no good way to know if width changes, we pull.
        // window.resize does not cover all resize cases
        this.resizeInterval = setInterval(onResizeHandler, 50);
      },

      /*
       * Called by Polymer when DOM is gone. We need to unbind custom event listeners here.
       * @private
       */
      detached: function() {
        clearInterval(this.resizeInterval);
      },

      /*
       * Provide the grid state to any component that expects it so they can mutate
       * without the grid needing to know about them at all.
       * @private
       */
      initGridStateDependents: function() {
        var gridStateDependents = this.querySelectorAll('[expects-grid-state]');
        for (var i = 0; i < gridStateDependents.length; i++) {
          gridStateDependents[i].gridState = this.gridState;
        }
      },

      /*
       * Refreshed the grid by fetching the data again and updating the UI in the next render tick
       */
      refresh: function() {
        var self = this;
        requestAnimationFrame(function() {
          self.shouldRefetchData = true;
        });
      },

      /*
       * Performs responsive changes for the grid.
       * Values of flex, minFlex and priority attributes on the grid column decides
       * the responsive behavior.
       * Grid assumes the original total number of columns can fit on a 768px width,
       * if width of the grid container is less than that, then it starts to reduce
       * flex values for each columns in reverse priority one by one until it reaches
       * the minFlex value for all columns.
       * If it still needs to reduce the width of the table at this point, it starts hiding
       * columns in reverse priority order.
       */
      adjustFlexWidths: function() {
        var minWidth = 768;
        var tableWidth = this.$.table.offsetWidth;

        // reset to original flex values
        for (var i = 0; i < this.columns.length; i++) {
          var col = this.columns[i];
          col.columnData.flex = col.columnData.origFlex;
        }

        if (tableWidth >= minWidth) {
          return;
        }

        // total of all flex values from all columns
        var totalFlex = this.columns.reduce( function(prev, col) {
          return prev + col.columnData.flex;
        }, 0);

        // number of pixels per flex point
        var pixelPerFlex = Math.floor(tableWidth / totalFlex);
        // number of flex points we need to eliminate to same pixelPerFlex as the minWidth case
        var numFlexToEliminate = Math.ceil((minWidth - tableWidth) / pixelPerFlex);

        // sort from least important to most important
        var sortedColumnsData = this.columns.map(function(col) {
          return col.columnData
        }).sort(function(a, b) {
          return b.priority - a.priority;
        });

        // first try to reduce each flex value until we hit min-flex for each column
        var numElimintedFlex = 0
        var numIrreducableColumns = 0;
        var numColumns = sortedColumnsData.length;
        while (numElimintedFlex < numFlexToEliminate && numIrreducableColumns < numColumns) {
          for (var i = 0; i < numColumns; i++) {
            var col = sortedColumnsData[i];
            if (col.flex > col.minFlex) {
              col.flex--;
              numElimintedFlex++;
            } else {
              numIrreducableColumns++;
            }
          }
        }

        // if still need to reduce, start eliminating whole columns based on priority
        // never eliminate the top priority column, hence only iterate to numColumns - 1
        if (numElimintedFlex < numFlexToEliminate) {
          for (var i = 0; i < numColumns - 1 && numElimintedFlex < numFlexToEliminate; i++) {
            var col = sortedColumnsData[i];
            numElimintedFlex += col.flex;
            col.flex = 0;
          }
        }

        // update the new totalFlex for each column
        this.columns.forEach(function(c) {
          c.columnData.totalFlex = totalFlex - numFlexToEliminate;
        });
      },

      /*
       * dataSourceResult is what the UI binds to and integrate over.
       * Only fetches data if scheduled to do so
       * @private
       */
      get dataSourceResult() {
        if (!this.shouldRefetchData || !this.dataSource) {
          return this.cachedDataSourceResult;
        }

        this.cachedDataSourceResult = this.dataSource.fetch(
          this.gridState.search,
          this.gridState.sort,
          this.gridState.filters
        );

        this.shouldRefetchData = false;

        return this.cachedDataSourceResult;
      },

      /*
       * collapse/show search and filter container.
       * @private
       */
      toggleSearchTools: function() {
        this.$.searchTools.toggle();
      }
    });
  </script>
</polymer-element>
