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

<include src="../uber/uber_utils.js">
<include src="history_focus_manager.js">

///////////////////////////////////////////////////////////////////////////////
// Globals:
/** @const */ var RESULTS_PER_PAGE = 150;

// Amount of time between pageviews that we consider a 'break' in browsing,
// measured in milliseconds.
/** @const */ var BROWSING_GAP_TIME = 15 * 60 * 1000;

// The largest bucket value for UMA histogram, based on entry ID. All entries
// with IDs greater than this will be included in this bucket.
/** @const */ var UMA_MAX_BUCKET_VALUE = 1000;

// The largest bucket value for a UMA histogram that is a subset of above.
/** @const */ var UMA_MAX_SUBSET_BUCKET_VALUE = 100;

// TODO(glen): Get rid of these global references, replace with a controller
//     or just make the classes own more of the page.
var historyModel;
var historyView;
var pageState;
var selectionAnchor = -1;
var activeVisit = null;

/** @const */ var Command = cr.ui.Command;
/** @const */ var Menu = cr.ui.Menu;
/** @const */ var MenuButton = cr.ui.MenuButton;

/**
 * Enum that shows the filtering behavior for a host or URL to a managed user.
 * Must behave like the FilteringBehavior enum from managed_mode_url_filter.h.
 * @enum {number}
 */
ManagedModeFilteringBehavior = {
  ALLOW: 0,
  WARN: 1,
  BLOCK: 2
};

MenuButton.createDropDownArrows();

/**
 * Returns true if the mobile (non-desktop) version is being shown.
 * @return {boolean} true if the mobile version is being shown.
 */
function isMobileVersion() {
  return !document.body.classList.contains('uber-frame');
}

/**
 * Record an action in UMA.
 * @param {string} actionDesc The name of the action to be logged.
 */
function recordUmaAction(actionDesc) {
  chrome.send('metricsHandler:recordAction', [actionDesc]);
}

/**
 * Record a histogram value in UMA. If specified value is larger than the max
 * bucket value, record the value in the largest bucket.
 * @param {string} histogram The name of the histogram to be recorded in.
 * @param {integer} maxBucketValue The max value for the last histogram bucket.
 * @param {integer} value The value to record in the histogram.
 */

function recordUmaHistogram(histogram, maxBucketValue, value) {
  chrome.send('metricsHandler:recordInHistogram',
              [histogram,
              ((value > maxBucketValue) ? maxBucketValue : value),
              maxBucketValue]);
}

///////////////////////////////////////////////////////////////////////////////
// Visit:

/**
 * Class to hold all the information about an entry in our model.
 * @param {Object} result An object containing the visit's data.
 * @param {boolean} continued Whether this visit is on the same day as the
 *     visit before it.
 * @param {HistoryModel} model The model object this entry belongs to.
 * @constructor
 */
function Visit(result, continued, model) {
  this.model_ = model;
  this.title_ = result.title;
  this.url_ = result.url;
  this.starred_ = result.starred;
  this.snippet_ = result.snippet || '';

  // These identify the name and type of the device on which this visit
  // occurred. They will be empty if the visit occurred on the current device.
  this.deviceName = result.deviceName;
  this.deviceType = result.deviceType;

  // The ID will be set according to when the visit was displayed, not
  // received. Set to -1 to show that it has not been set yet.
  this.id_ = -1;

  this.isRendered = false;  // Has the visit already been rendered on the page?

  // All the date information is public so that owners can compare properties of
  // two items easily.

  this.date = new Date(result.time);

  // See comment in BrowsingHistoryHandler::QueryComplete - we won't always
  // get all of these.
  this.dateRelativeDay = result.dateRelativeDay || '';
  this.dateTimeOfDay = result.dateTimeOfDay || '';
  this.dateShort = result.dateShort || '';

  // Shows the filtering behavior for that host (only used for managed users).
  // A value of |ManagedModeFilteringBehavior.ALLOW| is not displayed so it is
  // used as the default value.
  this.hostFilteringBehavior = ManagedModeFilteringBehavior.ALLOW;
  if (typeof result.hostFilteringBehavior != 'undefined')
    this.hostFilteringBehavior = result.hostFilteringBehavior;

  this.blockedVisit = result.blockedVisit || false;

  // Whether this is the continuation of a previous day.
  this.continued = continued;

  this.allTimestamps = result.allTimestamps;
}

// Visit, public: -------------------------------------------------------------

/**
 * Returns a dom structure for a browse page result or a search page result.
 * @param {Object} propertyBag A bag of configuration properties, false by
 * default:
 *  - isSearchResult: Whether or not the result is a search result.
 *  - addTitleFavicon: Whether or not the favicon should be added.
 *  - useMonthDate: Whether or not the full date should be inserted (used for
 * monthly view).
 * @return {Node} A DOM node to represent the history entry or search result.
 */
Visit.prototype.getResultDOM = function(propertyBag) {
  var isSearchResult = propertyBag.isSearchResult || false;
  var addTitleFavicon = propertyBag.addTitleFavicon || false;
  var useMonthDate = propertyBag.useMonthDate || false;
  var node = createElementWithClassName('li', 'entry');
  var time = createElementWithClassName('div', 'time');
  var entryBox = createElementWithClassName('label', 'entry-box');
  var domain = createElementWithClassName('div', 'domain');

  this.id_ = this.model_.nextVisitId_++;

  // Only create the checkbox if it can be used either to delete an entry or to
  // block/allow it.
  if (this.model_.editingEntriesAllowed) {
    var checkbox = document.createElement('input');
    checkbox.type = 'checkbox';
    checkbox.id = 'checkbox-' + this.id_;
    checkbox.time = this.date.getTime();
    checkbox.addEventListener('click', checkboxClicked);
    entryBox.appendChild(checkbox);

    // Clicking anywhere in the entryBox will check/uncheck the checkbox.
    entryBox.setAttribute('for', checkbox.id);
    entryBox.addEventListener('mousedown', entryBoxMousedown);
    entryBox.addEventListener('click', entryBoxClick);
  }

  // Keep track of the drop down that triggered the menu, so we know
  // which element to apply the command to.
  // TODO(dubroy): Ideally we'd use 'activate', but MenuButton swallows it.
  var self = this;
  var setActiveVisit = function(e) {
    activeVisit = self;
    var menu = $('action-menu');
    menu.dataset.devicename = self.deviceName;
    menu.dataset.devicetype = self.deviceType;
  };
  domain.textContent = this.getDomainFromURL_(this.url_);

  entryBox.appendChild(time);

  var bookmarkSection = createElementWithClassName('div', 'bookmark-section');
  if (this.starred_) {
    bookmarkSection.classList.add('starred');
    bookmarkSection.addEventListener('click', function f(e) {
      recordUmaAction('HistoryPage_BookmarkStarClicked');
      bookmarkSection.classList.remove('starred');
      chrome.send('removeBookmark', [self.url_]);
      bookmarkSection.removeEventListener('click', f);
      e.preventDefault();
    });
  }
  entryBox.appendChild(bookmarkSection);

  var visitEntryWrapper = entryBox.appendChild(document.createElement('div'));
  if (addTitleFavicon || this.blockedVisit)
    visitEntryWrapper.classList.add('visit-entry');
  if (this.blockedVisit) {
    visitEntryWrapper.classList.add('blocked-indicator');
    visitEntryWrapper.appendChild(this.getVisitAttemptDOM_());
  } else {
    visitEntryWrapper.appendChild(this.getTitleDOM_(isSearchResult));
    if (addTitleFavicon)
      this.addFaviconToElement_(visitEntryWrapper);
    visitEntryWrapper.appendChild(domain);
  }

  if (isMobileVersion()) {
    var removeButton = createElementWithClassName('button', 'remove-entry');
    removeButton.classList.add('custom-appearance');
    removeButton.addEventListener('click', function(e) {
      self.removeFromHistory();
      e.stopPropagation();
      e.preventDefault();
    });
    entryBox.appendChild(removeButton);

    // Support clicking anywhere inside the entry box.
    entryBox.addEventListener('click', function(e) {
      e.currentTarget.querySelector('a').click();
    });
  } else {
    var dropDown = createElementWithClassName('button', 'drop-down');
    dropDown.value = 'Open action menu';
    dropDown.title = loadTimeData.getString('actionMenuDescription');
    dropDown.setAttribute('menu', '#action-menu');
    cr.ui.decorate(dropDown, MenuButton);

    dropDown.addEventListener('mousedown', setActiveVisit);
    dropDown.addEventListener('focus', setActiveVisit);

    // Prevent clicks on the drop down from affecting the checkbox.
    dropDown.addEventListener('click', function(e) { e.preventDefault(); });
    entryBox.appendChild(dropDown);
  }

  // Let the entryBox be styled appropriately when it contains keyboard focus.
  entryBox.addEventListener('focus', function() {
    this.classList.add('contains-focus');
  }, true);
  entryBox.addEventListener('blur', function() {
    this.classList.remove('contains-focus');
  }, true);

  var entryBoxContainer =
      createElementWithClassName('div', 'entry-box-container');
  node.appendChild(entryBoxContainer);
  entryBoxContainer.appendChild(entryBox);

  if (isSearchResult) {
    time.appendChild(document.createTextNode(this.dateShort));
    var snippet = createElementWithClassName('div', 'snippet');
    this.addHighlightedText_(snippet,
                             this.snippet_,
                             this.model_.getSearchText());
    node.appendChild(snippet);
  } else if (useMonthDate) {
    // Show the day instead of the time.
    time.appendChild(document.createTextNode(this.dateShort));
  } else {
    time.appendChild(document.createTextNode(this.dateTimeOfDay));
  }

  this.domNode_ = node;
  node.visit = this;

  return node;
};

