// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * Custom column model for advanced auto-resizing.
 *
 * @param {!Array<cr.ui.table.TableColumn>} tableColumns Table columns.
 * @extends {cr.ui.table.TableColumnModel}
 * @constructor
 */
function FileTableColumnModel(tableColumns) {
  cr.ui.table.TableColumnModel.call(this, tableColumns);
}

/**
 * Inherits from cr.ui.TableColumnModel.
 */
FileTableColumnModel.prototype.__proto__ =
    cr.ui.table.TableColumnModel.prototype;

/**
 * Minimum width of column. Note that is not marked private as it is used in the
 * unit tests.
 * @const {number}
 */
FileTableColumnModel.MIN_WIDTH_ = 10;

/**
 * Sets column width so that the column dividers move to the specified position.
 * This function also check the width of each column and keep the width larger
 * than MIN_WIDTH_.
 *
 * @private
 * @param {Array<number>} newPos Positions of each column dividers.
 */
FileTableColumnModel.prototype.applyColumnPositions_ = function(newPos) {
  // Check the minimum width and adjust the positions.
  for (var i = 0; i < newPos.length - 2; i++) {
    if (!this.columns_[i].visible) {
      newPos[i + 1] = newPos[i];
    } else if (newPos[i + 1] - newPos[i] < FileTableColumnModel.MIN_WIDTH_) {
      newPos[i + 1] = newPos[i] + FileTableColumnModel.MIN_WIDTH_;
    }
  }
  for (var i = newPos.length - 1; i >= 2; i--) {
    if (!this.columns_[i - 1].visible) {
      newPos[i - 1] = newPos[i];
    } else if (newPos[i] - newPos[i - 1] < FileTableColumnModel.MIN_WIDTH_) {
      newPos[i - 1] = newPos[i] - FileTableColumnModel.MIN_WIDTH_;
    }
  }
  // Set the new width of columns
  for (var i = 0; i < this.columns_.length; i++) {
    if (!this.columns_[i].visible) {
      this.columns_[i].width = 0;
    } else {
      // Make sure each cell has the minumum width. This is necessary when the
      // window size is too small to contain all the columns.
      this.columns_[i].width = Math.max(FileTableColumnModel.MIN_WIDTH_,
                                        newPos[i + 1] - newPos[i]);
    }
  }
};

/**
 * Normalizes widths to make their sum 100% if possible. Uses the proportional
 * approach with some additional constraints.
 *
 * @param {number} contentWidth Target width.
 * @override
 */
FileTableColumnModel.prototype.normalizeWidths = function(contentWidth) {
  var totalWidth = 0;
  // Some columns have fixed width.
  for (var i = 0; i < this.columns_.length; i++) {
    totalWidth += this.columns_[i].width;
  }
  var positions = [0];
  var sum = 0;
  for (var i = 0; i < this.columns_.length; i++) {
    var column = this.columns_[i];
    sum += column.width;
    // Faster alternative to Math.floor for non-negative numbers.
    positions[i + 1] = ~~(contentWidth * sum / totalWidth);
  }
  this.applyColumnPositions_(positions);
};

/**
 * Handles to the start of column resizing by splitters.
 */
FileTableColumnModel.prototype.handleSplitterDragStart = function() {
  this.initializeColumnPos();
};

/**
 * Handles to the end of column resizing by splitters.
 */
FileTableColumnModel.prototype.handleSplitterDragEnd = function() {
  this.destroyColumnPos();
};

/**
 * Initialize a column snapshot which is used in setWidthAndKeepTotal().
 */
FileTableColumnModel.prototype.initializeColumnPos = function() {
  this.snapshot_ = new FileTableColumnModel.ColumnSnapshot(this.columns_);
};

/**
 * Destroy the column snapshot which is used in setWidthAndKeepTotal().
 */
FileTableColumnModel.prototype.destroyColumnPos = function() {
  this.snapshot_ = null;
};

/**
 * Sets the width of column while keeping the total width of table.
 * Before and after calling this method, you must initialize and destroy
 * columnPos with initializeColumnPos() and destroyColumnPos().
 * @param {number} columnIndex Index of column that is resized.
 * @param {number} columnWidth New width of the column.
 */
FileTableColumnModel.prototype.setWidthAndKeepTotal = function(
    columnIndex, columnWidth) {
  columnWidth = Math.max(columnWidth, FileTableColumnModel.MIN_WIDTH_);
  this.snapshot_.setWidth(columnIndex, columnWidth);
  this.applyColumnPositions_(this.snapshot_.newPos);

  // Notify about resizing
  cr.dispatchSimpleEvent(this, 'resize');
};

/**
 * Obtains a column by the specified horizontal position.
 * @param {number} x Horizontal position.
 * @return {Object} The object that contains column index, column width, and
 *     hitPosition where the horizontal position is hit in the column.
 */
