// 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.

/**
 * The current selection object.
 * @param {!Array<number>} indexes
 * @param {!Array<Entry>} entries
 * @constructor
 * @struct
 */
function FileSelection(indexes, entries) {
  /**
   * @public {!Array<number>}
   * @const
   */
  this.indexes = indexes;

  /**
   * @public {!Array<!Entry>}
   * @const
   */
  this.entries = entries;

  /**
   * @public {!Array<string>}
   */
  this.mimeTypes = [];

  /**
   * @public {number}
   */
  this.totalCount = 0;

  /**
   * @public {number}
   */
  this.fileCount = 0;

  /**
   * @public {number}
   */
  this.directoryCount = 0;

  /**
   * @public {boolean}
   */
  this.anyFilesNotInCache = true;

  /**
   * @public {boolean}
   */
  this.anyFilesHosted = true;

  /**
   * @public {?string}
   */
  this.iconType = null;

  /**
   * @private {Promise<boolean>}
   */
  this.additionalPromise_ = null;

  entries.forEach(function(entry) {
    if (this.iconType == null) {
      this.iconType = FileType.getIcon(entry);
    } else if (this.iconType != 'unknown') {
      var iconType = FileType.getIcon(entry);
      if (this.iconType != iconType)
        this.iconType = 'unknown';
    }

    if (entry.isFile) {
      this.fileCount += 1;
    } else {
      this.directoryCount += 1;
    }
    this.totalCount++;
  }.bind(this));
}

FileSelection.prototype.computeAdditional = function(metadataModel) {
  if (!this.additionalPromise_) {
    this.additionalPromise_ =
        metadataModel
            .get(
                this.entries,
                constants.FILE_SELECTION_METADATA_PREFETCH_PROPERTY_NAMES)
            .then(function(props) {
              var present = props.filter(function(p) {
                // If no availableOffline property, then assume it's available.
                return !('availableOffline' in p) || p.availableOffline;
              });
              const hosted = props.filter(function(p) {
                return p.hosted;
              });
              this.anyFilesNotInCache = present.length !== props.length;
              this.anyFilesHosted = !!hosted.length;
              this.mimeTypes = props.map(function(value) {
                return value.contentMimeType || '';
              });
              return true;
            }.bind(this));
  }
  return this.additionalPromise_;
};

/**
 * This object encapsulates everything related to current selection.
 *
 * @param {!DirectoryModel} directoryModel
 * @param {!FileOperationManager} fileOperationManager
 * @param {!ListContainer} listContainer
 * @param {!MetadataModel} metadataModel
 * @param {!VolumeManager} volumeManager
 * @param {!AllowedPaths} allowedPaths
 * @extends {cr.EventTarget}
 * @constructor
 * @struct
 */
function FileSelectionHandler(
    directoryModel, fileOperationManager, listContainer, metadataModel,
    volumeManager, allowedPaths) {
  cr.EventTarget.call(this);

  /**
   * @private {DirectoryModel}
   * @const
   */
  this.directoryModel_ = directoryModel;

  /**
   * @private {ListContainer}
   * @const
   */
  this.listContainer_ = listContainer;

  /**
   * @private {MetadataModel}
   * @const
   */
  this.metadataModel_ = metadataModel;

  /**
   * @private {VolumeManager}
   * @const
   */
  this.volumeManager_ = volumeManager;

  /**
   * @type {FileSelection}
   */
  this.selection = new FileSelection([], []);

  /**
   * @private {?number}
   */
  this.selectionUpdateTimer_ = 0;

  /**
   * @private {number}
   */
  this.lastFileSelectionTime_ = Date.now();

  /**
   * @private {AllowedPaths}
   * @const
   */
  this.allowedPaths_ = allowedPaths;

  util.addEventListenerToBackgroundComponent(
      assert(fileOperationManager), 'entries-changed',
      this.onFileSelectionChanged.bind(this));
  // Register evnets to update file selections.
  directoryModel.addEventListener(
      'directory-changed', this.onFileSelectionChanged.bind(this));
}

/**
 * @enum {string}
 */
