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

'use strict';

/**
 * Called from the main frame when unloading.
 * @param {boolean=} opt_exiting True if the app is exiting.
 */
function unload(opt_exiting) { Gallery.instance.onUnload(opt_exiting); }

/**
 * Overrided metadata worker's path.
 * @type {string}
 * @const
 */
ContentProvider.WORKER_SCRIPT = '/js/metadata_worker.js';

/**
 * Data model for gallery.
 *
 * @param {MetadataCache} metadataCache Metadata cache.
 * @constructor
 * @extends {cr.ui.ArrayDataModel}
 */
function GalleryDataModel(metadataCache) {
  cr.ui.ArrayDataModel.call(this, []);

  /**
   * Metadata cache.
   * @type {MetadataCache}
   * @private
   */
  this.metadataCache_ = metadataCache;

  /**
   * Directory where the image is saved if the image is located in a read-only
   * volume.
   * @type {DirectoryEntry}
   */
  this.fallbackSaveDirectory = null;
}

/**
 * Maximum number of full size image cache.
 * @type {number}
 * @const
 * @private
 */
GalleryDataModel.MAX_FULL_IMAGE_CACHE_ = 3;

/**
 * Maximum number of screen size image cache.
 * @type {number}
 * @const
 * @private
 */
GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_ = 5;

GalleryDataModel.prototype = {
  __proto__: cr.ui.ArrayDataModel.prototype
};

/**
 * Saves new image.
 *
 * @param {VolumeManager} volumeManager Volume manager instance.
 * @param {Gallery.Item} item Original gallery item.
 * @param {Canvas} canvas Canvas containing new image.
 * @param {boolean} overwrite Whether to overwrite the image to the item or not.
 * @return {Promise} Promise to be fulfilled with when the operation completes.
 */
GalleryDataModel.prototype.saveItem = function(
    volumeManager, item, canvas, overwrite) {
  var oldEntry = item.getEntry();
  var oldMetadata = item.getMetadata();
  var oldLocationInfo = item.getLocationInfo();
  var metadataEncoder = ImageEncoder.encodeMetadata(
      item.getMetadata(), canvas, 1 /* quality */);
  var newMetadata = ContentProvider.ConvertContentMetadata(
      metadataEncoder.getMetadata(),
      MetadataCache.cloneMetadata(item.getMetadata()));
  if (newMetadata.filesystem)
    newMetadata.filesystem.modificationTime = new Date();
  if (newMetadata.external)
    newMetadata.external.present = true;

  return new Promise(function(fulfill, reject) {
    item.saveToFile(
        volumeManager,
        this.fallbackSaveDirectory,
        overwrite,
        canvas,
        metadataEncoder,
        function(success) {
          if (!success) {
            reject('Failed to save the image.');
            return;
          }

          // The item's entry is updated to the latest entry. Update metadata.
          item.setMetadata(newMetadata);

          // Current entry is updated.
          // Dispatch an event.
          var event = new Event('content');
          event.item = item;
          event.oldEntry = oldEntry;
          event.metadata = newMetadata;
          this.dispatchEvent(event);

          if (util.isSameEntry(oldEntry, item.getEntry())) {
            // Need an update of metdataCache.
            this.metadataCache_.set(
                item.getEntry(),
                Gallery.METADATA_TYPE,
                newMetadata);
          } else {
            // New entry is added and the item now tracks it.
            // Add another item for the old entry.
            var anotherItem = new Gallery.Item(
                oldEntry,
                oldLocationInfo,
                oldMetadata,
                this.metadataCache_,
                item.isOriginal());
            // The item must be added behind the existing item so that it does
            // not change the index of the existing item.
            // TODO(hirono): Update the item index of the selection model
            // correctly.
            this.splice(this.indexOf(item) + 1, 0, anotherItem);
          }

          fulfill();
        }.bind(this));
  }.bind(this));
};

/**
 * Evicts image caches in the items.
 * @param {Gallery.Item} currentSelectedItem Current selected item.
 */