FileTableColumnModel.prototype.getHitColumn = function(x) {
  for (var i = 0; x >= this.columns_[i].width; i++) {
    x -= this.columns_[i].width;
  }
  if (i >= this.columns_.length) {
    return null;
  }
  return {index: i, hitPosition: x, width: this.columns_[i].width};
};

/** @override */
FileTableColumnModel.prototype.setVisible = function(index, visible) {
  if (index < 0 || index > this.columns_.length - 1) {
    return;
  }

  var column = this.columns_[index];
  if (column.visible === visible) {
    return;
  }

  // Re-layout the table.  This overrides the default column layout code in the
  // parent class.
  var snapshot = new FileTableColumnModel.ColumnSnapshot(this.columns_);

  column.visible = visible;

  // Keep the current column width, but adjust the other columns to accomodate
  // the new column.
  snapshot.setWidth(index, column.width);
  this.applyColumnPositions_(snapshot.newPos);
};

/**
 * Export a set of column widths for use by #restoreColumnWidths.  Use these two
 * methods instead of manually saving and setting column widths, because doing
 * the latter will not correctly save/restore column widths for hidden columns.
 * @see #restoreColumnWidths
 * @return {!Object} config
 */
FileTableColumnModel.prototype.exportColumnConfig = function() {
  // Make a snapshot, and use that to compute a column layout where all the
  // columns are visible.
  var snapshot = new FileTableColumnModel.ColumnSnapshot(this.columns_);
  for (var i = 0; i < this.columns_.length; i++) {
    if (!this.columns_[i].visible) {
      snapshot.setWidth(i, this.columns_[i].absoluteWidth);
    }
  }
  // Export the column widths.
  var config = {};
  for (var i = 0; i < this.columns_.length; i++) {
    config[this.columns_[i].id] = {
      width: snapshot.newPos[i + 1] - snapshot.newPos[i]
    };
  }
  return config;
};

/**
 * Restores a set of column widths previously created by calling
 * #exportColumnConfig.
 * @see #exportColumnConfig
 * @param {!Object} config
 */
FileTableColumnModel.prototype.restoreColumnConfig = function(config) {
  // Convert old-style raw column widths into new-style config objects.
  if (Array.isArray(config)) {
    var tmpConfig = {};
    tmpConfig[this.columns_[0].id] = config[0];
    tmpConfig[this.columns_[1].id] = config[1];
    tmpConfig[this.columns_[3].id] = config[2];
    tmpConfig[this.columns_[4].id] = config[3];
    config = tmpConfig;
  }

  // Columns must all be made visible before restoring their widths.  Save the
  // current visibility so it can be restored after.
  var visibility = [];
  for (var i = 0; i < this.columns_.length; i++) {
    visibility[i] = this.columns_[i].visible;
    this.columns_[i].visible = true;
  }

  // Do not use external setters (e.g. #setVisible, #setWidth) here because they
  // trigger layout thrash, and also try to dynamically resize columns, which
  // interferes with restoring the old column layout.
  for (var columnId in config) {
    var column = this.columns_[this.indexOf(columnId)];
    if (column) {
      // Set column width.  Ignore invalid widths.
      var width = ~~config[columnId].width;
      if (width > 0) {
        column.width = width;
      }
    }
  }

  // Restore column visibility.  Use setVisible here, to trigger table relayout.
  for (var i = 0; i < this.columns_.length; i++) {
    this.setVisible(i, visibility[i]);
  }
};

/**
 * A helper class for performing resizing of columns.
 * @param {!Array<!cr.ui.table.TableColumn>} columns
 * @constructor
 */
FileTableColumnModel.ColumnSnapshot = function(columns) {
  /** @private {!Array<number>} */
  this.columnPos_ = [0];
  for (var i = 0; i < columns.length; i++) {
    this.columnPos_[i + 1] = columns[i].width + this.columnPos_[i];
  }

  /**
   * Starts off as a copy of the current column positions, but gets modified.
   * @private {!Array<number>}
   */
  this.newPos = this.columnPos_.slice(0);
};

/**
 * Set the width of the given column.  The snapshot will keep the total width of
 * the table constant.
 * @param {number} index
 * @param {number} width
 */