/**
 * Remove this visit from the history.
 */
Visit.prototype.removeFromHistory = function() {
  recordUmaAction('HistoryPage_EntryMenuRemoveFromHistory');
  var self = this;
  this.model_.removeVisitsFromHistory([this], function() {
    removeEntryFromView(self.domNode_);
  });
};

// Visit, private: ------------------------------------------------------------

/**
 * Extracts and returns the domain (and subdomains) from a URL.
 * @param {string} url The url.
 * @return {string} The domain. An empty string is returned if no domain can
 *     be found.
 * @private
 */
Visit.prototype.getDomainFromURL_ = function(url) {
  // TODO(sergiu): Extract the domain from the C++ side and send it here.
  var domain = url.replace(/^.+?:\/\//, '').match(/[^/]+/);
  return domain ? domain[0] : '';
};

/**
 * Add child text nodes to a node such that occurrences of the specified text is
 * highlighted.
 * @param {Node} node The node under which new text nodes will be made as
 *     children.
 * @param {string} content Text to be added beneath |node| as one or more
 *     text nodes.
 * @param {string} highlightText Occurences of this text inside |content| will
 *     be highlighted.
 * @private
 */
Visit.prototype.addHighlightedText_ = function(node, content, highlightText) {
  var i = 0;
  if (highlightText) {
    var re = new RegExp(Visit.pregQuote_(highlightText), 'gim');
    var match;
    while (match = re.exec(content)) {
      if (match.index > i)
        node.appendChild(document.createTextNode(content.slice(i,
                                                               match.index)));
      i = re.lastIndex;
      // Mark the highlighted text in bold.
      var b = document.createElement('b');
      b.textContent = content.substring(match.index, i);
      node.appendChild(b);
    }
  }
  if (i < content.length)
    node.appendChild(document.createTextNode(content.slice(i)));
};

/**
 * Returns the DOM element containing a link on the title of the URL for the
 * current visit.
 * @param {boolean} isSearchResult Whether or not the entry is a search result.
 * @return {Element} DOM representation for the title block.
 * @private
 */
Visit.prototype.getTitleDOM_ = function(isSearchResult) {
  var node = createElementWithClassName('div', 'title');
  var link = document.createElement('a');
  link.href = this.url_;
  link.id = 'id-' + this.id_;
  link.target = '_top';
  var integerId = parseInt(this.id_, 10);
  link.addEventListener('click', function() {
    recordUmaAction('HistoryPage_EntryLinkClick');
    // Record the ID of the entry to signify how many entries are above this
    // link on the page.
    recordUmaHistogram('HistoryPage.ClickPosition',
                       UMA_MAX_BUCKET_VALUE,
                       integerId);
    if (integerId <= UMA_MAX_SUBSET_BUCKET_VALUE) {
      recordUmaHistogram('HistoryPage.ClickPositionSubset',
                         UMA_MAX_SUBSET_BUCKET_VALUE,
                         integerId);
    }
  });
  link.addEventListener('contextmenu', function() {
    recordUmaAction('HistoryPage_EntryLinkRightClick');
  });

  if (isSearchResult) {
    link.addEventListener('click', function() {
      recordUmaAction('HistoryPage_SearchResultClick');
    });
  }

  // Add a tooltip, since it might be ellipsized.
  // TODO(dubroy): Find a way to show the tooltip only when necessary.
  link.title = this.title_;

  this.addHighlightedText_(link, this.title_, this.model_.getSearchText());
  node.appendChild(link);

  return node;
};

/**
 * Returns the DOM element containing the text for a blocked visit attempt.
 * @return {Element} DOM representation of the visit attempt.
 * @private
 */
Visit.prototype.getVisitAttemptDOM_ = function() {
  var node = createElementWithClassName('div', 'title');
  node.innerHTML = loadTimeData.getStringF('blockedVisitText',
                                           this.url_,
                                           this.id_,
                                           this.getDomainFromURL_(this.url_));
  return node;
};

/**
 * Set the favicon for an element.
 * @param {Element} el The DOM element to which to add the icon.
 * @private
 */
Visit.prototype.addFaviconToElement_ = function(el) {
  var url = isMobileVersion() ?
      getFaviconImageSet(this.url_, 32, 'touch-icon') :
      getFaviconImageSet(this.url_);
  el.style.backgroundImage = url;
};

/**
 * Launch a search for more history entries from the same domain.
 * @private
 */
Visit.prototype.showMoreFromSite_ = function() {
  recordUmaAction('HistoryPage_EntryMenuShowMoreFromSite');
  historyView.setSearch(this.getDomainFromURL_(this.url_));
};

// Visit, private, static: ----------------------------------------------------

/**
 * Quote a string so it can be used in a regular expression.
 * @param {string} str The source string.
 * @return {string} The escaped string.
 * @private
 */
Visit.pregQuote_ = function(str) {
  return str.replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, '\\$1');
};

///////////////////////////////////////////////////////////////////////////////
// HistoryModel:

/**
 * Global container for history data. Future optimizations might include
 * allowing the creation of a HistoryModel for each search string, allowing
 * quick flips back and forth between results.
 *
 * The history model is based around pages, and only fetching the data to
 * fill the currently requested page. This is somewhat dependent on the view,
 * and so future work may wish to change history model to operate on
 * timeframe (day or week) based containers.
 *
 * @constructor
 */
function HistoryModel() {
  this.clearModel_();
}

// HistoryModel, Public: ------------------------------------------------------

/** @enum {number} */
HistoryModel.Range = {
  ALL_TIME: 0,
  WEEK: 1,
  MONTH: 2
};

/**
 * Sets our current view that is called when the history model changes.
 * @param {HistoryView} view The view to set our current view to.
 */
HistoryModel.prototype.setView = function(view) {
  this.view_ = view;
};

/**
 * Reload our model with the current parameters.
 */
HistoryModel.prototype.reload = function() {
  // Save user-visible state, clear the model, and restore the state.
  var search = this.searchText_;
  var page = this.requestedPage_;
  var range = this.rangeInDays_;
  var offset = this.offset_;
  var groupByDomain = this.groupByDomain_;

  this.clearModel_();
  this.searchText_ = search;
  this.requestedPage_ = page;
  this.rangeInDays_ = range;
  this.offset_ = offset;
  this.groupByDomain_ = groupByDomain;
  this.queryHistory_();
};