GalleryDataModel.prototype.evictCache = function(currentSelectedItem) {
  // Sort the item by the last accessed date.
  var sorted = this.slice().sort(function(a, b) {
    return b.getLastAccessedDate() - a.getLastAccessedDate();
  });

  // Evict caches.
  var contentCacheCount = 0;
  var screenCacheCount = 0;
  for (var i = 0; i < sorted.length; i++) {
    if (sorted[i].contentImage) {
      if (++contentCacheCount > GalleryDataModel.MAX_FULL_IMAGE_CACHE_) {
        if (sorted[i].contentImage.parentNode) {
          console.error('The content image has a parent node.');
        } else {
          // Force to free the buffer of the canvas by assigning zero size.
          sorted[i].contentImage.width = 0;
          sorted[i].contentImage.height = 0;
          sorted[i].contentImage = null;
        }
      }
    }
    if (sorted[i].screenImage) {
      if (++screenCacheCount > GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_) {
        if (sorted[i].screenImage.parentNode) {
          console.error('The screen image has a parent node.');
        } else {
          // Force to free the buffer of the canvas by assigning zero size.
          sorted[i].screenImage.width = 0;
          sorted[i].screenImage.height = 0;
          sorted[i].screenImage = null;
        }
      }
    }
  }
};

/**
 * Gallery for viewing and editing image files.
 *
 * @param {!VolumeManager} volumeManager The VolumeManager instance of the
 *     system.
 * @constructor
 */
function Gallery(volumeManager) {
  this.context_ = {
    appWindow: chrome.app.window.current(),
    onClose: function() { close(); },
    onMaximize: function() {
      var appWindow = chrome.app.window.current();
      if (appWindow.isMaximized())
        appWindow.restore();
      else
        appWindow.maximize();
    },
    onMinimize: function() { chrome.app.window.current().minimize(); },
    onAppRegionChanged: function() {},
    metadataCache: MetadataCache.createFull(volumeManager),
    readonlyDirName: '',
    displayStringFunction: function() { return ''; },
    loadTimeData: {}
  };
  this.container_ = document.querySelector('.gallery');
  this.document_ = document;
  this.metadataCache_ = this.context_.metadataCache;
  this.volumeManager_ = volumeManager;
  this.selectedEntry_ = null;
  this.metadataCacheObserverId_ = null;
  this.onExternallyUnmountedBound_ = this.onExternallyUnmounted_.bind(this);

  this.dataModel_ = new GalleryDataModel(
      this.context_.metadataCache);
  var downloadVolumeInfo = this.volumeManager_.getCurrentProfileVolumeInfo(
      VolumeManagerCommon.VolumeType.DOWNLOADS);
  downloadVolumeInfo.resolveDisplayRoot().then(function(entry) {
    this.dataModel_.fallbackSaveDirectory = entry;
  }.bind(this)).catch(function(error) {
    console.error(
        'Failed to obtain the fallback directory: ' + (error.stack || error));
  });
  this.selectionModel_ = new cr.ui.ListSelectionModel();

  this.initDom_();
  this.initListeners_();
}

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

/**
 * Tools fade-out timeout in milliseconds.
 * @const
 * @type {number}
 */
Gallery.FADE_TIMEOUT = 3000;

/**
 * First time tools fade-out timeout in milliseconds.
 * @const
 * @type {number}
 */
Gallery.FIRST_FADE_TIMEOUT = 1000;

/**
 * Time until mosaic is initialized in the background. Used to make gallery
 * in the slide mode load faster. In milliseconds.
 * @const
 * @type {number}
 */
Gallery.MOSAIC_BACKGROUND_INIT_DELAY = 1000;

/**
 * Types of metadata Gallery uses (to query the metadata cache).
 * @const
 * @type {string}
 */
Gallery.METADATA_TYPE = 'thumbnail|filesystem|media|external';

/**
 * Initializes listeners.
 * @private
 */