FileTableColumnModel.ColumnSnapshot.prototype.setWidth = function(
    index, width) {
  // Skip to resize 'selection' column
  if (index < 0 ||
      index >= this.columnPos_.length - 1 ||
      !this.columnPos_) {
    return;
  }

  // Round up if the column is shrinking, and down if the column is expanding.
  // This prevents off-by-one drift.
  var currentWidth = this.columnPos_[index + 1] - this.columnPos_[index];
  var round = width < currentWidth ? Math.ceil : Math.floor;

  // Calculate new positions of column splitters.
  var newPosStart = this.columnPos_[index] + width;
  var posEnd = this.columnPos_[this.columnPos_.length - 1];
  for (var i = 0; i < index + 1; i++) {
    this.newPos[i] = this.columnPos_[i];
  }
  for (var i = index + 1; i < this.columnPos_.length - 1; i++) {
    var posStart = this.columnPos_[index + 1];
    this.newPos[i] = (posEnd - newPosStart) *
                (this.columnPos_[i] - posStart) /
                (posEnd - posStart) +
                newPosStart;
    this.newPos[i] = round(this.newPos[i]);
  }
  this.newPos[index] = this.columnPos_[index];
  this.newPos[this.columnPos_.length - 1] = posEnd;
};

/**
 * Custom splitter that resizes column with retaining the sum of all the column
 * width.
 */
var FileTableSplitter = cr.ui.define('div');

/**
 * Inherits from cr.ui.TableSplitter.
 */
FileTableSplitter.prototype.__proto__ = cr.ui.TableSplitter.prototype;

/**
 * Handles the drag start event.
 */
FileTableSplitter.prototype.handleSplitterDragStart = function() {
  cr.ui.TableSplitter.prototype.handleSplitterDragStart.call(this);
  this.table_.columnModel.handleSplitterDragStart();
};

/**
 * Handles the drag move event.
 * @param {number} deltaX Horizontal mouse move offset.
 */
FileTableSplitter.prototype.handleSplitterDragMove = function(deltaX) {
  this.table_.columnModel.setWidthAndKeepTotal(this.columnIndex,
                                               this.columnWidth_ + deltaX,
                                               true);
};

/**
 * Handles the drag end event.
 */
FileTableSplitter.prototype.handleSplitterDragEnd = function() {
  cr.ui.TableSplitter.prototype.handleSplitterDragEnd.call(this);
  this.table_.columnModel.handleSplitterDragEnd();
};

/**
 * File list Table View.
 * @constructor
 * @extends {cr.ui.Table}
 */
function FileTable() {
  throw new Error('Designed to decorate elements');
}

/**
 * Inherits from cr.ui.Table.
 */
FileTable.prototype.__proto__ = cr.ui.Table.prototype;

/**
 * Decorates the element.
 * @param {!Element} self Table to decorate.
 * @param {!MetadataModel} metadataModel To retrieve
 *     metadata.
 * @param {!VolumeManager} volumeManager To retrieve volume info.
 * @param {!importer.HistoryLoader} historyLoader
 * @param {boolean} fullPage True if it's full page File Manager,
 *                           False if a file open/save dialog.
 */