/**
 * @return {string} The current search text.
 */
HistoryModel.prototype.getSearchText = function() {
  return this.searchText_;
};

/**
 * Tell the model that the view will want to see the current page. When
 * the data becomes available, the model will call the view back.
 * @param {number} page The page we want to view.
 */
HistoryModel.prototype.requestPage = function(page) {
  this.requestedPage_ = page;
  this.updateSearch_();
};

/**
 * Receiver for history query.
 * @param {Object} info An object containing information about the query.
 * @param {Array} results A list of results.
 */
HistoryModel.prototype.addResults = function(info, results) {
  // If no requests are in flight then this was an old request so we drop the
  // results. Double check the search term as well.
  if (!this.inFlight_ || info.term != this.searchText_)
    return;

  $('loading-spinner').hidden = true;
  this.inFlight_ = false;
  this.isQueryFinished_ = info.finished;
  this.queryStartTime = info.queryStartTime;
  this.queryEndTime = info.queryEndTime;

  var lastVisit = this.visits_.slice(-1)[0];
  var lastDay = lastVisit ? lastVisit.dateRelativeDay : null;

  for (var i = 0, result; result = results[i]; i++) {
    var thisDay = result.dateRelativeDay;
    var isSameDay = lastDay == thisDay;
    this.visits_.push(new Visit(result, isSameDay, this));
    lastDay = thisDay;
  }

  if (loadTimeData.getBoolean('isUserSignedIn')) {
    var message = loadTimeData.getString(
        info.hasSyncedResults ? 'hasSyncedResults' : 'noSyncedResults');
    this.view_.showNotification(message);
  }

  this.updateSearch_();
};

/**
 * @return {number} The number of visits in the model.
 */
HistoryModel.prototype.getSize = function() {
  return this.visits_.length;
};

/**
 * Get a list of visits between specified index positions.
 * @param {number} start The start index.
 * @param {number} end The end index.
 * @return {Array.<Visit>} A list of visits.
 */
HistoryModel.prototype.getNumberedRange = function(start, end) {
  return this.visits_.slice(start, end);
};

/**
 * Return true if there are more results beyond the current page.
 * @return {boolean} true if the there are more results, otherwise false.
 */
HistoryModel.prototype.hasMoreResults = function() {
  return this.haveDataForPage_(this.requestedPage_ + 1) ||
      !this.isQueryFinished_;
};

/**
 * Removes a list of visits from the history, and calls |callback| when the
 * removal has successfully completed.
 * @param {Array<Visit>} visits The visits to remove.
 * @param {Function} callback The function to call after removal succeeds.
 */
HistoryModel.prototype.removeVisitsFromHistory = function(visits, callback) {
  var toBeRemoved = [];
  for (var i = 0; i < visits.length; i++) {
    toBeRemoved.push({
      url: visits[i].url_,
      timestamps: visits[i].allTimestamps
    });
  }
  chrome.send('removeVisits', toBeRemoved);
  this.deleteCompleteCallback_ = callback;
};

/**
 * Called when visits have been succesfully removed from the history.
 */
HistoryModel.prototype.deleteComplete = function() {
  // Call the callback, with 'this' undefined inside the callback.
  this.deleteCompleteCallback_.call();
  this.deleteCompleteCallback_ = null;
};

// Getter and setter for HistoryModel.rangeInDays_.
Object.defineProperty(HistoryModel.prototype, 'rangeInDays', {
  get: function() {
    return this.rangeInDays_;
  },
  set: function(range) {
    this.rangeInDays_ = range;
  }
});

/**
 * Getter and setter for HistoryModel.offset_. The offset moves the current
 * query 'window' |range| days behind. As such for range set to WEEK an offset
 * of 0 refers to the last 7 days, an offset of 1 refers to the 7 day period
 * that ended 7 days ago, etc. For MONTH an offset of 0 refers to the current
 * calendar month, 1 to the previous one, etc.
 */
Object.defineProperty(HistoryModel.prototype, 'offset', {
  get: function() {
    return this.offset_;
  },
  set: function(offset) {
    this.offset_ = offset;
  }
});

// Setter for HistoryModel.requestedPage_.
Object.defineProperty(HistoryModel.prototype, 'requestedPage', {
  set: function(page) {
    this.requestedPage_ = page;
  }
});

// HistoryModel, Private: -----------------------------------------------------

/**
 * Clear the history model.
 * @private
 */
HistoryModel.prototype.clearModel_ = function() {
  this.inFlight_ = false;  // Whether a query is inflight.
  this.searchText_ = '';
  // Whether this user is a managed user.
  this.isManagedProfile = loadTimeData.getBoolean('isManagedProfile');
  this.deletingHistoryAllowed = loadTimeData.getBoolean('allowDeletingHistory');

  // Only create checkboxes for editing entries if they can be used either to
  // delete an entry or to block/allow it.
  this.editingEntriesAllowed = this.deletingHistoryAllowed;

  // Flag to show that the results are grouped by domain or not.
  this.groupByDomain_ = false;

  this.visits_ = [];  // Date-sorted list of visits (most recent first).
  this.nextVisitId_ = 0;
  selectionAnchor = -1;

  // The page that the view wants to see - we only fetch slightly past this
  // point. If the view requests a page that we don't have data for, we try
  // to fetch it and call back when we're done.
  this.requestedPage_ = 0;

  // The range of history to view or search over.
  this.rangeInDays_ = HistoryModel.Range.ALL_TIME;

  // Skip |offset_| * weeks/months from the begining.
  this.offset_ = 0;

  // Keeps track of whether or not there are more results available than are
  // currently held in |this.visits_|.
  this.isQueryFinished_ = false;

  if (this.view_)
    this.view_.clear_();
};

/**
 * Figure out if we need to do more queries to fill the currently requested
 * page. If we think we can fill the page, call the view and let it know
 * we're ready to show something. This only applies to the daily time-based
 * view.
 * @private
 */
HistoryModel.prototype.updateSearch_ = function() {
  var doneLoading = this.rangeInDays_ != HistoryModel.Range.ALL_TIME ||
                    this.isQueryFinished_ ||
                    this.canFillPage_(this.requestedPage_);

  // Try to fetch more results if more results can arrive and the page is not
  // full.
  if (!doneLoading && !this.inFlight_)
    this.queryHistory_();

  // Show the result or a message if no results were returned.
  this.view_.onModelReady(doneLoading);
};

/**
 * Query for history, either for a search or time-based browsing.
 * @private
 */
HistoryModel.prototype.queryHistory_ = function() {
  var maxResults =
      (this.rangeInDays_ == HistoryModel.Range.ALL_TIME) ? RESULTS_PER_PAGE : 0;

  // If there are already some visits, pick up the previous query where it
  // left off.
  var lastVisit = this.visits_.slice(-1)[0];
  var endTime = lastVisit ? lastVisit.date.getTime() : 0;

  $('loading-spinner').hidden = false;
  this.inFlight_ = true;
  chrome.send('queryHistory',
      [this.searchText_, this.offset_, this.rangeInDays_, endTime, maxResults]);
};

/**
 * Check to see if we have data for the given page.
 * @param {number} page The page number.
 * @return {boolean} Whether we have any data for the given page.
 * @private
 */
HistoryModel.prototype.haveDataForPage_ = function(page) {
  return page * RESULTS_PER_PAGE < this.getSize();
};

/**
 * Check to see if we have data to fill the given page.
 * @param {number} page The page number.
 * @return {boolean} Whether we have data to fill the page.
 * @private
 */
HistoryModel.prototype.canFillPage_ = function(page) {
  return ((page + 1) * RESULTS_PER_PAGE <= this.getSize());
};

/**
 * Enables or disables grouping by domain.
 * @param {boolean} groupByDomain New groupByDomain_ value.
 */