Gallery.prototype.initListeners_ = function() {
  this.keyDownBound_ = this.onKeyDown_.bind(this);
  this.document_.body.addEventListener('keydown', this.keyDownBound_);

  this.inactivityWatcher_ = new MouseInactivityWatcher(
      this.container_, Gallery.FADE_TIMEOUT, this.hasActiveTool.bind(this));

  // Search results may contain files from different subdirectories so
  // the observer is not going to work.
  if (!this.context_.searchResults && this.context_.curDirEntry) {
    this.metadataCacheObserverId_ = this.metadataCache_.addObserver(
        this.context_.curDirEntry,
        MetadataCache.CHILDREN,
        'thumbnail',
        this.updateThumbnails_.bind(this));
  }
  this.volumeManager_.addEventListener(
      'externally-unmounted', this.onExternallyUnmountedBound_);
};

/**
 * Closes gallery when a volume containing the selected item is unmounted.
 * @param {!Event} event The unmount event.
 * @private
 */
Gallery.prototype.onExternallyUnmounted_ = function(event) {
  if (!this.selectedEntry_)
    return;

  if (this.volumeManager_.getVolumeInfo(this.selectedEntry_) ===
      event.volumeInfo) {
    close();
  }
};

/**
 * Unloads the Gallery.
 * @param {boolean} exiting True if the app is exiting.
 */
Gallery.prototype.onUnload = function(exiting) {
  if (this.metadataCacheObserverId_ !== null)
    this.metadataCache_.removeObserver(this.metadataCacheObserverId_);
  this.volumeManager_.removeEventListener(
      'externally-unmounted', this.onExternallyUnmountedBound_);
  this.slideMode_.onUnload(exiting);
};

/**
 * Initializes DOM UI
 * @private
 */
Gallery.prototype.initDom_ = function() {
  // Initialize the dialog label.
  cr.ui.dialogs.BaseDialog.OK_LABEL = str('GALLERY_OK_LABEL');
  cr.ui.dialogs.BaseDialog.CANCEL_LABEL = str('GALLERY_CANCEL_LABEL');

  var content = document.querySelector('#content');
  content.addEventListener('click', this.onContentClick_.bind(this));

  this.header_ = document.querySelector('#header');
  this.toolbar_ = document.querySelector('#toolbar');

  var preventDefault = function(event) { event.preventDefault(); };

  var minimizeButton = util.createChild(this.header_,
                                        'minimize-button tool dimmable',
                                        'button');
  minimizeButton.tabIndex = -1;
  minimizeButton.addEventListener('click', this.onMinimize_.bind(this));
  minimizeButton.addEventListener('mousedown', preventDefault);

  var maximizeButton = util.createChild(this.header_,
                                        'maximize-button tool dimmable',
                                        'button');
  maximizeButton.tabIndex = -1;
  maximizeButton.addEventListener('click', this.onMaximize_.bind(this));
  maximizeButton.addEventListener('mousedown', preventDefault);

  var closeButton = util.createChild(this.header_,
                                     'close-button tool dimmable',
                                     'button');
  closeButton.tabIndex = -1;
  closeButton.addEventListener('click', this.onClose_.bind(this));
  closeButton.addEventListener('mousedown', preventDefault);

  this.filenameSpacer_ = this.toolbar_.querySelector('.filename-spacer');
  this.filenameEdit_ = util.createChild(this.filenameSpacer_,
                                        'namebox', 'input');

  this.filenameEdit_.setAttribute('type', 'text');
  this.filenameEdit_.addEventListener('blur',
      this.onFilenameEditBlur_.bind(this));

  this.filenameEdit_.addEventListener('focus',
      this.onFilenameFocus_.bind(this));

  this.filenameEdit_.addEventListener('keydown',
      this.onFilenameEditKeydown_.bind(this));

  var middleSpacer = this.filenameSpacer_ =
      this.toolbar_.querySelector('.middle-spacer');
  var buttonSpacer = this.toolbar_.querySelector('button-spacer');

  this.prompt_ = new ImageEditor.Prompt(this.container_, strf);

  this.modeButton_ = this.toolbar_.querySelector('button.mode');
  this.modeButton_.addEventListener('click', this.toggleMode_.bind(this, null));

  this.mosaicMode_ = new MosaicMode(content,
                                    this.dataModel_,
                                    this.selectionModel_,
                                    this.volumeManager_,
                                    this.toggleMode_.bind(this, null));

  this.slideMode_ = new SlideMode(this.container_,
                                  content,
                                  this.toolbar_,
                                  this.prompt_,
                                  this.dataModel_,
                                  this.selectionModel_,
                                  this.context_,
                                  this.volumeManager_,
                                  this.toggleMode_.bind(this),
                                  str);

  this.slideMode_.addEventListener('image-displayed', function() {
    cr.dispatchSimpleEvent(this, 'image-displayed');
  }.bind(this));
  this.slideMode_.addEventListener('image-saved', function() {
    cr.dispatchSimpleEvent(this, 'image-saved');
  }.bind(this));

  var deleteButton = this.initToolbarButton_('delete', 'GALLERY_DELETE');
  deleteButton.addEventListener('click', this.delete_.bind(this));

  this.shareButton_ = this.initToolbarButton_('share', 'GALLERY_SHARE');
  this.shareButton_.addEventListener(
      'click', this.onShareButtonClick_.bind(this));

  this.dataModel_.addEventListener('splice', this.onSplice_.bind(this));
  this.dataModel_.addEventListener('content', this.onContentChange_.bind(this));

  this.selectionModel_.addEventListener('change', this.onSelection_.bind(this));
  this.slideMode_.addEventListener('useraction', this.onUserAction_.bind(this));

  this.shareDialog_ = new ShareDialog(this.container_);
};