FileTable.decorate = function(
    self, metadataModel, volumeManager, historyLoader, fullPage) {
  cr.ui.Table.decorate(self);
  self.__proto__ = FileTable.prototype;
  FileTableList.decorate(self.list);
  self.list.setOnMergeItems(self.updateHighPriorityRange_.bind(self));
  self.metadataModel_ = metadataModel;
  self.volumeManager_ = volumeManager;
  self.historyLoader_ = historyLoader;

  /** @private {ListThumbnailLoader} */
  self.listThumbnailLoader_ = null;

  /** @private {number} */
  self.beginIndex_ = 0;

  /** @private {number} */
  self.endIndex_ = 0;

  /** @private {function(!Event)} */
  self.onThumbnailLoadedBound_ = self.onThumbnailLoaded_.bind(self);

  /**
   * Reflects the visibility of import status in the UI.  Assumption: import
   * status is only enabled in import-eligible locations.  See
   * ImportController#onDirectoryChanged.  For this reason, the code in this
   * class checks if import status is visible, and if so, assumes that all the
   * files are in an import-eligible location.
   * TODO(kenobi): Clean this up once import status is queryable from metadata.
   *
   * @private {boolean}
   */
  self.importStatusVisible_ = true;

  /** @private {boolean} */
  self.useModificationByMeTime_ = false;

  var nameColumn = new cr.ui.table.TableColumn(
      'name', str('NAME_COLUMN_LABEL'), fullPage ? 386 : 324);
  nameColumn.renderFunction = self.renderName_.bind(self);

  var sizeColumn = new cr.ui.table.TableColumn(
      'size', str('SIZE_COLUMN_LABEL'), 110, true);
  sizeColumn.renderFunction = self.renderSize_.bind(self);
  sizeColumn.defaultOrder = 'desc';

  var statusColumn = new cr.ui.table.TableColumn(
      'status', str('STATUS_COLUMN_LABEL'), 60, true);
  statusColumn.renderFunction = self.renderStatus_.bind(self);
  statusColumn.visible = self.importStatusVisible_;

  var typeColumn = new cr.ui.table.TableColumn(
      'type', str('TYPE_COLUMN_LABEL'), fullPage ? 110 : 110);
  typeColumn.renderFunction = self.renderType_.bind(self);

  var modTimeColumn = new cr.ui.table.TableColumn(
      'modificationTime', str('DATE_COLUMN_LABEL'), fullPage ? 150 : 210);
  modTimeColumn.renderFunction = self.renderDate_.bind(self);
  modTimeColumn.defaultOrder = 'desc';

  var columns = [
      nameColumn,
      sizeColumn,
      statusColumn,
      typeColumn,
      modTimeColumn
  ];

  var columnModel = new FileTableColumnModel(columns);

  self.columnModel = columnModel;

  self.formatter_ = new FileMetadataFormatter();

  var selfAsTable = /** @type {!cr.ui.Table} */ (self);
  selfAsTable.setRenderFunction(
      self.renderTableRow_.bind(self, selfAsTable.getRenderFunction()));

  // Keep focus on the file list when clicking on the header.
  selfAsTable.header.addEventListener('mousedown', function(e) {
    self.list.focus();
    e.preventDefault();
  });

  self.relayoutRateLimiter_ =
      new AsyncUtil.RateLimiter(self.relayoutImmediately_.bind(self));

  // Override header#redraw to use FileTableSplitter.
  /** @this {cr.ui.table.TableHeader} */
  selfAsTable.header.redraw = function() {
    this.__proto__.redraw.call(this);
    // Extend table splitters
    var splitters = this.querySelectorAll('.table-header-splitter');
    for (var i = 0; i < splitters.length; i++) {
      if (splitters[i] instanceof FileTableSplitter) {
        continue;
      }
      FileTableSplitter.decorate(splitters[i]);
    }
  };

  // Save the last selection. This is used by shouldStartDragSelection.
  self.list.addEventListener('mousedown', function(e) {
    this.lastSelection_ = this.selectionModel.selectedIndexes;
  }.bind(self), true);
  self.list.addEventListener('touchstart', function(e) {
    this.lastSelection_ = this.selectionModel.selectedIndexes;
  }.bind(self), true);
  self.list.shouldStartDragSelection =
      self.shouldStartDragSelection_.bind(self);
  self.list.hasDragHitElement = self.hasDragHitElement_.bind(self);

  /**
   * Obtains the index list of elements that are hit by the point or the
   * rectangle.
   *
   * @param {number} x X coordinate value.
   * @param {number} y Y coordinate value.
   * @param {number=} opt_width Width of the coordinate.
   * @param {number=} opt_height Height of the coordinate.
   * @return {Array<number>} Index list of hit elements.
   * @this {cr.ui.List}
   */
  self.list.getHitElements = function(x, y, opt_width, opt_height) {
    var currentSelection = [];
    var bottom = y + (opt_height || 0);
    for (var i = 0; i < this.selectionModel_.length; i++) {
      var itemMetrics = this.getHeightsForIndex(i);
      if (itemMetrics.top < bottom &&
          itemMetrics.top + itemMetrics.height >= y) {
        currentSelection.push(i);
      }
    }
    return currentSelection;
  };
};

/**
 * Updates high priority range of list thumbnail loader based on current
 * viewport.
 *
 * @param {number} beginIndex Begin index.
 * @param {number} endIndex End index.
 * @private
 */
FileTable.prototype.updateHighPriorityRange_ = function(beginIndex, endIndex) {
  // Keep these values to set range when a new list thumbnail loader is set.
  this.beginIndex_ = beginIndex;
  this.endIndex_ = endIndex;

  if (this.listThumbnailLoader_ !== null) {
    this.listThumbnailLoader_.setHighPriorityRange(beginIndex, endIndex);
  }
};

/**
 * Sets list thumbnail loader.
 * @param {ListThumbnailLoader} listThumbnailLoader A list thumbnail loader.
 */
FileTable.prototype.setListThumbnailLoader = function(listThumbnailLoader) {
  if (this.listThumbnailLoader_) {
    this.listThumbnailLoader_.removeEventListener(
        'thumbnailLoaded', this.onThumbnailLoadedBound_);
  }

  this.listThumbnailLoader_ = listThumbnailLoader;

  if (this.listThumbnailLoader_) {
    this.listThumbnailLoader_.addEventListener(
        'thumbnailLoaded', this.onThumbnailLoadedBound_);
    this.listThumbnailLoader_.setHighPriorityRange(
        this.beginIndex_, this.endIndex_);
  }
};

/**
 * Returns the element containing the thumbnail of a certain list item as
 * background image.
 * @param {number} index The index of the item containing the desired thumbnail.
 * @return {?Element} The element containing the thumbnail, or null, if an error
 *     occurred.
 */
FileTable.prototype.getThumbnail = function(index) {
  var listItem = this.getListItemByIndex(index);
  if (!listItem) {
    return null;
  }
  var container = listItem.querySelector('.detail-thumbnail');
  if (!container) {
    return null;
  }
  return container.querySelector('.thumbnail');
};