HistoryModel.prototype.setGroupByDomain = function(groupByDomain) {
  this.groupByDomain_ = groupByDomain;
  this.offset_ = 0;
};

/**
 * Gets whether we are grouped by domain.
 * @return {boolean} Whether the results are grouped by domain.
 */
HistoryModel.prototype.getGroupByDomain = function() {
  return this.groupByDomain_;
};

///////////////////////////////////////////////////////////////////////////////
// HistoryView:

/**
 * Functions and state for populating the page with HTML. This should one-day
 * contain the view and use event handlers, rather than pushing HTML out and
 * getting called externally.
 * @param {HistoryModel} model The model backing this view.
 * @constructor
 */
function HistoryView(model) {
  this.editButtonTd_ = $('edit-button');
  this.editingControlsDiv_ = $('editing-controls');
  this.resultDiv_ = $('results-display');
  this.pageDiv_ = $('results-pagination');
  this.model_ = model;
  this.pageIndex_ = 0;
  this.lastDisplayed_ = [];

  this.model_.setView(this);

  this.currentVisits_ = [];

  // If there is no search button, use the search button label as placeholder
  // text in the search field.
  if ($('search-button').offsetWidth == 0)
    $('search-field').placeholder = $('search-button').value;

  var self = this;

  $('clear-browsing-data').addEventListener('click', openClearBrowsingData);
  $('remove-selected').addEventListener('click', removeItems);

  // Add handlers for the page navigation buttons at the bottom.
  $('newest-button').addEventListener('click', function() {
    recordUmaAction('HistoryPage_NewestHistoryClick');
    self.setPage(0);
  });
  $('newer-button').addEventListener('click', function() {
    recordUmaAction('HistoryPage_NewerHistoryClick');
    self.setPage(self.pageIndex_ - 1);
  });
  $('older-button').addEventListener('click', function() {
    recordUmaAction('HistoryPage_OlderHistoryClick');
    self.setPage(self.pageIndex_ + 1);
  });

  var handleRangeChange = function(e) {
    // Update the results and save the last state.
    self.setRangeInDays(parseInt(e.target.value, 10));
  };

  // Add handlers for the range options.
  $('timeframe-filter-all').addEventListener('change', handleRangeChange);
  $('timeframe-filter-week').addEventListener('change', handleRangeChange);
  $('timeframe-filter-month').addEventListener('change', handleRangeChange);

  $('range-previous').addEventListener('click', function(e) {
    if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME)
      self.setPage(self.pageIndex_ + 1);
    else
      self.setOffset(self.getOffset() + 1);
  });
  $('range-next').addEventListener('click', function(e) {
    if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME)
      self.setPage(self.pageIndex_ - 1);
    else
      self.setOffset(self.getOffset() - 1);
  });
  $('range-today').addEventListener('click', function(e) {
    if (self.getRangeInDays() == HistoryModel.Range.ALL_TIME)
      self.setPage(0);
    else
      self.setOffset(0);
  });
}

// HistoryView, public: -------------------------------------------------------
/**
 * Do a search on a specific term.
 * @param {string} term The string to search for.
 */
HistoryView.prototype.setSearch = function(term) {
  window.scrollTo(0, 0);
  this.setPageState(term, 0, this.getRangeInDays(), this.getOffset());
};

/**
 * Reload the current view.
 */
HistoryView.prototype.reload = function() {
  this.model_.reload();
  this.updateSelectionEditButtons();
  this.updateRangeButtons_();
};

/**
 * Sets all the parameters for the history page and then reloads the view to
 * update the results.
 * @param {string} searchText The search string to set.
 * @param {number} page The page to be viewed.
 * @param {HistoryModel.Range} range The range to view or search over.
 * @param {number} offset Set the begining of the query to the specific offset.
 */
HistoryView.prototype.setPageState = function(searchText, page, range, offset) {
  this.clear_();
  this.model_.searchText_ = searchText;
  this.pageIndex_ = page;
  this.model_.requestedPage_ = page;
  this.model_.rangeInDays_ = range;
  this.model_.groupByDomain_ = false;
  if (range != HistoryModel.Range.ALL_TIME)
    this.model_.groupByDomain_ = true;
  this.model_.offset_ = offset;
  this.reload();
  pageState.setUIState(this.model_.getSearchText(),
                       this.pageIndex_,
                       this.getRangeInDays(),
                       this.getOffset());
};

/**
 * Switch to a specified page.
 * @param {number} page The page we wish to view.
 */
HistoryView.prototype.setPage = function(page) {
  // TODO(sergiu): Move this function to setPageState as well and see why one
  // of the tests fails when using setPageState.
  this.clear_();
  this.pageIndex_ = parseInt(page, 10);
  window.scrollTo(0, 0);
  this.model_.requestPage(page);
  pageState.setUIState(this.model_.getSearchText(),
                       this.pageIndex_,
                       this.getRangeInDays(),
                       this.getOffset());
};

/**
 * @return {number} The page number being viewed.
 */
HistoryView.prototype.getPage = function() {
  return this.pageIndex_;
};

/**
 * Set the current range for grouped results.
 * @param {string} range The number of days to which the range should be set.
 */
HistoryView.prototype.setRangeInDays = function(range) {
  // Set the range, offset and reset the page.
  this.setPageState(this.model_.getSearchText(), 0, range, 0);
};

/**
 * Get the current range in days.
 * @return {number} Current range in days from the model.
 */
HistoryView.prototype.getRangeInDays = function() {
  return this.model_.rangeInDays;
};

/**
 * Set the current offset for grouped results.
 * @param {number} offset Offset to set.
 */
HistoryView.prototype.setOffset = function(offset) {
  // If there is another query already in flight wait for that to complete.
  if (this.model_.inFlight_)
    return;
  this.setPageState(this.model_.getSearchText(),
                    this.pageIndex_,
                    this.getRangeInDays(),
                    offset);
};

/**
 * Get the current offset.
 * @return {number} Current offset from the model.
 */
HistoryView.prototype.getOffset = function() {
  return this.model_.offset;
};

/**
 * Callback for the history model to let it know that it has data ready for us
 * to view.
 * @param {boolean} doneLoading Whether the current request is complete.
 */
HistoryView.prototype.onModelReady = function(doneLoading) {
  this.displayResults_(doneLoading);

  // Allow custom styling based on whether there are any results on the page.
  // To make this easier, add a class to the body if there are any results.
  if (this.model_.visits_.length)
    document.body.classList.add('has-results');
  else
    document.body.classList.remove('has-results');

  this.updateNavBar_();
};

/**
 * Enables or disables the buttons that control editing entries depending on
 * whether there are any checked boxes.
 */
HistoryView.prototype.updateSelectionEditButtons = function() {
  if (loadTimeData.getBoolean('allowDeletingHistory')) {
    var anyChecked = document.querySelector('.entry input:checked') != null;
    $('remove-selected').disabled = !anyChecked;
  } else {
    $('remove-selected').disabled = true;
  }
};

/**
 * Shows the notification bar at the top of the page with |innerHTML| as its
 * content.
 * @param {string} innerHTML The HTML content of the warning.
 * @param {boolean} isWarning If true, style the notification as a warning.
 */
HistoryView.prototype.showNotification = function(innerHTML, isWarning) {
  var bar = $('notification-bar');
  bar.innerHTML = innerHTML;
  bar.hidden = false;
  if (isWarning)
    bar.classList.add('warning');
  else
    bar.classList.remove('warning');

  // Make sure that any links in the HTML are targeting the top level.
  var links = bar.querySelectorAll('a');
  for (var i = 0; i < links.length; i++)
    links[i].target = '_top';

  this.positionNotificationBar();
};

/**
 * Adjusts the position of the notification bar based on the size of the page.
 */
HistoryView.prototype.positionNotificationBar = function() {
  var bar = $('notification-bar');

  // If the bar does not fit beside the editing controls, put it into the
  // overflow state.
  if (bar.getBoundingClientRect().top >=
      $('editing-controls').getBoundingClientRect().bottom) {
    bar.classList.add('alone');
  } else {
    bar.classList.remove('alone');
  }
};