/**
 * Initializes a toolbar button.
 *
 * @param {string} className Class to add.
 * @param {string} title Button title.
 * @return {!HTMLElement} Newly created button.
 * @private
 */
Gallery.prototype.initToolbarButton_ = function(className, title) {
  var button = this.toolbar_.querySelector('button.' + className);
  button.title = str(title);
  return button;
};

/**
 * Loads the content.
 *
 * @param {!Array.<Entry>} entries Array of entries.
 * @param {!Array.<Entry>} selectedEntries Array of selected entries.
 */
Gallery.prototype.load = function(entries, selectedEntries) {
  // Obtains max chank size.
  var maxChunkSize = 20;
  var volumeInfo = this.volumeManager_.getVolumeInfo(entries[0]);
  if (volumeInfo &&
      volumeInfo.volumeType === VolumeManagerCommon.VolumeType.MTP) {
    maxChunkSize = 1;
  }
  if (volumeInfo.isReadOnly)
    this.context_.readonlyDirName = volumeInfo.label;

  // Make loading list.
  var entrySet = {};
  for (var i = 0; i < entries.length; i++) {
    var entry = entries[i];
    entrySet[entry.toURL()] = {
      entry: entry,
      selected: false,
      index: i
    };
  }
  for (var i = 0; i < selectedEntries.length; i++) {
    var entry = selectedEntries[i];
    entrySet[entry.toURL()] = {
      entry: entry,
      selected: true,
      index: i
    };
  }
  var loadingList = [];
  for (var url in entrySet) {
    loadingList.push(entrySet[url]);
  }
  loadingList = loadingList.sort(function(a, b) {
    if (a.selected && !b.selected)
      return -1;
    else if (!a.selected && b.selected)
      return 1;
    else
      return a.index - b.index;
  });

  // Load entries.
  // Use the self variable capture-by-closure because it is faster than bind.
  var self = this;
  var loadChunk = function(firstChunk) {
    // Extract chunk.
    var chunk = loadingList.splice(0, maxChunkSize);
    if (!chunk.length)
      return;

    return new Promise(function(fulfill) {
      // Obtains metadata for chunk.
      var entries = chunk.map(function(chunkItem) {
        return chunkItem.entry;
      });
      self.metadataCache_.get(entries, Gallery.METADATA_TYPE, fulfill);
    }).then(function(metadataList) {
      if (chunk.length !== metadataList.length)
        return Promise.reject('Failed to load metadata.');

      // Add items to the model.
      var items = [];
      chunk.forEach(function(chunkItem, index) {
        var locationInfo = self.volumeManager_.getLocationInfo(chunkItem.entry);
        if (!locationInfo)  // Skip the item, since gone.
          return;
        var clonedMetadata = MetadataCache.cloneMetadata(metadataList[index]);
        items.push(new Gallery.Item(
            chunkItem.entry,
            locationInfo,
            clonedMetadata,
            self.metadataCache_,
            /* original */ true));
      });
      self.dataModel_.push.apply(self.dataModel_, items);

      // Apply the selection.
      var selectionUpdated = false;
      for (var i = 0; i < chunk.length; i++) {
        if (!chunk[i].selected)
          continue;
        var index = self.dataModel_.indexOf(items[i]);
        if (index < 0)
          continue;
        self.selectionModel_.setIndexSelected(index, true);
        selectionUpdated = true;
      }
      if (selectionUpdated)
        self.onSelection_();

      // Init modes after the first chunk is loaded.
      if (firstChunk) {
        // Determine the initial mode.
        var shouldShowMosaic = selectedEntries.length > 1 ||
            (self.context_.pageState &&
             self.context_.pageState.gallery === 'mosaic');
        self.setCurrentMode_(
            shouldShowMosaic ? self.mosaicMode_ : self.slideMode_);

        // Init mosaic mode.
        var mosaic = self.mosaicMode_.getMosaic();
        mosaic.init();

        // Do the initialization for each mode.
        if (shouldShowMosaic) {
          mosaic.show();
          self.inactivityWatcher_.check();  // Show the toolbar.
          cr.dispatchSimpleEvent(self, 'loaded');
        } else {
          self.slideMode_.enter(
              null,
              function() {
                // Flash the toolbar briefly to show it is there.
                self.inactivityWatcher_.kick(Gallery.FIRST_FADE_TIMEOUT);
              },
              function() {
                cr.dispatchSimpleEvent(self, 'loaded');
              });
        }
      }

      // Continue to load chunks.
      return loadChunk(/* firstChunk */ false);
    });
  };
  loadChunk(/* firstChunk */ true).catch(function(error) {
    console.error(error.stack || error);
  });
};

