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

/**
 * FileManager constructor.
 *
 * FileManager objects encapsulate the functionality of the file selector
 * dialogs, as well as the full screen file manager application.
 *
 * @implements {CommandHandlerDeps}
 * @constructor
 * @struct
 */
function FileManager() {
  // --------------------------------------------------------------------------
  // Services FileManager depends on.

  /**
   * Volume manager.
   * @type {VolumeManagerWrapper}
   * @private
   */
  this.volumeManager_ = null;

  /** @private {importer.HistoryLoader} */
  this.historyLoader_ = null;

  /**
   * ImportHistory. Non-null only once history observer is added in
   * {@code addHistoryObserver}.
   *
   * @type {importer.ImportHistory}
   * @private
   */
  this.importHistory_ = null;

  /**
   * Bound observer for use with {@code importer.ImportHistory.Observer}.
   * The instance is bound once here as {@code ImportHistory.removeObserver}
   * uses object equivilency to remove observers.
   *
   * @private {function(!importer.ImportHistory.ChangedEvent)}
   */
  this.onHistoryChangedBound_ = this.onHistoryChanged_.bind(this);

  /** @private {importer.MediaScanner} */
  this.mediaScanner_ = null;

  /** @private {importer.ImportController} */
  this.importController_ = null;

  /** @private {importer.ImportRunner} */
  this.mediaImportHandler_ = null;

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

  /**
   * @private {!FileMetadataFormatter}
   */
  this.fileMetadataFormatter_ = new FileMetadataFormatter();

  /**
   * @private {ThumbnailModel}
   */
  this.thumbnailModel_ = null;

  /**
   * File operation manager.
   * @type {FileOperationManager}
   * @private
   */
  this.fileOperationManager_ = null;

  /**
   * File filter.
   * @private {FileFilter}
   */
  this.fileFilter_ = null;

  /**
   * Model of current directory.
   * @type {DirectoryModel}
   * @private
   */
  this.directoryModel_ = null;

  /**
   * Model of folder shortcuts.
   * @type {FolderShortcutsDataModel}
   * @private
   */
  this.folderShortcutsModel_ = null;

  /**
   * Model for providers (providing extensions).
   * @type {ProvidersModel}
   * @private
   */
  this.providersModel_ = null;

  /**
   * Model for quick view.
   * @type {QuickViewModel}
   * @private
   */
  this.quickViewModel_ = null;

  /**
   * Controller for actions for current selection.
   * @private {ActionsController}
   */
  this.actionsController_ = null;

  /**
   * Handler for command events.
   * @private {CommandHandler}
   */
  this.commandHandler_ = null;

  /**
   * Handler for the change of file selection.
   * @type {FileSelectionHandler}
   * @private
   */
  this.selectionHandler_ = null;

  /**
   * UI management class of file manager.
   * @type {FileManagerUI}
   * @private
   */
  this.ui_ = null;

  /**
   * @private {analytics.Tracker}
   */
  this.tracker_ = null;

  // --------------------------------------------------------------------------
  // Parameters determining the type of file manager.

  /**
   * Dialog type of this window.
   * @type {DialogType}
   */
  this.dialogType = DialogType.FULL_PAGE;

  /**
   * Startup parameters for this application.
   * @type {LaunchParam}
   * @private
   */
  this.launchParams_ = null;

  /**
   * Whether to allow touch-specific interaction.
   * @type {boolean}
   */
  this.enableTouchMode_ = false;

  // --------------------------------------------------------------------------
  // Controllers.

  /**
   * File transfer controller.
   * @type {FileTransferController}
   * @private
   */
  this.fileTransferController_ = null;

  /**
   * Naming controller.
   * @type {NamingController}
   * @private
   */
  this.namingController_ = null;

  /**
   * Directory tree naming controller.
   * @private {DirectoryTreeNamingController}
   */
  this.directoryTreeNamingController_ = null;

  /**
   * Controller for search UI.
   * @type {SearchController}
   * @private
   */
  this.searchController_ = null;

  /**
   * Controller for directory scan.
   * @type {ScanController}
   * @private
   */
  this.scanController_ = null;

  /**
   * Controller for spinner.
   * @type {SpinnerController}
   * @private
   */
  this.spinnerController_ = null;

  /**
   * Sort menu controller.
   * @type {SortMenuController}
   * @private
   */
  this.sortMenuController_ = null;

  /**
   * Gear menu controller.
   * @type {GearMenuController}
   * @private
   */
  this.gearMenuController_ = null;

  /**
   * Controller for the context menu opened by the action bar button in the
   * check-select mode.
   * @type {SelectionMenuController}
   * @private
   */
  this.selectionMenuController_ = null;

  /**
   * Toolbar controller.
   * @type {ToolbarController}
   * @private
   */
  this.toolbarController_ = null;

  /**
   * Empty folder controller.
   * @private {EmptyFolderController}
   */
  this.emptyFolderController_ = null;

  /**
   * App state controller.
   * @type {AppStateController}
   * @private
   */
  this.appStateController_ = null;

  /**
   * Dialog action controller.
   * @type {DialogActionController}
   * @private
   */
  this.dialogActionController_ = null;

  /**
   * List update controller.
   * @type {MetadataUpdateController}
   * @private
   */
  this.metadataUpdateController_ = null;

  /**
   * Last modified controller.
   * @private {LastModifiedController}
   */
  this.lastModifiedController_ = null;

  /**
   * Component for main window and its misc UI parts.
   * @type {MainWindowComponent}
   * @private
   */
  this.mainWindowComponent_ = null;

  /**
   * @type {TaskController}
   * @private
   */
  this.taskController_ = null;

  /** @private {ColumnVisibilityController} */
  this.columnVisibilityController_ = null;

  /**
   * @type {QuickViewUma}
   * @private
   */
  this.quickViewUma_ = null;

  /**
   * @type {QuickViewController}
   * @private
   */
  this.quickViewController_ = null;

  /**
   * Records histograms of directory-changed event.
   * @type {NavigationUma}
   * @private
   */
  this.navigationUma_ = null;

  // --------------------------------------------------------------------------
  // DOM elements.

  /**
   * Background page.
   * @type {BackgroundWindow}
   * @private
   */
  this.backgroundPage_ = null;

  /**
   * @type {FileBrowserBackgroundFull}
   * @private
   */
  this.fileBrowserBackground_ = null;

  /**
   * The root DOM element of this app.
   * @type {HTMLBodyElement}
   * @private
   */
  this.dialogDom_ = null;

  /**
   * The document object of this app.
   * @type {Document}
   * @private
   */
  this.document_ = null;

  // --------------------------------------------------------------------------
  // Miscellaneous FileManager's states.

  /**
   * Promise object which is fullfilled when initialization for app state
   * controller is done.
   * @type {Promise}
   * @private
   */
  this.initSettingsPromise_ = null;

  /**
   * Promise object which is fullfilled when initialization related to the
   * background page is done.
   * @type {Promise}
   * @private
   */
  this.initBackgroundPagePromise_ = null;

  /**
   * Flags async retrieved once at startup and can be used to switch behaviour
   * on sync functions.
   * @dict
   * @private
   */
  this.commandLineFlags_ = {};
}