// HistoryView, private: ------------------------------------------------------

/**
 * Clear the results in the view.  Since we add results piecemeal, we need
 * to clear them out when we switch to a new page or reload.
 * @private
 */
HistoryView.prototype.clear_ = function() {
  this.resultDiv_.textContent = '';

  this.currentVisits_.forEach(function(visit) {
    visit.isRendered = false;
  });
  this.currentVisits_ = [];

  document.body.classList.remove('has-results');
};

/**
 * Record that the given visit has been rendered.
 * @param {Visit} visit The visit that was rendered.
 * @private
 */
HistoryView.prototype.setVisitRendered_ = function(visit) {
  visit.isRendered = true;
  this.currentVisits_.push(visit);
};

/**
 * Generates and adds the grouped visits DOM for a certain domain. This
 * includes the clickable arrow and domain name and the visit entries for
 * that domain.
 * @param {Element} results DOM object to which to add the elements.
 * @param {string} domain Current domain name.
 * @param {Array} domainVisits Array of visits for this domain.
 * @private
 */
HistoryView.prototype.getGroupedVisitsDOM_ = function(
    results, domain, domainVisits) {
  // Add a new domain entry.
  var siteResults = results.appendChild(
      createElementWithClassName('li', 'site-entry'));

  // Make a wrapper that will contain the arrow, the favicon and the domain.
  var siteDomainWrapper = siteResults.appendChild(
      createElementWithClassName('div', 'site-domain-wrapper'));

  if (this.model_.editingEntriesAllowed) {
    var siteDomainCheckbox =
        createElementWithClassName('input', 'domain-checkbox');

    siteDomainCheckbox.type = 'checkbox';
    siteDomainCheckbox.addEventListener('click', domainCheckboxClicked);
    siteDomainCheckbox.domain_ = domain;

    siteDomainWrapper.appendChild(siteDomainCheckbox);
  }

  var siteArrow = siteDomainWrapper.appendChild(
      createElementWithClassName('div', 'site-domain-arrow collapse'));
  var siteDomain = siteDomainWrapper.appendChild(
      createElementWithClassName('div', 'site-domain'));
  var siteDomainLink = siteDomain.appendChild(
      createElementWithClassName('button', 'link-button'));
  siteDomainLink.addEventListener('click', function(e) { e.preventDefault(); });
  siteDomainLink.textContent = domain;
  var numberOfVisits = createElementWithClassName('span', 'number-visits');
  var domainElement = document.createElement('span');

  numberOfVisits.textContent = loadTimeData.getStringF('numberVisits',
                                                       domainVisits.length);
  siteDomain.appendChild(numberOfVisits);

  domainVisits[0].addFaviconToElement_(siteDomain);

  siteDomainWrapper.addEventListener('click', toggleHandler);

  if (this.model_.isManagedProfile) {
    siteDomainWrapper.appendChild(
        getManagedStatusDOM(domainVisits[0].hostFilteringBehavior));
  }

  siteResults.appendChild(siteDomainWrapper);
  var resultsList = siteResults.appendChild(
      createElementWithClassName('ol', 'site-results'));

  // Collapse until it gets toggled.
  resultsList.style.height = 0;

  // Add the results for each of the domain.
  var isMonthGroupedResult = this.getRangeInDays() == HistoryModel.Range.MONTH;
  for (var j = 0, visit; visit = domainVisits[j]; j++) {
    resultsList.appendChild(visit.getResultDOM({
      useMonthDate: isMonthGroupedResult
    }));
    this.setVisitRendered_(visit);
  }
};

/**
 * Enables or disables the time range buttons.
 * @private
 */
HistoryView.prototype.updateRangeButtons_ = function() {
  // The enabled state for the previous, today and next buttons.
  var previousState = false;
  var todayState = false;
  var nextState = false;
  var usePage = (this.getRangeInDays() == HistoryModel.Range.ALL_TIME);

  // Use pagination for most recent visits, offset otherwise.
  // TODO(sergiu): Maybe send just one variable in the future.
  if (usePage) {
    if (this.getPage() != 0) {
      nextState = true;
      todayState = true;
    }
    previousState = this.model_.hasMoreResults();
  } else {
    if (this.getOffset() != 0) {
      nextState = true;
      todayState = true;
    }
    previousState = !this.model_.isQueryFinished_;
  }

  $('range-previous').disabled = !previousState;
  $('range-today').disabled = !todayState;
  $('range-next').disabled = !nextState;
};

/**
 * Groups visits by domain, sorting them by the number of visits.
 * @param {Array} visits Visits received from the query results.
 * @param {Element} results Object where the results are added to.
 * @private
 */
HistoryView.prototype.groupVisitsByDomain_ = function(visits, results) {
  var visitsByDomain = {};
  var domains = [];

  // Group the visits into a dictionary and generate a list of domains.
  for (var i = 0, visit; visit = visits[i]; i++) {
    var domain = visit.getDomainFromURL_(visit.url_);
    if (!visitsByDomain[domain]) {
      visitsByDomain[domain] = [];
      domains.push(domain);
    }
    visitsByDomain[domain].push(visit);
  }
  var sortByVisits = function(a, b) {
    return visitsByDomain[b].length - visitsByDomain[a].length;
  };
  domains.sort(sortByVisits);

  for (var i = 0, domain; domain = domains[i]; i++)
    this.getGroupedVisitsDOM_(results, domain, visitsByDomain[domain]);
};

/**
 * Adds the results for a month.
 * @param {Array} visits Visits returned by the query.
 * @param {Element} parentElement Element to which to add the results to.
 * @private
 */
HistoryView.prototype.addMonthResults_ = function(visits, parentElement) {
  if (visits.length == 0)
    return;

  var monthResults = parentElement.appendChild(
      createElementWithClassName('ol', 'month-results'));
  // Don't add checkboxes if entries can not be edited.
  if (!this.model_.editingEntriesAllowed)
    monthResults.classList.add('no-checkboxes');

  this.groupVisitsByDomain_(visits, monthResults);
};

/**
 * Adds the results for a certain day. This includes a title with the day of
 * the results and the results themselves, grouped or not.
 * @param {Array} visits Visits returned by the query.
 * @param {Element} parentElement Element to which to add the results to.
 * @private
 */
HistoryView.prototype.addDayResults_ = function(visits, parentElement) {
  if (visits.length == 0)
    return;

  var firstVisit = visits[0];
  var day = parentElement.appendChild(createElementWithClassName('h3', 'day'));
  day.appendChild(document.createTextNode(firstVisit.dateRelativeDay));
  if (firstVisit.continued) {
    day.appendChild(document.createTextNode(' ' +
                                            loadTimeData.getString('cont')));
  }
  var dayResults = parentElement.appendChild(
      createElementWithClassName('ol', 'day-results'));

  // Don't add checkboxes if entries can not be edited.
  if (!this.model_.editingEntriesAllowed)
    dayResults.classList.add('no-checkboxes');

  if (this.model_.getGroupByDomain()) {
    this.groupVisitsByDomain_(visits, dayResults);
  } else {
    var lastTime;

    for (var i = 0, visit; visit = visits[i]; i++) {
      // If enough time has passed between visits, indicate a gap in browsing.
      var thisTime = visit.date.getTime();
      if (lastTime && lastTime - thisTime > BROWSING_GAP_TIME)
        dayResults.appendChild(createElementWithClassName('li', 'gap'));

      // Insert the visit into the DOM.
      dayResults.appendChild(visit.getResultDOM({ addTitleFavicon: true }));
      this.setVisitRendered_(visit);

      lastTime = thisTime;
    }
  }
};

/**
 * Adds the text that shows the current interval, used for week and month
 * results.
 * @param {Element} resultsFragment The element to which the interval will be
 *     added to.
 * @private
 */