/**
 * Handles user's 'Close' action.
 * @private
 */
Gallery.prototype.onClose_ = function() {
  this.executeWhenReady(this.context_.onClose);
};

/**
 * Handles user's 'Maximize' action (Escape or a click on the X icon).
 * @private
 */
Gallery.prototype.onMaximize_ = function() {
  this.executeWhenReady(this.context_.onMaximize);
};

/**
 * Handles user's 'Maximize' action (Escape or a click on the X icon).
 * @private
 */
Gallery.prototype.onMinimize_ = function() {
  this.executeWhenReady(this.context_.onMinimize);
};

/**
 * Executes a function when the editor is done with the modifications.
 * @param {function} callback Function to execute.
 */
Gallery.prototype.executeWhenReady = function(callback) {
  this.currentMode_.executeWhenReady(callback);
};

/**
 * @return {Object} File manager private API.
 */
Gallery.getFileManagerPrivate = function() {
  return chrome.fileManagerPrivate || window.top.chrome.fileManagerPrivate;
};

/**
 * @return {boolean} True if some tool is currently active.
 */
Gallery.prototype.hasActiveTool = function() {
  return (this.currentMode_ && this.currentMode_.hasActiveTool()) ||
      this.isRenaming_();
};

/**
* External user action event handler.
* @private
*/
Gallery.prototype.onUserAction_ = function() {
  // Show the toolbar and hide it after the default timeout.
  this.inactivityWatcher_.kick();
};

/**
 * Sets the current mode, update the UI.
 * @param {Object} mode Current mode.
 * @private
 */