FileManager.prototype = /** @struct */ {
  __proto__: cr.EventTarget.prototype,
  /**
   * @return {DirectoryModel}
   */
  get directoryModel() {
    return this.directoryModel_;
  },
  /**
   * @return {DirectoryTreeNamingController}
   */
  get directoryTreeNamingController() {
    return this.directoryTreeNamingController_;
  },
  /**
   * @return {FileFilter}
   */
  get fileFilter() {
    return this.fileFilter_;
  },
  /**
   * @return {FolderShortcutsDataModel}
   */
  get folderShortcutsModel() {
    return this.folderShortcutsModel_;
  },
  /**
   * @return {ActionsController}
   */
  get actionsController() {
    return this.actionsController_;
  },
  /**
   * @return {CommandHandler}
   */
  get commandHandler() {
    return this.commandHandler_;
  },
  /**
   * @return {ProvidersModel}
   */
  get providersModel() {
    return this.providersModel_;
  },
  /**
   * @return {MetadataModel}
   */
  get metadataModel() {
    return this.metadataModel_;
  },
  /**
   * @return {FileSelectionHandler}
   */
  get selectionHandler() {
    return this.selectionHandler_;
  },
  /**
   * @return {DirectoryTree}
   */
  get directoryTree() {
    return this.ui_.directoryTree;
  },
  /**
   * @return {Document}
   */
  get document() {
    return this.document_;
  },
  /**
   * @return {FileTransferController}
   */
  get fileTransferController() {
    return this.fileTransferController_;
  },
  /**
   * @return {NamingController}
   */
  get namingController() {
    return this.namingController_;
  },
  /**
   * @return {TaskController}
   */
  get taskController() {
    return this.taskController_;
  },
  /**
   * @return {SpinnerController}
   */
  get spinnerController() {
    return this.spinnerController_;
  },
  /**
   * @return {FileOperationManager}
   */
  get fileOperationManager() {
    return this.fileOperationManager_;
  },
  /**
   * @return {BackgroundWindow}
   */
  get backgroundPage() {
    return this.backgroundPage_;
  },
  /**
   * @return {VolumeManagerWrapper}
   */
  get volumeManager() {
    return this.volumeManager_;
  },
  /**
   * @return {importer.ImportController}
   */
  get importController() {
    return this.importController_;
  },
  /**
   * @return {importer.HistoryLoader}
   */
  get historyLoader() {
    return this.historyLoader_;
  },
  /**
   * @return {importer.ImportRunner}
   */
  get mediaImportHandler() {
    return this.mediaImportHandler_;
  },
  /**
   * @return {FileManagerUI}
   */
  get ui() {
    return this.ui_;
  },
  /**
   * @return {analytics.Tracker}
   */
  get tracker() {
    return this.tracker_;
  }
};

