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

#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"

#include "base/mac/bundle_locations.h"
#include "base/mac/mac_util.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h"
#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/themes/theme_service.h"
#import "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/bookmarks/bookmark_editor.h"
#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/chrome_pages.h"
#import "chrome/browser/ui/cocoa/background_gradient_view.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_window.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_context_menu_cocoa_controller.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_folder_target.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_name_folder_controller.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h"
#import "chrome/browser/ui/cocoa/menu_button.h"
#import "chrome/browser/ui/cocoa/presentation_mode_controller.h"
#import "chrome/browser/ui/cocoa/themed_window.h"
#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
#import "chrome/browser/ui/cocoa/view_id_util.h"
#import "chrome/browser/ui/cocoa/view_resizer.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "grit/ui_resources.h"
#import "ui/base/cocoa/cocoa_event_utils.h"
#include "ui/base/l10n/l10n_util_mac.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"

using content::OpenURLParams;
using content::Referrer;
using content::UserMetricsAction;
using content::WebContents;

// Bookmark bar state changing and animations
//
// The bookmark bar has three real states: "showing" (a normal bar attached to
// the toolbar), "hidden", and "detached" (pretending to be part of the web
// content on the NTP). It can, or at least should be able to, animate between
// these states. There are several complications even without animation:
//  - The placement of the bookmark bar is done by the BWC, and it needs to know
//    the state in order to place the bookmark bar correctly (immediately below
//    the toolbar when showing, below the infobar when detached).
//  - The "divider" (a black line) needs to be drawn by either the toolbar (when
//    the bookmark bar is hidden or detached) or by the bookmark bar (when it is
//    showing). It should not be drawn by both.
//  - The toolbar needs to vertically "compress" when the bookmark bar is
//    showing. This ensures the proper display of both the bookmark bar and the
//    toolbar, and gives a padded area around the bookmark bar items for right
//    clicks, etc.
//
// Our model is that the BWC controls us and also the toolbar. We try not to
// talk to the browser nor the toolbar directly, instead centralizing control in
// the BWC. The key method by which the BWC controls us is
// |-updateState:ChangeType:|. This invokes state changes, and at appropriate
// times we request that the BWC do things for us via either the resize delegate
// or our general delegate. If the BWC needs any information about what it
// should do, or tell the toolbar to do, it can then query us back (e.g.,
// |-isShownAs...|, |-getDesiredToolbarHeightCompression|,
// |-toolbarDividerOpacity|, etc.).
//
// Animation-related complications:
//  - Compression of the toolbar is touchy during animation. It must not be
//    compressed while the bookmark bar is animating to/from showing (from/to
//    hidden), otherwise it would look like the bookmark bar's contents are
//    sliding out of the controls inside the toolbar. As such, we have to make
//    sure that the bookmark bar is shown at the right location and at the
//    right height (at various points in time).
//  - Showing the divider is also complicated during animation between hidden
//    and showing. We have to make sure that the toolbar does not show the
//    divider despite the fact that it's not compressed. The exception to this
//    is at the beginning/end of the animation when the toolbar is still
//    uncompressed but the bookmark bar has height 0. If we're not careful, we
//    get a flicker at this point.
//  - We have to ensure that we do the right thing if we're told to change state
//    while we're running an animation. The generic/easy thing to do is to jump
//    to the end state of our current animation, and (if the new state change
//    again involves an animation) begin the new animation. We can do better
//    than that, however, and sometimes just change the current animation to go
//    to the new end state (e.g., by "reversing" the animation in the showing ->
//    hidden -> showing case). We also have to ensure that demands to
//    immediately change state are always honoured.
//
// Pointers to animation logic:
//  - |-moveToState:withAnimation:| starts animations, deciding which ones we
//    know how to handle.
//  - |-doBookmarkBarAnimation| has most of the actual logic.
//  - |-getDesiredToolbarHeightCompression| and |-toolbarDividerOpacity| contain
//    related logic.
//  - The BWC's |-layoutSubviews| needs to know how to position things.
//  - The BWC should implement |-bookmarkBar:didChangeFromState:toState:| and
//    |-bookmarkBar:willAnimateFromState:toState:| in order to inform the
//    toolbar of required changes.

namespace {

// Duration of the bookmark bar animations.
const NSTimeInterval kBookmarkBarAnimationDuration = 0.12;

void RecordAppLaunch(Profile* profile, GURL url) {
  DCHECK(profile->GetExtensionService());
  const extensions::Extension* extension =
      profile->GetExtensionService()->GetInstalledApp(url);
  if (!extension)
    return;

  CoreAppLauncherHandler::RecordAppLaunchType(
      extension_misc::APP_LAUNCH_BOOKMARK_BAR,
      extension->GetType());
}

}  // namespace

@interface BookmarkBarController(Private)

// Moves to the given next state (from the current state), possibly animating.
// If |animate| is NO, it will stop any running animation and jump to the given
// state. If YES, it may either (depending on implementation) jump to the end of
// the current animation and begin the next one, or stop the current animation
// mid-flight and animate to the next state.
- (void)moveToState:(BookmarkBar::State)nextState
      withAnimation:(BOOL)animate;

// Return the backdrop to the bookmark bar as various types.
- (BackgroundGradientView*)backgroundGradientView;
- (AnimatableView*)animatableView;

// Create buttons for all items in the given bookmark node tree.
// Modifies self->buttons_.  Do not add more buttons than will fit on the view.
- (void)addNodesToButtonList:(const BookmarkNode*)node;

// Create an autoreleased button appropriate for insertion into the bookmark
// bar. Update |xOffset| with the offset appropriate for the subsequent button.
- (BookmarkButton*)buttonForNode:(const BookmarkNode*)node
                         xOffset:(int*)xOffset;

// Puts stuff into the final state without animating, stopping a running
// animation if necessary.
- (void)finalizeState;

// Stops any current animation in its tracks (midway).
- (void)stopCurrentAnimation;

// Show/hide the bookmark bar.
// if |animate| is YES, the changes are made using the animator; otherwise they
// are made immediately.
- (void)showBookmarkBarWithAnimation:(BOOL)animate;

// Handles animating the resize of the content view. Returns YES if it handled
// the animation, NO if not (and hence it should be done instantly).
- (BOOL)doBookmarkBarAnimation;

// |point| is in the base coordinate system of the destination window;
// it comes from an id<NSDraggingInfo>. |copy| is YES if a copy is to be
// made and inserted into the new location while leaving the bookmark in
// the old location, otherwise move the bookmark by removing from its old
// location and inserting into the new location.
- (BOOL)dragBookmark:(const BookmarkNode*)sourceNode
                  to:(NSPoint)point
                copy:(BOOL)copy;

// Returns the index in the model for a drag to the location given by
// |point|. This is determined by finding the first button before the center
// of which |point| falls, scanning left to right. Note that, currently, only
// the x-coordinate of |point| is considered. Though not currently implemented,
// we may check for errors, in which case this would return negative value;
// callers should check for this.
- (int)indexForDragToPoint:(NSPoint)point;

// Add or remove buttons to/from the bar until it is filled but not overflowed.
- (void)redistributeButtonsOnBarAsNeeded;

// Determine the nature of the bookmark bar contents based on the number of
// buttons showing. If too many then show the off-the-side list, if none
// then show the no items label.
- (void)reconfigureBookmarkBar;

- (void)addNode:(const BookmarkNode*)child toMenu:(NSMenu*)menu;
- (void)addFolderNode:(const BookmarkNode*)node toMenu:(NSMenu*)menu;
- (void)tagEmptyMenu:(NSMenu*)menu;
- (void)clearMenuTagMap;
- (int)preferredHeight;
- (void)addButtonsToView;
- (BOOL)setOtherBookmarksButtonVisibility;
- (BOOL)setAppsPageShortcutButtonVisibility;
- (BookmarkButton*)customBookmarkButtonForCell:(NSCell*)cell;
- (void)createOtherBookmarksButton;
- (void)createAppsPageShortcutButton;
- (void)openAppsPage:(id)sender;
- (void)centerNoItemsLabel;
- (void)positionRightSideButtons;
- (void)watchForExitEvent:(BOOL)watch;
- (void)resetAllButtonPositionsWithAnimation:(BOOL)animate;

@end

@implementation BookmarkBarController

@synthesize currentState = currentState_;
@synthesize lastState = lastState_;
@synthesize isAnimationRunning = isAnimationRunning_;
@synthesize delegate = delegate_;
@synthesize stateAnimationsEnabled = stateAnimationsEnabled_;
@synthesize innerContentAnimationsEnabled = innerContentAnimationsEnabled_;

- (id)initWithBrowser:(Browser*)browser
         initialWidth:(CGFloat)initialWidth
             delegate:(id<BookmarkBarControllerDelegate>)delegate
       resizeDelegate:(id<ViewResizer>)resizeDelegate {
  if ((self = [super initWithNibName:@"BookmarkBar"
                              bundle:base::mac::FrameworkBundle()])) {
    currentState_ = BookmarkBar::HIDDEN;
    lastState_ = BookmarkBar::HIDDEN;

    browser_ = browser;
    initialWidth_ = initialWidth;
    bookmarkModel_ = BookmarkModelFactory::GetForProfile(browser_->profile());
    buttons_.reset([[NSMutableArray alloc] init]);
    delegate_ = delegate;
    resizeDelegate_ = resizeDelegate;
    folderTarget_.reset([[BookmarkFolderTarget alloc] initWithController:self]);

    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    folderImage_.reset(
        rb.GetNativeImageNamed(IDR_BOOKMARK_BAR_FOLDER).CopyNSImage());
    defaultImage_.reset(
        rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).CopyNSImage());

    innerContentAnimationsEnabled_ = YES;
    stateAnimationsEnabled_ = YES;

    // Register for theme changes, bookmark button pulsing, ...
    NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
    [defaultCenter addObserver:self
                      selector:@selector(themeDidChangeNotification:)
                          name:kBrowserThemeDidChangeNotification
                        object:nil];
    [defaultCenter addObserver:self
                      selector:@selector(pulseBookmarkNotification:)
                          name:bookmark_button::kPulseBookmarkButtonNotification
                        object:nil];

    contextMenuController_.reset(
        [[BookmarkContextMenuCocoaController alloc]
            initWithBookmarkBarController:self]);

    // This call triggers an -awakeFromNib, which builds the bar, which might
    // use |folderImage_| and |contextMenuController_|. Ensure it happens after
    // |folderImage_| is loaded and |contextMenuController_| is created.
    [[self animatableView] setResizeDelegate:resizeDelegate];
  }
  return self;
}

- (Browser*)browser {
  return browser_;
}

- (BookmarkContextMenuCocoaController*)menuController {
  return contextMenuController_.get();
}

- (void)pulseBookmarkNotification:(NSNotification*)notification {
  NSDictionary* dict = [notification userInfo];
  const BookmarkNode* node = NULL;
  NSValue *value = [dict objectForKey:bookmark_button::kBookmarkKey];
  DCHECK(value);
  if (value)
    node = static_cast<const BookmarkNode*>([value pointerValue]);
  NSNumber* number = [dict objectForKey:bookmark_button::kBookmarkPulseFlagKey];
  DCHECK(number);
  BOOL doPulse = number ? [number boolValue] : NO;

  // 3 cases:
  // button on the bar: flash it
  // button in "other bookmarks" folder: flash other bookmarks
  // button in "off the side" folder: flash the chevron
  for (BookmarkButton* button in [self buttons]) {
    if ([button bookmarkNode] == node) {
      [button setIsContinuousPulsing:doPulse];
      return;
    }
  }
  if ([otherBookmarksButton_ bookmarkNode] == node) {
    [otherBookmarksButton_ setIsContinuousPulsing:doPulse];
    return;
  }
  if (node->parent() == bookmarkModel_->bookmark_bar_node()) {
    [offTheSideButton_ setIsContinuousPulsing:doPulse];
    return;
  }

  NOTREACHED() << "no bookmark button found to pulse!";
}

- (void)dealloc {
  // Clear delegate so it doesn't get called during stopAnimation.
  [[self animatableView] setResizeDelegate:nil];

  // We better stop any in-flight animation if we're being killed.
  [[self animatableView] stopAnimation];

  // Remove our view from its superview so it doesn't attempt to reference
  // it when the controller is gone.
  //TODO(dmaclach): Remove -- http://crbug.com/25845
  [[self view] removeFromSuperview];

  // Be sure there is no dangling pointer.
  if ([[self view] respondsToSelector:@selector(setController:)])
    [[self view] performSelector:@selector(setController:) withObject:nil];

  // For safety, make sure the buttons can no longer call us.
  for (BookmarkButton* button in buttons_.get()) {
    [button setDelegate:nil];
    [button setTarget:nil];
    [button setAction:nil];
  }

  bridge_.reset(NULL);
  [[NSNotificationCenter defaultCenter] removeObserver:self];
  [self watchForExitEvent:NO];
  [super dealloc];
}