Gallery.prototype.setCurrentMode_ = function(mode) {
  if (mode !== this.slideMode_ && mode !== this.mosaicMode_)
    console.error('Invalid Gallery mode');

  this.currentMode_ = mode;
  this.container_.setAttribute('mode', this.currentMode_.getName());
  this.updateSelectionAndState_();
  this.updateButtons_();
};

/**
 * Mode toggle event handler.
 * @param {function=} opt_callback Callback.
 * @param {Event=} opt_event Event that caused this call.
 * @private
 */
Gallery.prototype.toggleMode_ = function(opt_callback, opt_event) {
  if (!this.modeButton_)
    return;

  if (this.changingMode_) // Do not re-enter while changing the mode.
    return;

  if (opt_event)
    this.onUserAction_();

  this.changingMode_ = true;

  var onModeChanged = function() {
    this.changingMode_ = false;
    if (opt_callback) opt_callback();
  }.bind(this);

  var tileIndex = Math.max(0, this.selectionModel_.selectedIndex);

  var mosaic = this.mosaicMode_.getMosaic();
  var tileRect = mosaic.getTileRect(tileIndex);

  if (this.currentMode_ === this.slideMode_) {
    this.setCurrentMode_(this.mosaicMode_);
    mosaic.transform(
        tileRect, this.slideMode_.getSelectedImageRect(), true /* instant */);
    this.slideMode_.leave(
        tileRect,
        function() {
          // Animate back to normal position.
          mosaic.transform();
          mosaic.show();
          onModeChanged();
        }.bind(this));
  } else {
    this.setCurrentMode_(this.slideMode_);
    this.slideMode_.enter(
        tileRect,
        function() {
          // Animate to zoomed position.
          mosaic.transform(tileRect, this.slideMode_.getSelectedImageRect());
          mosaic.hide();
        }.bind(this),
        onModeChanged);
  }
};

/**
 * Deletes the selected items.
 * @private
 */
Gallery.prototype.delete_ = function() {
  this.onUserAction_();

  // Clone the sorted selected indexes array.
  var indexesToRemove = this.selectionModel_.selectedIndexes.slice();
  if (!indexesToRemove.length)
    return;

  /* TODO(dgozman): Implement Undo delete, Remove the confirmation dialog. */

  var itemsToRemove = this.getSelectedItems();
  var plural = itemsToRemove.length > 1;
  var param = plural ? itemsToRemove.length : itemsToRemove[0].getFileName();

  function deleteNext() {
    if (!itemsToRemove.length)
      return;  // All deleted.

    var entry = itemsToRemove.pop().getEntry();
    entry.remove(deleteNext, function() {
      util.flog('Error deleting: ' + entry.name, deleteNext);
    });
  }

  // Prevent the Gallery from handling Esc and Enter.
  this.document_.body.removeEventListener('keydown', this.keyDownBound_);
  var restoreListener = function() {
    this.document_.body.addEventListener('keydown', this.keyDownBound_);
  }.bind(this);


  var confirm = new cr.ui.dialogs.ConfirmDialog(this.container_);
  confirm.setOkLabel(str('DELETE_BUTTON_LABEL'));
  confirm.show(strf(plural ?
      'GALLERY_CONFIRM_DELETE_SOME' : 'GALLERY_CONFIRM_DELETE_ONE', param),
      function() {
        restoreListener();
        this.selectionModel_.unselectAll();
        this.selectionModel_.leadIndex = -1;
        // Remove items from the data model, starting from the highest index.
        while (indexesToRemove.length)
          this.dataModel_.splice(indexesToRemove.pop(), 1);
        // Delete actual files.
        deleteNext();
      }.bind(this),
      function() {
        // Restore the listener after a timeout so that ESC is processed.
        setTimeout(restoreListener, 0);
      });
};

/**
 * @return {Array.<Gallery.Item>} Current selection.
 */
Gallery.prototype.getSelectedItems = function() {
  return this.selectionModel_.selectedIndexes.map(
      this.dataModel_.item.bind(this.dataModel_));
};

/**
 * @return {Array.<Entry>} Array of currently selected entries.
 */