/**
 * Handles thumbnail loaded event.
 * @param {!Event} event An event.
 * @private
 */
FileTable.prototype.onThumbnailLoaded_ = function(event) {
  var listItem = this.getListItemByIndex(event.index);
  if (listItem) {
    var box = listItem.querySelector('.detail-thumbnail');
    if (box) {
      if (event.dataUrl) {
        this.setThumbnailImage_(
            assertInstanceof(box, HTMLDivElement), event.dataUrl,
            true /* with animation */);
      } else {
        this.clearThumbnailImage_(
            assertInstanceof(box, HTMLDivElement));
      }
    }
  }
};

/**
 * Adjust column width to fit its content.
 * @param {number} index Index of the column to adjust width.
 * @override
 */
FileTable.prototype.fitColumn = function(index) {
  var render = this.columnModel.getRenderFunction(index);
  var MAXIMUM_ROWS_TO_MEASURE = 1000;

  // Create a temporaty list item, put all cells into it and measure its
  // width. Then remove the item. It fits "list > *" CSS rules.
  var container = this.ownerDocument.createElement('li');
  container.style.display = 'inline-block';
  container.style.textAlign = 'start';
  // The container will have width of the longest cell.
  container.style.webkitBoxOrient = 'vertical';

  // Select at most MAXIMUM_ROWS_TO_MEASURE items around visible area.
  var items = this.list.getItemsInViewPort(this.list.scrollTop,
                                           this.list.clientHeight);
  var firstIndex = Math.floor(Math.max(0,
      (items.last + items.first - MAXIMUM_ROWS_TO_MEASURE) / 2));
  var lastIndex = Math.min(this.dataModel.length,
                           firstIndex + MAXIMUM_ROWS_TO_MEASURE);
  for (var i = firstIndex; i < lastIndex; i++) {
    var item = this.dataModel.item(i);
    var div = this.ownerDocument.createElement('div');
    div.className = 'table-row-cell';
    div.appendChild(render(item, this.columnModel.getId(index), this));
    container.appendChild(div);
  }
  this.list.appendChild(container);
  var width = parseFloat(window.getComputedStyle(container).width);
  this.list.removeChild(container);

  this.columnModel.initializeColumnPos();
  this.columnModel.setWidthAndKeepTotal(index, Math.ceil(width));
  this.columnModel.destroyColumnPos();
};

/**
 * Sets the visibility of the cloud import status column.
 * @param {boolean} visible
 */
FileTable.prototype.setImportStatusVisible = function(visible) {
  if (this.importStatusVisible_ != visible) {
    this.importStatusVisible_ = visible;
    this.columnModel.setVisible(this.columnModel.indexOf('status'), visible);
    this.relayout();
  }
};

/**
 * Sets date and time format.
 * @param {boolean} use12hourClock True if 12 hours clock, False if 24 hours.
 */
FileTable.prototype.setDateTimeFormat = function(use12hourClock) {
  this.formatter_.setDateTimeFormat(use12hourClock);
};

/**
 * Sets whether to use modificationByMeTime as "Last Modified" time.
 * @param {boolean} useModificationByMeTime
 */
FileTable.prototype.setUseModificationByMeTime = function(
    useModificationByMeTime) {
  this.useModificationByMeTime_ = useModificationByMeTime;
};

/**
 * Returns whether the drag event is inside a file entry in the list (and not
 * the background padding area).
 * @param {MouseEvent} event Drag start event.
 * @return {boolean} True if the mouse is over an element in the list, False if
 *                   it is in the background.
 */
FileTable.prototype.hasDragHitElement_ = function(event) {
  var pos = DragSelector.getScrolledPosition(this.list, event);
  return this.list.getHitElements(pos.x, pos.y).length !== 0;
};

/**
 * Obtains if the drag selection should be start or not by referring the mouse
 * event.
 * @param {MouseEvent} event Drag start event.
 * @return {boolean} True if the mouse is hit to the background of the list, or
 *                   certain areas of the inside of the list that would start a
 *                   drag selection.
 * @private
 */