- (void)awakeFromNib {
  // We default to NOT open, which means height=0.
  DCHECK([[self view] isHidden]);  // Hidden so it's OK to change.

  // Set our initial height to zero, since that is what the superview
  // expects.  We will resize ourselves open later if needed.
  [[self view] setFrame:NSMakeRect(0, 0, initialWidth_, 0)];

  // Complete init of the "off the side" button, as much as we can.
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  [offTheSideButton_ setImage:
        rb.GetNativeImageNamed(IDR_BOOKMARK_BAR_CHEVRONS).ToNSImage()];
  [offTheSideButton_.draggableButton setDraggable:NO];
  [offTheSideButton_.draggableButton setActsOnMouseDown:YES];

  // We are enabled by default.
  barIsEnabled_ = YES;

  // Remember the original sizes of the 'no items' and 'import bookmarks'
  // fields to aid in resizing when the window frame changes.
  originalNoItemsRect_ = [[buttonView_ noItemTextfield] frame];
  originalImportBookmarksRect_ = [[buttonView_ importBookmarksButton] frame];

  // To make life happier when the bookmark bar is floating, the chevron is a
  // child of the button view.
  [offTheSideButton_ removeFromSuperview];
  [buttonView_ addSubview:offTheSideButton_];

  // When resized we may need to add new buttons, or remove them (if
  // no longer visible), or add/remove the "off the side" menu.
  [[self view] setPostsFrameChangedNotifications:YES];
  [[NSNotificationCenter defaultCenter]
    addObserver:self
       selector:@selector(frameDidChange)
           name:NSViewFrameDidChangeNotification
         object:[self view]];

  // Watch for things going to or from fullscreen.
  [[NSNotificationCenter defaultCenter]
    addObserver:self
       selector:@selector(willEnterOrLeaveFullscreen:)
           name:kWillEnterFullscreenNotification
         object:nil];
  [[NSNotificationCenter defaultCenter]
    addObserver:self
       selector:@selector(willEnterOrLeaveFullscreen:)
           name:kWillLeaveFullscreenNotification
         object:nil];

  // Don't pass ourself along (as 'self') until our init is completely
  // done.  Thus, this call is (almost) last.
  bridge_.reset(new BookmarkBarBridge(browser_->profile(), self,
                                      bookmarkModel_));
}

// Called by our main view (a BookmarkBarView) when it gets moved to a
// window.  We perform operations which need to know the relevant
// window (e.g. watch for a window close) so they can't be performed
// earlier (such as in awakeFromNib).
- (void)viewDidMoveToWindow {
  NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];

  // Remove any existing notifications before registering for new ones.
  [defaultCenter removeObserver:self
                           name:NSWindowWillCloseNotification
                         object:nil];
  [defaultCenter removeObserver:self
                           name:NSWindowDidResignMainNotification
                         object:nil];

  [defaultCenter addObserver:self
                    selector:@selector(parentWindowWillClose:)
                        name:NSWindowWillCloseNotification
                      object:[[self view] window]];
  [defaultCenter addObserver:self
                    selector:@selector(parentWindowDidResignMain:)
                        name:NSWindowDidResignMainNotification
                      object:[[self view] window]];
}

// When going fullscreen we can run into trouble.  Our view is removed
// from the non-fullscreen window before the non-fullscreen window
// loses key, so our parentDidResignKey: callback never gets called.
// In addition, a bookmark folder controller needs to be autoreleased
// (in case it's in the event chain when closed), but the release
// implicitly needs to happen while it's connected to the original
// (non-fullscreen) window to "unlock bar visibility".  Such a
// contract isn't honored when going fullscreen with the menu option
// (not with the keyboard shortcut).  We fake it as best we can here.
// We have a similar problem leaving fullscreen.
- (void)willEnterOrLeaveFullscreen:(NSNotification*)notification {
  if (folderController_) {
    [self childFolderWillClose:folderController_];
    [self closeFolderAndStopTrackingMenus];
  }
}

// NSNotificationCenter callback.
- (void)parentWindowWillClose:(NSNotification*)notification {
  [self closeFolderAndStopTrackingMenus];
}

// NSNotificationCenter callback.
- (void)parentWindowDidResignMain:(NSNotification*)notification {
  [self closeFolderAndStopTrackingMenus];
}

// Change the layout of the bookmark bar's subviews in response to a visibility
// change (e.g., show or hide the bar) or style change (attached or floating).
- (void)layoutSubviews {
  NSRect frame = [[self view] frame];
  NSRect buttonViewFrame = NSMakeRect(0, 0, NSWidth(frame), NSHeight(frame));

  // Add padding to the detached bookmark bar.
  // The state of our morph (if any); 1 is total bubble, 0 is the regular bar.
  CGFloat morph = [self detachedMorphProgress];
  CGFloat padding = bookmarks::kNTPBookmarkBarPadding;
  buttonViewFrame =
      NSInsetRect(buttonViewFrame, morph * padding, morph * padding);

  [buttonView_ setFrame:buttonViewFrame];

  // Update bookmark button backgrounds.
  if ([self isAnimationRunning]) {
    for (NSButton* button in buttons_.get())
      [button setNeedsDisplay:YES];
  }
}

// We don't change a preference; we only change visibility. Preference changing
// (global state) is handled in |BrowserWindowCocoa::ToggleBookmarkBar()|. We
// simply update based on what we're told.
- (void)updateVisibility {
  [self showBookmarkBarWithAnimation:NO];
}

- (void)updateAppsPageShortcutButtonVisibility {
  if (!appsPageShortcutButton_.get())
    return;
  [self setAppsPageShortcutButtonVisibility];
  [self resetAllButtonPositionsWithAnimation:NO];
  [self reconfigureBookmarkBar];
}

- (void)updateHiddenState {
  BOOL oldHidden = [[self view] isHidden];
  BOOL newHidden = ![self isVisible];
  if (oldHidden != newHidden)
    [[self view] setHidden:newHidden];
}

- (void)setBookmarkBarEnabled:(BOOL)enabled {
  if (enabled != barIsEnabled_) {
    barIsEnabled_ = enabled;
    [self updateVisibility];
  }
}

- (CGFloat)getDesiredToolbarHeightCompression {
  // Some special cases....
  if (!barIsEnabled_)
    return 0;

  if ([self isAnimationRunning]) {
    // No toolbar compression when animating between hidden and showing, nor
    // between showing and detached.
    if ([self isAnimatingBetweenState:BookmarkBar::HIDDEN
                             andState:BookmarkBar::SHOW] ||
        [self isAnimatingBetweenState:BookmarkBar::SHOW
                             andState:BookmarkBar::DETACHED])
      return 0;

    // If we ever need any other animation cases, code would go here.
  }

  return [self isInState:BookmarkBar::SHOW] ? bookmarks::kBookmarkBarOverlap
                                            : 0;
}

- (CGFloat)toolbarDividerOpacity {
  // Some special cases....
  if ([self isAnimationRunning]) {
    // In general, the toolbar shouldn't show a divider while we're animating
    // between showing and hidden. The exception is when our height is < 1, in
    // which case we can't draw it. It's all-or-nothing (no partial opacity).
    if ([self isAnimatingBetweenState:BookmarkBar::HIDDEN
                             andState:BookmarkBar::SHOW])
      return (NSHeight([[self view] frame]) < 1) ? 1 : 0;

    // The toolbar should show the divider when animating between showing and
    // detached (but opacity will vary).
    if ([self isAnimatingBetweenState:BookmarkBar::SHOW
                             andState:BookmarkBar::DETACHED])
      return static_cast<CGFloat>([self detachedMorphProgress]);

    // If we ever need any other animation cases, code would go here.
  }

  // In general, only show the divider when it's in the normal showing state.
  return [self isInState:BookmarkBar::SHOW] ? 0 : 1;
}

- (NSImage*)faviconForNode:(const BookmarkNode*)node {
  if (!node)
    return defaultImage_;

  if (node->is_folder())
    return folderImage_;

  const gfx::Image& favicon = bookmarkModel_->GetFavicon(node);
  if (!favicon.IsEmpty())
    return favicon.ToNSImage();

  return defaultImage_;
}

- (void)closeFolderAndStopTrackingMenus {
  showFolderMenus_ = NO;
  [self closeAllBookmarkFolders];
}

- (BOOL)canEditBookmarks {
  PrefService* prefs = browser_->profile()->GetPrefs();
  return prefs->GetBoolean(prefs::kEditBookmarksEnabled);
}

- (BOOL)canEditBookmark:(const BookmarkNode*)node {
  // Don't allow edit/delete of the permanent nodes.
  if (node == nil || bookmarkModel_->is_permanent_node(node))
    return NO;
  return YES;
}

#pragma mark Actions

// Helper methods called on the main thread by runMenuFlashThread.

- (void)setButtonFlashStateOn:(id)sender {
  [sender highlight:YES];
}

- (void)setButtonFlashStateOff:(id)sender {
  [sender highlight:NO];
}

- (void)cleanupAfterMenuFlashThread:(id)sender {
  [self closeFolderAndStopTrackingMenus];

  // Items retained by doMenuFlashOnSeparateThread below.
  [sender release];
  [self release];
}

// End runMenuFlashThread helper methods.

// This call is invoked only by doMenuFlashOnSeparateThread below.
// It makes the selected BookmarkButton (which is masquerading as a menu item)
// flash a few times to give confirmation feedback, then it closes the menu.
// It spends all its time sleeping or scheduling UI work on the main thread.
- (void)runMenuFlashThread:(id)sender {

  // Check this is not running on the main thread, as it sleeps.
  DCHECK(![NSThread isMainThread]);

  // Duration of flash phases and number of flashes designed to evoke a
  // slightly retro "more mac-like than the Mac" feel.
  // Current Cocoa UI has a barely perceptible flash,probably because Apple
  // doesn't fire the action til after the animation and so there's a hurry.
  // As this code is fully asynchronous, it can take its time.
  const float kBBOnFlashTime = 0.08;
  const float kBBOffFlashTime = 0.08;
  const int kBookmarkButtonMenuFlashes = 3;

  for (int count = 0 ; count < kBookmarkButtonMenuFlashes ; count++) {
    [self performSelectorOnMainThread:@selector(setButtonFlashStateOn:)
                           withObject:sender
                        waitUntilDone:NO];
    [NSThread sleepForTimeInterval:kBBOnFlashTime];
    [self performSelectorOnMainThread:@selector(setButtonFlashStateOff:)
                           withObject:sender
                        waitUntilDone:NO];
    [NSThread sleepForTimeInterval:kBBOffFlashTime];
  }
  [self performSelectorOnMainThread:@selector(cleanupAfterMenuFlashThread:)
                         withObject:sender
                      waitUntilDone:NO];
}

// Non-blocking call which starts the process to make the selected menu item
// flash a few times to give confirmation feedback, after which it closes the
// menu. The item is of course actually a BookmarkButton masquerading as a menu
// item).
- (void)doMenuFlashOnSeparateThread:(id)sender {

  // Ensure that self and sender don't go away before the animation completes.
  // These retains are balanced in cleanupAfterMenuFlashThread above.
  [self retain];
  [sender retain];
  [NSThread detachNewThreadSelector:@selector(runMenuFlashThread:)
                           toTarget:self
                         withObject:sender];
}

- (IBAction)openBookmark:(id)sender {
  BOOL isMenuItem = [[sender cell] isFolderButtonCell];
  BOOL animate = isMenuItem && innerContentAnimationsEnabled_;
  if (animate)
    [self doMenuFlashOnSeparateThread:sender];
  DCHECK([sender respondsToSelector:@selector(bookmarkNode)]);
  const BookmarkNode* node = [sender bookmarkNode];
  DCHECK(node);
  WindowOpenDisposition disposition =
      ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
  RecordAppLaunch(browser_->profile(), node->url());
  [self openURL:node->url() disposition:disposition];

  if (!animate)
    [self closeFolderAndStopTrackingMenus];
  bookmark_utils::RecordBookmarkLaunch([self bookmarkLaunchLocation]);
}

// Common function to open a bookmark folder of any type.
- (void)openBookmarkFolder:(id)sender {
  DCHECK([sender isKindOfClass:[BookmarkButton class]]);
  DCHECK([[sender cell] isKindOfClass:[BookmarkButtonCell class]]);

  // Only record the action if it's the initial folder being opened.
  if (!showFolderMenus_)
    bookmark_utils::RecordBookmarkFolderOpen([self bookmarkLaunchLocation]);
  showFolderMenus_ = !showFolderMenus_;

  if (sender == offTheSideButton_)
    [[sender cell] setStartingChildIndex:displayedButtonCount_];

  // Toggle presentation of bar folder menus.
  [folderTarget_ openBookmarkFolderFromButton:sender];
}