Gallery.prototype.getSelectedEntries = function() {
  return this.selectionModel_.selectedIndexes.map(function(index) {
    return this.dataModel_.item(index).getEntry();
  }.bind(this));
};

/**
 * @return {?Gallery.Item} Current single selection.
 */
Gallery.prototype.getSingleSelectedItem = function() {
  var items = this.getSelectedItems();
  if (items.length > 1) {
    console.error('Unexpected multiple selection');
    return null;
  }
  return items[0];
};

/**
  * Selection change event handler.
  * @private
  */
Gallery.prototype.onSelection_ = function() {
  this.updateSelectionAndState_();
};

/**
  * Data model splice event handler.
  * @private
  */
Gallery.prototype.onSplice_ = function() {
  this.selectionModel_.adjustLength(this.dataModel_.length);
};

/**
 * Content change event handler.
 * @param {Event} event Event.
 * @private
*/
Gallery.prototype.onContentChange_ = function(event) {
  var index = this.dataModel_.indexOf(event.item);
  if (index !== this.selectionModel_.selectedIndex)
    console.error('Content changed for unselected item');
  this.updateSelectionAndState_();
};

/**
 * Keydown handler.
 *
 * @param {Event} event Event.
 * @private
 */
Gallery.prototype.onKeyDown_ = function(event) {
  if (this.currentMode_.onKeyDown(event))
    return;

  switch (util.getKeyModifiers(event) + event.keyIdentifier) {
    case 'U+0008': // Backspace.
      // The default handler would call history.back and close the Gallery.
      event.preventDefault();
      break;

    case 'U+004D':  // 'm' switches between Slide and Mosaic mode.
      this.toggleMode_(null, event);
      break;

    case 'U+0056':  // 'v'
    case 'MediaPlayPause':
      this.slideMode_.startSlideshow(SlideMode.SLIDESHOW_INTERVAL_FIRST, event);
      break;

    case 'U+007F':  // Delete
    case 'Shift-U+0033':  // Shift+'3' (Delete key might be missing).
    case 'U+0044':  // 'd'
      this.delete_();
      break;
  }
};

// Name box and rename support.

/**
 * Updates the UI related to the selected item and the persistent state.
 *
 * @private
 */
Gallery.prototype.updateSelectionAndState_ = function() {
  var numSelectedItems = this.selectionModel_.selectedIndexes.length;
  var selectedEntryURL = null;

  // If it's selecting something, update the variable values.
  if (numSelectedItems) {
    // Obtains selected item.
    var selectedItem =
        this.dataModel_.item(this.selectionModel_.selectedIndex);
    this.selectedEntry_ = selectedItem.getEntry();
    selectedEntryURL = this.selectedEntry_.toURL();

    // Update cache.
    selectedItem.touch();
    this.dataModel_.evictCache();

    // Update the title and the display name.
    if (numSelectedItems === 1) {
      document.title = this.selectedEntry_.name;
      this.filenameEdit_.disabled = selectedItem.getLocationInfo().isReadOnly;
      this.filenameEdit_.value =
          ImageUtil.getDisplayNameFromName(this.selectedEntry_.name);
      this.shareButton_.hidden = !selectedItem.getLocationInfo().isDriveBased;
    } else {
      if (this.context_.curDirEntry) {
        // If the Gallery was opened on search results the search query will not
        // be recorded in the app state and the relaunch will just open the
        // gallery in the curDirEntry directory.
        document.title = this.context_.curDirEntry.name;
      } else {
        document.title = '';
      }
      this.filenameEdit_.disabled = true;
      this.filenameEdit_.value =
          strf('GALLERY_ITEMS_SELECTED', numSelectedItems);
      this.shareButton_.hidden = true;
    }
  } else {
    document.title = '';
    this.filenameEdit_.disabled = true;
    this.filenameEdit_.value = '';
    this.shareButton_.hidden = true;
  }

  util.updateAppState(
      null,  // Keep the current directory.
      selectedEntryURL,  // Update the selection.
      {gallery: (this.currentMode_ === this.mosaicMode_ ? 'mosaic' : 'slide')});
};