HistoryView.prototype.addTimeframeInterval_ = function(resultsFragment) {
  if (this.getRangeInDays() == HistoryModel.Range.ALL_TIME)
    return;

  // If this is a time range result add some text that shows what is the
  // time range for the results the user is viewing.
  var timeFrame = resultsFragment.appendChild(
      createElementWithClassName('h2', 'timeframe'));
  // TODO(sergiu): Figure the best way to show this for the first day of
  // the month.
  timeFrame.appendChild(document.createTextNode(loadTimeData.getStringF(
      'historyInterval',
      this.model_.queryStartTime,
      this.model_.queryEndTime)));
};

/**
 * Update the page with results.
 * @param {boolean} doneLoading Whether the current request is complete.
 * @private
 */
HistoryView.prototype.displayResults_ = function(doneLoading) {
  // Either show a page of results received for the all time results or all the
  // received results for the weekly and monthly view.
  var results = this.model_.visits_;
  if (this.getRangeInDays() == HistoryModel.Range.ALL_TIME) {
    var rangeStart = this.pageIndex_ * RESULTS_PER_PAGE;
    var rangeEnd = rangeStart + RESULTS_PER_PAGE;
    results = this.model_.getNumberedRange(rangeStart, rangeEnd);
  }
  var searchText = this.model_.getSearchText();
  var groupByDomain = this.model_.getGroupByDomain();

  if (searchText) {
    // Add a header for the search results, if there isn't already one.
    if (!this.resultDiv_.querySelector('h3')) {
      var header = document.createElement('h3');
      header.textContent = loadTimeData.getStringF('searchResultsFor',
                                                   searchText);
      this.resultDiv_.appendChild(header);
    }

    this.addTimeframeInterval_(this.resultDiv_);

    var searchResults = createElementWithClassName('ol', 'search-results');

    // Don't add checkboxes if entries can not be edited.
    if (!this.model_.editingEntriesAllowed)
      searchResults.classList.add('no-checkboxes');

    if (results.length == 0 && doneLoading) {
      var noSearchResults = searchResults.appendChild(
          createElementWithClassName('div', 'no-results-message'));
      noSearchResults.textContent = loadTimeData.getString('noSearchResults');
    } else {
      for (var i = 0, visit; visit = results[i]; i++) {
        if (!visit.isRendered) {
          searchResults.appendChild(visit.getResultDOM({
            isSearchResult: true,
            addTitleFavicon: true
          }));
          this.setVisitRendered_(visit);
        }
      }
    }
    this.resultDiv_.appendChild(searchResults);
  } else {
    var resultsFragment = document.createDocumentFragment();

    this.addTimeframeInterval_(resultsFragment);

    if (results.length == 0 && doneLoading) {
      var noResults = resultsFragment.appendChild(
          createElementWithClassName('div', 'no-results-message'));
      noResults.textContent = loadTimeData.getString('noResults');
      this.resultDiv_.appendChild(resultsFragment);
      this.updateNavBar_();
      return;
    }

    if (this.getRangeInDays() == HistoryModel.Range.MONTH &&
        groupByDomain) {
      // Group everything together in the month view.
      this.addMonthResults_(results, resultsFragment);
    } else {
      var dayStart = 0;
      var dayEnd = 0;
      // Go through all of the visits and process them in chunks of one day.
      while (dayEnd < results.length) {
        // Skip over the ones that are already rendered.
        while (dayStart < results.length && results[dayStart].isRendered)
          ++dayStart;
        var dayEnd = dayStart + 1;
        while (dayEnd < results.length && results[dayEnd].continued)
          ++dayEnd;

        this.addDayResults_(
            results.slice(dayStart, dayEnd), resultsFragment, groupByDomain);
      }
    }

    // Add all the days and their visits to the page.
    this.resultDiv_.appendChild(resultsFragment);
  }
  this.updateNavBar_();
};

/**
 * Update the visibility of the page navigation buttons.
 * @private
 */
HistoryView.prototype.updateNavBar_ = function() {
  this.updateRangeButtons_();
  if (!loadTimeData.getBoolean('isManagedProfile')) {
    // Managed users have the control bar on top, don't show it on the bottom
    // as well.
    $('newest-button').hidden = this.pageIndex_ == 0;
    $('newer-button').hidden = this.pageIndex_ == 0;
    $('older-button').hidden =
        this.model_.rangeInDays_ != HistoryModel.Range.ALL_TIME ||
        !this.model_.hasMoreResults();
  }
};

/**
 * Updates the visibility of the 'Clear browsing data' button.
 * Only used on mobile platforms.
 * @private
 */
HistoryView.prototype.updateClearBrowsingDataButton_ = function() {
  // Ideally, we should hide the 'Clear browsing data' button whenever the
  // soft keyboard is visible. This is not possible, so instead, hide the
  // button whenever the search field has focus.
  $('clear-browsing-data').hidden =
      (document.activeElement === $('search-field'));
};

///////////////////////////////////////////////////////////////////////////////
// State object:
/**
 * An 'AJAX-history' implementation.
 * @param {HistoryModel} model The model we're representing.
 * @param {HistoryView} view The view we're representing.
 * @constructor
 */
function PageState(model, view) {
  // Enforce a singleton.
  if (PageState.instance) {
    return PageState.instance;
  }

  this.model = model;
  this.view = view;

  if (typeof this.checker_ != 'undefined' && this.checker_) {
    clearInterval(this.checker_);
  }

  // TODO(glen): Replace this with a bound method so we don't need
  //     public model and view.
  this.checker_ = window.setInterval(function(stateObj) {
    var hashData = stateObj.getHashData();
    var page = parseInt(hashData.page, 10);
    var range = parseInt(hashData.range, 10);
    var offset = parseInt(hashData.offset, 10);
    if (hashData.q != stateObj.model.getSearchText() ||
        page != stateObj.view.getPage() ||
        range != stateObj.model.rangeInDays ||
        offset != stateObj.model.offset) {
      stateObj.view.setPageState(hashData.q, page, range, offset);
    }
  }, 50, this);
}

/**
 * Holds the singleton instance.
 */
PageState.instance = null;

/**
 * @return {Object} An object containing parameters from our window hash.
 */
PageState.prototype.getHashData = function() {
  var result = {
    q: '',
    page: 0,
    grouped: false,
    range: 0,
    offset: 0
  };

  if (!window.location.hash)
    return result;

  var hashSplit = window.location.hash.substr(1).split('&');
  for (var i = 0; i < hashSplit.length; i++) {
    var pair = hashSplit[i].split('=');
    if (pair.length > 1) {
      result[pair[0]] = decodeURIComponent(pair[1].replace(/\+/g, ' '));
    }
  }

  return result;
};

/**
 * Set the hash to a specified state, this will create an entry in the
 * session history so the back button cycles through hash states, which
 * are then picked up by our listener.
 * @param {string} term The current search string.
 * @param {number} page The page currently being viewed.
 * @param {HistoryModel.Range} range The range to view or search over.
 * @param {number} offset Set the begining of the query to the specific offset.
 */
PageState.prototype.setUIState = function(term, page, range, offset) {
  // Make sure the form looks pretty.
  $('search-field').value = term;
  var hash = this.getHashData();
  if (hash.q != term || hash.page != page || hash.range != range ||
      hash.offset != offset) {
    window.location.hash = PageState.getHashString(term, page, range, offset);
  }
};

/**
 * Static method to get the hash string for a specified state
 * @param {string} term The current search string.
 * @param {number} page The page currently being viewed.
 * @param {HistoryModel.Range} range The range to view or search over.
 * @param {number} offset Set the begining of the query to the specific offset.
 * @return {string} The string to be used in a hash.
 */
PageState.getHashString = function(term, page, range, offset) {
  // Omit elements that are empty.
  var newHash = [];

  if (term)
    newHash.push('q=' + encodeURIComponent(term));

  if (page)
    newHash.push('page=' + page);

  if (range)
    newHash.push('range=' + range);

  if (offset)
    newHash.push('offset=' + offset);

  return newHash.join('&');
};