// Click on a bookmark folder button.
- (IBAction)openBookmarkFolderFromButton:(id)sender {
  [self openBookmarkFolder:sender];
}

// Click on the "off the side" button (chevron), which opens like a folder
// button but isn't exactly a parent folder.
- (IBAction)openOffTheSideFolderFromButton:(id)sender {
  [self openBookmarkFolder:sender];
}

- (IBAction)importBookmarks:(id)sender {
  chrome::ShowImportDialog(browser_);
}

#pragma mark Private Methods

// Called after a theme change took place, possibly for a different profile.
- (void)themeDidChangeNotification:(NSNotification*)notification {
  [self updateTheme:[[[self view] window] themeProvider]];
}

// (Private) Method is the same as [self view], but is provided to be explicit.
- (BackgroundGradientView*)backgroundGradientView {
  DCHECK([[self view] isKindOfClass:[BackgroundGradientView class]]);
  return (BackgroundGradientView*)[self view];
}

// (Private) Method is the same as [self view], but is provided to be explicit.
- (AnimatableView*)animatableView {
  DCHECK([[self view] isKindOfClass:[AnimatableView class]]);
  return (AnimatableView*)[self view];
}

- (bookmark_utils::BookmarkLaunchLocation)bookmarkLaunchLocation {
  return currentState_ == BookmarkBar::DETACHED ?
      bookmark_utils::LAUNCH_DETACHED_BAR :
      bookmark_utils::LAUNCH_ATTACHED_BAR;
}

// Position the right-side buttons including the off-the-side chevron.
- (void)positionRightSideButtons {
  int maxX = NSMaxX([[self buttonView] bounds]) -
      bookmarks::kBookmarkHorizontalPadding;
  int right = maxX;

  int ignored = 0;
  NSRect frame = [self frameForBookmarkButtonFromCell:
      [otherBookmarksButton_ cell] xOffset:&ignored];
  if (![otherBookmarksButton_ isHidden]) {
    right -= NSWidth(frame);
    frame.origin.x = right;
  } else {
    frame.origin.x = maxX - NSWidth(frame);
  }
  [otherBookmarksButton_ setFrame:frame];

  frame = [offTheSideButton_ frame];
  frame.size.height = bookmarks::kBookmarkFolderButtonHeight;
  right -= frame.size.width;
  frame.origin.x = right;
  [offTheSideButton_ setFrame:frame];
}

// Configure the off-the-side button (e.g. specify the node range,
// check if we should enable or disable it, etc).
- (void)configureOffTheSideButtonContentsAndVisibility {
  // If deleting a button while off-the-side is open, buttons may be
  // promoted from off-the-side to the bar.  Accomodate.
  if (folderController_ &&
      ([folderController_ parentButton] == offTheSideButton_)) {
    [folderController_ reconfigureMenu];
  }

  [[offTheSideButton_ cell] setStartingChildIndex:displayedButtonCount_];
  [[offTheSideButton_ cell]
   setBookmarkNode:bookmarkModel_->bookmark_bar_node()];
  int bookmarkChildren = bookmarkModel_->bookmark_bar_node()->child_count();
  if (bookmarkChildren > displayedButtonCount_) {
    [offTheSideButton_ setHidden:NO];
  } else {
    // If we just deleted the last item in an off-the-side menu so the
    // button will be going away, make sure the menu goes away.
    if (folderController_ &&
        ([folderController_ parentButton] == offTheSideButton_))
      [self closeAllBookmarkFolders];
    // (And hide the button, too.)
    [offTheSideButton_ setHidden:YES];
  }
}

// Main menubar observation code, so we can know to close our fake menus if the
// user clicks on the actual menubar, as multiple unconnected menus sharing
// the screen looks weird.
// Needed because the local event monitor doesn't see the click on the menubar.

// Gets called when the menubar is clicked.
- (void)begunTracking:(NSNotification *)notification {
  [self closeFolderAndStopTrackingMenus];
}

// Install the callback.
- (void)startObservingMenubar {
  NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
  [nc addObserver:self
         selector:@selector(begunTracking:)
             name:NSMenuDidBeginTrackingNotification
           object:[NSApp mainMenu]];
}

// Remove the callback.
- (void)stopObservingMenubar {
  NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
  [nc removeObserver:self
                name:NSMenuDidBeginTrackingNotification
              object:[NSApp mainMenu]];
}

// End of menubar observation code.

// Begin (or end) watching for a click outside this window.  Unlike
// normal NSWindows, bookmark folder "fake menu" windows do not become
// key or main.  Thus, traditional notification (e.g. WillResignKey)
// won't work.  Our strategy is to watch (at the app level) for a
// "click outside" these windows to detect when they logically lose
// focus.
- (void)watchForExitEvent:(BOOL)watch {
  if (watch) {
    if (!exitEventTap_) {
      exitEventTap_ = [NSEvent
          addLocalMonitorForEventsMatchingMask:NSAnyEventMask
          handler:^NSEvent* (NSEvent* event) {
              if ([self isEventAnExitEvent:event])
                [self closeFolderAndStopTrackingMenus];
              return event;
          }];
      [self startObservingMenubar];
    }
  } else {
    if (exitEventTap_) {
      [NSEvent removeMonitor:exitEventTap_];
      exitEventTap_ = nil;
      [self stopObservingMenubar];
    }
  }
}

// Keep the "no items" label centered in response to a frame size change.
- (void)centerNoItemsLabel {
  // Note that this computation is done in the parent's coordinate system,
  // which is unflipped. Also, we want the label to be a fixed distance from
  // the bottom, so that it slides up properly (on animating to hidden).
  // The textfield sits in the itemcontainer, so to center it we maintain
  // equal vertical padding on the top and bottom.
  int yoffset = (NSHeight([[buttonView_ noItemTextfield] frame]) -
                 NSHeight([[buttonView_ noItemContainer] frame])) / 2;
  [[buttonView_ noItemContainer] setFrameOrigin:NSMakePoint(0, yoffset)];
}

// (Private)
- (void)showBookmarkBarWithAnimation:(BOOL)animate {
  if (animate && stateAnimationsEnabled_) {
    // If |-doBookmarkBarAnimation| does the animation, we're done.
    if ([self doBookmarkBarAnimation])
      return;

    // Else fall through and do the change instantly.
  }

  // Set our height.
  [resizeDelegate_ resizeView:[self view]
                    newHeight:[self preferredHeight]];

  // Only show the divider if showing the normal bookmark bar.
  BOOL showsDivider = [self isInState:BookmarkBar::SHOW];
  [[self backgroundGradientView] setShowsDivider:showsDivider];

  // Make sure we're shown.
  [[self view] setHidden:![self isVisible]];

  // Update everything else.
  [self layoutSubviews];
  [self frameDidChange];
}

// (Private)
- (BOOL)doBookmarkBarAnimation {
  if ([self isAnimatingFromState:BookmarkBar::HIDDEN
                         toState:BookmarkBar::SHOW]) {
    [[self backgroundGradientView] setShowsDivider:YES];
    [[self view] setHidden:NO];
    AnimatableView* view = [self animatableView];
    // Height takes into account the extra height we have since the toolbar
    // only compresses when we're done.
    [view animateToNewHeight:(bookmarks::kBookmarkBarHeight -
                              bookmarks::kBookmarkBarOverlap)
                    duration:kBookmarkBarAnimationDuration];
  } else if ([self isAnimatingFromState:BookmarkBar::SHOW
                                toState:BookmarkBar::HIDDEN]) {
    [[self backgroundGradientView] setShowsDivider:YES];
    [[self view] setHidden:NO];
    AnimatableView* view = [self animatableView];
    [view animateToNewHeight:0
                    duration:kBookmarkBarAnimationDuration];
  } else if ([self isAnimatingFromState:BookmarkBar::SHOW
                                toState:BookmarkBar::DETACHED]) {
    [[self backgroundGradientView] setShowsDivider:YES];
    [[self view] setHidden:NO];
    AnimatableView* view = [self animatableView];
    [view animateToNewHeight:chrome::kNTPBookmarkBarHeight
                    duration:kBookmarkBarAnimationDuration];
  } else if ([self isAnimatingFromState:BookmarkBar::DETACHED
                                toState:BookmarkBar::SHOW]) {
    [[self backgroundGradientView] setShowsDivider:YES];
    [[self view] setHidden:NO];
    AnimatableView* view = [self animatableView];
    // Height takes into account the extra height we have since the toolbar
    // only compresses when we're done.
    [view animateToNewHeight:(bookmarks::kBookmarkBarHeight -
                              bookmarks::kBookmarkBarOverlap)
                    duration:kBookmarkBarAnimationDuration];
  } else {
    // Oops! An animation we don't know how to handle.
    return NO;
  }

  return YES;
}

// Actually open the URL.  This is the last chance for a unit test to
// override.
- (void)openURL:(GURL)url disposition:(WindowOpenDisposition)disposition {
  OpenURLParams params(
      url, Referrer(), disposition, content::PAGE_TRANSITION_AUTO_BOOKMARK,
      false);
  browser_->OpenURL(params);
}

- (void)clearMenuTagMap {
  seedId_ = 0;
  menuTagMap_.clear();
}

- (int)preferredHeight {
  DCHECK(![self isAnimationRunning]);

  if (!barIsEnabled_)
    return 0;

  switch (currentState_) {
    case BookmarkBar::SHOW:
      return bookmarks::kBookmarkBarHeight;
    case BookmarkBar::DETACHED:
      return chrome::kNTPBookmarkBarHeight;
    case BookmarkBar::HIDDEN:
      return 0;
  }
}

// Recursively add the given bookmark node and all its children to
// menu, one menu item per node.
- (void)addNode:(const BookmarkNode*)child toMenu:(NSMenu*)menu {
  NSString* title = [BookmarkMenuCocoaController menuTitleForNode:child];
  NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:title
                                                 action:nil
                                          keyEquivalent:@""] autorelease];
  [menu addItem:item];
  [item setImage:[self faviconForNode:child]];
  if (child->is_folder()) {
    NSMenu* submenu = [[[NSMenu alloc] initWithTitle:title] autorelease];
    [menu setSubmenu:submenu forItem:item];
    if (!child->empty()) {
      [self addFolderNode:child toMenu:submenu];  // potentially recursive
    } else {
      [self tagEmptyMenu:submenu];
    }
  } else {
    [item setTarget:self];
    [item setAction:@selector(openBookmarkMenuItem:)];
    [item setTag:[self menuTagFromNodeId:child->id()]];
    if (child->is_url())
      [item setToolTip:[BookmarkMenuCocoaController tooltipForNode:child]];
  }
}

// Empty menus are odd; if empty, add something to look at.
// Matches windows behavior.
- (void)tagEmptyMenu:(NSMenu*)menu {
  NSString* empty_menu_title = l10n_util::GetNSString(IDS_MENU_EMPTY_SUBMENU);
  [menu addItem:[[[NSMenuItem alloc] initWithTitle:empty_menu_title
                                            action:NULL
                                     keyEquivalent:@""] autorelease]];
}

// Add the children of the given bookmark node (and their children...)
// to menu, one menu item per node.
- (void)addFolderNode:(const BookmarkNode*)node toMenu:(NSMenu*)menu {
  for (int i = 0; i < node->child_count(); i++) {
    const BookmarkNode* child = node->GetChild(i);
    [self addNode:child toMenu:menu];
  }
}

// Return an autoreleased NSMenu that represents the given bookmark
// folder node.
- (NSMenu *)menuForFolderNode:(const BookmarkNode*)node {
  if (!node->is_folder())
    return nil;
  NSString* title = base::SysUTF16ToNSString(node->GetTitle());
  NSMenu* menu = [[[NSMenu alloc] initWithTitle:title] autorelease];
  [self addFolderNode:node toMenu:menu];

  if (![menu numberOfItems]) {
    [self tagEmptyMenu:menu];
  }
  return menu;
}

// Return an appropriate width for the given bookmark button cell.
// The "+2" is needed because, sometimes, Cocoa is off by a tad.
// Example: for a bookmark named "Moma" or "SFGate", it is one pixel
// too small.  For "FBL" it is 2 pixels too small.
// For a bookmark named "SFGateFooWoo", it is just fine.
- (CGFloat)widthForBookmarkButtonCell:(NSCell*)cell {
  CGFloat desired = [cell cellSize].width + 2;
  return std::min(desired, bookmarks::kDefaultBookmarkWidth);
}

- (IBAction)openBookmarkMenuItem:(id)sender {
  int64 tag = [self nodeIdFromMenuTag:[sender tag]];
  const BookmarkNode* node = bookmarkModel_->GetNodeByID(tag);
  WindowOpenDisposition disposition =
      ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
  [self openURL:node->url() disposition:disposition];
}

