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

'use strict';

document.addEventListener('DOMContentLoaded', function() {
  PhotoImport.load();
});

/**
 * The main Photo App object.
 * @param {HTMLElement} dom Container.
 * @param {VolumeManagerWrapper} volumeManager The initialized
 *     VolumeManagerWrapper instance.
 * @param {Object} params Parameters.
 * @constructor
 */
function PhotoImport(dom, volumeManager, params) {
  this.dom_ = dom;
  this.document_ = this.dom_.ownerDocument;
  this.metadataCache_ = params.metadataCache;
  this.volumeManager_ = volumeManager;
  this.fileOperationManager_ = FileOperationManagerWrapper.getInstance();
  this.mediaFilesList_ = null;
  this.destination_ = null;
  this.myPhotosDirectory_ = null;
  this.parentWindowId_ = params.parentWindowId;

  this.initDom_();
  this.initMyPhotos_();
  this.loadSource_(params.source);
}

PhotoImport.prototype = { __proto__: cr.EventTarget.prototype };

/**
 * Single item width.
 * Keep in sync with .grid-item rule in photo_import.css.
 */
PhotoImport.ITEM_WIDTH = 164 + 8;

/**
 * Number of tries in creating a destination directory.
 */
PhotoImport.CREATE_DESTINATION_TRIES = 100;

/**
 * Loads app in the document body.
 * @param {Object=} opt_params Parameters.
 */
PhotoImport.load = function(opt_params) {
  ImageUtil.metrics = metrics;

  var hash = location.hash ? location.hash.substr(1) : '';
  var query = location.search ? location.search.substr(1) : '';
  var params = opt_params || {};
  if (!params.source) params.source = hash;
  if (!params.parentWindowId && query) params.parentWindowId = query;
  if (!params.metadataCache) params.metadataCache = MetadataCache.createFull();

  var api = chrome.fileBrowserPrivate || window.top.chrome.fileBrowserPrivate;
  api.getStrings(function(strings) {
    loadTimeData.data = strings;
    var dom = document.querySelector('.photo-import');

    var volumeManager = new VolumeManagerWrapper(
        VolumeManagerWrapper.DriveEnabledStatus.DRIVE_ENABLED);
    volumeManager.ensureInitialized(function() {
      new PhotoImport(dom, volumeManager, params);
    });
  });
};

/**
 * One-time initialization of dom elements.
 * @private
 */
PhotoImport.prototype.initDom_ = function() {
  this.dom_.setAttribute('loading', '');
  this.dom_.ownerDocument.defaultView.addEventListener(
      'resize', this.onResize_.bind(this));

  this.spinner_ = this.dom_.querySelector('.spinner');

  this.document_.querySelector('title').textContent =
      loadTimeData.getString('PHOTO_IMPORT_TITLE');
  this.dom_.querySelector('.caption').textContent =
      loadTimeData.getString('PHOTO_IMPORT_CAPTION');
  this.selectAllNone_ = this.dom_.querySelector('.select');
  this.selectAllNone_.addEventListener('click',
      this.onSelectAllNone_.bind(this));

  this.dom_.querySelector('label[for=delete-after-checkbox]').textContent =
      loadTimeData.getString('PHOTO_IMPORT_DELETE_AFTER');
  this.selectedCount_ = this.dom_.querySelector('.selected-count');

  this.importButton_ = this.dom_.querySelector('button.import');
  this.importButton_.textContent =
      loadTimeData.getString('PHOTO_IMPORT_IMPORT_BUTTON');
  this.importButton_.addEventListener('click', this.onImportClick_.bind(this));

  this.cancelButton_ = this.dom_.querySelector('button.cancel');
  this.cancelButton_.textContent = str('CANCEL_LABEL');
  this.cancelButton_.addEventListener('click', this.onCancelClick_.bind(this));

  this.grid_ = this.dom_.querySelector('grid');
  cr.ui.Grid.decorate(this.grid_);
  this.grid_.itemConstructor = GridItem.bind(null, this);
  this.fileList_ = new cr.ui.ArrayDataModel([]);
  this.grid_.selectionModel = new cr.ui.ListSelectionModel();
  this.grid_.dataModel = this.fileList_;
  this.grid_.selectionModel.addEventListener('change',
      this.onSelectionChanged_.bind(this));
  this.onSelectionChanged_();

  this.importingDialog_ = new ImportingDialog(
      this.dom_, this.fileOperationManager_,
      this.metadataCache_, this.parentWindowId_);

  var dialogs = cr.ui.dialogs;
  dialogs.BaseDialog.OK_LABEL = str('OK_LABEL');
  dialogs.BaseDialog.CANCEL_LABEL = str('CANCEL_LABEL');
  this.alert_ = new dialogs.AlertDialog(this.dom_);
};