FileTable.prototype.shouldStartDragSelection_ = function(event) {
  // If the shift key is pressed, it should starts drag selection.
  if (event.shiftKey) {
    return true;
  }

  // If we're outside of the element list, start the drag selection.
  if (!this.list.hasDragHitElement(event)) {
    return true;
  }

  // If the position values are negative, it points the out of list.
  var pos = DragSelector.getScrolledPosition(this.list, event);
  if (!pos) {
    return false;
  }
  if (pos.x < 0 || pos.y < 0) {
    return true;
  }

  // If the item index is out of range, it should start the drag selection.
  var itemHeight = this.list.measureItem().height;
  // Faster alternative to Math.floor for non-negative numbers.
  var itemIndex = ~~(pos.y / itemHeight);
  if (itemIndex >= this.list.dataModel.length) {
    return true;
  }

  // If the pointed item is already selected, it should not start the drag
  // selection.
  if (this.lastSelection_ && this.lastSelection_.indexOf(itemIndex) !== -1) {
    return false;
  }

  // If the horizontal value is not hit to column, it should start the drag
  // selection.
  var hitColumn = this.columnModel.getHitColumn(pos.x);
  if (!hitColumn) {
    return true;
  }

  // Check if the point is on the column contents or not.
  switch (this.columnModel.columns_[hitColumn.index].id) {
    case 'name':
      var item = this.list.getListItemByIndex(itemIndex);
      if (!item) {
        return false;
      }

      var spanElement = item.querySelector('.filename-label span');
      var spanRect = spanElement.getBoundingClientRect();
      // The this.list.cachedBounds_ object is set by
      // DragSelector.getScrolledPosition.
      if (!this.list.cachedBounds) {
        return true;
      }
      var textRight =
          spanRect.left - this.list.cachedBounds.left + spanRect.width;
      return textRight <= hitColumn.hitPosition;
    default:
      return true;
  }
};

/**
 * Render the Name column of the detail table.
 *
 * Invoked by cr.ui.Table when a file needs to be rendered.
 *
 * @param {!Entry} entry The Entry object to render.
 * @param {string} columnId The id of the column to be rendered.
 * @param {cr.ui.Table} table The table doing the rendering.
 * @return {!HTMLDivElement} Created element.
 * @private
 */
FileTable.prototype.renderName_ = function(entry, columnId, table) {
  var label = /** @type {!HTMLDivElement} */
      (this.ownerDocument.createElement('div'));

  var mimeType = this.metadataModel_.getCache([entry],
      ['contentMimeType'])[0].contentMimeType;
  const locationInfo = this.volumeManager_.getLocationInfo(entry);
  var icon = filelist.renderFileTypeIcon(
      this.ownerDocument, entry, locationInfo, mimeType);
  if (FileType.isImage(entry, mimeType) || FileType.isVideo(entry, mimeType) ||
      FileType.isAudio(entry, mimeType) || FileType.isRaw(entry, mimeType)) {
    icon.appendChild(this.renderThumbnail_(entry));
  }
  icon.appendChild(this.renderCheckmark_());
  label.appendChild(icon);

  label.entry = entry;
  label.className = 'detail-name';
  label.appendChild(
      filelist.renderFileNameLabel(this.ownerDocument, entry, locationInfo));
  return label;
};

/**
 * Render the Size column of the detail table.
 *
 * @param {Entry} entry The Entry object to render.
 * @param {string} columnId The id of the column to be rendered.
 * @param {cr.ui.Table} table The table doing the rendering.
 * @return {!HTMLDivElement} Created element.
 * @private
 */
FileTable.prototype.renderSize_ = function(entry, columnId, table) {
  var div = /** @type {!HTMLDivElement} */
      (this.ownerDocument.createElement('div'));
  div.className = 'size';
  this.updateSize_(div, entry);

  return div;
};

/**
 * Sets up or updates the size cell.
 *
 * @param {HTMLDivElement} div The table cell.
 * @param {Entry} entry The corresponding entry.
 * @private
 */
FileTable.prototype.updateSize_ = function(div, entry) {
  var metadata = this.metadataModel_.getCache(
      [entry], ['size', 'hosted'])[0];
  var size = metadata.size;
  var hosted = metadata.hosted;
  div.textContent = this.formatter_.formatSize(size, hosted);
};

/**
 * Render the Status column of the detail table.
 *
 * @param {Entry} entry The Entry object to render.
 * @param {string} columnId The id of the column to be rendered.
 * @param {cr.ui.Table} table The table doing the rendering.
 * @return {!HTMLDivElement} Created element.
 * @private
 */
FileTable.prototype.renderStatus_ = function(entry, columnId, table) {
  var div = /** @type {!HTMLDivElement} */ (
      this.ownerDocument.createElement('div'));
  div.className = 'status status-icon';
  if (entry) {
    this.updateStatus_(div, entry);
  }

  return div;
};

/**
 * Returns the status of the entry w.r.t. the given import destination.
 * @param {Entry} entry
 * @param {!importer.Destination} destination
 * @return {!Promise<string>} The import status - will be 'imported', 'copied',
 *     or 'unknown'.
 */