// For the given root node of the bookmark bar, show or hide (as
// appropriate) the "no items" container (text which says "bookmarks
// go here").
- (void)showOrHideNoItemContainerForNode:(const BookmarkNode*)node {
  BOOL hideNoItemWarning = !node->empty();
  [[buttonView_ noItemContainer] setHidden:hideNoItemWarning];
}

// TODO(jrg): write a "build bar" so there is a nice spot for things
// like the contextual menu which is invoked when not over a
// bookmark.  On Safari that menu has a "new folder" option.
- (void)addNodesToButtonList:(const BookmarkNode*)node {
  [self showOrHideNoItemContainerForNode:node];

  CGFloat maxViewX = NSMaxX([[self view] bounds]);
  int xOffset =
      bookmarks::kBookmarkLeftMargin - bookmarks::kBookmarkHorizontalPadding;

  // Draw the apps bookmark if needed.
  if (![appsPageShortcutButton_ isHidden]) {
    NSRect frame =
        [self frameForBookmarkButtonFromCell:[appsPageShortcutButton_ cell]
                                     xOffset:&xOffset];
    [appsPageShortcutButton_ setFrame:frame];
  }

  for (int i = 0; i < node->child_count(); i++) {
    const BookmarkNode* child = node->GetChild(i);
    BookmarkButton* button = [self buttonForNode:child xOffset:&xOffset];
    if (NSMinX([button frame]) >= maxViewX) {
      [button setDelegate:nil];
      break;
    }
    [buttons_ addObject:button];
  }
}

- (BookmarkButton*)buttonForNode:(const BookmarkNode*)node
                         xOffset:(int*)xOffset {
  BookmarkButtonCell* cell = [self cellForBookmarkNode:node];
  NSRect frame = [self frameForBookmarkButtonFromCell:cell xOffset:xOffset];

  base::scoped_nsobject<BookmarkButton> button(
      [[BookmarkButton alloc] initWithFrame:frame]);
  DCHECK(button.get());

  // [NSButton setCell:] warns to NOT use setCell: other than in the
  // initializer of a control.  However, we are using a basic
  // NSButton whose initializer does not take an NSCell as an
  // object.  To honor the assumed semantics, we do nothing with
  // NSButton between alloc/init and setCell:.
  [button setCell:cell];
  [button setDelegate:self];

  // We cannot set the button cell's text color until it is placed in
  // the button (e.g. the [button setCell:cell] call right above).  We
  // also cannot set the cell's text color until the view is added to
  // the hierarchy.  If that second part is now true, set the color.
  // (If not we'll set the color on the 1st themeChanged:
  // notification.)
  ui::ThemeProvider* themeProvider = [[[self view] window] themeProvider];
  if (themeProvider) {
    NSColor* color =
        themeProvider->GetNSColor(ThemeProperties::COLOR_BOOKMARK_TEXT);
    [cell setTextColor:color];
  }

  if (node->is_folder()) {
    [button setTarget:self];
    [button setAction:@selector(openBookmarkFolderFromButton:)];
    [[button draggableButton] setActsOnMouseDown:YES];
    // If it has a title, and it will be truncated, show full title in
    // tooltip.
    NSString* title = base::SysUTF16ToNSString(node->GetTitle());
    if ([title length] &&
        [[button cell] cellSize].width > bookmarks::kDefaultBookmarkWidth) {
      [button setToolTip:title];
    }
  } else {
    // Make the button do something
    [button setTarget:self];
    [button setAction:@selector(openBookmark:)];
    if (node->is_url())
      [button setToolTip:[BookmarkMenuCocoaController tooltipForNode:node]];
  }
  return [[button.get() retain] autorelease];
}

// Add bookmark buttons to the view only if they are completely
// visible and don't overlap the "other bookmarks".  Remove buttons
// which are clipped.  Called when building the bookmark bar the first time.
- (void)addButtonsToView {
  displayedButtonCount_ = 0;
  NSMutableArray* buttons = [self buttons];
  for (NSButton* button in buttons) {
    if (NSMaxX([button frame]) > (NSMinX([offTheSideButton_ frame]) -
                                  bookmarks::kBookmarkHorizontalPadding))
      break;
    [buttonView_ addSubview:button];
    ++displayedButtonCount_;
  }
  NSUInteger removalCount =
      [buttons count] - (NSUInteger)displayedButtonCount_;
  if (removalCount > 0) {
    NSRange removalRange = NSMakeRange(displayedButtonCount_, removalCount);
    [buttons removeObjectsInRange:removalRange];
  }
}

// Shows or hides the Other Bookmarks button as appropriate, and returns
// whether it ended up visible.
- (BOOL)setOtherBookmarksButtonVisibility {
  if (!otherBookmarksButton_.get())
    return NO;

  BOOL visible = ![otherBookmarksButton_ bookmarkNode]->empty();
  [otherBookmarksButton_ setHidden:!visible];
  return visible;
}

// Shows or hides the Apps button as appropriate, and returns whether it ended
// up visible.
- (BOOL)setAppsPageShortcutButtonVisibility {
  if (!appsPageShortcutButton_.get())
    return NO;

  BOOL visible = bookmarkModel_->loaded() &&
      chrome::ShouldShowAppsShortcutInBookmarkBar(browser_->profile());
  [appsPageShortcutButton_ setHidden:!visible];
  return visible;
}

// Creates a bookmark bar button that does not correspond to a regular bookmark
// or folder. It is used by the "Other Bookmarks" and the "Apps" buttons.
- (BookmarkButton*)customBookmarkButtonForCell:(NSCell*)cell {
  BookmarkButton* button = [[BookmarkButton alloc] init];
  [[button draggableButton] setDraggable:NO];
  [[button draggableButton] setActsOnMouseDown:YES];
  [button setCell:cell];
  [button setDelegate:self];
  [button setTarget:self];
  // Make sure this button, like all other BookmarkButtons, lives
  // until the end of the current event loop.
  [[button retain] autorelease];
  return button;
}

// Creates the button for "Other Bookmarks", but does not position it.
- (void)createOtherBookmarksButton {
  // Can't create this until the model is loaded, but only need to
  // create it once.
  if (otherBookmarksButton_.get()) {
    [self setOtherBookmarksButtonVisibility];
    return;
  }

  NSCell* cell = [self cellForBookmarkNode:bookmarkModel_->other_node()];
  otherBookmarksButton_.reset([self customBookmarkButtonForCell:cell]);
  // Peg at right; keep same height as bar.
  [otherBookmarksButton_ setAutoresizingMask:(NSViewMinXMargin)];
  [otherBookmarksButton_ setAction:@selector(openBookmarkFolderFromButton:)];
  view_id_util::SetID(otherBookmarksButton_.get(), VIEW_ID_OTHER_BOOKMARKS);
  [buttonView_ addSubview:otherBookmarksButton_.get()];

  [self setOtherBookmarksButtonVisibility];
}

// Creates the button for "Apps", but does not position it.
- (void)createAppsPageShortcutButton {
  // Can't create this until the model is loaded, but only need to
  // create it once.
  if (appsPageShortcutButton_.get()) {
    [self setAppsPageShortcutButtonVisibility];
    return;
  }

  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  NSString* text = l10n_util::GetNSString(IDS_BOOKMARK_BAR_APPS_SHORTCUT_NAME);
  NSImage* image = rb.GetNativeImageNamed(
      IDR_BOOKMARK_BAR_APPS_SHORTCUT).ToNSImage();
  NSCell* cell = [self cellForCustomButtonWithText:text
                                             image:image];
  appsPageShortcutButton_.reset([self customBookmarkButtonForCell:cell]);
  [[appsPageShortcutButton_ draggableButton] setActsOnMouseDown:NO];
  [appsPageShortcutButton_ setAction:@selector(openAppsPage:)];
  NSString* tooltip =
      l10n_util::GetNSString(IDS_BOOKMARK_BAR_APPS_SHORTCUT_TOOLTIP);
  [appsPageShortcutButton_ setToolTip:tooltip];
  [buttonView_ addSubview:appsPageShortcutButton_.get()];

  [self setAppsPageShortcutButtonVisibility];
}

- (void)openAppsPage:(id)sender {
  WindowOpenDisposition disposition =
      ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
  [self openURL:GURL(chrome::kChromeUIAppsURL) disposition:disposition];
  bookmark_utils::RecordAppsPageOpen([self bookmarkLaunchLocation]);
}

// To avoid problems with sync, changes that may impact the current
// bookmark (e.g. deletion) make sure context menus are closed.  This
// prevents deleting a node which no longer exists.
- (void)cancelMenuTracking {
  [contextMenuController_ cancelTracking];
}

- (void)moveToState:(BookmarkBar::State)nextState
      withAnimation:(BOOL)animate {
  BOOL isAnimationRunning = [self isAnimationRunning];

  // No-op if the next state is the same as the "current" one, subject to the
  // following conditions:
  //  - no animation is running; or
  //  - an animation is running and |animate| is YES ([*] if it's NO, we'd want
  //    to cancel the animation and jump to the final state).
  if ((nextState == currentState_) && (!isAnimationRunning || animate))
    return;

  // If an animation is running, we want to finalize it. Otherwise we'd have to
  // be able to animate starting from the middle of one type of animation. We
  // assume that animations that we know about can be "reversed".
  if (isAnimationRunning) {
    // Don't cancel if we're going to reverse the animation.
    if (nextState != lastState_) {
      [self stopCurrentAnimation];
      [self finalizeState];
    }

    // If we're in case [*] above, we can stop here.
    if (nextState == currentState_)
      return;
  }

  // Now update with the new state change.
  lastState_ = currentState_;
  currentState_ = nextState;
  isAnimationRunning_ = YES;

  // Animate only if told to and if bar is enabled.
  if (animate && stateAnimationsEnabled_ && barIsEnabled_) {
    [self closeAllBookmarkFolders];
    // Take care of any animation cases we know how to handle.

    // We know how to handle hidden <-> normal, normal <-> detached....
    if ([self isAnimatingBetweenState:BookmarkBar::HIDDEN
                             andState:BookmarkBar::SHOW] ||
        [self isAnimatingBetweenState:BookmarkBar::SHOW
                             andState:BookmarkBar::DETACHED]) {
      [delegate_ bookmarkBar:self
        willAnimateFromState:lastState_
                     toState:currentState_];
      [self showBookmarkBarWithAnimation:YES];
      return;
    }

    // If we ever need any other animation cases, code would go here.
    // Let any animation cases which we don't know how to handle fall through to
    // the unanimated case.
  }

  // Just jump to the state.
  [self finalizeState];
}

// N.B.: |-moveToState:...| will check if this should be a no-op or not.
- (void)updateState:(BookmarkBar::State)newState
         changeType:(BookmarkBar::AnimateChangeType)changeType {
  BOOL animate = changeType == BookmarkBar::ANIMATE_STATE_CHANGE &&
                 stateAnimationsEnabled_;
  [self moveToState:newState withAnimation:animate];
}

// (Private)
- (void)finalizeState {
  // We promise that our delegate that the variables will be finalized before
  // the call to |-bookmarkBar:didChangeFromState:toState:|.
  BookmarkBar::State oldState = lastState_;
  lastState_ = currentState_;
  isAnimationRunning_ = NO;

  // Notify our delegate.
  [delegate_ bookmarkBar:self
      didChangeFromState:oldState
                 toState:currentState_];

  // Update ourselves visually.
  [self updateVisibility];
}

// (Private)
- (void)stopCurrentAnimation {
  [[self animatableView] stopAnimation];
}

// Delegate method for |AnimatableView| (a superclass of
// |BookmarkBarToolbarView|).
- (void)animationDidEnd:(NSAnimation*)animation {
  [self finalizeState];
}

- (void)reconfigureBookmarkBar {
  [self redistributeButtonsOnBarAsNeeded];
  [self positionRightSideButtons];
  [self configureOffTheSideButtonContentsAndVisibility];
  [self centerNoItemsLabel];
}

// Determine if the given |view| can completely fit within the constraint of
// maximum x, given by |maxViewX|, and, if not, narrow the view up to a minimum
// width. If the minimum width is not achievable then hide the view. Return YES
// if the view was hidden.
- (BOOL)shrinkOrHideView:(NSView*)view forMaxX:(CGFloat)maxViewX {
  BOOL wasHidden = NO;
  // See if the view needs to be narrowed.
  NSRect frame = [view frame];
  if (NSMaxX(frame) > maxViewX) {
    // Resize if more than 30 pixels are showing, otherwise hide.
    if (NSMinX(frame) + 30.0 < maxViewX) {
      frame.size.width = maxViewX - NSMinX(frame);
      [view setFrame:frame];
    } else {
      [view setHidden:YES];
      wasHidden = YES;
    }
  }
  return wasHidden;
}

