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

(function() {
/** @const */ var BookmarkList = bmm.BookmarkList;
/** @const */ var BookmarkTree = bmm.BookmarkTree;
/** @const */ var Command = cr.ui.Command;
/** @const */ var CommandBinding = cr.ui.CommandBinding;
/** @const */ var LinkKind = cr.LinkKind;
/** @const */ var ListItem = cr.ui.ListItem;
/** @const */ var Menu = cr.ui.Menu;
/** @const */ var MenuButton = cr.ui.MenuButton;
/** @const */ var Promise = cr.Promise;
/** @const */ var Splitter = cr.ui.Splitter;
/** @const */ var TreeItem = cr.ui.TreeItem;

/**
 * An array containing the BookmarkTreeNodes that were deleted in the last
 * deletion action. This is used for implementing undo.
 * @type {Array.<BookmarkTreeNode>}
 */
var lastDeletedNodes;

/**
 *
 * Holds the last DOMTimeStamp when mouse pointer hovers on folder in tree
 * view. Zero means pointer doesn't hover on folder.
 * @type {number}
 */
var lastHoverOnFolderTimeStamp = 0;

/**
 * Holds a function that will undo that last action, if global undo is enabled.
 * @type {Function}
 */
var performGlobalUndo;

/**
 * Holds a link controller singleton. Use getLinkController() rarther than
 * accessing this variabie.
 * @type {LinkController}
 */
var linkController;

/**
 * New Windows are not allowed in Windows 8 metro mode.
 */
var canOpenNewWindows = true;

/**
 * Incognito mode availability can take the following values: ,
 *   - 'enabled' for when both normal and incognito modes are available;
 *   - 'disabled' for when incognito mode is disabled;
 *   - 'forced' for when incognito mode is forced (normal mode is unavailable).
 */
var incognitoModeAvailability = 'enabled';

/**
 * Whether bookmarks can be modified.
 * @type {boolean}
 */
var canEdit = true;

/**
 * @type {TreeItem}
 * @const
 */
var searchTreeItem = new TreeItem({
  bookmarkId: 'q='
});

/**
 * Command shortcut mapping.
 * @const
 */
var commandShortcutMap = cr.isMac ? {
  'edit': 'Enter',
  // On Mac we also allow Meta+Backspace.
  'delete': 'U+007F  U+0008 Meta-U+0008',
  'open-in-background-tab': 'Meta-Enter',
  'open-in-new-tab': 'Shift-Meta-Enter',
  'open-in-same-window': 'Meta-Down',
  'open-in-new-window': 'Shift-Enter',
  'rename-folder': 'Enter',
  // Global undo is Command-Z. It is not in any menu.
  'undo': 'Meta-U+005A',
} : {
  'edit': 'F2',
  'delete': 'U+007F',
  'open-in-background-tab': 'Ctrl-Enter',
  'open-in-new-tab': 'Shift-Ctrl-Enter',
  'open-in-same-window': 'Enter',
  'open-in-new-window': 'Shift-Enter',
  'rename-folder': 'F2',
  // Global undo is Ctrl-Z. It is not in any menu.
  'undo': 'Ctrl-U+005A',
};

/**
 * Mapping for folder id to suffix of UMA. These names will be appeared
 * after "BookmarkManager_NavigateTo_" in UMA dashboard.
 * @const
 */
var folderMetricsNameMap = {
  '1': 'BookmarkBar',
  '2': 'Other',
  '3': 'Mobile',
  'q=': 'Search',
  'subfolder': 'SubFolder',
};

/**
 * Adds an event listener to a node that will remove itself after firing once.
 * @param {!Element} node The DOM node to add the listener to.
 * @param {string} name The name of the event listener to add to.
 * @param {function(Event)} handler Function called when the event fires.
 */
function addOneShotEventListener(node, name, handler) {
  var f = function(e) {
    handler(e);
    node.removeEventListener(name, f);
  };
  node.addEventListener(name, f);
}

// Get the localized strings from the backend via bookmakrManagerPrivate API.
function loadLocalizedStrings(data) {
  // The strings may contain & which we need to strip.
  for (var key in data) {
    data[key] = data[key].replace(/&/, '');
  }

  loadTimeData.data = data;
  i18nTemplate.process(document, loadTimeData);

  searchTreeItem.label = loadTimeData.getString('search');
  searchTreeItem.icon = isRTL() ? 'images/bookmark_manager_search_rtl.png' :
                                  'images/bookmark_manager_search.png';
}

/**
 * Updates the location hash to reflect the current state of the application.
 */
function updateHash() {
  window.location.hash = tree.selectedItem.bookmarkId;
}

/**
 * Navigates to a bookmark ID.
 * @param {string} id The ID to navigate to.
 * @param {function()} callback Function called when list view loaded or
 *     displayed specified folder.
 */
function navigateTo(id, callback) {
  if (list.parentId == id) {
    callback();
    return;
  }

  var metricsId = folderMetricsNameMap[id.replace(/^q=.*/, 'q=')] ||
                  folderMetricsNameMap['subfolder'];
  chrome.metricsPrivate.recordUserAction(
      'BookmarkManager_NavigateTo_' + metricsId);

  addOneShotEventListener(list, 'load', callback);
  updateParentId(id);
}

/**
 * Updates the parent ID of the bookmark list and selects the correct tree item.
 * @param {string} id The id.
 */
function updateParentId(id) {
  // Setting list.parentId fires 'load' event.
  list.parentId = id;

  // When tree.selectedItem changed, tree view calls navigatTo() then it
  // calls updateHash() when list view displayed specified folder.
  tree.selectedItem = bmm.treeLookup[id] || tree.selectedItem;
}

// Process the location hash. This is called by onhashchange and when the page
// is first loaded.
function processHash() {
  var id = window.location.hash.slice(1);
  if (!id) {
    // If we do not have a hash, select first item in the tree.
    id = tree.items[0].bookmarkId;
  }

  var valid = false;
  if (/^e=/.test(id)) {
    id = id.slice(2);

    // If hash contains e=, edit the item specified.
    chrome.bookmarks.get(id, function(bookmarkNodes) {
      // Verify the node to edit is a valid node.
      if (!bookmarkNodes || bookmarkNodes.length != 1)
        return;
      var bookmarkNode = bookmarkNodes[0];

      // After the list reloads, edit the desired bookmark.
      var editBookmark = function(e) {
        var index = list.dataModel.findIndexById(bookmarkNode.id);
        if (index != -1) {
          var sm = list.selectionModel;
          sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index;
          scrollIntoViewAndMakeEditable(index);
        }
      };

      navigateTo(bookmarkNode.parentId, editBookmark);
    });

    // We handle the two cases of navigating to the bookmark to be edited
    // above. Don't run the standard navigation code below.
    return;
  } else if (/^q=/.test(id)) {
    // In case we got a search hash, update the text input and the
    // bmm.treeLookup to use the new id.
    setSearch(id.slice(2));
    valid = true;
  }

  // Navigate to bookmark 'id' (which may be a query of the form q=query).
  if (valid) {
    updateParentId(id);
  } else {
    // We need to verify that this is a correct ID.
    chrome.bookmarks.get(id, function(items) {
      if (items && items.length == 1)
        updateParentId(id);
    });
  }
}

// Activate is handled by the open-in-same-window-command.
function handleDoubleClickForList(e) {
  if (e.button == 0)
    $('open-in-same-window-command').execute();
}

// The list dispatches an event when the user clicks on the URL or the Show in
// folder part.
function handleUrlClickedForList(e) {
  getLinkController().openUrlFromEvent(e.url, e.originalEvent);
  chrome.bookmarkManagerPrivate.recordLaunch();
}

function handleSearch(e) {
  setSearch(this.value);
}

/**
 * Navigates to the search results for the search text.
 * @param {string} searchText The text to search for.
 */
function setSearch(searchText) {
  if (searchText) {
    // Only update search item if we have a search term. We never want the
    // search item to be for an empty search.
    delete bmm.treeLookup[searchTreeItem.bookmarkId];
    var id = searchTreeItem.bookmarkId = 'q=' + searchText;
    bmm.treeLookup[searchTreeItem.bookmarkId] = searchTreeItem;
  }

  var input = $('term');
  // Do not update the input if the user is actively using the text input.
  if (document.activeElement != input)
    input.value = searchText;

  if (searchText) {
    tree.add(searchTreeItem);
    tree.selectedItem = searchTreeItem;
  } else {
    // Go "home".
    tree.selectedItem = tree.items[0];
    id = tree.selectedItem.bookmarkId;
  }

  // Navigate now and update hash immediately.
  navigateTo(id, updateHash);
}

// Handle the logo button UI.
// When the user clicks the button we should navigate "home" and focus the list.
function handleClickOnLogoButton(e) {
  setSearch('');
  $('list').focus();
}

/**
 * This returns the user visible path to the folder where the bookmark is
 * located.
 * @param {number} parentId The ID of the parent folder.
 * @return {string} The path to the the bookmark,
 */
function getFolder(parentId) {
  var parentNode = tree.getBookmarkNodeById(parentId);
  if (parentNode) {
    var s = parentNode.title;
    if (parentNode.parentId != bmm.ROOT_ID) {
      return getFolder(parentNode.parentId) + '/' + s;
    }
    return s;
  }
}

function handleLoadForTree(e) {
  processHash();
}

function getAllUrls(nodes) {
  var urls = [];

  // Adds the node and all its direct children.
  function addNodes(node) {
    if (node.id == 'new')
      return;

    if (node.children) {
      node.children.forEach(function(child) {
        if (!bmm.isFolder(child))
          urls.push(child.url);
      });
    } else {
      urls.push(node.url);
    }
  }

  // Get a future promise for the nodes.
  var promises = nodes.map(function(node) {
    if (bmm.isFolder(node))
      return bmm.loadSubtree(node.id);
    // Not a folder so we already have all the data we need.
    return new Promise(node);
  });

  var urlsPromise = new Promise();

  var p = Promise.all.apply(null, promises);
  p.addListener(function(nodes) {
    nodes.forEach(function(node) {
      addNodes(node);
    });
    urlsPromise.value = urls;
  });

  return urlsPromise;
}

/**
 * Returns the nodes (non recursive) to use for the open commands.
 * @param {HTMLElement} target .
 * @return {Array.<BookmarkTreeNode>} .
 */
function getNodesForOpen(target) {
  if (target == tree) {
    var folderItem = tree.selectedItem;
    return folderItem == searchTreeItem ?
        list.dataModel.slice() : tree.selectedFolders;
  }
  var items = list.selectedItems;
  return items.length ? items : list.dataModel.slice();
}

/**
 * Returns a promise that will contain all URLs of all the selected bookmarks
 * and the nested bookmarks for use with the open commands.
 * @param {HTMLElement} target The target list or tree.
 * @return {Promise} .
 */
function getUrlsForOpenCommands(target) {
  return getAllUrls(getNodesForOpen(target));
}

function notNewNode(node) {
  return node.id != 'new';
}

/**
 * Helper function that updates the canExecute and labels for the open-like
 * commands.
 * @param {!cr.ui.CanExecuteEvent} e The event fired by the command system.
 * @param {!cr.ui.Command} command The command we are currently processing.
 * @param {string} singularId The string id of singular form of the menu label.
 * @param {string} pluralId The string id of menu label if the singular form is
       not used.
 * @param {boolean} commandDisabled Whether the menu item should be disabled
       no matter what bookmarks are selected.
 */
function updateOpenCommand(e, command, singularId, pluralId, commandDisabled) {
  if (singularId) {
    // The command label reflects the selection which might not reflect
    // how many bookmarks will be opened. For example if you right click an
    // empty area in a folder with 1 bookmark the text should still say "all".
    var selectedNodes = getSelectedBookmarkNodes(e.target).filter(notNewNode);
    var singular = selectedNodes.length == 1 && !bmm.isFolder(selectedNodes[0]);
    command.label = loadTimeData.getString(singular ? singularId : pluralId);
  }

  if (commandDisabled) {
    command.disabled = true;
    e.canExecute = false;
    return;
  }

  getUrlsForOpenCommands(e.target).addListener(function(urls) {
    var disabled = !urls.length;
    command.disabled = disabled;
    e.canExecute = !disabled;
  });
}

/**
 * Calls the backend to figure out if we can paste the clipboard into the active
 * folder.
 * @param {Function=} opt_f Function to call after the state has been updated.
 */
function updatePasteCommand(opt_f) {
  function update(canPaste) {
    var organizeMenuCommand = $('paste-from-organize-menu-command');
    var contextMenuCommand = $('paste-from-context-menu-command');
    organizeMenuCommand.disabled = !canPaste;
    contextMenuCommand.disabled = !canPaste;
    if (opt_f)
      opt_f();
  }
  // We cannot paste into search view.
  if (list.isSearch())
    update(false);
  else
    chrome.bookmarkManagerPrivate.canPaste(list.parentId, update);
}

function handleCanExecuteForDocument(e) {
  var command = e.command;
  switch (command.id) {
    case 'import-menu-command':
      e.canExecute = canEdit;
      break;
    case 'export-menu-command':
      // We can always execute the export-menu command.
      e.canExecute = true;
      break;
    case 'sort-command':
      e.canExecute = !list.isSearch() && list.dataModel.length > 1;
      break;
    case 'undo-command':
      // The global undo command has no visible UI, so always enable it, and
      // just make it a no-op if undo is not possible.
      e.canExecute = true;
      break;
    default:
      canExecuteForList(e);
      break;
  }
}

/**
 * Helper function for handling canExecute for the list and the tree.
 * @param {!Event} e Can execute event object.
 * @param {boolean} isSearch Whether the user is trying to do a command on
 *     search.
 */
function canExecuteShared(e, isSearch) {
  var command = e.command;
  var commandId = command.id;
  switch (commandId) {
    case 'paste-from-organize-menu-command':
    case 'paste-from-context-menu-command':
      updatePasteCommand();
      break;

    case 'add-new-bookmark-command':
    case 'new-folder-command':
      e.canExecute = !isSearch && canEdit;
      break;

    case 'open-in-new-tab-command':
      updateOpenCommand(e, command, 'open_in_new_tab', 'open_all', false);
      break;
    case 'open-in-background-tab-command':
      updateOpenCommand(e, command, '', '', false);
      break;
    case 'open-in-new-window-command':
      updateOpenCommand(e, command,
          'open_in_new_window', 'open_all_new_window',
          // Disabled when incognito is forced.
          incognitoModeAvailability == 'forced' || !canOpenNewWindows);
      break;
    case 'open-incognito-window-command':
      updateOpenCommand(e, command,
          'open_incognito', 'open_all_incognito',
          // Not available when incognito is disabled.
          incognitoModeAvailability == 'disabled');
      break;

    case 'undo-delete-command':
      e.canExecute = !!lastDeletedNodes;
      break;
  }
}

/**
 * Helper function for handling canExecute for the list and document.
 * @param {!Event} e Can execute event object.
 */
function canExecuteForList(e) {
  var command = e.command;
  var commandId = command.id;

  function hasSelected() {
    return !!list.selectedItem;
  }

  function hasSingleSelected() {
    return list.selectedItems.length == 1;
  }

  function canCopyItem(item) {
    return item.id != 'new';
  }

  function canCopyItems() {
    var selectedItems = list.selectedItems;
    return selectedItems && selectedItems.some(canCopyItem);
  }

  function isSearch() {
    return list.isSearch();
  }

  switch (commandId) {
    case 'rename-folder-command':
      // Show rename if a single folder is selected.
      var items = list.selectedItems;
      if (items.length != 1) {
        e.canExecute = false;
        command.hidden = true;
      } else {
        var isFolder = bmm.isFolder(items[0]);
        e.canExecute = isFolder && canEdit;
        command.hidden = !isFolder;
      }
      break;

    case 'edit-command':
      // Show the edit command if not a folder.
      var items = list.selectedItems;
      if (items.length != 1) {
        e.canExecute = false;
        command.hidden = false;
      } else {
        var isFolder = bmm.isFolder(items[0]);
        e.canExecute = !isFolder && canEdit;
        command.hidden = isFolder;
      }
      break;

    case 'show-in-folder-command':
      e.canExecute = isSearch() && hasSingleSelected();
      break;

    case 'delete-command':
    case 'cut-command':
      e.canExecute = canCopyItems() && canEdit;
      break;

    case 'copy-command':
      e.canExecute = canCopyItems();
      break;

    case 'open-in-same-window-command':
      e.canExecute = hasSelected();
      break;

    default:
      canExecuteShared(e, isSearch());
  }
}

// Update canExecute for the commands when the list is the active element.
function handleCanExecuteForList(e) {
  if (e.target != list) return;
  canExecuteForList(e);
}

// Update canExecute for the commands when the tree is the active element.
function handleCanExecuteForTree(e) {
  if (e.target != tree) return;

  var command = e.command;
  var commandId = command.id;

  function hasSelected() {
    return !!e.target.selectedItem;
  }

  function isSearch() {
    var item = e.target.selectedItem;
    return item == searchTreeItem;
  }

  function isTopLevelItem() {
    return e.target.selectedItem.parentNode == tree;
  }

  switch (commandId) {
    case 'rename-folder-command':
      command.hidden = false;
      e.canExecute = hasSelected() && !isTopLevelItem() && canEdit;
      break;

    case 'edit-command':
      command.hidden = true;
      e.canExecute = false;
      break;

    case 'delete-command':
    case 'cut-command':
      e.canExecute = hasSelected() && !isTopLevelItem() && canEdit;
      break;

    case 'copy-command':
      e.canExecute = hasSelected() && !isTopLevelItem();
      break;

    default:
      canExecuteShared(e, isSearch());
  }
}

/**
 * Update the canExecute state of the commands when the selection changes.
 * @param {Event} e The change event object.
 */
function updateCommandsBasedOnSelection(e) {
  if (e.target == document.activeElement) {
    // Paste only needs to be updated when the tree selection changes.
    var commandNames = ['copy', 'cut', 'delete', 'rename-folder', 'edit',
      'add-new-bookmark', 'new-folder', 'open-in-new-tab',
      'open-in-background-tab', 'open-in-new-window', 'open-incognito-window',
      'open-in-same-window', 'show-in-folder'];

    if (e.target == tree) {
      commandNames.push('paste-from-context-menu', 'paste-from-organize-menu',
                        'sort');
    }

    commandNames.forEach(function(baseId) {
      $(baseId + '-command').canExecuteChange();
    });
  }
}

function updateEditingCommands() {
  var editingCommands = ['cut', 'delete', 'rename-folder', 'edit',
      'add-new-bookmark', 'new-folder', 'sort',
      'paste-from-context-menu', 'paste-from-organize-menu'];

  chrome.bookmarkManagerPrivate.canEdit(function(result) {
    if (result != canEdit) {
      canEdit = result;
      editingCommands.forEach(function(baseId) {
        $(baseId + '-command').canExecuteChange();
      });
    }
  });
}

function handleChangeForTree(e) {
  updateCommandsBasedOnSelection(e);
  navigateTo(tree.selectedItem.bookmarkId, updateHash);
}

function handleOrganizeButtonClick(e) {
  updateEditingCommands();
  $('add-new-bookmark-command').canExecuteChange();
  $('new-folder-command').canExecuteChange();
  $('sort-command').canExecuteChange();
}

function handleRename(e) {
  var item = e.target;
  var bookmarkNode = item.bookmarkNode;
  chrome.bookmarks.update(bookmarkNode.id, {title: item.label});
  performGlobalUndo = null;  // This can't be undone, so disable global undo.
}

function handleEdit(e) {
  var item = e.target;
  var bookmarkNode = item.bookmarkNode;
  var context = {
    title: bookmarkNode.title
  };
  if (!bmm.isFolder(bookmarkNode))
    context.url = bookmarkNode.url;

  if (bookmarkNode.id == 'new') {
    selectItemsAfterUserAction(list);

    // New page
    context.parentId = bookmarkNode.parentId;
    chrome.bookmarks.create(context, function(node) {
      // A new node was created and will get added to the list due to the
      // handler.
      var dataModel = list.dataModel;
      var index = dataModel.indexOf(bookmarkNode);
      dataModel.splice(index, 1);

      // Select new item.
      var newIndex = dataModel.findIndexById(node.id);
      if (newIndex != -1) {
        var sm = list.selectionModel;
        list.scrollIndexIntoView(newIndex);
        sm.leadIndex = sm.anchorIndex = sm.selectedIndex = newIndex;
      }
    });
  } else {
    // Edit
    chrome.bookmarks.update(bookmarkNode.id, context);
  }
  performGlobalUndo = null;  // This can't be undone, so disable global undo.
}

function handleCancelEdit(e) {
  var item = e.target;
  var bookmarkNode = item.bookmarkNode;
  if (bookmarkNode.id == 'new') {
    var dataModel = list.dataModel;
    var index = dataModel.findIndexById('new');
    dataModel.splice(index, 1);
  }
}

/**
 * Navigates to the folder that the selected item is in and selects it. This is
 * used for the show-in-folder command.
 */
function showInFolder() {
  var bookmarkNode = list.selectedItem;
  if (!bookmarkNode)
    return;
  var parentId = bookmarkNode.parentId;

  // After the list is loaded we should select the revealed item.
  function selectItem() {
    var index = list.dataModel.findIndexById(bookmarkNode.id);
    if (index == -1)
      return;
    var sm = list.selectionModel;
    sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index;
    list.scrollIndexIntoView(index);
  }

  var treeItem = bmm.treeLookup[parentId];
  treeItem.reveal();

  navigateTo(parentId, selectItem);
}

/**
 * @return {!cr.LinkController} The link controller used to open links based on
 *     user clicks and keyboard actions.
 */
function getLinkController() {
  return linkController ||
      (linkController = new cr.LinkController(loadTimeData));
}

/**
 * Returns the selected bookmark nodes of the provided tree or list.
 * If |opt_target| is not provided or null the active element is used.
 * Only call this if the list or the tree is focused.
 * @param {BookmarkList|BookmarkTree} opt_target The target list or tree.
 * @return {!Array} Array of bookmark nodes.
 */
function getSelectedBookmarkNodes(opt_target) {
  return (opt_target || document.activeElement) == tree ?
      tree.selectedFolders : list.selectedItems;
}

/**
 * @return {!Array.<string>} An array of the selected bookmark IDs.
 */
function getSelectedBookmarkIds() {
  var selectedNodes = getSelectedBookmarkNodes();
  selectedNodes.sort(function(a, b) { return a.index - b.index });
  return selectedNodes.map(function(node) {
    return node.id;
  });
}

/**
 * Opens the selected bookmarks.
 * @param {LinkKind} kind The kind of link we want to open.
 * @param {HTMLElement} opt_eventTarget The target of the user initiated event.
 */
function openBookmarks(kind, opt_eventTarget) {
  // If we have selected any folders, we need to find all the bookmarks one
  // level down. We use multiple async calls to getSubtree instead of getting
  // the whole tree since we would like to minimize the amount of data sent.

  var urlsP = getUrlsForOpenCommands(opt_eventTarget);
  urlsP.addListener(function(urls) {
    getLinkController().openUrls(urls, kind);
    chrome.bookmarkManagerPrivate.recordLaunch();
  });
}

/**
 * Opens an item in the list.
 */
function openItem() {
  var bookmarkNodes = getSelectedBookmarkNodes();
  // If we double clicked or pressed enter on a single folder, navigate to it.
  if (bookmarkNodes.length == 1 && bmm.isFolder(bookmarkNodes[0])) {
    navigateTo(bookmarkNodes[0].id, updateHash);
  } else {
    openBookmarks(LinkKind.FOREGROUND_TAB);
  }
}

/**
 * Deletes the selected bookmarks. The bookmarks are saved in memory in case
 * the user needs to undo the deletion.
 */
function deleteBookmarks() {
  var selectedIds = getSelectedBookmarkIds();
  lastDeletedNodes = [];

  function performDelete() {
    chrome.bookmarkManagerPrivate.removeTrees(selectedIds);
    $('undo-delete-command').canExecuteChange();
    performGlobalUndo = undoDelete;
  }

  // First, store information about the bookmarks being deleted.
  selectedIds.forEach(function(id) {
    chrome.bookmarks.getSubTree(id, function(results) {
      lastDeletedNodes.push(results);

      // When all nodes have been saved, perform the deletion.
      if (lastDeletedNodes.length === selectedIds.length)
        performDelete();
    });
  });
}

/**
 * Restores a tree of bookmarks under a specified folder.
 * @param {BookmarkTreeNode} node The node to restore.
 * @param {=string} parentId The ID of the folder to restore under. If not
 *     specified, the original parentId of the node will be used.
 */
function restoreTree(node, parentId) {
  var bookmarkInfo = {
    parentId: parentId || node.parentId,
    title: node.title,
    index: node.index,
    url: node.url
  };

  chrome.bookmarks.create(bookmarkInfo, function(result) {
    if (!result) {
      console.error('Failed to restore bookmark.');
      return;
    }

    if (node.children) {
      // Restore the children using the new ID for this node.
      node.children.forEach(function(child) {
        restoreTree(child, result.id);
      });
    }
  });
}

/**
 * Restores the last set of bookmarks that was deleted.
 */
function undoDelete() {
  lastDeletedNodes.forEach(function(arr) {
    arr.forEach(restoreTree);
  });
  lastDeletedNodes = null;
  $('undo-delete-command').canExecuteChange();

  // Only a single level of undo is supported, so disable global undo now.
  performGlobalUndo = null;
}

/**
 * Computes folder for "Add Page" and "Add Folder".
 * @return {string} The id of folder node where we'll create new page/folder.
 */
function computeParentFolderForNewItem() {
  if (document.activeElement == tree)
    return list.parentId;
  var selectedItem = list.selectedItem;
  return selectedItem && bmm.isFolder(selectedItem) ?
      selectedItem.id : list.parentId;
}

/**
 * Callback for rename folder and edit command. This starts editing for
 * selected item.
 */
function editSelectedItem() {
  if (document.activeElement == tree) {
    tree.selectedItem.editing = true;
  } else {
    var li = list.getListItem(list.selectedItem);
    if (li)
      li.editing = true;
  }
}

/**
 * Callback for the new folder command. This creates a new folder and starts
 * a rename of it.
 */
function newFolder() {
  performGlobalUndo = null;  // This can't be undone, so disable global undo.

  var parentId = computeParentFolderForNewItem();

  // Callback is called after tree and list data model updated.
  function createFolder(callback) {
    chrome.bookmarks.create({
      title: loadTimeData.getString('new_folder_name'),
      parentId: parentId
    }, callback);
  }

  if (document.activeElement == tree) {
    createFolder(function(newNode) {
      navigateTo(newNode.id, function() {
        bmm.treeLookup[newNode.id].editing = true;
      });
    });
    return;
  }

  function editNewFolderInList() {
    createFolder(function() {
      var index = list.dataModel.length - 1;
      var sm = list.selectionModel;
      sm.anchorIndex = sm.leadIndex = sm.selectedIndex = index;
      scrollIntoViewAndMakeEditable(index);
    });
  }

  navigateTo(parentId, editNewFolderInList);
}

/**
 * Scrolls the list item into view and makes it editable.
 * @param {number} index The index of the item to make editable.
 */
function scrollIntoViewAndMakeEditable(index) {
  list.scrollIndexIntoView(index);
  // onscroll is now dispatched asynchronously so we have to postpone
  // the rest.
  setTimeout(function() {
    var item = list.getListItemByIndex(index);
    if (item)
      item.editing = true;
  });
}

/**
 * Adds a page to the current folder. This is called by the
 * add-new-bookmark-command handler.
 */
function addPage() {
  var parentId = computeParentFolderForNewItem();

  function editNewBookmark() {
    var fakeNode = {
      title: '',
      url: '',
      parentId: parentId,
      id: 'new'
    };
    var dataModel = list.dataModel;
    var length = dataModel.length;
    dataModel.splice(length, 0, fakeNode);
    var sm = list.selectionModel;
    sm.anchorIndex = sm.leadIndex = sm.selectedIndex = length;
    scrollIntoViewAndMakeEditable(length);
  };

  navigateTo(parentId, editNewBookmark);
}

/**
 * This function is used to select items after a user action such as paste, drop
 * add page etc.
 * @param {BookmarkList|BookmarkTree} target The target of the user action.
 * @param {=string} opt_selectedTreeId If provided, then select that tree id.
 */
function selectItemsAfterUserAction(target, opt_selectedTreeId) {
  // We get one onCreated event per item so we delay the handling until we get
  // no more events coming.

  var ids = [];
  var timer;

  function handle(id, bookmarkNode) {
    clearTimeout(timer);
    if (opt_selectedTreeId || list.parentId == bookmarkNode.parentId)
      ids.push(id);
    timer = setTimeout(handleTimeout, 50);
  }

  function handleTimeout() {
    chrome.bookmarks.onCreated.removeListener(handle);
    chrome.bookmarks.onMoved.removeListener(handle);

    if (opt_selectedTreeId && ids.indexOf(opt_selectedTreeId) != -1) {
      var index = ids.indexOf(opt_selectedTreeId);
      if (index != -1 && opt_selectedTreeId in bmm.treeLookup) {
        tree.selectedItem = bmm.treeLookup[opt_selectedTreeId];
      }
    } else if (target == list) {
      var dataModel = list.dataModel;
      var firstIndex = dataModel.findIndexById(ids[0]);
      var lastIndex = dataModel.findIndexById(ids[ids.length - 1]);
      if (firstIndex != -1 && lastIndex != -1) {
        var selectionModel = list.selectionModel;
        selectionModel.selectedIndex = -1;
        selectionModel.selectRange(firstIndex, lastIndex);
        selectionModel.anchorIndex = selectionModel.leadIndex = lastIndex;
        list.focus();
      }
    }

    list.endBatchUpdates();
  }

  list.startBatchUpdates();

  chrome.bookmarks.onCreated.addListener(handle);
  chrome.bookmarks.onMoved.addListener(handle);
  timer = setTimeout(handleTimeout, 300);
}

/**
 * Record user action.
 * @param {string} name An user action name.
 */
function recordUserAction(name) {
  chrome.metricsPrivate.recordUserAction('BookmarkManager_Command_' + name);
}

/**
 * The currently selected bookmark, based on where the user is clicking.
 * @return {string} The ID of the currently selected bookmark (could be from
 *     tree view or list view).
 */
function getSelectedId() {
  if (document.activeElement == tree)
    return tree.selectedItem.bookmarkId;
  var selectedItem = list.selectedItem;
  return selectedItem && bmm.isFolder(selectedItem) ?
      selectedItem.id : tree.selectedItem.bookmarkId;
}

/**
 * Pastes the copied/cutted bookmark into the right location depending whether
 * if it was called from Organize Menu or from Context Menu.
 * @param {string} id The id of the element being pasted from.
 */
function pasteBookmark(id) {
  recordUserAction('Paste');
  selectItemsAfterUserAction(list);
  chrome.bookmarkManagerPrivate.paste(id, getSelectedBookmarkIds());
}

/**
 * Handler for the command event. This is used for context menu of list/tree
 * and organized menu.
 * @param {!Event} e The event object.
 */
function handleCommand(e) {
  var command = e.command;
  var commandId = command.id;
  switch (commandId) {
    case 'import-menu-command':
      recordUserAction('Import');
      chrome.bookmarks.import();
      break;
    case 'export-menu-command':
      recordUserAction('Export');
      chrome.bookmarks.export();
      break;
    case 'undo-command':
      if (performGlobalUndo) {
        recordUserAction('UndoGlobal');
        performGlobalUndo();
      } else {
        recordUserAction('UndoNone');
      }
      break;
    case 'show-in-folder-command':
      recordUserAction('ShowInFolder');
      showInFolder();
      break;
    case 'open-in-new-tab-command':
    case 'open-in-background-tab-command':
      recordUserAction('OpenInNewTab');
      openBookmarks(LinkKind.BACKGROUND_TAB, e.target);
      break;
    case 'open-in-new-window-command':
      recordUserAction('OpenInNewWindow');
      openBookmarks(LinkKind.WINDOW, e.target);
      break;
    case 'open-incognito-window-command':
      recordUserAction('OpenIncognito');
      openBookmarks(LinkKind.INCOGNITO, e.target);
      break;
    case 'delete-command':
      recordUserAction('Delete');
      deleteBookmarks();
      break;
    case 'copy-command':
      recordUserAction('Copy');
      chrome.bookmarkManagerPrivate.copy(getSelectedBookmarkIds(),
                                         updatePasteCommand);
      break;
    case 'cut-command':
      recordUserAction('Cut');
      chrome.bookmarkManagerPrivate.cut(getSelectedBookmarkIds(),
                                        updatePasteCommand);
      break;
    case 'paste-from-organize-menu-command':
      pasteBookmark(list.parentId);
      break;
    case 'paste-from-context-menu-command':
      pasteBookmark(getSelectedId());
      break;
    case 'sort-command':
      recordUserAction('Sort');
      chrome.bookmarkManagerPrivate.sortChildren(list.parentId);
      break;
    case 'rename-folder-command':
      editSelectedItem();
      break;
    case 'edit-command':
      recordUserAction('Edit');
      editSelectedItem();
      break;
    case 'new-folder-command':
      recordUserAction('NewFolder');
      newFolder();
      break;
    case 'add-new-bookmark-command':
      recordUserAction('AddPage');
      addPage();
      break;
    case 'open-in-same-window-command':
      recordUserAction('OpenInSame');
      openItem();
      break;
    case 'undo-delete-command':
      recordUserAction('UndoDelete');
      undoDelete();
      break;
  }
}

// Execute the copy, cut and paste commands when those events are dispatched by
// the browser. This allows us to rely on the browser to handle the keyboard
// shortcuts for these commands.
function installEventHandlerForCommand(eventName, commandId) {
  function handle(e) {
    if (document.activeElement != list && document.activeElement != tree)
      return;
    var command = $(commandId);
    if (!command.disabled) {
      command.execute();
      if (e)
        e.preventDefault();  // Prevent the system beep.
    }
  }
  if (eventName == 'paste') {
    // Paste is a bit special since we need to do an async call to see if we
    // can paste because the paste command might not be up to date.
    document.addEventListener(eventName, function(e) {
      updatePasteCommand(handle);
    });
  } else {
    document.addEventListener(eventName, handle);
  }
}

function initializeSplitter() {
  var splitter = document.querySelector('.main > .splitter');
  Splitter.decorate(splitter);

  // The splitter persists the size of the left component in the local store.
  if ('treeWidth' in localStorage)
    splitter.previousElementSibling.style.width = localStorage['treeWidth'];

  splitter.addEventListener('resize', function(e) {
    localStorage['treeWidth'] = splitter.previousElementSibling.style.width;
  });
}

function initializeBookmarkManager() {
  // Sometimes the extension API is not initialized.
  if (!chrome.bookmarks)
    console.error('Bookmarks extension API is not available');

  chrome.bookmarkManagerPrivate.getStrings(loadLocalizedStrings);

  bmm.treeLookup[searchTreeItem.bookmarkId] = searchTreeItem;

  cr.ui.decorate('menu', Menu);
  cr.ui.decorate('button[menu]', MenuButton);
  cr.ui.decorate('command', Command);
  BookmarkList.decorate(list);
  BookmarkTree.decorate(tree);

  list.addEventListener('canceledit', handleCancelEdit);
  list.addEventListener('canExecute', handleCanExecuteForList);
  list.addEventListener('change', updateCommandsBasedOnSelection);
  list.addEventListener('contextmenu', updateEditingCommands);
  list.addEventListener('dblclick', handleDoubleClickForList);
  list.addEventListener('edit', handleEdit);
  list.addEventListener('rename', handleRename);
  list.addEventListener('urlClicked', handleUrlClickedForList);

  tree.addEventListener('canExecute', handleCanExecuteForTree);
  tree.addEventListener('change', handleChangeForTree);
  tree.addEventListener('contextmenu', updateEditingCommands);
  tree.addEventListener('rename', handleRename);
  tree.addEventListener('load', handleLoadForTree);

  cr.ui.contextMenuHandler.addContextMenuProperty(tree);
  list.contextMenu = $('context-menu');
  tree.contextMenu = $('context-menu');

  // We listen to hashchange so that we can update the currently shown folder
  // when // the user goes back and forward in the history.
  window.addEventListener('hashchange', processHash);

  document.querySelector('.header form').onsubmit = function(e) {
    setSearch($('term').value);
    e.preventDefault();
  };

  $('term').addEventListener('search', handleSearch);

  document.querySelector('.summary > button').addEventListener(
      'click', handleOrganizeButtonClick);

  document.querySelector('button.logo').addEventListener(
      'click', handleClickOnLogoButton);

  document.addEventListener('canExecute', handleCanExecuteForDocument);
  document.addEventListener('command', handleCommand);

  // Listen to copy, cut and paste events and execute the associated commands.
  installEventHandlerForCommand('copy', 'copy-command');
  installEventHandlerForCommand('cut', 'cut-command');
  installEventHandlerForCommand('paste', 'paste-from-organize-menu-command');

  // Install shortcuts
  for (var name in commandShortcutMap) {
    $(name + '-command').shortcut = commandShortcutMap[name];
  }

  // Disable almost all commands at startup.
  var commands = document.querySelectorAll('command');
  for (var i = 0, command; command = commands[i]; ++i) {
    if (command.id != 'import-menu-command' &&
        command.id != 'export-menu-command') {
      command.disabled = true;
    }
  }

  chrome.bookmarkManagerPrivate.canEdit(function(result) {
    canEdit = result;
  });

  chrome.systemPrivate.getIncognitoModeAvailability(function(result) {
    // TODO(rustema): propagate policy value to the bookmark manager when it
    // changes.
    incognitoModeAvailability = result;
  });

  chrome.bookmarkManagerPrivate.canOpenNewWindows(function(result) {
    canOpenNewWindows = result;
  });

  initializeSplitter();
  bmm.addBookmarkModelListeners();
  dnd.init(selectItemsAfterUserAction);
  tree.reload();
}

initializeBookmarkManager();
})();