/**
 * One-time initialization of the My Photos directory.
 * @private
 */
PhotoImport.prototype.initMyPhotos_ = function() {
  var driveVolume = this.volumeManager_.getVolumeInfo(RootDirectory.DRIVE);
  if (!driveVolume || driveVolume.error || !driveVolume.root) {
    this.onError_(loadTimeData.getString('PHOTO_IMPORT_DRIVE_ERROR'));
    return;
  }

  util.getOrCreateDirectory(
      driveVolume.root,
      loadTimeData.getString('PHOTO_IMPORT_MY_PHOTOS_DIRECTORY_NAME'),
      function(entry) {
        // This may enable the import button, so check that.
        this.myPhotosDirectory_ = entry;
        this.onSelectionChanged_();
      },
      function(error) {
        this.onError_(loadTimeData.getString('PHOTO_IMPORT_DRIVE_ERROR'));
      }.bind(this));
};

/**
 * Creates the destination directory.
 * @param {function} onSuccess Callback on success.
 * @private
 */
PhotoImport.prototype.createDestination_ = function(onSuccess) {
  var onError = this.onError_.bind(
      this, loadTimeData.getString('PHOTO_IMPORT_DESTINATION_ERROR'));

  var dateFormatter = Intl.DateTimeFormat(
      [] /* default locale */,
      {year: 'numeric', month: 'short', day: 'numeric'});

  var baseName = PathUtil.join(
      RootDirectory.DRIVE,
      loadTimeData.getString('PHOTO_IMPORT_MY_PHOTOS_DIRECTORY_NAME'),
      dateFormatter.format(new Date()));

  var driveVolume = this.volumeManager_.getVolumeInfo(RootDirectory.DRIVE);
  if (!driveVolume || driveVolume.error || !driveVolume.root) {
    onError();
    return;
  }

  var tryNext = function(number) {
    if (number > PhotoImport.CREATE_DESTINATION_TRIES) {
      console.error('Too many directories with the same base name exist.');
      onError();
      return;
    }

    var directoryName = baseName;
    if (number > 1)
      directoryName += ' (' + (tryNumber) + ')';
    driveVolume.root.getDirectory(
        directoryName,
        {create: true, exclusive: true},
        function(entry) {
          this.destination_ = entry;
          onSuccess();
        }.bind(this),
        function(error) {
          if (error.code === FileError.PATH_EXISTS_ERR) {
            // If there already exists an entry, retry with incrementing the
            // number.
            tryNext(number + 1);
            return;
          }
          onError();
        }.bind(this));
  }.bind(this);

  tryNext(1);
};


/**
 * Load the source contents.
 * @param {string} source Path to source.
 * @private
 */
PhotoImport.prototype.loadSource_ = function(source) {
  var onError = this.onError_.bind(
      this, loadTimeData.getString('PHOTO_IMPORT_SOURCE_ERROR'));

  var result = [];
  this.volumeManager_.resolvePath(
      source,
      function(sourceEntry) {
        util.traverseTree(
            entry,
            function(entry) {
              if (!FileType.isVisible(entry))
                return false;
              if (FileType.isImageOrVideo(entry))
                result.push(entry);
              return true;
            },
            function() {
              this.dom_.removeAttribute('loading');
              this.mediaFilesList_ = result;
              this.fillGrid_();
            }.bind(this),
            onError);
      }.bind(this),
      onError);
};

/**
 * Renders files into grid.
 * @private
 */
PhotoImport.prototype.fillGrid_ = function() {
  if (!this.mediaFilesList_) return;
  this.fileList_.splice(0, this.fileList_.length);
  this.fileList_.push.apply(this.fileList_, this.mediaFilesList_);
};

/**
 * Creates groups for files based on modification date.
 * @param {Array.<Entry>} files File list.
 * @param {Object} filesystem Filesystem metadata.
 * @return {Array.<Object>} List of grouped items.
 * @private
 */