// Bookmark button menu items that open a new window (e.g., open in new window,
// open in incognito, edit, etc.) cause us to lose a mouse-exited event
// on the button, which leaves it in a hover state.
// Since the showsBorderOnlyWhileMouseInside uses a tracking area, simple
// tricks (e.g. sending an extra mouseExited: to the button) don't
// fix the problem.
// http://crbug.com/129338
- (void)unhighlightBookmark:(const BookmarkNode*)node {
  // Only relevant if context menu was opened from a button on the
  // bookmark bar.
  const BookmarkNode* parent = node->parent();
  BookmarkNode::Type parentType = parent->type();
  if (parentType == BookmarkNode::BOOKMARK_BAR) {
    int index = parent->GetIndexOf(node);
    if ((index >= 0) && (static_cast<NSUInteger>(index) < [buttons_ count])) {
      NSButton* button =
          [buttons_ objectAtIndex:static_cast<NSUInteger>(index)];
      if ([button showsBorderOnlyWhileMouseInside]) {
        [button setShowsBorderOnlyWhileMouseInside:NO];
        [button setShowsBorderOnlyWhileMouseInside:YES];
      }
    }
  }
}


// Adjust the horizontal width, x position and the visibility of the "For quick
// access" text field and "Import bookmarks..." button based on the current
// width of the containing |buttonView_| (which is affected by window width).
- (void)adjustNoItemContainerForMaxX:(CGFloat)maxViewX {
  if (![[buttonView_ noItemContainer] isHidden]) {
    // Reset initial frames for the two items, then adjust as necessary.
    NSTextField* noItemTextfield = [buttonView_ noItemTextfield];
    NSRect noItemsRect = originalNoItemsRect_;
    NSRect importBookmarksRect = originalImportBookmarksRect_;
    if (![appsPageShortcutButton_ isHidden]) {
      float width = NSWidth([appsPageShortcutButton_ frame]);
      noItemsRect.origin.x += width;
      importBookmarksRect.origin.x += width;
    }
    [noItemTextfield setFrame:noItemsRect];
    [noItemTextfield setHidden:NO];
    NSButton* importBookmarksButton = [buttonView_ importBookmarksButton];
    [importBookmarksButton setFrame:importBookmarksRect];
    [importBookmarksButton setHidden:NO];
    // Check each to see if they need to be shrunk or hidden.
    if ([self shrinkOrHideView:importBookmarksButton forMaxX:maxViewX])
      [self shrinkOrHideView:noItemTextfield forMaxX:maxViewX];
  }
}

// Scans through all buttons from left to right, calculating from scratch where
// they should be based on the preceding widths, until it finds the one
// requested.
// Returns NSZeroRect if there is no such button in the bookmark bar.
// Enables you to work out where a button will end up when it is done animating.
- (NSRect)finalRectOfButton:(BookmarkButton*)wantedButton {
  CGFloat left = bookmarks::kBookmarkLeftMargin;
  NSRect buttonFrame = NSZeroRect;

  // Draw the apps bookmark if needed.
  if (![appsPageShortcutButton_ isHidden]) {
    left = NSMaxX([appsPageShortcutButton_ frame]) +
        bookmarks::kBookmarkHorizontalPadding;
  }

  for (NSButton* button in buttons_.get()) {
    // Hidden buttons get no space.
    if ([button isHidden])
      continue;
    buttonFrame = [button frame];
    buttonFrame.origin.x = left;
    left += buttonFrame.size.width + bookmarks::kBookmarkHorizontalPadding;
    if (button == wantedButton)
      return buttonFrame;
  }
  return NSZeroRect;
}

// Calculates the final position of the last button in the bar.
// We can't just use [[self buttons] lastObject] frame] because the button
// may be animating currently.
- (NSRect)finalRectOfLastButton {
  return [self finalRectOfButton:[[self buttons] lastObject]];
}

- (CGFloat)buttonViewMaxXWithOffTheSideButtonIsVisible:(BOOL)visible {
  CGFloat maxViewX = NSMaxX([buttonView_ bounds]);
  // If necessary, pull in the width to account for the Other Bookmarks button.
  if ([self setOtherBookmarksButtonVisibility]) {
    maxViewX = [otherBookmarksButton_ frame].origin.x -
        bookmarks::kBookmarkRightMargin;
  }

  [self positionRightSideButtons];
  // If we're already overflowing, then we need to account for the chevron.
  if (visible) {
    maxViewX =
        [offTheSideButton_ frame].origin.x - bookmarks::kBookmarkRightMargin;
  }

  return maxViewX;
}

- (void)redistributeButtonsOnBarAsNeeded {
  const BookmarkNode* node = bookmarkModel_->bookmark_bar_node();
  NSInteger barCount = node->child_count();

  // Determine the current maximum extent of the visible buttons.
  [self positionRightSideButtons];
  BOOL offTheSideButtonVisible = (barCount > displayedButtonCount_);
  CGFloat maxViewX = [self buttonViewMaxXWithOffTheSideButtonIsVisible:
      offTheSideButtonVisible];

  // As a result of pasting or dragging, the bar may now have more buttons
  // than will fit so remove any which overflow.  They will be shown in
  // the off-the-side folder.
  while (displayedButtonCount_ > 0) {
    BookmarkButton* button = [buttons_ lastObject];
    if (NSMaxX([self finalRectOfLastButton]) < maxViewX)
      break;
    [buttons_ removeLastObject];
    [button setDelegate:nil];
    [button removeFromSuperview];
    --displayedButtonCount_;
    // Account for the fact that the chevron might now be visible.
    if (!offTheSideButtonVisible) {
      offTheSideButtonVisible = YES;
      maxViewX = [self buttonViewMaxXWithOffTheSideButtonIsVisible:YES];
    }
  }

  // As a result of cutting, deleting and dragging, the bar may now have room
  // for more buttons.
  int xOffset;
  if (displayedButtonCount_ > 0) {
    xOffset = NSMaxX([self finalRectOfLastButton]) +
        bookmarks::kBookmarkHorizontalPadding;
  } else if (![appsPageShortcutButton_ isHidden]) {
    xOffset = NSMaxX([appsPageShortcutButton_ frame]) +
        bookmarks::kBookmarkHorizontalPadding;
  } else {
    xOffset = bookmarks::kBookmarkLeftMargin -
        bookmarks::kBookmarkHorizontalPadding;
  }
  for (int i = displayedButtonCount_; i < barCount; ++i) {
    const BookmarkNode* child = node->GetChild(i);
    BookmarkButton* button = [self buttonForNode:child xOffset:&xOffset];
    // If we're testing against the last possible button then account
    // for the chevron no longer needing to be shown.
    if (i == barCount - 1)
      maxViewX = [self buttonViewMaxXWithOffTheSideButtonIsVisible:NO];
    if (NSMaxX([button frame]) > maxViewX) {
      [button setDelegate:nil];
      break;
    }
    ++displayedButtonCount_;
    [buttons_ addObject:button];
    [buttonView_ addSubview:button];
  }

  // While we're here, adjust the horizontal width and the visibility
  // of the "For quick access" and "Import bookmarks..." text fields.
  if (![buttons_ count])
    [self adjustNoItemContainerForMaxX:maxViewX];
}

#pragma mark Private Methods Exposed for Testing

- (BookmarkBarView*)buttonView {
  return buttonView_;
}

- (NSMutableArray*)buttons {
  return buttons_.get();
}

- (NSButton*)offTheSideButton {
  return offTheSideButton_;
}

- (NSButton*)appsPageShortcutButton {
  return appsPageShortcutButton_;
}

- (BOOL)offTheSideButtonIsHidden {
  return [offTheSideButton_ isHidden];
}

- (BOOL)appsPageShortcutButtonIsHidden {
  return [appsPageShortcutButton_ isHidden];
}

- (BookmarkButton*)otherBookmarksButton {
  return otherBookmarksButton_.get();
}

- (BookmarkBarFolderController*)folderController {
  return folderController_;
}

- (id)folderTarget {
  return folderTarget_.get();
}

- (int)displayedButtonCount {
  return displayedButtonCount_;
}

// Delete all buttons (bookmarks, chevron, "other bookmarks") from the
// bookmark bar; reset knowledge of bookmarks.
- (void)clearBookmarkBar {
  for (BookmarkButton* button in buttons_.get()) {
    [button setDelegate:nil];
    [button removeFromSuperview];
  }
  [buttons_ removeAllObjects];
  [self clearMenuTagMap];
  displayedButtonCount_ = 0;

  // Make sure there are no stale pointers in the pasteboard.  This
  // can be important if a bookmark is deleted (via bookmark sync)
  // while in the middle of a drag.  The "drag completed" code
  // (e.g. [BookmarkBarView performDragOperationForBookmarkButton:]) is
  // careful enough to bail if there is no data found at "drop" time.
  //
  // Unfortunately the clearContents selector is 10.6 only.  The best
  // we can do is make sure something else is present in place of the
  // stale bookmark.
  NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
  [pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self];
  [pboard setString:@"" forType:NSStringPboardType];
}

// Return an autoreleased NSCell suitable for a bookmark button.
// TODO(jrg): move much of the cell config into the BookmarkButtonCell class.
- (BookmarkButtonCell*)cellForBookmarkNode:(const BookmarkNode*)node {
  NSImage* image = node ? [self faviconForNode:node] : nil;
  BookmarkButtonCell* cell =
      [BookmarkButtonCell buttonCellForNode:node
                                       text:nil
                                      image:image
                             menuController:contextMenuController_];
  [cell setTag:kStandardButtonTypeWithLimitedClickFeedback];

  // Note: a quirk of setting a cell's text color is that it won't work
  // until the cell is associated with a button, so we can't theme the cell yet.

  return cell;
}

// Return an autoreleased NSCell suitable for a special button displayed on the
// bookmark bar that is not attached to any bookmark node.
// TODO(jrg): move much of the cell config into the BookmarkButtonCell class.
- (BookmarkButtonCell*)cellForCustomButtonWithText:(NSString*)text
                                             image:(NSImage*)image {
  BookmarkButtonCell* cell =
      [BookmarkButtonCell buttonCellWithText:text
                                       image:image
                              menuController:contextMenuController_];
  [cell setTag:kStandardButtonTypeWithLimitedClickFeedback];

  // Note: a quirk of setting a cell's text color is that it won't work
  // until the cell is associated with a button, so we can't theme the cell yet.

  return cell;
}

// Returns a frame appropriate for the given bookmark cell, suitable
// for creating an NSButton that will contain it.  |xOffset| is the X
// offset for the frame; it is increased to be an appropriate X offset
// for the next button.
- (NSRect)frameForBookmarkButtonFromCell:(NSCell*)cell
                                 xOffset:(int*)xOffset {
  DCHECK(xOffset);
  NSRect bounds = [buttonView_ bounds];
  bounds.size.height = bookmarks::kBookmarkButtonHeight;

  NSRect frame = NSInsetRect(bounds,
                             bookmarks::kBookmarkHorizontalPadding,
                             bookmarks::kBookmarkVerticalPadding);
  frame.size.width = [self widthForBookmarkButtonCell:cell];

  // Add an X offset based on what we've already done
  frame.origin.x += *xOffset;

  // And up the X offset for next time.
  *xOffset = NSMaxX(frame);

  return frame;
}

// A bookmark button's contents changed.  Check for growth
// (e.g. increase the width up to the maximum).  If we grew, move
// other bookmark buttons over.
- (void)checkForBookmarkButtonGrowth:(NSButton*)changedButton {
  NSRect frame = [changedButton frame];
  CGFloat desiredSize = [self widthForBookmarkButtonCell:[changedButton cell]];
  CGFloat delta = desiredSize - frame.size.width;
  if (delta) {
    frame.size.width = desiredSize;
    [changedButton setFrame:frame];
    for (NSButton* button in buttons_.get()) {
      NSRect buttonFrame = [button frame];
      if (buttonFrame.origin.x > frame.origin.x) {
        buttonFrame.origin.x += delta;
        [button setFrame:buttonFrame];
      }
    }
  }
  // We may have just crossed a threshold to enable the off-the-side
  // button.
  [self configureOffTheSideButtonContentsAndVisibility];
}

// Called when our controlled frame has changed size.
- (void)frameDidChange {
  if (!bookmarkModel_->loaded())
    return;
  [self updateTheme:[[[self view] window] themeProvider]];
  [self reconfigureBookmarkBar];
}

// Given a NSMenuItem tag, return the appropriate bookmark node id.
- (int64)nodeIdFromMenuTag:(int32)tag {
  return menuTagMap_[tag];
}

// Create and return a new tag for the given node id.
- (int32)menuTagFromNodeId:(int64)menuid {
  int tag = seedId_++;
  menuTagMap_[tag] = menuid;
  return tag;
}