FileSelectionHandler.EventType = {
  /**
   * Dispatched every time when selection is changed.
   */
  CHANGE: 'change',

  /**
   * Dispatched |UPDATE_DELAY| ms after the selecton is changed.
   * If multiple changes are happened during the term, only one CHANGE_THROTTLED
   * event is dispatched.
   */
  CHANGE_THROTTLED: 'changethrottled'
};

/**
 * Delay in milliseconds before recalculating the selection in case the
 * selection is changed fast, or there are many items. Used to avoid freezing
 * the UI.
 * @const {number}
 */
FileSelectionHandler.UPDATE_DELAY = 200;

/**
 * Number of items in the selection which triggers the update delay. Used to
 * let the Material Design animations complete before performing a heavy task
 * which would cause the UI freezing.
 * @const {number}
 */
FileSelectionHandler.NUMBER_OF_ITEMS_HEAVY_TO_COMPUTE = 100;

/**
 * FileSelectionHandler extends cr.EventTarget.
 */
FileSelectionHandler.prototype.__proto__ = cr.EventTarget.prototype;

/**
 * Update the UI when the selection model changes.
 */
FileSelectionHandler.prototype.onFileSelectionChanged = function() {
  var indexes = this.listContainer_.selectionModel.selectedIndexes;
  var entries = indexes.map(function(index) {
    return /** @type {!Entry} */ (
        this.directoryModel_.getFileList().item(index));
  }.bind(this));
  this.selection = new FileSelection(indexes, entries);

  if (this.selectionUpdateTimer_) {
    clearTimeout(this.selectionUpdateTimer_);
    this.selectionUpdateTimer_ = null;
  }

  // The rest of the selection properties are computed via (sometimes lengthy)
  // asynchronous calls. We initiate these calls after a timeout. If the
  // selection is changing quickly we only do this once when it slows down.

  var updateDelay = FileSelectionHandler.UPDATE_DELAY;
  var now = Date.now();

  if (now > (this.lastFileSelectionTime_ || 0) + updateDelay &&
      indexes.length < FileSelectionHandler.NUMBER_OF_ITEMS_HEAVY_TO_COMPUTE) {
    // The previous selection change happened a while ago and there is few
    // selected items, so computation is lightweight. Update the UI without
    // delay.
    updateDelay = 0;
  }
  this.lastFileSelectionTime_ = now;

  var selection = this.selection;
  this.selectionUpdateTimer_ = setTimeout(function() {
    this.selectionUpdateTimer_ = null;
    if (this.selection === selection)
      this.updateFileSelectionAsync_(selection);
  }.bind(this), updateDelay);

  cr.dispatchSimpleEvent(this, FileSelectionHandler.EventType.CHANGE);
};

/**
 * Calculates async selection stats and updates secondary UI elements.
 *
 * @param {FileSelection} selection The selection object.
 * @private
 */
FileSelectionHandler.prototype.updateFileSelectionAsync_ = function(selection) {
  if (this.selection !== selection)
    return;

  // Calculate all additional and heavy properties.
  selection.computeAdditional(this.metadataModel_).then(() => {
    if (this.selection !== selection)
      return;

    cr.dispatchSimpleEvent(
        this, FileSelectionHandler.EventType.CHANGE_THROTTLED);
  });
};

/**
 * Returns true if all files in the selection files are selectable.
 * @return {boolean}
 */
FileSelectionHandler.prototype.isAvailable = function() {
  if (!this.directoryModel_.isOnDrive()) {
    return true;
  }

  return !(
      this.isOfflineWithUncachedFilesSelected_() ||
      this.isDialogWithHostedFilesSelected_());
};


/**
 * Returns true if we're offline with any selected files absent from the cache.
 * @return {boolean}
 * @private
 */
FileSelectionHandler.prototype.isOfflineWithUncachedFilesSelected_ =
    function() {
  return this.volumeManager_.getDriveConnectionState().type ===
      VolumeManagerCommon.DriveConnectionType.OFFLINE &&
      this.selection.anyFilesNotInCache;
};

/**
 * Returns true if we're a dialog requiring real files with hosted files
 * selected.
 * @return {boolean}
 * @private
 */
FileSelectionHandler.prototype.isDialogWithHostedFilesSelected_ = function() {
  return this.allowedPaths_ !== AllowedPaths.ANY_PATH_OR_URL &&
      this.selection.anyFilesHosted;
};