PhotoImport.prototype.createGroups_ = function(files, filesystem) {
  var dateFormatter = Intl.DateTimeFormat(
      [] /* default locale */,
      {year: 'numeric', month: 'short', day: 'numeric'});

  var columns = this.grid_.columns;

  var unknownGroup = {
    type: 'group',
    date: 0,
    title: loadTimeData.getString('PHOTO_IMPORT_UNKNOWN_DATE'),
    items: []
  };

  var groupsMap = {};

  for (var index = 0; index < files.length; index++) {
    var props = filesystem[index];
    var item = { type: 'entry', entry: files[index] };

    if (!props || !props.modificationTime) {
      item.group = unknownGroup;
      unknownGroup.items.push(item);
      continue;
    }

    var date = new Date(props.modificationTime);
    date.setHours(0);
    date.setMinutes(0);
    date.setSeconds(0);
    date.setMilliseconds(0);

    var time = date.getTime();
    if (!(time in groupsMap)) {
      groupsMap[time] = {
        type: 'group',
        date: date,
        title: dateFormatter.format(date),
        items: []
      };
    }

    var group = groupsMap[time];
    group.items.push(item);
    item.group = group;
  }

  var groups = [];
  for (var time in groupsMap) {
    if (groupsMap.hasOwnProperty(time)) {
      groups.push(groupsMap[time]);
    }
  }
  if (unknownGroup.items.length > 0)
    groups.push(unknownGroup);

  groups.sort(function(a, b) {
    return b.date.getTime() - a.date.getTime();
  });

  var list = [];
  for (var index = 0; index < groups.length; index++) {
    var group = groups[index];

    list.push(group);
    for (var t = 1; t < columns; t++) {
      list.push({ type: 'empty' });
    }

    for (var j = 0; j < group.items.length; j++) {
      list.push(group.items[j]);
    }

    var count = group.items.length;
    while (count % columns != 0) {
      list.push({ type: 'empty' });
      count++;
    }
  }

  return list;
};

/**
 * Decorates grid item.
 * @param {HTMLLIElement} li The list item.
 * @param {FileEntry} entry The file entry.
 * @private
 */
PhotoImport.prototype.decorateGridItem_ = function(li, entry) {
  li.className = 'grid-item';
  li.entry = entry;

  var frame = this.document_.createElement('div');
  frame.className = 'grid-frame';
  li.appendChild(frame);

  var box = this.document_.createElement('div');
  box.className = 'img-container';
  this.metadataCache_.get(entry, 'thumbnail|filesystem',
      function(metadata) {
        new ThumbnailLoader(entry.toURL(),
                            ThumbnailLoader.LoaderType.IMAGE,
                            metadata).
            load(box, ThumbnailLoader.FillMode.FIT,
            ThumbnailLoader.OptimizationMode.DISCARD_DETACHED);
      });
  frame.appendChild(box);

  var check = this.document_.createElement('div');
  check.className = 'check';
  li.appendChild(check);
};

/**
 * Handles the 'pick all/none' action.
 * @private
 */
PhotoImport.prototype.onSelectAllNone_ = function() {
  var sm = this.grid_.selectionModel;
  if (sm.selectedIndexes.length == this.fileList_.length) {
    sm.unselectAll();
  } else {
    sm.selectAll();
  }
};

/**
 * Show error message.
 * @param {string} message Error message.
 * @private
 */
PhotoImport.prototype.onError_ = function(message) {
  this.importingDialog_.hide(function() {
    this.alert_.show(message,
                     function() {
                       window.close();
                     });
  }.bind(this));
};

/**
 * Resize event handler.
 * @private
 */
PhotoImport.prototype.onResize_ = function() {
  var g = this.grid_;
  g.startBatchUpdates();
  setTimeout(function() {
    g.columns = 0;
    g.redraw();
    g.endBatchUpdates();
  }, 0);
};

/**
 * @return {Array.<Object>} The list of selected entries.
 * @private
 */
PhotoImport.prototype.getSelectedItems_ = function() {
  var indexes = this.grid_.selectionModel.selectedIndexes;
  var list = [];
  for (var i = 0; i < indexes.length; i++) {
    list.push(this.fileList_.item(indexes[i]));
  }
  return list;
};

/**
 * Event handler for picked items change.
 * @private
 */