FileTable.prototype.getImportStatus_ = function(entry, destination) {
  // If import status is not visible, early out because there's no point
  // retrieving it.
  if (!this.importStatusVisible_ || !importer.isEligibleType(entry)) {
    // Our import history doesn't deal with directories.
    // TODO(kenobi): May need to revisit this if the above assumption changes.
    return Promise.resolve('unknown');
  }
  // For the compiler.
  var fileEntry = /** @type {!FileEntry} */ (entry);

  return this.historyLoader_.getHistory()
      .then(
          /** @param {!importer.ImportHistory} history */
          function(history) {
            return Promise.all([
                history.wasImported(fileEntry, destination),
                history.wasCopied(fileEntry, destination)
            ]);
          })
      .then(
          /** @param {!Array<boolean>} status */
          function(status) {
            if (status[0]) {
              return 'imported';
            } else if (status[1]) {
              return 'copied';
            } else {
              return 'unknown';
            }
          });
};

/**
 * Render the status icon of the detail table.
 *
 * @param {HTMLDivElement} div
 * @param {Entry} entry The Entry object to render.
 * @private
 */
FileTable.prototype.updateStatus_ = function(div, entry) {
  this.getImportStatus_(entry, importer.Destination.GOOGLE_DRIVE).then(
      /** @param {string} status */
      function(status) {
        div.setAttribute('file-status-icon', status);
      });
};

/**
 * Render the Type column of the detail table.
 *
 * @param {Entry} entry The Entry object to render.
 * @param {string} columnId The id of the column to be rendered.
 * @param {cr.ui.Table} table The table doing the rendering.
 * @return {!HTMLDivElement} Created element.
 * @private
 */
FileTable.prototype.renderType_ = function(entry, columnId, table) {
  var div = /** @type {!HTMLDivElement} */
      (this.ownerDocument.createElement('div'));
  div.className = 'type';

  var mimeType = this.metadataModel_.getCache([entry],
      ['contentMimeType'])[0].contentMimeType;
  div.textContent = FileListModel.getFileTypeString(
      FileType.getType(entry, mimeType));

  // For removable partitions, display file system type.
  if (!mimeType && entry.volumeInfo && entry.volumeInfo.diskFileSystemType) {
    div.textContent = entry.volumeInfo.diskFileSystemType;
  }

  return div;
};

/**
 * Render the Date column of the detail table.
 *
 * @param {Entry} entry The Entry object to render.
 * @param {string} columnId The id of the column to be rendered.
 * @param {cr.ui.Table} table The table doing the rendering.
 * @return {HTMLDivElement} Created element.
 * @private
 */
FileTable.prototype.renderDate_ = function(entry, columnId, table) {
  var div = /** @type {!HTMLDivElement} */
      (this.ownerDocument.createElement('div'));
  div.className = 'date';

  this.updateDate_(div, entry);
  return div;
};

/**
 * Sets up or updates the date cell.
 *
 * @param {HTMLDivElement} div The table cell.
 * @param {Entry} entry Entry of file to update.
 * @private
 */
FileTable.prototype.updateDate_ = function(div, entry) {
  // For now, Team Drive roots have the incorrect modified date value. Hide it
  // until we get the proper one (see https://crbug.com/861622).
  if (util.isTeamDriveRoot(entry)) {
    div.textContent = '--';
    return;
  }

  var item = this.metadataModel_.getCache(
      [entry], ['modificationTime', 'modificationByMeTime'])[0];
  var modTime = this.useModificationByMeTime_ ?
      item.modificationByMeTime || item.modificationTime :
      item.modificationTime;

  div.textContent = this.formatter_.formatModDate(modTime);
};

/**
 * Updates the file metadata in the table item.
 *
 * @param {Element} item Table item.
 * @param {Entry} entry File entry.
 */
FileTable.prototype.updateFileMetadata = function(item, entry) {
  this.updateDate_(
      /** @type {!HTMLDivElement} */ (item.querySelector('.date')), entry);
  this.updateSize_(
      /** @type {!HTMLDivElement} */ (item.querySelector('.size')), entry);
  this.updateStatus_(
      /** @type {!HTMLDivElement} */ (item.querySelector('.status')), entry);
};

/**
 * Updates list items 'in place' on metadata change.
 * @param {string} type Type of metadata change.
 * @param {Array<Entry>} entries Entries to update.
 */
FileTable.prototype.updateListItemsMetadata = function(type, entries) {
  var urls = util.entriesToURLs(entries);
  var forEachCell = function(selector, callback) {
    var cells = this.querySelectorAll(selector);
    for (var i = 0; i < cells.length; i++) {
      var cell = cells[i];
      var listItem = this.list_.getListItemAncestor(cell);
      var entry = this.dataModel.item(listItem.listIndex);
      if (entry && urls.indexOf(entry.toURL()) !== -1) {
        callback.call(this, cell, entry, listItem);
      }
    }
  }.bind(this);
  if (type === 'filesystem') {
    forEachCell('.table-row-cell > .date', function(item, entry, unused) {
      this.updateDate_(item, entry);
    });
    forEachCell('.table-row-cell > .size', function(item, entry, unused) {
      this.updateSize_(item, entry);
    });
  } else if (type === 'external') {
    // The cell name does not matter as the entire list item is needed.
    forEachCell('.table-row-cell > .date', function(item, entry, listItem) {
      filelist.updateListItemExternalProps(
          listItem,
          this.metadataModel_.getCache(
              [entry],
              [
                'availableOffline', 'customIconUrl', 'shared', 'isMachineRoot',
                'isExternalMedia', 'hosted'
              ])[0],
          util.isTeamDriveRoot(entry));
    });
  } else if (type === 'import-history') {
    forEachCell('.table-row-cell > .status', function(item, entry, unused) {
      this.updateStatus_(item, entry);
    });
  }
};