// Adapt appearance of buttons to the current theme. Called after
// theme changes, or when our view is added to the view hierarchy.
// Oddly, the view pings us instead of us pinging our view.  This is
// because our trigger is an [NSView viewWillMoveToWindow:], which the
// controller doesn't normally know about.  Otherwise we don't have
// access to the theme before we know what window we will be on.
- (void)updateTheme:(ui::ThemeProvider*)themeProvider {
  if (!themeProvider)
    return;
  NSColor* color =
      themeProvider->GetNSColor(ThemeProperties::COLOR_BOOKMARK_TEXT);
  for (BookmarkButton* button in buttons_.get()) {
    BookmarkButtonCell* cell = [button cell];
    [cell setTextColor:color];
  }
  [[otherBookmarksButton_ cell] setTextColor:color];
  [[appsPageShortcutButton_ cell] setTextColor:color];
}

// Return YES if the event indicates an exit from the bookmark bar
// folder menus.  E.g. "click outside" of the area we are watching.
// At this time we are watching the area that includes all popup
// bookmark folder windows.
- (BOOL)isEventAnExitEvent:(NSEvent*)event {
  NSWindow* eventWindow = [event window];
  NSWindow* myWindow = [[self view] window];
  switch ([event type]) {
    case NSLeftMouseDown:
    case NSRightMouseDown:
      // If the click is in my window but NOT in the bookmark bar, consider
      // it a click 'outside'. Clicks directly on an active button (i.e. one
      // that is a folder and for which its folder menu is showing) are 'in'.
      // All other clicks on the bookmarks bar are counted as 'outside'
      // because they should close any open bookmark folder menu.
      if (eventWindow == myWindow) {
        NSView* hitView =
            [[eventWindow contentView] hitTest:[event locationInWindow]];
        if (hitView == [folderController_ parentButton])
          return NO;
        if (![hitView isDescendantOf:[self view]] || hitView == buttonView_)
          return YES;
      }
      // If a click in a bookmark bar folder window and that isn't
      // one of my bookmark bar folders, YES is click outside.
      if (![eventWindow isKindOfClass:[BookmarkBarFolderWindow
                                       class]]) {
        return YES;
      }
      break;
    case NSKeyDown: {
      // Event hooks often see the same keydown event twice due to the way key
      // events get dispatched and redispatched, so ignore if this keydown
      // event has the EXACT same timestamp as the previous keydown.
      static NSTimeInterval lastKeyDownEventTime;
      NSTimeInterval thisTime = [event timestamp];
      if (lastKeyDownEventTime != thisTime) {
        lastKeyDownEventTime = thisTime;
        if ([event modifierFlags] & NSCommandKeyMask)
          return YES;
        else if (folderController_)
          return [folderController_ handleInputText:[event characters]];
      }
      return NO;
    }
    case NSKeyUp:
      return NO;
    case NSLeftMouseDragged:
      // We can get here with the following sequence:
      // - open a bookmark folder
      // - right-click (and unclick) on it to open context menu
      // - move mouse to window titlebar then click-drag it by the titlebar
      // http://crbug.com/49333
      return NO;
    default:
      break;
  }
  return NO;
}

#pragma mark Drag & Drop

// Find something like std::is_between<T>?  I can't believe one doesn't exist.
static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) {
  return ((value >= low) && (value <= high));
}

// Return the proposed drop target for a hover open button from the
// given array, or nil if none.  We use this for distinguishing
// between a hover-open candidate or drop-indicator draw.
// Helper for buttonForDroppingOnAtPoint:.
// Get UI review on "middle half" ness.
// http://crbug.com/36276
- (BookmarkButton*)buttonForDroppingOnAtPoint:(NSPoint)point
                                    fromArray:(NSArray*)array {
  for (BookmarkButton* button in array) {
    // Hidden buttons can overlap valid visible buttons, just ignore.
    if ([button isHidden])
      continue;
    // Break early if we've gone too far.
    if ((NSMinX([button frame]) > point.x) || (![button superview]))
      return nil;
    // Careful -- this only applies to the bar with horiz buttons.
    // Intentionally NOT using NSPointInRect() so that scrolling into
    // a submenu doesn't cause it to be closed.
    if (ValueInRangeInclusive(NSMinX([button frame]),
                              point.x,
                              NSMaxX([button frame]))) {
      // Over a button but let's be a little more specific (make sure
      // it's over the middle half, not just over it).
      NSRect frame = [button frame];
      NSRect middleHalfOfButton = NSInsetRect(frame, frame.size.width / 4, 0);
      if (ValueInRangeInclusive(NSMinX(middleHalfOfButton),
                                point.x,
                                NSMaxX(middleHalfOfButton))) {
        // It makes no sense to drop on a non-folder; there is no hover.
        if (![button isFolder])
          return nil;
        // Got it!
        return button;
      } else {
        // Over a button but not over the middle half.
        return nil;
      }
    }
  }
  // Not hovering over a button.
  return nil;
}

// Return the proposed drop target for a hover open button, or nil if
// none.  Works with both the bookmark buttons and the "Other
// Bookmarks" button.  Point is in [self view] coordinates.
- (BookmarkButton*)buttonForDroppingOnAtPoint:(NSPoint)point {
  point = [[self view] convertPoint:point
                           fromView:[[[self view] window] contentView]];

  // If there's a hover button, return it if the point is within its bounds.
  // Since the logic in -buttonForDroppingOnAtPoint:fromArray: only matches a
  // button when the point is over the middle half, this is needed to prevent
  // the button's folder being closed if the mouse temporarily leaves the
  // middle half but is still within the button bounds.
  if (hoverButton_ && NSPointInRect(point, [hoverButton_ frame]))
     return hoverButton_.get();

  BookmarkButton* button = [self buttonForDroppingOnAtPoint:point
                                                  fromArray:buttons_.get()];
  // One more chance -- try "Other Bookmarks" and "off the side" (if visible).
  // This is different than BookmarkBarFolderController.
  if (!button) {
    NSMutableArray* array = [NSMutableArray array];
    if (![self offTheSideButtonIsHidden])
      [array addObject:offTheSideButton_];
    [array addObject:otherBookmarksButton_];
    button = [self buttonForDroppingOnAtPoint:point
                                    fromArray:array];
  }
  return button;
}

- (int)indexForDragToPoint:(NSPoint)point {
  // TODO(jrg): revisit position info based on UI team feedback.
  // dropLocation is in bar local coordinates.
  NSPoint dropLocation =
      [[self view] convertPoint:point
                       fromView:[[[self view] window] contentView]];
  BookmarkButton* buttonToTheRightOfDraggedButton = nil;
  for (BookmarkButton* button in buttons_.get()) {
    CGFloat midpoint = NSMidX([button frame]);
    if (dropLocation.x <= midpoint) {
      buttonToTheRightOfDraggedButton = button;
      break;
    }
  }
  if (buttonToTheRightOfDraggedButton) {
    const BookmarkNode* afterNode =
        [buttonToTheRightOfDraggedButton bookmarkNode];
    DCHECK(afterNode);
    int index = afterNode->parent()->GetIndexOf(afterNode);
    // Make sure we don't get confused by buttons which aren't visible.
    return std::min(index, displayedButtonCount_);
  }

  // If nothing is to my right I am at the end!
  return displayedButtonCount_;
}

// TODO(mrossetti,jrg): Yet more duplicated code.
// http://crbug.com/35966
- (BOOL)dragBookmark:(const BookmarkNode*)sourceNode
                  to:(NSPoint)point
                copy:(BOOL)copy {
  DCHECK(sourceNode);
  // Drop destination.
  const BookmarkNode* destParent = NULL;
  int destIndex = 0;

  // First check if we're dropping on a button.  If we have one, and
  // it's a folder, drop in it.
  BookmarkButton* button = [self buttonForDroppingOnAtPoint:point];
  if ([button isFolder]) {
    destParent = [button bookmarkNode];
    // Drop it at the end.
    destIndex = [button bookmarkNode]->child_count();
  } else {
    // Else we're dropping somewhere on the bar, so find the right spot.
    destParent = bookmarkModel_->bookmark_bar_node();
    destIndex = [self indexForDragToPoint:point];
  }

  // Be sure we don't try and drop a folder into itself.
  if (sourceNode != destParent) {
    if (copy)
      bookmarkModel_->Copy(sourceNode, destParent, destIndex);
    else
      bookmarkModel_->Move(sourceNode, destParent, destIndex);
  }

  [self closeFolderAndStopTrackingMenus];

  // Movement of a node triggers observers (like us) to rebuild the
  // bar so we don't have to do so explicitly.

  return YES;
}

- (void)draggingEnded:(id<NSDraggingInfo>)info {
  [self closeFolderAndStopTrackingMenus];
  [[BookmarkButton draggedButton] setHidden:NO];
  [self resetAllButtonPositionsWithAnimation:YES];
}

// Set insertionPos_ and hasInsertionPos_, and make insertion space for a
// hypothetical drop with the new button having a left edge of |where|.
// Gets called only by our view.
- (void)setDropInsertionPos:(CGFloat)where {
  if (!hasInsertionPos_ || where != insertionPos_) {
    insertionPos_ = where;
    hasInsertionPos_ = YES;
    CGFloat left = [appsPageShortcutButton_ isHidden] ?
        bookmarks::kBookmarkLeftMargin :
        NSMaxX([appsPageShortcutButton_ frame]) +
            bookmarks::kBookmarkHorizontalPadding;
    CGFloat paddingWidth = bookmarks::kDefaultBookmarkWidth;
    BookmarkButton* draggedButton = [BookmarkButton draggedButton];
    if (draggedButton) {
      paddingWidth = std::min(bookmarks::kDefaultBookmarkWidth,
                              NSWidth([draggedButton frame]));
    }
    // Put all the buttons where they belong, with all buttons to the right
    // of the insertion point shuffling right to make space for it.
    for (NSButton* button in buttons_.get()) {
      // Hidden buttons get no space.
      if ([button isHidden])
        continue;
      NSRect buttonFrame = [button frame];
      buttonFrame.origin.x = left;
      // Update "left" for next time around.
      left += buttonFrame.size.width;
      if (left > insertionPos_)
        buttonFrame.origin.x += paddingWidth;
      left += bookmarks::kBookmarkHorizontalPadding;
      if (innerContentAnimationsEnabled_)
        [[button animator] setFrame:buttonFrame];
      else
        [button setFrame:buttonFrame];
    }
  }
}

// Put all visible bookmark bar buttons in their normal locations, either with
// or without animation according to the |animate| flag.
// This is generally useful, so is called from various places internally.
- (void)resetAllButtonPositionsWithAnimation:(BOOL)animate {

  // Position the apps bookmark if needed.
  CGFloat left = bookmarks::kBookmarkLeftMargin;
  if (![appsPageShortcutButton_ isHidden]) {
    int xOffset =
        bookmarks::kBookmarkLeftMargin - bookmarks::kBookmarkHorizontalPadding;
    NSRect frame =
        [self frameForBookmarkButtonFromCell:[appsPageShortcutButton_ cell]
                                     xOffset:&xOffset];
    [appsPageShortcutButton_ setFrame:frame];
    left = xOffset + bookmarks::kBookmarkHorizontalPadding;
  }
  animate &= innerContentAnimationsEnabled_;

  for (NSButton* button in buttons_.get()) {
    // Hidden buttons get no space.
    if ([button isHidden])
      continue;
    NSRect buttonFrame = [button frame];
    buttonFrame.origin.x = left;
    left += buttonFrame.size.width + bookmarks::kBookmarkHorizontalPadding;
    if (animate)
      [[button animator] setFrame:buttonFrame];
    else
      [button setFrame:buttonFrame];
  }
}

// Clear insertion flag, remove insertion space and put all visible bookmark
// bar buttons in their normal locations.
// Gets called only by our view.
- (void)clearDropInsertionPos {
  if (hasInsertionPos_) {
    hasInsertionPos_ = NO;
    [self resetAllButtonPositionsWithAnimation:YES];
  }
}

#pragma mark Bridge Notification Handlers

// TODO(jrg): for now this is brute force.
- (void)loaded:(BookmarkModel*)model {
  DCHECK(model == bookmarkModel_);
  if (!model->loaded())
    return;

  // If this is a rebuild request while we have a folder open, close it.
  // TODO(mrossetti): Eliminate the need for this because it causes the folder
  // menu to disappear after a cut/copy/paste/delete change.
  // See: http://crbug.com/36614
  if (folderController_)
    [self closeAllBookmarkFolders];

  // Brute force nuke and build.
  savedFrameWidth_ = NSWidth([[self view] frame]);
  const BookmarkNode* node = model->bookmark_bar_node();
  [self clearBookmarkBar];
  [self createAppsPageShortcutButton];
  [self addNodesToButtonList:node];
  [self createOtherBookmarksButton];
  [self updateTheme:[[[self view] window] themeProvider]];
  [self positionRightSideButtons];
  [self addButtonsToView];
  [self configureOffTheSideButtonContentsAndVisibility];
  [self reconfigureBookmarkBar];
}