/**
 * Click event handler on filename edit box
 * @private
 */
Gallery.prototype.onFilenameFocus_ = function() {
  ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', true);
  this.filenameEdit_.originalValue = this.filenameEdit_.value;
  setTimeout(this.filenameEdit_.select.bind(this.filenameEdit_), 0);
  this.onUserAction_();
};

/**
 * Blur event handler on filename edit box.
 *
 * @param {Event} event Blur event.
 * @return {Promise} Promise fulfilled on renaming completed.
 * @private
 */
Gallery.prototype.onFilenameEditBlur_ = function(event) {
  var item = this.getSingleSelectedItem();
  if (item) {
    var oldEntry = item.getEntry();

    item.rename(this.filenameEdit_.value).then(function() {
      var event = new Event('content');
      event.item = item;
      event.oldEntry = oldEntry;
      event.metadata = null;  // Metadata unchanged.
      this.dataModel_.dispatchEvent(event);
    }.bind(this), function(error) {
      if (error === 'NOT_CHANGED')
        return Promise.resolve();
      this.filenameEdit_.value =
          ImageUtil.getDisplayNameFromName(item.getEntry().name);
      this.filenameEdit_.focus();
      if (typeof error === 'string')
        this.prompt_.showStringAt('center', error, 5000);
      else
        return Promise.reject(error);
    }.bind(this)).catch(function(error) {
      console.error(error.stack || error);
    });
  }

  ImageUtil.setAttribute(this.filenameSpacer_, 'renaming', false);
  this.onUserAction_();
  return Promise.resolve();
};

/**
 * Keydown event handler on filename edit box
 * @private
 */
Gallery.prototype.onFilenameEditKeydown_ = function() {
  switch (event.keyCode) {
    case 27:  // Escape
      this.filenameEdit_.value = this.filenameEdit_.originalValue;
      this.filenameEdit_.blur();
      break;

    case 13:  // Enter
      this.filenameEdit_.blur();
      break;
  }
  event.stopPropagation();
};

/**
 * @return {boolean} True if file renaming is currently in progress.
 * @private
 */
Gallery.prototype.isRenaming_ = function() {
  return this.filenameSpacer_.hasAttribute('renaming');
};

/**
 * Content area click handler.
 * @private
 */
Gallery.prototype.onContentClick_ = function() {
  this.filenameEdit_.blur();
};

/**
 * Share button handler.
 * @private
 */
Gallery.prototype.onShareButtonClick_ = function() {
  var item = this.getSingleSelectedItem();
  if (!item)
    return;
  this.shareDialog_.show(item.getEntry(), function() {});
};

/**
 * Updates thumbnails.
 * @private
 */
Gallery.prototype.updateThumbnails_ = function() {
  if (this.currentMode_ === this.slideMode_)
    this.slideMode_.updateThumbnails();

  if (this.mosaicMode_) {
    var mosaic = this.mosaicMode_.getMosaic();
    if (mosaic.isInitialized())
      mosaic.reload();
  }
};

/**
 * Updates buttons.
 * @private
 */
Gallery.prototype.updateButtons_ = function() {
  if (this.modeButton_) {
    var oppositeMode =
        this.currentMode_ === this.slideMode_ ? this.mosaicMode_ :
                                                this.slideMode_;
    this.modeButton_.title = str(oppositeMode.getTitle());
  }
};

/**
 * Singleton gallery.
 * @type {Gallery}
 */
var gallery = null;

/**
 * Initialize the window.
 * @param {Object} backgroundComponents Background components.
 */
window.initialize = function(backgroundComponents) {
  window.loadTimeData.data = backgroundComponents.stringData;
  gallery = new Gallery(backgroundComponents.volumeManager);
};

/**
 * Loads entries.
 * @param {!Array.<Entry>} entries Array of entries.
 * @param {!Array.<Entry>} selectedEntries Array of selected entries.
 */
window.loadEntries = function(entries, selectedEntries) {
  gallery.load(entries, selectedEntries);
};