///////////////////////////////////////////////////////////////////////////////
// Document Functions:
/**
 * Window onload handler, sets up the page.
 */
function load() {
  uber.onContentFrameLoaded();

  var searchField = $('search-field');

  historyModel = new HistoryModel();
  historyView = new HistoryView(historyModel);
  pageState = new PageState(historyModel, historyView);

  // Create default view.
  var hashData = pageState.getHashData();
  var grouped = (hashData.grouped == 'true') || historyModel.getGroupByDomain();
  var page = parseInt(hashData.page, 10) || historyView.getPage();
  var range = parseInt(hashData.range, 10) || historyView.getRangeInDays();
  var offset = parseInt(hashData.offset, 10) || historyView.getOffset();
  historyView.setPageState(hashData.q, page, range, offset);

  if ($('overlay')) {
    cr.ui.overlay.setupOverlay($('overlay'));
    cr.ui.overlay.globalInitialization();
  }
  HistoryFocusManager.getInstance().initialize();

  var doSearch = function(e) {
    recordUmaAction('HistoryPage_Search');
    historyView.setSearch(searchField.value);

    if (isMobileVersion())
      searchField.blur();  // Dismiss the keyboard.
  };

  var mayRemoveVisits = loadTimeData.getBoolean('allowDeletingHistory');
  $('remove-visit').disabled = !mayRemoveVisits;

  if (mayRemoveVisits) {
    $('remove-visit').addEventListener('activate', function(e) {
      activeVisit.removeFromHistory();
      activeVisit = null;
    });
  }

  if (!loadTimeData.getBoolean('showDeleteVisitUI'))
    $('remove-visit').hidden = true;

  searchField.addEventListener('search', doSearch);
  $('search-button').addEventListener('click', doSearch);

  $('more-from-site').addEventListener('activate', function(e) {
    activeVisit.showMoreFromSite_();
    activeVisit = null;
  });

  // Only show the controls if the command line switch is activated.
  if (loadTimeData.getBoolean('groupByDomain') ||
      loadTimeData.getBoolean('isManagedProfile')) {
    // Hide the top container which has the "Clear browsing data" and "Remove
    // selected entries" buttons since they're unavailable in managed mode
    $('top-container').hidden = true;
    $('history-page').classList.add('big-topbar-page');
    $('filter-controls').hidden = false;
  }

  var title = loadTimeData.getString('title');
  uber.invokeMethodOnParent('setTitle', {title: title});

  // Adjust the position of the notification bar when the window size changes.
  window.addEventListener('resize',
      historyView.positionNotificationBar.bind(historyView));

  cr.ui.FocusManager.disableMouseFocusOnButtons();

  if (isMobileVersion()) {
    if (searchField) {
      // Move the search box out of the header.
      var resultsDisplay = $('results-display');
      resultsDisplay.parentNode.insertBefore($('search-field'), resultsDisplay);

      window.addEventListener(
          'resize', historyView.updateClearBrowsingDataButton_);

      // When the search field loses focus, add a delay before updating the
      // visibility, otherwise the button will flash on the screen before the
      // keyboard animates away.
      searchField.addEventListener('blur', function() {
        setTimeout(historyView.updateClearBrowsingDataButton_, 250);
      });
    }

    // Move the button to the bottom of the body.
    document.body.appendChild($('clear-browsing-data'));
  } else {
    window.addEventListener('message', function(e) {
      if (e.data.method == 'frameSelected')
        searchField.focus();
    });
    searchField.focus();
  }
}

/**
 * Updates the managed filter status labels of a host/URL entry to the current
 * value.
 * @param {Element} statusElement The div which contains the status labels.
 * @param {ManagedModeFilteringBehavior} newStatus The filter status of the
 *     current domain/URL.
 */
function updateHostStatus(statusElement, newStatus) {
  var filteringBehaviorDiv =
      statusElement.querySelector('.filtering-behavior');
  // Reset to the base class first, then add modifier classes if needed.
  filteringBehaviorDiv.className = 'filtering-behavior';
  if (newStatus == ManagedModeFilteringBehavior.BLOCK) {
    filteringBehaviorDiv.textContent =
        loadTimeData.getString('filterBlocked');
    filteringBehaviorDiv.classList.add('filter-blocked');
  } else {
    filteringBehaviorDiv.textContent = '';
  }
}

/**
 * Click handler for the 'Clear browsing data' dialog.
 * @param {Event} e The click event.
 */
function openClearBrowsingData(e) {
  recordUmaAction('HistoryPage_InitClearBrowsingData');
  chrome.send('clearBrowsingData');
}

/**
 * Shows the dialog for the user to confirm removal of selected history entries.
 */
function showConfirmationOverlay() {
  $('alertOverlay').classList.add('showing');
  $('overlay').hidden = false;
  uber.invokeMethodOnParent('beginInterceptingEvents');
}

/**
 * Hides the confirmation overlay used to confirm selected history entries.
 */
function hideConfirmationOverlay() {
  $('alertOverlay').classList.remove('showing');
  $('overlay').hidden = true;
  uber.invokeMethodOnParent('stopInterceptingEvents');
}

/**
 * Shows the confirmation alert for history deletions and permits browser tests
 * to override the dialog.
 * @param {function=} okCallback A function to be called when the user presses
 *     the ok button.
 * @param {function=} cancelCallback A function to be called when the user
 *     presses the cancel button.
 */
function confirmDeletion(okCallback, cancelCallback) {
  alertOverlay.setValues(
      loadTimeData.getString('removeSelected'),
      loadTimeData.getString('deleteWarning'),
      loadTimeData.getString('cancel'),
      loadTimeData.getString('deleteConfirm'),
      cancelCallback,
      okCallback);
  showConfirmationOverlay();
}

/**
 * Click handler for the 'Remove selected items' button.
 * Confirms the deletion with the user, and then deletes the selected visits.
 */
function removeItems() {
  recordUmaAction('HistoryPage_RemoveSelected');
  if (!loadTimeData.getBoolean('allowDeletingHistory'))
    return;

  var checked = $('results-display').querySelectorAll(
      '.entry-box input[type=checkbox]:checked:not([disabled])');
  var disabledItems = [];
  var toBeRemoved = [];

  for (var i = 0; i < checked.length; i++) {
    var checkbox = checked[i];
    var entry = findAncestorByClass(checkbox, 'entry');
    toBeRemoved.push(entry.visit);

    // Disable the checkbox and put a strikethrough style on the link, so the
    // user can see what will be deleted.
    var link = entry.querySelector('a');
    checkbox.disabled = true;
    link.classList.add('to-be-removed');
    disabledItems.push(checkbox);
    var integerId = parseInt(entry.visit.id_, 10);
    // Record the ID of the entry to signify how many entries are above this
    // link on the page.
    recordUmaHistogram('HistoryPage.RemoveEntryPosition',
                       UMA_MAX_BUCKET_VALUE,
                       integerId);
    if (integerId <= UMA_MAX_SUBSET_BUCKET_VALUE) {
      recordUmaHistogram('HistoryPage.RemoveEntryPositionSubset',
                         UMA_MAX_SUBSET_BUCKET_VALUE,
                         integerId);
    }
    if (entry.parentNode.className == 'search-results')
      recordUmaAction('HistoryPage_SearchResultRemove');
  }

  function onConfirmRemove() {
    recordUmaAction('HistoryPage_ConfirmRemoveSelected');
    historyModel.removeVisitsFromHistory(toBeRemoved,
        historyView.reload.bind(historyView));
    $('overlay').removeEventListener('cancelOverlay', onCancelRemove);
    hideConfirmationOverlay();
  }

  function onCancelRemove() {
    recordUmaAction('HistoryPage_CancelRemoveSelected');
    // Return everything to its previous state.
    for (var i = 0; i < disabledItems.length; i++) {
      var checkbox = disabledItems[i];
      checkbox.disabled = false;

      var entryBox = findAncestorByClass(checkbox, 'entry-box');
      entryBox.querySelector('a').classList.remove('to-be-removed');
    }
    $('overlay').removeEventListener('cancelOverlay', onCancelRemove);
    hideConfirmationOverlay();
  }

  if (checked.length) {
    confirmDeletion(onConfirmRemove, onCancelRemove);
    $('overlay').addEventListener('cancelOverlay', onCancelRemove);
  }
}