- (void)beingDeleted:(BookmarkModel*)model {
  // The browser may be being torn down; little is safe to do.  As an
  // example, it may not be safe to clear the pasteboard.
  // http://crbug.com/38665
}

- (void)nodeAdded:(BookmarkModel*)model
           parent:(const BookmarkNode*)newParent index:(int)newIndex {
  // If a context menu is open, close it.
  [self cancelMenuTracking];

  const BookmarkNode* newNode = newParent->GetChild(newIndex);
  id<BookmarkButtonControllerProtocol> newController =
      [self controllerForNode:newParent];
  [newController addButtonForNode:newNode atIndex:newIndex];
  // If we go from 0 --> 1 bookmarks we may need to hide the
  // "bookmarks go here" text container.
  [self showOrHideNoItemContainerForNode:model->bookmark_bar_node()];
  // Cope with chevron or "Other Bookmarks" buttons possibly changing state.
  [self reconfigureBookmarkBar];
}

// TODO(jrg): for now this is brute force.
- (void)nodeChanged:(BookmarkModel*)model
               node:(const BookmarkNode*)node {
  [self loaded:model];
}

- (void)nodeMoved:(BookmarkModel*)model
        oldParent:(const BookmarkNode*)oldParent oldIndex:(int)oldIndex
        newParent:(const BookmarkNode*)newParent newIndex:(int)newIndex {
  const BookmarkNode* movedNode = newParent->GetChild(newIndex);
  id<BookmarkButtonControllerProtocol> oldController =
      [self controllerForNode:oldParent];
  id<BookmarkButtonControllerProtocol> newController =
      [self controllerForNode:newParent];
  if (newController == oldController) {
    [oldController moveButtonFromIndex:oldIndex toIndex:newIndex];
  } else {
    [oldController removeButton:oldIndex animate:NO];
    [newController addButtonForNode:movedNode atIndex:newIndex];
  }
  // If the bar is one of the parents we may need to update the visibility
  // of the "bookmarks go here" presentation.
  [self showOrHideNoItemContainerForNode:model->bookmark_bar_node()];
  // Cope with chevron or "Other Bookmarks" buttons possibly changing state.
  [self reconfigureBookmarkBar];
}

- (void)nodeRemoved:(BookmarkModel*)model
             parent:(const BookmarkNode*)oldParent index:(int)index {
  // If a context menu is open, close it.
  [self cancelMenuTracking];

  // Locate the parent node. The parent may not be showing, in which case
  // we do nothing.
  id<BookmarkButtonControllerProtocol> parentController =
      [self controllerForNode:oldParent];
  [parentController removeButton:index animate:YES];
  // If we go from 1 --> 0 bookmarks we may need to show the
  // "bookmarks go here" text container.
  [self showOrHideNoItemContainerForNode:model->bookmark_bar_node()];
  // If we deleted the only item on the "off the side" menu we no
  // longer need to show it.
  [self reconfigureBookmarkBar];
}

// TODO(jrg): linear searching is bad.
// Need a BookmarkNode-->NSCell mapping.
//
// TODO(jrg): if the bookmark bar is open on launch, we see the
// buttons all placed, then "scooted over" as the favicons load.  If
// this looks bad I may need to change widthForBookmarkButtonCell to
// add space for an image even if not there on the assumption that
// favicons will eventually load.
- (void)nodeFaviconLoaded:(BookmarkModel*)model
                     node:(const BookmarkNode*)node {
  for (BookmarkButton* button in buttons_.get()) {
    const BookmarkNode* cellnode = [button bookmarkNode];
    if (cellnode == node) {
      [[button cell] setBookmarkCellText:[button title]
                                   image:[self faviconForNode:node]];
      // Adding an image means we might need more room for the
      // bookmark.  Test for it by growing the button (if needed)
      // and shifting everything else over.
      [self checkForBookmarkButtonGrowth:button];
      return;
    }
  }

  if (folderController_)
    [folderController_ faviconLoadedForNode:node];
}

// TODO(jrg): for now this is brute force.
- (void)nodeChildrenReordered:(BookmarkModel*)model
                         node:(const BookmarkNode*)node {
  [self loaded:model];
}

#pragma mark BookmarkBarState Protocol

// (BookmarkBarState protocol)
- (BOOL)isVisible {
  return barIsEnabled_ && (currentState_ == BookmarkBar::SHOW ||
                           currentState_ == BookmarkBar::DETACHED ||
                           lastState_ == BookmarkBar::SHOW ||
                           lastState_ == BookmarkBar::DETACHED);
}

// (BookmarkBarState protocol)
- (BOOL)isInState:(BookmarkBar::State)state {
  return currentState_ == state && ![self isAnimationRunning];
}

// (BookmarkBarState protocol)
- (BOOL)isAnimatingToState:(BookmarkBar::State)state {
  return currentState_ == state && [self isAnimationRunning];
}

// (BookmarkBarState protocol)
- (BOOL)isAnimatingFromState:(BookmarkBar::State)state {
  return lastState_ == state && [self isAnimationRunning];
}

// (BookmarkBarState protocol)
- (BOOL)isAnimatingFromState:(BookmarkBar::State)fromState
                     toState:(BookmarkBar::State)toState {
  return lastState_ == fromState &&
         currentState_ == toState &&
         [self isAnimationRunning];
}

// (BookmarkBarState protocol)
- (BOOL)isAnimatingBetweenState:(BookmarkBar::State)fromState
                       andState:(BookmarkBar::State)toState {
  return [self isAnimatingFromState:fromState toState:toState] ||
         [self isAnimatingFromState:toState toState:fromState];
}

// (BookmarkBarState protocol)
- (CGFloat)detachedMorphProgress {
  if ([self isInState:BookmarkBar::DETACHED]) {
    return 1;
  }
  if ([self isAnimatingToState:BookmarkBar::DETACHED]) {
    return static_cast<CGFloat>(
        [[self animatableView] currentAnimationProgress]);
  }
  if ([self isAnimatingFromState:BookmarkBar::DETACHED]) {
    return static_cast<CGFloat>(
        1 - [[self animatableView] currentAnimationProgress]);
  }
  return 0;
}

#pragma mark BookmarkBarToolbarViewController Protocol

- (int)currentTabContentsHeight {
  BrowserWindowController* browserController =
      [BrowserWindowController browserWindowControllerForView:[self view]];
  return NSHeight([[browserController tabContentArea] frame]);
}

- (ThemeService*)themeService {
  return ThemeServiceFactory::GetForProfile(browser_->profile());
}

#pragma mark BookmarkButtonDelegate Protocol

- (void)fillPasteboard:(NSPasteboard*)pboard
       forDragOfButton:(BookmarkButton*)button {
  [[self folderTarget] fillPasteboard:pboard forDragOfButton:button];
}

// BookmarkButtonDelegate protocol implementation.  When menus are
// "active" (e.g. you clicked to open one), moving the mouse over
// another folder button should close the 1st and open the 2nd (like
// real menus).  We detect and act here.
- (void)mouseEnteredButton:(id)sender event:(NSEvent*)event {
  DCHECK([sender isKindOfClass:[BookmarkButton class]]);

  // If folder menus are not being shown, do nothing.  This is different from
  // BookmarkBarFolderController's implementation because the bar should NOT
  // automatically open folder menus when the mouse passes over a folder
  // button while the BookmarkBarFolderController DOES automatically open
  // a subfolder menu.
  if (!showFolderMenus_)
    return;

  // From here down: same logic as BookmarkBarFolderController.
  // TODO(jrg): find a way to share these 4 non-comment lines?
  // http://crbug.com/35966
  // If already opened, then we exited but re-entered the button, so do nothing.
  if ([folderController_ parentButton] == sender)
    return;
  // Else open a new one if it makes sense to do so.
  const BookmarkNode* node = [sender bookmarkNode];
  if (node && node->is_folder()) {
    // Update |hoverButton_| so that it corresponds to the open folder.
    hoverButton_.reset([sender retain]);
    [folderTarget_ openBookmarkFolderFromButton:sender];
  } else {
    // We're over a non-folder bookmark so close any old folders.
    [folderController_ close];
    folderController_ = nil;
  }
}

// BookmarkButtonDelegate protocol implementation.
- (void)mouseExitedButton:(id)sender event:(NSEvent*)event {
  // Don't care; do nothing.
  // This is different behavior that the folder menus.
}

- (NSWindow*)browserWindow {
  return [[self view] window];
}

- (BOOL)canDragBookmarkButtonToTrash:(BookmarkButton*)button {
  return [self canEditBookmarks] &&
         [self canEditBookmark:[button bookmarkNode]];
}

- (void)didDragBookmarkToTrash:(BookmarkButton*)button {
  if ([self canDragBookmarkButtonToTrash:button]) {
    const BookmarkNode* node = [button bookmarkNode];
    if (node) {
      const BookmarkNode* parent = node->parent();
      bookmarkModel_->Remove(parent,
                             parent->GetIndexOf(node));
    }
  }
}

- (void)bookmarkDragDidEnd:(BookmarkButton*)button
                 operation:(NSDragOperation)operation {
  [button setHidden:NO];
  [self resetAllButtonPositionsWithAnimation:YES];
}


#pragma mark BookmarkButtonControllerProtocol

// Close all bookmark folders.  "Folder" here is the fake menu for
// bookmark folders, not a button context menu.
- (void)closeAllBookmarkFolders {
  [self watchForExitEvent:NO];
  [folderController_ close];
  folderController_ = nil;
}

- (void)closeBookmarkFolder:(id)sender {
  // We're the top level, so close one means close them all.
  [self closeAllBookmarkFolders];
}

- (BookmarkModel*)bookmarkModel {
  return bookmarkModel_;
}

- (BOOL)draggingAllowed:(id<NSDraggingInfo>)info {
  return [self canEditBookmarks];
}