PhotoImport.prototype.onSelectionChanged_ = function() {
  var count = this.grid_.selectionModel.selectedIndexes.length;
  this.selectedCount_.textContent = count == 0 ? '' :
      count == 1 ? loadTimeData.getString('PHOTO_IMPORT_ONE_SELECTED') :
                   loadTimeData.getStringF('PHOTO_IMPORT_MANY_SELECTED', count);
  this.importButton_.disabled = count == 0 || this.myPhotosDirectory_ == null;
  this.selectAllNone_.textContent = loadTimeData.getString(
      count == this.fileList_.length && count > 0 ?
          'PHOTO_IMPORT_SELECT_NONE' : 'PHOTO_IMPORT_SELECT_ALL');
};

/**
 * Event handler for import button click.
 * @param {Event} event The event.
 * @private
 */
PhotoImport.prototype.onImportClick_ = function(event) {
  var entries = this.getSelectedItems_();
  var move = this.dom_.querySelector('#delete-after-checkbox').checked;
  this.importingDialog_.show(entries, move);

  this.createDestination_(function() {
    var percentage = Math.round(entries.length / this.fileList_.length * 100);
    metrics.recordMediumCount('PhotoImport.ImportCount', entries.length);
    metrics.recordSmallCount('PhotoImport.ImportPercentage', percentage);

    this.importingDialog_.start(this.destination_);
  }.bind(this));
};

/**
 * Click event handler for the cancel button.
 * @param {Event} event The event.
 * @private
 */
PhotoImport.prototype.onCancelClick_ = function(event) {
  window.close();
};

/**
 * Item in the grid.
 * @param {PhotoImport} app Application instance.
 * @param {Entry} entry File entry.
 * @constructor
 */
function GridItem(app, entry) {
  var li = app.document_.createElement('li');
  li.__proto__ = GridItem.prototype;
  app.decorateGridItem_(li, entry);
  return li;
}

GridItem.prototype = {
  __proto__: cr.ui.ListItem.prototype,
  get label() {},
  set label(value) {}
};

/**
 * Creates a selection controller that is to be used with grid.
 * @param {cr.ui.ListSelectionModel} selectionModel The selection model to
 *     interact with.
 * @param {cr.ui.Grid} grid The grid to interact with.
 * @constructor
 * @extends {!cr.ui.ListSelectionController}
 */
function GridSelectionController(selectionModel, grid) {
  this.selectionModel_ = selectionModel;
  this.grid_ = grid;
}

/**
 * Extends cr.ui.ListSelectionController.
 */
GridSelectionController.prototype.__proto__ =
    cr.ui.ListSelectionController.prototype;

/** @override */
GridSelectionController.prototype.getIndexBelow = function(index) {
  if (index == this.getLastIndex()) {
    return -1;
  }

  var dm = this.grid_.dataModel;
  var columns = this.grid_.columns;
  var min = (Math.floor(index / columns) + 1) * columns;

  for (var row = 1; true; row++) {
    var end = index + columns * row;
    var start = Math.max(min, index + columns * (row - 1));
    if (start > dm.length) break;

    for (var i = end; i > start; i--) {
      if (i < dm.length && dm.item(i).type == 'entry')
        return i;
    }
  }

  return this.getLastIndex();
};

/** @override */
GridSelectionController.prototype.getIndexAbove = function(index) {
  if (index == this.getFirstIndex()) {
    return -1;
  }

  var dm = this.grid_.dataModel;
  index -= this.grid_.columns;
  while (index >= 0 && dm.item(index).type != 'entry') {
    index--;
  }

  return index < 0 ? this.getFirstIndex() : index;
};

/** @override */
GridSelectionController.prototype.getIndexBefore = function(index) {
  var dm = this.grid_.dataModel;
  index--;
  while (index >= 0 && dm.item(index).type != 'entry') {
    index--;
  }
  return index;
};

/** @override */
GridSelectionController.prototype.getIndexAfter = function(index) {
  var dm = this.grid_.dataModel;
  index++;
  while (index < dm.length && dm.item(index).type != 'entry') {
    index++;
  }
  return index == dm.length ? -1 : index;
};

/** @override */
GridSelectionController.prototype.getFirstIndex = function() {
  var dm = this.grid_.dataModel;
  for (var index = 0; index < dm.length; index++) {
    if (dm.item(index).type == 'entry')
      return index;
  }
  return -1;
};

/** @override */
GridSelectionController.prototype.getLastIndex = function() {
  var dm = this.grid_.dataModel;
  for (var index = dm.length - 1; index >= 0; index--) {
    if (dm.item(index).type == 'entry')
      return index;
  }
  return -1;
};