/**
 * Handler for the 'click' event on a checkbox.
 * @param {Event} e The click event.
 */
function checkboxClicked(e) {
  handleCheckboxStateChange(e.currentTarget, e.shiftKey);
}

/**
 * Post-process of checkbox state change. This handles range selection and
 * updates internal state.
 * @param {!HTMLInputElement} checkbox Clicked checkbox.
 * @param {boolean} shiftKey true if shift key is pressed.
 */
function handleCheckboxStateChange(checkbox, shiftKey) {
  updateParentCheckbox(checkbox);
  var id = Number(checkbox.id.slice('checkbox-'.length));
  // Handle multi-select if shift was pressed.
  if (shiftKey && (selectionAnchor != -1)) {
    var checked = checkbox.checked;
    // Set all checkboxes from the anchor up to the clicked checkbox to the
    // state of the clicked one.
    var begin = Math.min(id, selectionAnchor);
    var end = Math.max(id, selectionAnchor);
    for (var i = begin; i <= end; i++) {
      var checkbox = document.querySelector('#checkbox-' + i);
      if (checkbox) {
        checkbox.checked = checked;
        updateParentCheckbox(checkbox);
      }
    }
  }
  selectionAnchor = id;

  historyView.updateSelectionEditButtons();
}

/**
 * Handler for the 'click' event on a domain checkbox. Checkes or unchecks the
 * checkboxes of the visits to this domain in the respective group.
 * @param {Event} e The click event.
 */
function domainCheckboxClicked(e) {
  var siteEntry = findAncestorByClass(e.currentTarget, 'site-entry');
  var checkboxes =
      siteEntry.querySelectorAll('.site-results input[type=checkbox]');
  for (var i = 0; i < checkboxes.length; i++)
    checkboxes[i].checked = e.currentTarget.checked;
  historyView.updateSelectionEditButtons();
  // Stop propagation as clicking the checkbox would otherwise trigger the
  // group to collapse/expand.
  e.stopPropagation();
}

/**
 * Updates the domain checkbox for this visit checkbox if it has been
 * unchecked.
 * @param {Element} checkbox The checkbox that has been clicked.
 */
function updateParentCheckbox(checkbox) {
  if (checkbox.checked)
    return;

  var entry = findAncestorByClass(checkbox, 'site-entry');
  if (!entry)
    return;

  var groupCheckbox = entry.querySelector('.site-domain-wrapper input');
  if (groupCheckbox)
      groupCheckbox.checked = false;
}

function entryBoxMousedown(event) {
  // Prevent text selection when shift-clicking to select multiple entries.
  if (event.shiftKey)
    event.preventDefault();
}

/**
 * Handle click event for entryBox labels.
 * @param {!MouseEvent} event A click event.
 */
function entryBoxClick(event) {
  // Do nothing if a bookmark star is clicked.
  if (event.defaultPrevented)
    return;
  var element = event.target;
  // Do nothing if the event happened in an interactive element.
  for (; element != event.currentTarget; element = element.parentNode) {
    switch (element.tagName) {
      case 'A':
      case 'BUTTON':
      case 'INPUT':
        return;
    }
  }
  var checkbox = event.currentTarget.control;
  checkbox.checked = !checkbox.checked;
  handleCheckboxStateChange(checkbox, event.shiftKey);
  // We don't want to focus on the checkbox.
  event.preventDefault();
}

// This is pulled out so we can wait for it in tests.
function removeNodeWithoutTransition(node) {
  node.parentNode.removeChild(node);
}

/**
 * Triggers a fade-out animation, and then removes |node| from the DOM.
 * @param {Node} node The node to be removed.
 * @param {Function?} onRemove A function to be called after the node
 *     has been removed from the DOM.
 */
function removeNode(node, onRemove) {
  node.classList.add('fade-out'); // Trigger CSS fade out animation.

  // Delete the node when the animation is complete.
  node.addEventListener('webkitTransitionEnd', function() {
    removeNodeWithoutTransition(node);
    if (onRemove)
      onRemove();
  });
}

/**
 * Removes a single entry from the view. Also removes gaps before and after
 * entry if necessary.
 * @param {Node} entry The DOM node representing the entry to be removed.
 */
function removeEntryFromView(entry) {
  var nextEntry = entry.nextSibling;
  var previousEntry = entry.previousSibling;

  removeNode(entry, function() {
    historyView.updateSelectionEditButtons();
  });

  // if there is no previous entry, and the next entry is a gap, remove it
  if (!previousEntry && nextEntry && nextEntry.className == 'gap')
    removeNode(nextEntry);

  // if there is no next entry, and the previous entry is a gap, remove it
  if (!nextEntry && previousEntry && previousEntry.className == 'gap')
    removeNode(previousEntry);

  // if both the next and previous entries are gaps, remove one
  if (nextEntry && nextEntry.className == 'gap' &&
      previousEntry && previousEntry.className == 'gap') {
    removeNode(nextEntry);
  }
}

/**
 * Toggles an element in the grouped history.
 * @param {Element} e The element which was clicked on.
 */
function toggleHandler(e) {
  var innerResultList = e.currentTarget.parentElement.querySelector(
      '.site-results');
  var innerArrow = e.currentTarget.parentElement.querySelector(
      '.site-domain-arrow');
  if (innerArrow.classList.contains('collapse')) {
    innerResultList.style.height = 'auto';
    // -webkit-transition does not work on height:auto elements so first set
    // the height to auto so that it is computed and then set it to the
    // computed value in pixels so the transition works properly.
    var height = innerResultList.clientHeight;
    innerResultList.style.height = height + 'px';
    innerArrow.classList.remove('collapse');
    innerArrow.classList.add('expand');
  } else {
    innerResultList.style.height = 0;
    innerArrow.classList.remove('expand');
    innerArrow.classList.add('collapse');
  }
}

/**
 * Builds the DOM elements to show the managed status of a domain/URL.
 * @param {ManagedModeFilteringBehavior} filteringBehavior The filter behavior
 *     for this item.
 * @return {Element} Returns the DOM elements which show the status.
 */
function getManagedStatusDOM(filteringBehavior) {
  var filterStatusDiv = createElementWithClassName('div', 'filter-status');
  var filteringBehaviorDiv =
      createElementWithClassName('div', 'filtering-behavior');
  filterStatusDiv.appendChild(filteringBehaviorDiv);

  updateHostStatus(filterStatusDiv, filteringBehavior);
  return filterStatusDiv;
}


///////////////////////////////////////////////////////////////////////////////
// Chrome callbacks:

/**
 * Our history system calls this function with results from searches.
 * @param {Object} info An object containing information about the query.
 * @param {Array} results A list of results.
 */
function historyResult(info, results) {
  historyModel.addResults(info, results);
}

/**
 * Called by the history backend when history removal is successful.
 */
function deleteComplete() {
  historyModel.deleteComplete();
}

/**
 * Called by the history backend when history removal is unsuccessful.
 */
function deleteFailed() {
  window.console.log('Delete failed');
}

/**
 * Called when the history is deleted by someone else.
 */
function historyDeleted() {
  var anyChecked = document.querySelector('.entry input:checked') != null;
  // Reload the page, unless the user has any items checked.
  // TODO(dubroy): We should just reload the page & restore the checked items.
  if (!anyChecked)
    historyView.reload();
}

// Add handlers to HTML elements.
document.addEventListener('DOMContentLoaded', load);

// This event lets us enable and disable menu items before the menu is shown.
document.addEventListener('canExecute', function(e) {
  e.canExecute = true;
});