// Anonymous "namespace".
(function() {
  /**
   * One time initialization for app state controller to load view option from
   * local storage.
   * @return {!Promise} A promise to be fillfilled when initialization is done.
   * @private
   */
  FileManager.prototype.startInitSettings_ = function() {
    metrics.startInterval('Load.InitSettings');
    this.appStateController_ = new AppStateController(this.dialogType);
    return Promise
        .all([
          this.appStateController_.loadInitialViewOptions(),
          util.isMyFilesNavigationDisabled(),
        ])
        .then(values => {
          this.commandLineFlags_['disable-my-files-navigation'] =
              /** @type {boolean} */ (values[1]);
          metrics.recordInterval('Load.InitSettings');
        });
  };

  /**
   * One time initialization for the file system and related things.
   * @private
   */
  FileManager.prototype.initFileSystemUI_ = function() {
    this.ui_.listContainer.startBatchUpdates();

    this.initFileList_();
    this.setupCurrentDirectory_();

    var self = this;

    var listBeingUpdated = null;
    this.directoryModel_.addEventListener('begin-update-files', function() {
      self.ui_.listContainer.currentList.startBatchUpdates();
      // Remember the list which was used when updating files started, so
      // endBatchUpdates() is called on the same list.
      listBeingUpdated = self.ui_.listContainer.currentList;
    });
    this.directoryModel_.addEventListener('end-update-files', function() {
      self.namingController_.restoreItemBeingRenamed();
      listBeingUpdated.endBatchUpdates();
      listBeingUpdated = null;
    });
    this.volumeManager_.addEventListener(
        VolumeManagerCommon.ARCHIVE_OPENED_EVENT_TYPE, function(event) {
          assert(event.detail.mountPoint);
          if (window.isFocused())
            this.directoryModel_.changeDirectoryEntry(event.detail.mountPoint);
        }.bind(this));

    this.directoryModel_.addEventListener(
        'directory-changed',
        (/** @param {!Event} event */
        function(event) {
          this.navigationUma_.onDirectoryChanged(event.newDirEntry);
        }).bind(this));

    this.initCommands_();

    assert(this.directoryModel_);
    assert(this.spinnerController_);
    assert(this.commandHandler_);
    assert(this.selectionHandler_);
    assert(this.launchParams_);
    assert(this.volumeManager_);
    assert(this.dialogDom_);
    assert(this.fileFilter_);

    this.scanController_ = new ScanController(
        this.directoryModel_,
        this.ui_.listContainer,
        this.spinnerController_,
        this.commandHandler_,
        this.selectionHandler_);
    this.sortMenuController_ = new SortMenuController(
        this.ui_.sortButton,
        this.ui_.sortButtonToggleRipple,
        assert(this.directoryModel_.getFileList()));
    this.gearMenuController_ = new GearMenuController(
        this.ui_.gearButton,
        this.ui_.gearButtonToggleRipple,
        this.ui_.gearMenu,
        this.directoryModel_,
        this.commandHandler_,
        assert(this.providersModel_));
    this.selectionMenuController_ = new SelectionMenuController(
        this.ui_.selectionMenuButton,
        util.queryDecoratedElement('#file-context-menu', cr.ui.Menu));
    this.toolbarController_ = new ToolbarController(
        this.ui_.toolbar,
        this.ui_.dialogNavigationList,
        this.ui_.listContainer,
        assert(this.ui_.locationLine),
        this.selectionHandler_,
        this.directoryModel_);
    this.emptyFolderController_ = new EmptyFolderController(
        this.ui_.emptyFolder, this.directoryModel_, this.ui_.alertDialog);
    this.actionsController_ = new ActionsController(
        this.volumeManager_, assert(this.metadataModel_), this.directoryModel_,
        assert(this.folderShortcutsModel_),
        this.fileBrowserBackground_.driveSyncHandler,
        this.selectionHandler_, assert(this.ui_));
    this.lastModifiedController_ = new LastModifiedController(
        this.ui_.listContainer.table, this.directoryModel_);

    this.quickViewModel_ = new QuickViewModel();
    var fileListSelectionModel = /** @type {!cr.ui.ListSelectionModel} */ (
        this.directoryModel_.getFileListSelection());
    this.quickViewUma_ =
        new QuickViewUma(assert(this.volumeManager_), assert(this.dialogType));
    var metadataBoxController = new MetadataBoxController(
        this.metadataModel_, this.quickViewModel_, this.fileMetadataFormatter_);
    this.quickViewController_ = new QuickViewController(
        assert(this.metadataModel_), assert(this.selectionHandler_),
        assert(this.ui_.listContainer), assert(this.ui_.selectionMenuButton),
        assert(this.quickViewModel_), assert(this.taskController_),
        fileListSelectionModel, assert(this.quickViewUma_),
        metadataBoxController, this.dialogType, assert(this.volumeManager_));

    if (this.dialogType === DialogType.FULL_PAGE) {
      importer.importEnabled().then(
          function(enabled) {
            if (enabled) {
              this.importController_ = new importer.ImportController(
                  new importer.RuntimeControllerEnvironment(
                      this,
                      assert(this.selectionHandler_)),
                  assert(this.mediaScanner_),
                  assert(this.mediaImportHandler_),
                  new importer.RuntimeCommandWidget(),
                  assert(this.tracker_));
            }
          }.bind(this));
    }

    assert(this.fileFilter_);
    assert(this.namingController_);
    assert(this.appStateController_);
    assert(this.taskController_);
    this.mainWindowComponent_ = new MainWindowComponent(
        this.dialogType,
        this.ui_,
        this.volumeManager_,
        this.directoryModel_,
        this.fileFilter_,
        this.selectionHandler_,
        this.namingController_,
        this.appStateController_,
        this.taskController_);

    this.initDataTransferOperations_();

    this.selectionHandler_.onFileSelectionChanged();
    this.ui_.listContainer.endBatchUpdates();

    this.ui_.initBanners(
        new Banners(
            this.directoryModel_,
            this.volumeManager_,
            this.document_,
            // Whether to show any welcome banner.
            this.dialogType === DialogType.FULL_PAGE));

    this.ui_.attachFilesTooltip();

    this.ui_.decorateFilesMenuItems();

    util.isTouchModeEnabled().then(function(isEnabled) {
      if (isEnabled) {
        this.ui_.selectionMenuButton.hidden = false;
        this.enableTouchMode_ = true;
      }
    }.bind(this));
  };

  /**
   * @private
   */
  FileManager.prototype.initDataTransferOperations_ = function() {
    // CopyManager are required for 'Delete' operation in
    // Open and Save dialogs. But drag-n-drop and copy-paste are not needed.
    if (this.dialogType !== DialogType.FULL_PAGE)
      return;

    this.fileTransferController_ = new FileTransferController(
        assert(this.document_), assert(this.ui_.listContainer),
        assert(this.ui_.directoryTree), this.ui_.multiProfileShareDialog,
        this.ui_.showConfirmationDialog.bind(this.ui_),
        assert(this.fileBrowserBackground_.progressCenter),
        assert(this.fileOperationManager_), assert(this.metadataModel_),
        assert(this.thumbnailModel_), assert(this.directoryModel_),
        assert(this.volumeManager_), assert(this.selectionHandler_),
        CommandUtil.shouldShowMenuItemsForEntry.bind(
            null, assert(this.volumeManager_)));
  };

  /**
   * One-time initialization of commands.
   * @private
   */
  FileManager.prototype.initCommands_ = function() {
    assert(this.ui_.textContextMenu);

    this.commandHandler_ =
        new CommandHandler(this, assert(this.selectionHandler_));

    // TODO(hirono): Move the following block to the UI part.
    var commandButtons = this.dialogDom_.querySelectorAll('button[command]');
    for (var j = 0; j < commandButtons.length; j++)
      CommandButton.decorate(commandButtons[j]);

    var inputs = this.getDomInputs_();

    for (let input of inputs)
      this.setContextMenuForInput_(input);

    this.setContextMenuForInput_(this.ui_.listContainer.renameInput);
    this.setContextMenuForInput_(
        this.directoryTreeNamingController_.getInputElement());

    this.document_.addEventListener(
        'command',
        this.ui_.listContainer.clearHover.bind(this.ui_.listContainer));
  };

  /**
   * Get input elements from root DOM element of this app.
   * @private
   */
  FileManager.prototype.getDomInputs_ = function() {
    return this.dialogDom_.querySelectorAll(
        'input[type=text], input[type=search], textarea, cr-input');
  };

  /**
   * Set context menu and handlers for an input element.
   * @private
   */
  FileManager.prototype.setContextMenuForInput_ = function(input) {
    var touchInduced = false;

    // stop contextmenu propagation for touch-induced events.
    input.addEventListener('touchstart', (e) => {
      touchInduced = true;
    });
    input.addEventListener('contextmenu', (e) => {
      if (touchInduced) {
        e.stopImmediatePropagation();
      }
      touchInduced = false;
    });
    input.addEventListener('click', (e) => {
      touchInduced = false;
    });

    cr.ui.contextMenuHandler.setContextMenu(input, this.ui_.textContextMenu);
    this.registerInputCommands_(input);
  };

  /**
   * Registers cut, copy, paste and delete commands on input element.
   *
   * @param {Node} node Text input element to register on.
   * @private
   */
  FileManager.prototype.registerInputCommands_ = function(node) {
    CommandUtil.forceDefaultHandler(node, 'cut');
    CommandUtil.forceDefaultHandler(node, 'copy');
    CommandUtil.forceDefaultHandler(node, 'paste');
    CommandUtil.forceDefaultHandler(node, 'delete');
    node.addEventListener('keydown', function(e) {
      var key = util.getKeyModifiers(e) + e.keyCode;
      if (key === '190' /* '/' */ || key === '191' /* '.' */) {
        // If this key event is propagated, this is handled search command,
        // which calls 'preventDefault' method.
        e.stopPropagation();
      }
    });
  };

  /**
   * Entry point of the initialization.
   * This method is called from main.js.
   */
  FileManager.prototype.initializeCore = function() {
    this.initGeneral_();
    this.initSettingsPromise_ = this.startInitSettings_();
    this.initBackgroundPagePromise_ = this.startInitBackgroundPage_();
    this.initBackgroundPagePromise_.then(function() {
      this.initVolumeManager_();
    }.bind(this));

    window.addEventListener('pagehide', this.onUnload_.bind(this));
  };

  /**
   * @return {!Promise} A promise to be fillfilled when initialization is done.
   */
  FileManager.prototype.initializeUI = function(dialogDom) {
    this.dialogDom_ = dialogDom;
    this.document_ = this.dialogDom_.ownerDocument;

    metrics.startInterval('Load.InitDocuments');
    return Promise
        .all([this.initBackgroundPagePromise_, window.importElementsPromise])
        .then(function() {
          metrics.recordInterval('Load.InitDocuments');
          metrics.startInterval('Load.InitUI');
          this.initEssentialUI_();
          this.initAdditionalUI_();
          return this.initSettingsPromise_;
        }.bind(this))
        .then(function() {
          this.initFileSystemUI_();
          this.initUIFocus_();
          metrics.recordInterval('Load.InitUI');
        }.bind(this));
  };

  /**
   * Initializes general purpose basic things, which are used by other
   * initializing methods.
   *
   * @private
   */
  FileManager.prototype.initGeneral_ = function() {
    // Initialize the application state.
    // TODO(mtomasz): Unify window.appState with location.search format.
    if (window.appState) {
      var params = {};
      for (var name in window.appState) {
        params[name] = window.appState[name];
      }
      for (var name in window.appState.params) {
        params[name] = window.appState.params[name];
      }
      this.launchParams_ = new LaunchParam(params);
    } else {
      // Used by the select dialog only.
      var json = location.search ?
          JSON.parse(decodeURIComponent(location.search.substr(1))) : {};
      this.launchParams_ = new LaunchParam(json instanceof Object ? json : {});
    }

    // Initialize the member variables that depend this.launchParams_.
    this.dialogType = this.launchParams_.type;

    // We used to share the tracker with background, but due to
    // its use of instanceof checks for some functionality
    // we really can't do this (as instanceof checks fail across
    // different script contexts).
    this.tracker_ = metrics.getTracker();
  };

  /**
   * Initializes the background page.
   * @return {!Promise} A promise to be fillfilled when initialization is done.
   * @private
   */
  FileManager.prototype.startInitBackgroundPage_ = function() {
    return new Promise(function(resolve) {
      metrics.startInterval('Load.InitBackgroundPage');
      chrome.runtime.getBackgroundPage(/** @type {function(Window=)} */ (
          function(opt_backgroundPage) {
            assert(opt_backgroundPage);
            this.backgroundPage_ =
                /** @type {!BackgroundWindow} */ (opt_backgroundPage);
            this.fileBrowserBackground_ =
                /** @type {!FileBrowserBackgroundFull} */ (
                    this.backgroundPage_.background);
            this.fileBrowserBackground_.ready(function() {
              loadTimeData.data = this.fileBrowserBackground_.stringData;
              if (util.runningInBrowser())
                this.backgroundPage_.registerDialog(window);
              this.fileOperationManager_ =
                  this.fileBrowserBackground_.fileOperationManager;
              this.mediaImportHandler_ =
                  this.fileBrowserBackground_.mediaImportHandler;
              this.mediaScanner_ =
                  this.fileBrowserBackground_.mediaScanner;
              this.historyLoader_ =
                  this.fileBrowserBackground_.historyLoader;
              metrics.recordInterval('Load.InitBackgroundPage');
              resolve();
            }.bind(this));
          }.bind(this)));
    }.bind(this));
  };

  /**
   * Initializes the VolumeManager instance.
   * @private
   */
  FileManager.prototype.initVolumeManager_ = function() {
    var allowedPaths = this.getAllowedPaths_();
    var writableOnly =
        this.launchParams_.type === DialogType.SELECT_SAVEAS_FILE;

    // VolumeManagerWrapper hides virtual file system related event and data
    // even depends on the value of |supportVirtualPath|. If it is
    // VirtualPathSupport.NO_VIRTUAL_PATH, it hides Drive even if Drive is
    // enabled on preference.
    // In other words, even if Drive is disabled on preference but the Files app
    // should show Drive when it is re-enabled, then the value should be set to
    // true.
    // Note that the Drive enabling preference change is listened by
    // DriveIntegrationService, so here we don't need to take care about it.
    this.volumeManager_ = new VolumeManagerWrapper(
        allowedPaths, writableOnly, this.backgroundPage_);
  };

  /**
   * One time initialization of the essential UI elements in the Files app.
   * These elements will be shown to the user. Only visible elements should be
   * initialized here. Any heavy operation should be avoided. The Files app's
   * window is shown at the end of this routine.
   * @private
   */
  FileManager.prototype.initEssentialUI_ = function() {
    // Record stats of dialog types. New values must NOT be inserted into the
    // array enumerating the types. It must be in sync with
    // FileDialogType enum in tools/metrics/histograms/histogram.xml.
    metrics.recordEnum('Create', this.dialogType,
        [DialogType.SELECT_FOLDER,
         DialogType.SELECT_UPLOAD_FOLDER,
         DialogType.SELECT_SAVEAS_FILE,
         DialogType.SELECT_OPEN_FILE,
         DialogType.SELECT_OPEN_MULTI_FILE,
         DialogType.FULL_PAGE]);

    // Create the metadata cache.
    assert(this.volumeManager_);
    this.metadataModel_ = MetadataModel.create(this.volumeManager_);
    this.thumbnailModel_ = new ThumbnailModel(this.metadataModel_);
    this.providersModel_ = new ProvidersModel(this.volumeManager_);
    this.fileFilter_ = new FileFilter(this.metadataModel_);

    // Create the root view of FileManager.
    assert(this.dialogDom_);
    assert(this.launchParams_);
    this.ui_ = new FileManagerUI(
        assert(this.providersModel_), this.dialogDom_, this.launchParams_);
  };

  /**
   * One-time initialization of various DOM nodes. Loads the additional DOM
   * elements visible to the user. Initialize here elements, which are expensive
   * or hidden in the beginning.
   * @private
   */
  FileManager.prototype.initAdditionalUI_ = function() {
    assert(this.metadataModel_);
    assert(this.volumeManager_);
    assert(this.historyLoader_);
    assert(this.dialogDom_);

    // Cache nodes we'll be manipulating.
    var dom = this.dialogDom_;
    assert(dom);

    var table = queryRequiredElement('.detail-table', dom);
    FileTable.decorate(
        table,
        this.metadataModel_,
        this.volumeManager_,
        this.historyLoader_,
        this.dialogType == DialogType.FULL_PAGE);
    var grid = queryRequiredElement('.thumbnail-grid', dom);
    FileGrid.decorate(
        grid,
        this.metadataModel_,
        this.volumeManager_,
        this.historyLoader_);

    this.addHistoryObserver_();

    this.ui_.initAdditionalUI(
        assertInstanceof(table, FileTable),
        assertInstanceof(grid, FileGrid),
        new LocationLine(
            queryRequiredElement('#location-breadcrumbs', dom),
            this.volumeManager_));

    // Handle UI events.
    this.fileBrowserBackground_.progressCenter.addPanel(
        this.ui_.progressCenterPanel);

    util.addIsFocusedMethod();

    // Populate the static localized strings.
    i18nTemplate.process(this.document_, loadTimeData);

    // The cwd is not known at this point.  Hide the import status column before
    // redrawing, to avoid ugly flashing in the UI, caused when the first redraw
    // has a visible status column, and then the cwd is later discovered to be
    // not an import-eligible location.
    this.ui_.listContainer.table.setImportStatusVisible(false);

    // Arrange the file list.
    this.ui_.listContainer.table.normalizeColumns();
    this.ui_.listContainer.table.redraw();
  };

  /**
   * One-time initialization of focus. This should run at the last of UI
   *  initialization.
   * @private
   */
  FileManager.prototype.initUIFocus_ = function() {
    this.ui_.initUIFocus();
  };

  /**
   * One-time initialization of import history observer. Provides
   * the glue that updates the UI when history changes.
   *
   * @private
   */
  FileManager.prototype.addHistoryObserver_ = function() {
    // If, and only if history is ever fully loaded (it may not be),
    // we want to update grid/list view when it changes.
    this.historyLoader_.addHistoryLoadedListener(
        (/**
         * @param {!importer.ImportHistory} history
         * @this {FileManager}
         */
        function(history) {
          this.importHistory_ = history;
          history.addObserver(this.onHistoryChangedBound_);
        }).bind(this));

  };

  /**
   * Handles events when import history changed.
   *
   * @param {!importer.ImportHistory.ChangedEvent} event
   * @private
   */
  FileManager.prototype.onHistoryChanged_ = function(event) {
    // Ignore any entry that isn't an immediate child of the
    // current directory.
    util.isChildEntry(event.entry, this.getCurrentDirectoryEntry())
        .then(
            (/**
             * @param {boolean} isChild
             * @this {FileManager}
             */
            function(isChild) {
              if (isChild) {
                this.ui_.listContainer.grid.updateListItemsMetadata(
                    'import-history',
                    [event.entry]);
                this.ui_.listContainer.table.updateListItemsMetadata(
                    'import-history',
                    [event.entry]);
              }
            }).bind(this));
  };

  /**
   * Constructs table and grid (heavy operation).
   * @private
   */
  FileManager.prototype.initFileList_ = function() {
    var singleSelection =
        this.dialogType == DialogType.SELECT_OPEN_FILE ||
        this.dialogType == DialogType.SELECT_FOLDER ||
        this.dialogType == DialogType.SELECT_UPLOAD_FOLDER ||
        this.dialogType == DialogType.SELECT_SAVEAS_FILE;

    assert(this.volumeManager_);
    assert(this.fileOperationManager_);
    assert(this.metadataModel_);
    this.directoryModel_ = new DirectoryModel(
        singleSelection,
        this.fileFilter_,
        this.metadataModel_,
        this.volumeManager_,
        this.fileOperationManager_,
        assert(this.tracker_));

    this.folderShortcutsModel_ = new FolderShortcutsDataModel(
        this.volumeManager_);

    this.selectionHandler_ = new FileSelectionHandler(
        assert(this.directoryModel_), assert(this.fileOperationManager_),
        assert(this.ui_.listContainer), assert(this.metadataModel_),
        assert(this.volumeManager_));

    this.directoryModel_.getFileListSelection().addEventListener('change',
        this.selectionHandler_.onFileSelectionChanged.bind(
            this.selectionHandler_));

    // TODO(mtomasz, yoshiki): Create navigation list earlier, and here just
    // attach the directory model.
    this.initDirectoryTree_();

    this.ui_.listContainer.listThumbnailLoader = new ListThumbnailLoader(
        this.directoryModel_,
        assert(this.thumbnailModel_),
        this.volumeManager_);
    this.ui_.listContainer.dataModel = this.directoryModel_.getFileList();
    this.ui_.listContainer.emptyDataModel =
        this.directoryModel_.getEmptyFileList();
    this.ui_.listContainer.selectionModel =
        this.directoryModel_.getFileListSelection();

    this.appStateController_.initialize(this.ui_, this.directoryModel_);

    if (this.dialogType === DialogType.FULL_PAGE) {
      this.columnVisibilityController_ = new ColumnVisibilityController(
          this.ui_, this.directoryModel_, this.volumeManager_);
    }

    // Create metadata update controller.
    this.metadataUpdateController_ = new MetadataUpdateController(
        this.ui_.listContainer,
        this.directoryModel_,
        this.metadataModel_,
        this.fileMetadataFormatter_);

    // Create task controller.
    this.taskController_ = new TaskController(
        this.dialogType,
        this.volumeManager_,
        this.ui_,
        this.metadataModel_,
        this.directoryModel_,
        this.selectionHandler_,
        this.metadataUpdateController_);

    // Create search controller.
    this.searchController_ = new SearchController(
        this.ui_.searchBox,
        assert(this.ui_.locationLine),
        this.directoryModel_,
        this.volumeManager_,
        assert(this.taskController_));

    // Create naming controller.
    assert(this.ui_.alertDialog);
    assert(this.ui_.confirmDialog);
    assert(this.fileFilter_);
    this.namingController_ = new NamingController(
        this.ui_.listContainer,
        this.ui_.alertDialog,
        this.ui_.confirmDialog,
        this.directoryModel_,
        this.fileFilter_,
        this.selectionHandler_);

    // Create directory tree naming controller.
    this.directoryTreeNamingController_ = new DirectoryTreeNamingController(
        this.directoryModel_,
        assert(this.ui_.directoryTree),
        this.ui_.alertDialog);

    // Create spinner controller.
    this.spinnerController_ = new SpinnerController(
        this.ui_.listContainer.spinner);
    this.spinnerController_.blink();

    // Create dialog action controller.
    assert(this.launchParams_);
    this.dialogActionController_ = new DialogActionController(
        this.dialogType,
        this.ui_.dialogFooter,
        this.directoryModel_,
        this.metadataModel_,
        this.volumeManager_,
        this.fileFilter_,
        this.namingController_,
        this.selectionHandler_,
        this.launchParams_);
  };

  /**
   * @private
   */
  FileManager.prototype.initDirectoryTree_ = function() {
    var directoryTree = /** @type {DirectoryTree} */
        (this.dialogDom_.querySelector('#directory-tree'));
    var fakeEntriesVisible =
        this.dialogType !== DialogType.SELECT_SAVEAS_FILE;
    this.navigationUma_ = new NavigationUma(assert(this.volumeManager_));
    DirectoryTree.decorate(directoryTree,
                           assert(this.directoryModel_),
                           assert(this.volumeManager_),
                           assert(this.metadataModel_),
                           assert(this.fileOperationManager_),
                           fakeEntriesVisible);
    directoryTree.dataModel = new NavigationListModel(
        assert(this.volumeManager_), assert(this.folderShortcutsModel_),
        fakeEntriesVisible &&
                !DialogType.isFolderDialog(this.launchParams_.type) ?
            new NavigationModelFakeItem(
                str('RECENT_ROOT_LABEL'), NavigationModelItemType.RECENT,
                new FakeEntry(
                    str('RECENT_ROOT_LABEL'),
                    VolumeManagerCommon.RootType.RECENT, true,
                    this.getSourceRestriction_())) :
            null,
        null,  // TODO(crbug.com/869252) remove this null.
        this.commandLineFlags_['disable-my-files-navigation']);
    this.setupCrostini_();
    this.ui_.initDirectoryTree(directoryTree);
  };

  /**
   * Check if crostini is enabled to create linuxFilesItem.
   * @private
   */
  FileManager.prototype.setupCrostini_ = function() {
    chrome.fileManagerPrivate.isCrostiniEnabled((enabled) => {
      this.directoryTree.dataModel.linuxFilesItem = enabled ?
          new NavigationModelFakeItem(
              str('LINUX_FILES_ROOT_LABEL'), NavigationModelItemType.CROSTINI,
              new FakeEntry(
                  str('LINUX_FILES_ROOT_LABEL'),
                  VolumeManagerCommon.RootType.CROSTINI, true)) :
          null;
      // Redraw the tree even if not enabled.  This is required for testing.
      this.directoryTree.redraw(false);

      if (!enabled)
        return;

      // Load any existing shared paths.
      chrome.fileManagerPrivate.getCrostiniSharedPaths((entries) => {
        for (let i = 0; i < entries.length; i++) {
          Crostini.registerSharedPath(entries[i], assert(this.volumeManager_));
        }
      });

    });
  };

  /**
   * Sets up the current directory during initialization.
   * @private
   */
  FileManager.prototype.setupCurrentDirectory_ = function() {
    var tracker = this.directoryModel_.createDirectoryChangeTracker();
    var queue = new AsyncUtil.Queue();

    // Wait until the volume manager is initialized.
    queue.run(function(callback) {
      tracker.start();
      this.volumeManager_.ensureInitialized(callback);
    }.bind(this));

    var nextCurrentDirEntry;
    var selectionEntry;

    // Resolve the selectionURL to selectionEntry or to currentDirectoryEntry
    // in case of being a display root or a default directory to open files.
    queue.run(function(callback) {
      if (!this.launchParams_.selectionURL) {
        callback();
        return;
      }

      window.webkitResolveLocalFileSystemURL(
          this.launchParams_.selectionURL,
          function(inEntry) {
            var locationInfo = this.volumeManager_.getLocationInfo(inEntry);
            // If location information is not available, then the volume is
            // no longer (or never) available.
            if (!locationInfo) {
              callback();
              return;
            }
            // If the selection is root, then use it as a current directory
            // instead. This is because, selecting a root entry is done as
            // opening it.
            if (locationInfo.isRootEntry)
              nextCurrentDirEntry = inEntry;

            // If this dialog attempts to open file(s) and the selection is a
            // directory, the selection should be the current directory.
            if (DialogType.isOpenFileDialog(this.dialogType) &&
                inEntry.isDirectory) {
              nextCurrentDirEntry = inEntry;
            }

            // By default, the selection should be selected entry and the
            // parent directory of it should be the current directory.
            if (!nextCurrentDirEntry)
              selectionEntry = inEntry;

            callback();
          }.bind(this), callback);
    }.bind(this));
    // Resolve the currentDirectoryURL to currentDirectoryEntry (if not done
    // by the previous step).
    queue.run(function(callback) {
      if (nextCurrentDirEntry || !this.launchParams_.currentDirectoryURL) {
        callback();
        return;
      }

      window.webkitResolveLocalFileSystemURL(
          this.launchParams_.currentDirectoryURL,
          function(inEntry) {
            var locationInfo = this.volumeManager_.getLocationInfo(inEntry);
            if (!locationInfo) {
              callback();
              return;
            }
            nextCurrentDirEntry = inEntry;
            callback();
          }.bind(this), callback);
      // TODO(mtomasz): Implement reopening on special search, when fake
      // entries are converted to directory providers. crbug.com/433161.
    }.bind(this));

    // If the directory to be changed to is not available, then first fallback
    // to the parent of the selection entry.
    queue.run(function(callback) {
      if (nextCurrentDirEntry || !selectionEntry) {
        callback();
        return;
      }
      selectionEntry.getParent(function(inEntry) {
        nextCurrentDirEntry = inEntry;
        callback();
      }.bind(this));
    }.bind(this));

    // Check if the next current directory is not a virtual directory which is
    // not available in UI. This may happen to shared on Drive.
    queue.run(function(callback) {
      if (!nextCurrentDirEntry) {
        callback();
        return;
      }
      var locationInfo = this.volumeManager_.getLocationInfo(
          nextCurrentDirEntry);
      // If we can't check, assume that the directory is illegal.
      if (!locationInfo) {
        nextCurrentDirEntry = null;
        callback();
        return;
      }
      // Having root directory of DRIVE_OTHER here should be only for shared
      // with me files. Fallback to Drive root in such case.
      if (locationInfo.isRootEntry && locationInfo.rootType ===
              VolumeManagerCommon.RootType.DRIVE_OTHER) {
        var volumeInfo = this.volumeManager_.getVolumeInfo(nextCurrentDirEntry);
        if (!volumeInfo) {
          nextCurrentDirEntry = null;
          callback();
          return;
        }
        volumeInfo.resolveDisplayRoot().then(
            function(entry) {
              nextCurrentDirEntry = entry;
              callback();
            }).catch(function(error) {
              console.error(error.stack || error);
              nextCurrentDirEntry = null;
              callback();
            });
      } else {
        callback();
      }
    }.bind(this));

    // If the directory to be changed to is still not resolved, then fallback
    // to the default display root.
    queue.run(function(callback) {
      if (nextCurrentDirEntry) {
        callback();
        return;
      }
      this.volumeManager_.getDefaultDisplayRoot(function(displayRoot) {
        nextCurrentDirEntry = displayRoot;
        callback();
      }.bind(this));
    }.bind(this));

    // If selection failed to be resolved (eg. didn't exist, in case of saving
    // a file, or in case of a fallback of the current directory, then try to
    // resolve again using the target name.
    queue.run(function(callback) {
      if (selectionEntry ||
          !nextCurrentDirEntry ||
          !this.launchParams_.targetName) {
        callback();
        return;
      }
      // Try to resolve as a file first. If it fails, then as a directory.
      nextCurrentDirEntry.getFile(
          this.launchParams_.targetName,
          {},
          function(targetEntry) {
            selectionEntry = targetEntry;
            callback();
          }, function() {
            // Failed to resolve as a file
            nextCurrentDirEntry.getDirectory(
                this.launchParams_.targetName,
                {},
                function(targetEntry) {
                  selectionEntry = targetEntry;
                  callback();
                }, function() {
                  // Failed to resolve as either file or directory.
                  callback();
                });
          }.bind(this));
    }.bind(this));

    // Finalize.
    queue.run(function(callback) {
      // Check directory change.
      tracker.stop();
      if (tracker.hasChanged) {
        callback();
        return;
      }
      // Finish setup current directory.
      this.finishSetupCurrentDirectory_(
          nextCurrentDirEntry,
          selectionEntry,
          this.launchParams_.targetName);
      callback();
    }.bind(this));
  };

  /**
   * @param {!DirectoryEntry} directoryEntry Directory to be opened.
   * @param {Entry=} opt_selectionEntry Entry to be selected.
   * @param {string=} opt_suggestedName Suggested name for a non-existing\
   *     selection.
   * @private
   */
  FileManager.prototype.finishSetupCurrentDirectory_ = function(
      directoryEntry, opt_selectionEntry, opt_suggestedName) {
    // Open the directory, and select the selection (if passed).
    this.directoryModel_.changeDirectoryEntry(directoryEntry, function() {
      if (opt_selectionEntry)
        this.directoryModel_.selectEntry(opt_selectionEntry);
    }.bind(this));

    if (this.dialogType === DialogType.FULL_PAGE) {
      // In the FULL_PAGE mode if the restored URL points to a file we might
      // have to invoke a task after selecting it.
      if (this.launchParams_.action === 'select')
        return;

      var task = null;

      // TODO(mtomasz): Implement remounting archives after crash.
      //                See: crbug.com/333139

      // If there is a task to be run, run it after the scan is completed.
      if (task) {
        var listener = function() {
          if (!util.isSameEntry(this.directoryModel_.getCurrentDirEntry(),
                                directoryEntry)) {
            // Opened on a different URL. Probably fallbacked. Therefore,
            // do not invoke a task.
            return;
          }
          this.directoryModel_.removeEventListener(
              'scan-completed', listener);
          task();
        }.bind(this);
        this.directoryModel_.addEventListener('scan-completed', listener);
      }
    } else if (this.dialogType === DialogType.SELECT_SAVEAS_FILE) {
      this.ui_.dialogFooter.filenameInput.value = opt_suggestedName || '';
      this.ui_.dialogFooter.selectTargetNameInFilenameInput();
    }
  };

  /**
   * Return DirectoryEntry of the current directory or null.
   * @return {DirectoryEntry|FakeEntry|FilesAppDirEntry} DirectoryEntry of the
   *     current directory.
   *     Returns null if the directory model is not ready or the current
   *     directory is not set.
   */
  FileManager.prototype.getCurrentDirectoryEntry = function() {
    return this.directoryModel_ && this.directoryModel_.getCurrentDirEntry();
  };

  /**
   * Unload handler for the page.
   * @private
   */
  FileManager.prototype.onUnload_ = function() {
    if (this.importHistory_)
      this.importHistory_.removeObserver(this.onHistoryChangedBound_);
    if (this.directoryModel_)
      this.directoryModel_.dispose();
    if (this.volumeManager_)
      this.volumeManager_.dispose();
    if (this.fileTransferController_) {
      for (var i = 0;
           i < this.fileTransferController_.pendingTaskIds.length;
           i++) {
        var taskId = this.fileTransferController_.pendingTaskIds[i];
        var item =
            this.fileBrowserBackground_.progressCenter.getItemById(taskId);
        item.message = '';
        item.state = ProgressItemState.CANCELED;
        this.fileBrowserBackground_.progressCenter.updateItem(item);
      }
    }
    if (this.ui_ && this.ui_.progressCenterPanel) {
      this.fileBrowserBackground_.progressCenter.removePanel(
          this.ui_.progressCenterPanel);
    }
  };

  /**
   * Returns allowed path for the dialog by considering:
   * 1) The launch parameter which specifies generic category of valid files
   * paths.
   * 2) Files app's unique capabilities and restrictions.
   * @returns {AllowedPaths}
   */
  FileManager.prototype.getAllowedPaths_ = function() {
    var allowedPaths = this.launchParams_.allowedPaths;
    // The native implementation of the Files app creates snapshot files for
    // non-native files. But it does not work for folders (e.g., dialog for
    // loading unpacked extensions).
    if (allowedPaths === AllowedPaths.NATIVE_PATH &&
        !DialogType.isFolderDialog(this.launchParams_.type)) {
      if (this.launchParams_.type == DialogType.SELECT_SAVEAS_FILE) {
        // Only drive can create snapshot files for saving.
        allowedPaths = AllowedPaths.NATIVE_OR_DRIVE_PATH;
      } else {
        allowedPaths = AllowedPaths.ANY_PATH;
      }
    }
    return allowedPaths;
  };

  /**
   * Returns SourceRestriction which is used to communicate restrictions about
   * sources to chrome.fileManagerPrivate.getRecentFiles API.
   * @returns {chrome.fileManagerPrivate.SourceRestriction}
   */
  FileManager.prototype.getSourceRestriction_ = function() {
    var allowedPaths = this.getAllowedPaths_();
    if (allowedPaths == AllowedPaths.NATIVE_PATH)
      return chrome.fileManagerPrivate.SourceRestriction.NATIVE_SOURCE;
    if (allowedPaths == AllowedPaths.NATIVE_OR_DRIVE_PATH)
      return chrome.fileManagerPrivate.SourceRestriction.NATIVE_OR_DRIVE_SOURCE;
    return chrome.fileManagerPrivate.SourceRestriction.ANY_SOURCE;
  };

  /**
   * @return {FileSelection} Selection object.
   */
  FileManager.prototype.getSelection = function() {
    return this.selectionHandler_.selection;
  };

  /**
   * @return {cr.ui.ArrayDataModel} File list.
   */
  FileManager.prototype.getFileList = function() {
    return this.directoryModel_.getFileList();
  };

  /**
   * @return {!cr.ui.List} Current list object.
   */
  FileManager.prototype.getCurrentList = function() {
    return this.ui.listContainer.currentList;
  };

  /**
   * Outputs the current state for debugging.
   */
  FileManager.prototype.debugMe = function() {
    var out = 'Debug information.\n';

    out += '1. VolumeManagerWrapper\n' +
        this.volumeManager_.toString() + '\n';

    out += 'End of debug information.';
    console.log(out);
  };
})();