/**
 * Renders table row.
 * @param {function(Entry, cr.ui.Table)} baseRenderFunction Base renderer.
 * @param {Entry} entry Corresponding entry.
 * @return {HTMLLIElement} Created element.
 * @private
 */
FileTable.prototype.renderTableRow_ = function(baseRenderFunction, entry) {
  var item = baseRenderFunction(entry, this);
  var nameId = item.id + '-entry-name';
  var sizeId = item.id + '-size';
  var dateId = item.id + '-date';
  filelist.decorateListItem(item, entry, this.metadataModel_);
  item.setAttribute('file-name', entry.name);
  item.querySelector('.entry-name').setAttribute('id', nameId);
  item.querySelector('.size').setAttribute('id', sizeId);
  item.querySelector('.date').setAttribute('id', dateId);
  item.setAttribute('aria-labelledby', nameId + ' ' + sizeId + ' ' + dateId);
  return item;
};

/**
 * Renders the file thumbnail in the detail table.
 * @param {Entry} entry The Entry object to render.
 * @return {!HTMLDivElement} Created element.
 * @private
 */
FileTable.prototype.renderThumbnail_ = function(entry) {
  var box = /** @type {!HTMLDivElement} */
      (this.ownerDocument.createElement('div'));
  box.className = 'detail-thumbnail';

  // Set thumbnail if it's already in cache.
  var thumbnailData = this.listThumbnailLoader_ ?
      this.listThumbnailLoader_.getThumbnailFromCache(entry) : null;
  if (thumbnailData && thumbnailData.dataUrl) {
    this.setThumbnailImage_(
        box, this.listThumbnailLoader_.getThumbnailFromCache(entry).dataUrl,
        false /* without animation */);
  }

  return box;
};

/**
 * Sets thumbnail image to the box.
 * @param {!HTMLDivElement} box Detail thumbnail div element.
 * @param {string} dataUrl Data url of thumbnail.
 * @param {boolean} shouldAnimate Whether the thumbnail is shown with animation
 *     or not.
 * @private
 */
FileTable.prototype.setThumbnailImage_ = function(box, dataUrl, shouldAnimate) {
  var oldThumbnails = box.querySelectorAll('.thumbnail');

  var thumbnail = box.ownerDocument.createElement('div');
  thumbnail.classList.add('thumbnail');
  thumbnail.style.backgroundImage = 'url(' + dataUrl + ')';
  thumbnail.addEventListener('animationend', function() {
    // Remove animation css once animation is completed in order not to animate
    // again when an item is attached to the dom again.
    thumbnail.classList.remove('animate');

    for (var i = 0; i < oldThumbnails.length; i++) {
      if (box.contains(oldThumbnails[i])) {
        box.removeChild(oldThumbnails[i]);
      }
    }
  });

  if (shouldAnimate) {
    thumbnail.classList.add('animate');
  }

  box.appendChild(thumbnail);
};

/**
 * Clears thumbnail image from the box.
 * @param {!HTMLDivElement} box Detail thumbnail div element.
 * @private
 */
FileTable.prototype.clearThumbnailImage_ = function(box) {
  var oldThumbnails = box.querySelectorAll('.thumbnail');

  for (var i = 0; i < oldThumbnails.length; i++) {
    box.removeChild(oldThumbnails[i]);
  }
};

/**
 * Renders the selection checkmark in the detail table.
 * @return {!HTMLDivElement} Created element.
 * @private
 */
FileTable.prototype.renderCheckmark_ = function() {
  var checkmark = /** @type {!HTMLDivElement} */
      (this.ownerDocument.createElement('div'));
  checkmark.className = 'detail-checkmark';
  return checkmark;
};

/**
 * Redraws the UI. Skips multiple consecutive calls.
 */
FileTable.prototype.relayout = function() {
  this.relayoutRateLimiter_.run();
};

/**
 * Redraws the UI immediately.
 * @private
 */
FileTable.prototype.relayoutImmediately_ = function() {
  if (this.clientWidth > 0) {
    this.normalizeColumns();
  }
  this.redraw();
  cr.dispatchSimpleEvent(this.list, 'relayout');
};