// TODO(jrg): much of this logic is duped with
// [BookmarkBarFolderController draggingEntered:] except when noted.
// http://crbug.com/35966
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info {
  NSPoint point = [info draggingLocation];
  BookmarkButton* button = [self buttonForDroppingOnAtPoint:point];

  // Don't allow drops that would result in cycles.
  if (button) {
    NSData* data = [[info draggingPasteboard]
                    dataForType:kBookmarkButtonDragType];
    if (data && [info draggingSource]) {
      BookmarkButton* sourceButton = nil;
      [data getBytes:&sourceButton length:sizeof(sourceButton)];
      const BookmarkNode* sourceNode = [sourceButton bookmarkNode];
      const BookmarkNode* destNode = [button bookmarkNode];
      if (destNode->HasAncestor(sourceNode))
        button = nil;
    }
  }

  if ([button isFolder]) {
    if (hoverButton_ == button) {
      return NSDragOperationMove;  // already open or timed to open
    }
    if (hoverButton_) {
      // Oops, another one triggered or open.
      [NSObject cancelPreviousPerformRequestsWithTarget:[hoverButton_
                                                         target]];
      // Unlike BookmarkBarFolderController, we do not delay the close
      // of the previous one.  Given the lack of diagonal movement,
      // there is no need, and it feels awkward to do so.  See
      // comments about kDragHoverCloseDelay in
      // bookmark_bar_folder_controller.mm for more details.
      [[hoverButton_ target] closeBookmarkFolder:hoverButton_];
      hoverButton_.reset();
    }
    hoverButton_.reset([button retain]);
    DCHECK([[hoverButton_ target]
            respondsToSelector:@selector(openBookmarkFolderFromButton:)]);
    [[hoverButton_ target]
     performSelector:@selector(openBookmarkFolderFromButton:)
     withObject:hoverButton_
     afterDelay:bookmarks::kDragHoverOpenDelay
     inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
  }
  if (!button) {
    if (hoverButton_) {
      [NSObject cancelPreviousPerformRequestsWithTarget:[hoverButton_ target]];
      [[hoverButton_ target] closeBookmarkFolder:hoverButton_];
      hoverButton_.reset();
    }
  }

  // Thrown away but kept to be consistent with the draggingEntered: interface.
  return NSDragOperationMove;
}

- (void)draggingExited:(id<NSDraggingInfo>)info {
  // Only close the folder menu if the user dragged up past the BMB. If the user
  // dragged to below the BMB, they might be trying to drop a link into the open
  // folder menu.
  // TODO(asvitkine): Need a way to close the menu if the user dragged below but
  //                  not into the menu.
  NSRect bounds = [[self view] bounds];
  NSPoint origin = [[self view] convertPoint:bounds.origin toView:nil];
  if ([info draggingLocation].y > origin.y + bounds.size.height)
    [self closeFolderAndStopTrackingMenus];

  // NOT the same as a cancel --> we may have moved the mouse into the submenu.
  if (hoverButton_) {
    [NSObject cancelPreviousPerformRequestsWithTarget:[hoverButton_ target]];
    hoverButton_.reset();
  }
}

- (BOOL)dragShouldLockBarVisibility {
  return ![self isInState:BookmarkBar::DETACHED] &&
  ![self isAnimatingToState:BookmarkBar::DETACHED];
}

// TODO(mrossetti,jrg): Yet more code dup with BookmarkBarFolderController.
// http://crbug.com/35966
- (BOOL)dragButton:(BookmarkButton*)sourceButton
                to:(NSPoint)point
              copy:(BOOL)copy {
  DCHECK([sourceButton isKindOfClass:[BookmarkButton class]]);
  const BookmarkNode* sourceNode = [sourceButton bookmarkNode];
  return [self dragBookmark:sourceNode to:point copy:copy];
}

- (BOOL)dragBookmarkData:(id<NSDraggingInfo>)info {
  BOOL dragged = NO;
  std::vector<const BookmarkNode*> nodes([self retrieveBookmarkNodeData]);
  if (nodes.size()) {
    BOOL copy = !([info draggingSourceOperationMask] & NSDragOperationMove);
    NSPoint dropPoint = [info draggingLocation];
    for (std::vector<const BookmarkNode*>::const_iterator it = nodes.begin();
         it != nodes.end(); ++it) {
      const BookmarkNode* sourceNode = *it;
      dragged = [self dragBookmark:sourceNode to:dropPoint copy:copy];
    }
  }
  return dragged;
}

- (std::vector<const BookmarkNode*>)retrieveBookmarkNodeData {
  std::vector<const BookmarkNode*> dragDataNodes;
  BookmarkNodeData dragData;
  if (dragData.ReadFromDragClipboard()) {
    std::vector<const BookmarkNode*> nodes(
        dragData.GetNodes(browser_->profile()));
    dragDataNodes.assign(nodes.begin(), nodes.end());
  }
  return dragDataNodes;
}

// Return YES if we should show the drop indicator, else NO.
- (BOOL)shouldShowIndicatorShownForPoint:(NSPoint)point {
  return ![self buttonForDroppingOnAtPoint:point];
}

// Return the x position for a drop indicator.
- (CGFloat)indicatorPosForDragToPoint:(NSPoint)point {
  CGFloat x = 0;
  CGFloat halfHorizontalPadding = 0.5 * bookmarks::kBookmarkHorizontalPadding;
  int destIndex = [self indexForDragToPoint:point];
  int numButtons = displayedButtonCount_;

  CGFloat leftmostX;
  if ([appsPageShortcutButton_ isHidden])
    leftmostX = bookmarks::kBookmarkLeftMargin - halfHorizontalPadding;
  else
    leftmostX = NSMaxX([appsPageShortcutButton_ frame]) + halfHorizontalPadding;

  // If it's a drop strictly between existing buttons ...
  if (destIndex == 0) {
    x = leftmostX;
  } else if (destIndex > 0 && destIndex < numButtons) {
    // ... put the indicator right between the buttons.
    BookmarkButton* button =
        [buttons_ objectAtIndex:static_cast<NSUInteger>(destIndex-1)];
    DCHECK(button);
    NSRect buttonFrame = [button frame];
    x = NSMaxX(buttonFrame) + halfHorizontalPadding;

    // If it's a drop at the end (past the last button, if there are any) ...
  } else if (destIndex == numButtons) {
    // and if it's past the last button ...
    if (numButtons > 0) {
      // ... find the last button, and put the indicator to its right.
      BookmarkButton* button =
          [buttons_ objectAtIndex:static_cast<NSUInteger>(destIndex - 1)];
      DCHECK(button);
      x = NSMaxX([button frame]) + halfHorizontalPadding;

      // Otherwise, put it right at the beginning.
    } else {
      x = leftmostX;
    }
  } else {
    NOTREACHED();
  }

  return x;
}

- (void)childFolderWillShow:(id<BookmarkButtonControllerProtocol>)child {
  // If the bookmarkbar is not in detached mode, lock bar visibility, forcing
  // the overlay to stay open when in fullscreen mode.
  if (![self isInState:BookmarkBar::DETACHED] &&
      ![self isAnimatingToState:BookmarkBar::DETACHED]) {
    BrowserWindowController* browserController =
        [BrowserWindowController browserWindowControllerForView:[self view]];
    [browserController lockBarVisibilityForOwner:child
                                   withAnimation:NO
                                           delay:NO];
  }
}

- (void)childFolderWillClose:(id<BookmarkButtonControllerProtocol>)child {
  // Release bar visibility, allowing the overlay to close if in fullscreen
  // mode.
  BrowserWindowController* browserController =
      [BrowserWindowController browserWindowControllerForView:[self view]];
  [browserController releaseBarVisibilityForOwner:child
                                    withAnimation:NO
                                            delay:NO];
}

// Add a new folder controller as triggered by the given folder button.
- (void)addNewFolderControllerWithParentButton:(BookmarkButton*)parentButton {

  // If doing a close/open, make sure the fullscreen chrome doesn't
  // have a chance to begin animating away in the middle of things.
  BrowserWindowController* browserController =
      [BrowserWindowController browserWindowControllerForView:[self view]];
  // Confirm we're not re-locking with ourself as an owner before locking.
  DCHECK([browserController isBarVisibilityLockedForOwner:self] == NO);
  [browserController lockBarVisibilityForOwner:self
                                 withAnimation:NO
                                         delay:NO];

  if (folderController_)
    [self closeAllBookmarkFolders];

  // Folder controller, like many window controllers, owns itself.
  folderController_ =
      [[BookmarkBarFolderController alloc]
          initWithParentButton:parentButton
              parentController:nil
                 barController:self
                       profile:browser_->profile()];
  [folderController_ showWindow:self];

  // Only BookmarkBarController has this; the
  // BookmarkBarFolderController does not.
  [self watchForExitEvent:YES];

  // No longer need to hold the lock; the folderController_ now owns it.
  [browserController releaseBarVisibilityForOwner:self
                                    withAnimation:NO
                                            delay:NO];
}

- (void)openAll:(const BookmarkNode*)node
    disposition:(WindowOpenDisposition)disposition {
  [self closeFolderAndStopTrackingMenus];
  chrome::OpenAll([[self view] window], browser_, node, disposition,
                  browser_->profile());
}

- (void)addButtonForNode:(const BookmarkNode*)node
                 atIndex:(NSInteger)buttonIndex {
  int newOffset =
      bookmarks::kBookmarkLeftMargin - bookmarks::kBookmarkHorizontalPadding;
  if (buttonIndex == -1)
    buttonIndex = [buttons_ count];  // New button goes at the end.
  if (buttonIndex <= (NSInteger)[buttons_ count]) {
    if (buttonIndex) {
      BookmarkButton* targetButton = [buttons_ objectAtIndex:buttonIndex - 1];
      NSRect targetFrame = [targetButton frame];
      newOffset = targetFrame.origin.x + NSWidth(targetFrame) +
          bookmarks::kBookmarkHorizontalPadding;
    }
    BookmarkButton* newButton = [self buttonForNode:node xOffset:&newOffset];
    ++displayedButtonCount_;
    [buttons_ insertObject:newButton atIndex:buttonIndex];
    [buttonView_ addSubview:newButton];
    [self resetAllButtonPositionsWithAnimation:NO];
    // See if any buttons need to be pushed off to or brought in from the side.
    [self reconfigureBookmarkBar];
  } else  {
    // A button from somewhere else (not the bar) is being moved to the
    // off-the-side so insure it gets redrawn if its showing.
    [self reconfigureBookmarkBar];
    [folderController_ reconfigureMenu];
  }
}

// TODO(mrossetti): Duplicate code with BookmarkBarFolderController.
// http://crbug.com/35966
- (BOOL)addURLs:(NSArray*)urls withTitles:(NSArray*)titles at:(NSPoint)point {
  DCHECK([urls count] == [titles count]);
  BOOL nodesWereAdded = NO;
  // Figure out where these new bookmarks nodes are to be added.
  BookmarkButton* button = [self buttonForDroppingOnAtPoint:point];
  const BookmarkNode* destParent = NULL;
  int destIndex = 0;
  if ([button isFolder]) {
    destParent = [button bookmarkNode];
    // Drop it at the end.
    destIndex = [button bookmarkNode]->child_count();
  } else {
    // Else we're dropping somewhere on the bar, so find the right spot.
    destParent = bookmarkModel_->bookmark_bar_node();
    destIndex = [self indexForDragToPoint:point];
  }

  // Don't add the bookmarks if the destination index shows an error.
  if (destIndex >= 0) {
    // Create and add the new bookmark nodes.
    size_t urlCount = [urls count];
    for (size_t i = 0; i < urlCount; ++i) {
      GURL gurl;
      const char* string = [[urls objectAtIndex:i] UTF8String];
      if (string)
        gurl = GURL(string);
      // We only expect to receive valid URLs.
      DCHECK(gurl.is_valid());
      if (gurl.is_valid()) {
        bookmarkModel_->AddURL(destParent,
                               destIndex++,
                               base::SysNSStringToUTF16(
                                  [titles objectAtIndex:i]),
                               gurl);
        nodesWereAdded = YES;
      }
    }
  }
  return nodesWereAdded;
}

- (void)moveButtonFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex {
  if (fromIndex != toIndex) {
    NSInteger buttonCount = (NSInteger)[buttons_ count];
    if (toIndex == -1)
      toIndex = buttonCount;
    // See if we have a simple move within the bar, which will be the case if
    // both button indexes are in the visible space.
    if (fromIndex < buttonCount && toIndex < buttonCount) {
      BookmarkButton* movedButton = [buttons_ objectAtIndex:fromIndex];
      [buttons_ removeObjectAtIndex:fromIndex];
      [buttons_ insertObject:movedButton atIndex:toIndex];
      [movedButton setHidden:NO];
      [self resetAllButtonPositionsWithAnimation:NO];
    } else if (fromIndex < buttonCount) {
      // A button is being removed from the bar and added to off-the-side.
      // By now the node has already been inserted into the model so the
      // button to be added is represented by |toIndex|. Things get
      // complicated because the off-the-side is showing and must be redrawn
      // while possibly re-laying out the bookmark bar.
      [self removeButton:fromIndex animate:NO];
      [self reconfigureBookmarkBar];
      [folderController_ reconfigureMenu];
    } else if (toIndex < buttonCount) {
      // A button is being added to the bar and removed from off-the-side.
      // By now the node has already been inserted into the model so the
      // button to be added is represented by |toIndex|.
      const BookmarkNode* node = bookmarkModel_->bookmark_bar_node();
      const BookmarkNode* movedNode = node->GetChild(toIndex);
      DCHECK(movedNode);
      [self addButtonForNode:movedNode atIndex:toIndex];
      [self reconfigureBookmarkBar];
    } else {
      // A button is being moved within the off-the-side.
      fromIndex -= buttonCount;
      toIndex -= buttonCount;
      [folderController_ moveButtonFromIndex:fromIndex toIndex:toIndex];
    }
  }
}

- (void)removeButton:(NSInteger)buttonIndex animate:(BOOL)animate {
  if (buttonIndex < (NSInteger)[buttons_ count]) {
    // The button being removed is showing in the bar.
    BookmarkButton* oldButton = [buttons_ objectAtIndex:buttonIndex];
    if (oldButton == [folderController_ parentButton]) {
      // If we are deleting a button whose folder is currently open, close it!
      [self closeAllBookmarkFolders];
    }
    if (animate && innerContentAnimationsEnabled_ && [self isVisible] &&
        [[self browserWindow] isMainWindow]) {
      NSPoint poofPoint = [oldButton screenLocationForRemoveAnimation];
      NSShowAnimationEffect(NSAnimationEffectDisappearingItemDefault, poofPoint,
                            NSZeroSize, nil, nil, nil);
    }
    [oldButton setDelegate:nil];
    [oldButton removeFromSuperview];
    [buttons_ removeObjectAtIndex:buttonIndex];
    --displayedButtonCount_;
    [self resetAllButtonPositionsWithAnimation:YES];
    [self reconfigureBookmarkBar];
  } else if (folderController_ &&
             [folderController_ parentButton] == offTheSideButton_) {
    // The button being removed is in the OTS (off-the-side) and the OTS
    // menu is showing so we need to remove the button.
    NSInteger index = buttonIndex - displayedButtonCount_;
    [folderController_ removeButton:index animate:YES];
  }
}

- (id<BookmarkButtonControllerProtocol>)controllerForNode:
    (const BookmarkNode*)node {
  // See if it's in the bar, then if it is in the hierarchy of visible
  // folder menus.
  if (bookmarkModel_->bookmark_bar_node() == node)
    return self;
  return [folderController_ controllerForNode:node];
}

@end
