Moves some utility functions out of bookmark model into
bookmark_utils. In addition I've converted to using
TreeNodeIterator. This doesn't contain any functionality changes.

BUG=4065
TEST=none

Review URL: http://codereview.chromium.org/13642

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6589 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/bookmarks/bookmark_utils.cc b/chrome/browser/bookmarks/bookmark_utils.cc
index 9e0b7c8..1a25556a 100644
--- a/chrome/browser/bookmarks/bookmark_utils.cc
+++ b/chrome/browser/bookmarks/bookmark_utils.cc
@@ -4,16 +4,19 @@
 
 #include "chrome/browser/bookmarks/bookmark_utils.h"
 
+#include "base/time.h"
 #include "chrome/browser/bookmarks/bookmark_drag_data.h"
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/browser.h"
 #include "chrome/browser/browser_list.h"
+#include "chrome/browser/history/query_parser.h"
 #include "chrome/browser/page_navigator.h"
 #include "chrome/browser/tab_contents.h"
 #include "chrome/common/drag_drop_types.h"
 #include "chrome/common/l10n_util.h"
 #include "chrome/common/os_exchange_data.h"
 #include "chrome/views/event.h"
+#include "chrome/views/tree_node_iterator.h"
 
 #include "chromium_strings.h"
 #include "generated_resources.h"
@@ -138,6 +141,11 @@
                     MB_YESNO | MB_ICONWARNING | MB_TOPMOST) == IDYES;
 }
 
+// Comparison function that compares based on date modified of the two nodes.
+bool MoreRecentlyModified(BookmarkNode* n1, BookmarkNode* n2) {
+  return n1->date_group_modified() > n2->date_group_modified();
+}
+
 }  // namespace
 
 namespace bookmark_utils {
@@ -289,4 +297,110 @@
   return bookmark_data.Read(data_wrapper);
 }
 
+std::vector<BookmarkNode*> GetMostRecentlyModifiedGroups(
+    BookmarkModel* model,
+    size_t max_count) {
+  std::vector<BookmarkNode*> nodes;
+  views::TreeNodeIterator<BookmarkNode> iterator(model->root_node());
+  while (iterator.has_next()) {
+    BookmarkNode* parent = iterator.Next();
+    if (parent->is_folder() && parent->date_group_modified() > base::Time()) {
+      if (max_count == 0) {
+        nodes.push_back(parent);
+      } else {
+        std::vector<BookmarkNode*>::iterator i =
+            std::upper_bound(nodes.begin(), nodes.end(), parent,
+                             &MoreRecentlyModified);
+        if (nodes.size() < max_count || i != nodes.end()) {
+          nodes.insert(i, parent);
+          while (nodes.size() > max_count)
+            nodes.pop_back();
+        }
+      }
+    }  // else case, the root node, which we don't care about or imported nodes
+       // (which have a time of 0).
+  }
+
+  if (nodes.size() < max_count) {
+    // Add the bookmark bar and other nodes if there is space.
+    if (find(nodes.begin(), nodes.end(), model->GetBookmarkBarNode()) ==
+        nodes.end()) {
+      nodes.push_back(model->GetBookmarkBarNode());
+    }
+
+    if (nodes.size() < max_count &&
+        find(nodes.begin(), nodes.end(), model->other_node()) == nodes.end()) {
+      nodes.push_back(model->other_node());
+    }
+  }
+  return nodes;
+}
+
+void GetMostRecentlyAddedEntries(BookmarkModel* model,
+                                 size_t count,
+                                 std::vector<BookmarkNode*>* nodes) {
+  views::TreeNodeIterator<BookmarkNode> iterator(model->root_node());
+  while (iterator.has_next()) {
+    BookmarkNode* node = iterator.Next();
+    if (node->is_url()) {
+      std::vector<BookmarkNode*>::iterator insert_position =
+          std::upper_bound(nodes->begin(), nodes->end(), node,
+                           &MoreRecentlyAdded);
+      if (nodes->size() < count || insert_position != nodes->end()) {
+        nodes->insert(insert_position, node);
+        while (nodes->size() > count)
+          nodes->pop_back();
+      }
+    }
+  }
+}
+
+void GetBookmarksMatchingText(BookmarkModel* model,
+                              const std::wstring& text,
+                              size_t max_count,
+                              std::vector<TitleMatch>* matches) {
+  QueryParser parser;
+  ScopedVector<QueryNode> query_nodes;
+  parser.ParseQuery(text, &query_nodes.get());
+  if (query_nodes.empty())
+    return;
+
+  views::TreeNodeIterator<BookmarkNode> iterator(model->root_node());
+  Snippet::MatchPositions match_position;
+  while (iterator.has_next()) {
+    BookmarkNode* node = iterator.Next();
+    if (node->GetURL().spec() == "http://www.google.com/") {
+      DLOG(INFO) << "BLAH";
+    }
+    if (node->is_url() &&
+        parser.DoesQueryMatch(node->GetTitle(), query_nodes.get(),
+                              &match_position)) {
+      matches->push_back(TitleMatch());
+      matches->back().node = node;
+      matches->back().match_positions.swap(match_position);
+      if (matches->size() == max_count)
+        break;
+    }
+  }
+}
+
+bool DoesBookmarkMatchText(const std::wstring& text, BookmarkNode* node) {
+  if (!node->is_url())
+    return false;
+
+  QueryParser parser;
+  ScopedVector<QueryNode> query_nodes;
+  parser.ParseQuery(text, &query_nodes.get());
+  if (query_nodes.empty())
+    return false;
+
+  Snippet::MatchPositions match_position;
+  return parser.DoesQueryMatch(node->GetTitle(), query_nodes.get(),
+                               &match_position);
+}
+
+bool MoreRecentlyAdded(BookmarkNode* n1, BookmarkNode* n2) {
+  return n1->date_added() > n2->date_added();
+}
+
 }  // namespace bookmark_utils