// 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/toolbar/toolbar_controller.h"

#include <algorithm>

#include "base/mac/bundle_locations.h"
#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/mac/sdk_forward_declarations.h"
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/command_observer.h"
#include "chrome/browser/command_updater.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/sync/sync_global_error_factory.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_window.h"
#import "chrome/browser/ui/cocoa/app_menu/app_menu_controller.h"
#import "chrome/browser/ui/cocoa/background_gradient_view.h"
#include "chrome/browser/ui/cocoa/drag_util.h"
#import "chrome/browser/ui/cocoa/extensions/browser_action_button.h"
#import "chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h"
#import "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h"
#import "chrome/browser/ui/cocoa/gradient_button_cell.h"
#import "chrome/browser/ui/cocoa/image_button_cell.h"
#import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h"
#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
#import "chrome/browser/ui/cocoa/menu_button.h"
#import "chrome/browser/ui/cocoa/toolbar/app_toolbar_button.h"
#import "chrome/browser/ui/cocoa/toolbar/app_toolbar_button_cell.h"
#import "chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.h"
#import "chrome/browser/ui/cocoa/toolbar/reload_button_cocoa.h"
#import "chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.h"
#import "chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.h"
#import "chrome/browser/ui/cocoa/view_id_util.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/toolbar/app_menu_icon_controller.h"
#include "chrome/browser/ui/toolbar/app_menu_model.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h"
#include "components/metrics/proto/omnibox_event.pb.h"
#include "components/omnibox/browser/autocomplete_classifier.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/omnibox_edit_model.h"
#include "components/omnibox/browser/omnibox_view.h"
#include "components/prefs/pref_service.h"
#include "components/search_engines/template_url_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/url_formatter/url_fixer.h"
#include "content/public/browser/web_contents.h"
#import "ui/base/cocoa/menu_controller.h"
#import "ui/base/cocoa/nsview_additions.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_mac.h"
#include "ui/base/material_design/material_design_controller.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/image/image.h"

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

namespace {

// Duration of the toolbar animation.
const NSTimeInterval kToolBarAnimationDuration = 0.12;

// The height of the location bar in Material Design.
const CGFloat kMaterialDesignLocationBarHeight = 28;

// The padding between the top of the toolbar and the top of the
// location bar.
const CGFloat kMaterialDesignLocationBarPadding = 2;

// The padding between Material Design elements and the edges of the toolbar.
const CGFloat kMaterialDesignElementPadding = 4;

// Toolbar buttons are 24x24 and centered in a 28x28 space, so there is a 2pt-
// wide inset.
const CGFloat kMaterialDesignButtonInset = 2;

// The y-offset of the browser actions container from the location bar.
const CGFloat kMaterialDesignContainerYOffset = 2;

// The minimum width of the location bar in pixels.
const CGFloat kMinimumLocationBarWidth = 100.0;

class BrowserActionsContainerDelegate :
    public BrowserActionsContainerViewSizeDelegate {
 public:
  BrowserActionsContainerDelegate(
      AutocompleteTextField* location_bar,
      BrowserActionsContainerView* browser_actions_container_view);
  ~BrowserActionsContainerDelegate() override;

 private:
  // BrowserActionsContainerSizeDelegate:
  CGFloat GetMaxAllowedWidth() override;

  AutocompleteTextField* location_bar_;
  BrowserActionsContainerView* browser_actions_container_;

  DISALLOW_COPY_AND_ASSIGN(BrowserActionsContainerDelegate);
};

BrowserActionsContainerDelegate::BrowserActionsContainerDelegate(
    AutocompleteTextField* location_bar,
    BrowserActionsContainerView* browser_actions_container_view)
    : location_bar_(location_bar),
      browser_actions_container_(browser_actions_container_view) {
  [browser_actions_container_ setDelegate:this];
}

BrowserActionsContainerDelegate::~BrowserActionsContainerDelegate() {
  [browser_actions_container_ setDelegate:nil];
}

CGFloat BrowserActionsContainerDelegate::GetMaxAllowedWidth() {
  CGFloat location_bar_flex =
      NSWidth([location_bar_ frame]) - kMinimumLocationBarWidth;
  return NSWidth([browser_actions_container_ frame]) + location_bar_flex;
}

}  // namespace

@interface ToolbarController()
@property(assign, nonatomic) Browser* browser;
// Height of the location bar. Used for animating the toolbar in and out when
// the location bar is displayed stand-alone for bookmark apps.
+ (CGFloat)locationBarHeight;
// Return the amount of left padding that the app menu should have.
+ (CGFloat)appMenuLeftPadding;
- (void)cleanUp;
- (void)addAccessibilityDescriptions;
- (void)initCommandStatus:(CommandUpdater*)commands;
- (void)prefChanged:(const std::string&)prefName;
- (ToolbarView*)toolbarView;
// Height of the toolbar in pixels when the bookmark bar is closed.
- (CGFloat)baseToolbarHeight;
- (void)toolbarFrameChanged;
- (void)showLocationBarOnly;
- (void)pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:(BOOL)animate;
- (void)maintainMinimumLocationBarWidth;
- (void)adjustBrowserActionsContainerForNewWindow:(NSNotification*)notification;
- (void)browserActionsContainerDragged:(NSNotification*)notification;
- (void)browserActionsVisibilityChanged:(NSNotification*)notification;
- (void)browserActionsContainerWillAnimate:(NSNotification*)notification;
- (void)adjustLocationSizeBy:(CGFloat)dX animate:(BOOL)animate;
- (void)updateAppMenuButtonSeverity:(AppMenuIconPainter::Severity)severity
                           iconType:(AppMenuIconController::IconType)iconType
                            animate:(BOOL)animate;
@end

namespace ToolbarControllerInternal {

// A C++ bridge class that handles listening for updates to commands and
// passing them back to ToolbarController. ToolbarController will create one of
// these bridges, pass them to CommandUpdater::AddCommandObserver, and then wait
// for update notifications, delivered via
// -enabledStateChangedForCommand:enabled:.
class CommandObserverBridge : public CommandObserver {
 public:
  explicit CommandObserverBridge(ToolbarController* observer)
      : observer_(observer) {
    DCHECK(observer_);
  }

 protected:
  // Overridden from CommandObserver
  void EnabledStateChangedForCommand(int command, bool enabled) override {
    [observer_ enabledStateChangedForCommand:command enabled:enabled];
  }

 private:
  ToolbarController* observer_;  // weak, owns me

  DISALLOW_COPY_AND_ASSIGN(CommandObserverBridge);
};

// A class registered for C++ notifications. This is used to detect changes in
// preferences and upgrade available notifications. Bridges the notification
// back to the ToolbarController.
class NotificationBridge : public AppMenuIconController::Delegate {
 public:
  explicit NotificationBridge(ToolbarController* controller)
      : controller_(controller),
        app_menu_icon_controller_([controller browser]->profile(), this) {}
  ~NotificationBridge() override {}

  void UpdateSeverity() { app_menu_icon_controller_.UpdateDelegate(); }

  void UpdateSeverity(AppMenuIconController::IconType type,
                      AppMenuIconPainter::Severity severity,
                      bool animate) override {
    [controller_ updateAppMenuButtonSeverity:severity
                                    iconType:type
                                     animate:animate];
  }

  void OnPreferenceChanged(const std::string& pref_name) {
    [controller_ prefChanged:pref_name];
  }

 private:
  ToolbarController* controller_;  // weak, owns us

  AppMenuIconController app_menu_icon_controller_;

  DISALLOW_COPY_AND_ASSIGN(NotificationBridge);
};

}  // namespace ToolbarControllerInternal

@implementation ToolbarController

@synthesize browser = browser_;

+ (CGFloat)locationBarHeight {
  if (!ui::MaterialDesignController::IsModeMaterial()) {
    return 29;
  }

  return kMaterialDesignLocationBarHeight;
}

+ (CGFloat)appMenuLeftPadding {
  if (!ui::MaterialDesignController::IsModeMaterial()) {
    return 3;
  }

  return kMaterialDesignElementPadding;
}

+ (CGFloat)materialDesignButtonInset {
  return kMaterialDesignButtonInset;
}

- (id)initWithCommands:(CommandUpdater*)commands
               profile:(Profile*)profile
               browser:(Browser*)browser
        resizeDelegate:(id<ViewResizer>)resizeDelegate {
  DCHECK(commands && profile);
  if ((self = [super initWithNibName:@"Toolbar"
                              bundle:base::mac::FrameworkBundle()])) {
    commands_ = commands;
    profile_ = profile;
    browser_ = browser;
    hasToolbar_ = YES;
    hasLocationBar_ = YES;

    // Register for notifications about state changes for the toolbar buttons
    commandObserver_.reset(
        new ToolbarControllerInternal::CommandObserverBridge(self));

    commands->AddCommandObserver(IDC_BACK, commandObserver_.get());
    commands->AddCommandObserver(IDC_FORWARD, commandObserver_.get());
    commands->AddCommandObserver(IDC_RELOAD, commandObserver_.get());
    commands->AddCommandObserver(IDC_HOME, commandObserver_.get());
    commands->AddCommandObserver(IDC_BOOKMARK_PAGE, commandObserver_.get());
    // NOTE: Don't remove the command observers. ToolbarController is
    // autoreleased at about the same time as the CommandUpdater (owned by the
    // Browser), so |commands_| may not be valid any more.

    [[self toolbarView] setResizeDelegate:resizeDelegate];

    // Start global error services now so we badge the menu correctly.
    SyncGlobalErrorFactory::GetForProfile(profile);
  }
  return self;
}

// Called after the view is done loading and the outlets have been hooked up.
// Now we can hook up bridges that rely on UI objects such as the location bar
// and button state. -viewDidLoad is the recommended way to do this in 10.10
// SDK. When running on 10.10 or above -awakeFromNib still works but for some
// reason is not guaranteed to be called (http://crbug.com/526276), so implement
// both.
- (void)awakeFromNib {
  [self viewDidLoad];
}

- (void)viewDidLoad {
  // When linking and running on 10.10+, both -awakeFromNib and -viewDidLoad may
  // be called, don't initialize twice.
  if (locationBarView_) {
    DCHECK(base::mac::IsAtLeastOS10_10());
    return;
  }

  // Make Material Design layout adjustments to the NIB items.
  bool isModeMaterial = ui::MaterialDesignController::IsModeMaterial();
  if (isModeMaterial) {
    ToolbarView* toolbarView = [self toolbarView];
    NSRect toolbarBounds = [toolbarView bounds];
    NSSize toolbarButtonSize = [ToolbarButton toolbarButtonSize];

    // Set the toolbar height.
    NSRect frame = [toolbarView frame];
    frame.size.height = [self baseToolbarHeight];
    [toolbarView setFrame:frame];

    NSRect backButtonFrame = [backButton_ frame];
    backButtonFrame.origin.x =
        kMaterialDesignElementPadding + kMaterialDesignButtonInset;
    backButtonFrame.origin.y = NSMaxY(toolbarBounds) -
        kMaterialDesignElementPadding - toolbarButtonSize.height;
    backButtonFrame.size = toolbarButtonSize;
    [backButton_ setFrame:backButtonFrame];

    NSRect forwardButtonFrame = [forwardButton_ frame];
    forwardButtonFrame.origin.x =
        NSMaxX(backButtonFrame) + 2 * kMaterialDesignButtonInset;
    forwardButtonFrame.origin.y = backButtonFrame.origin.y;
    forwardButtonFrame.size = toolbarButtonSize;
    [forwardButton_ setFrame:forwardButtonFrame];

    NSRect reloadButtonFrame = [reloadButton_ frame];
    reloadButtonFrame.origin.x =
        NSMaxX(forwardButtonFrame) + 2 * kMaterialDesignButtonInset;
    reloadButtonFrame.origin.y = forwardButtonFrame.origin.y;
    reloadButtonFrame.size = toolbarButtonSize;
    [reloadButton_ setFrame:reloadButtonFrame];

    NSRect homeButtonFrame = [homeButton_ frame];
    homeButtonFrame.origin.x =
        NSMaxX(reloadButtonFrame) + 2 * kMaterialDesignButtonInset;
    homeButtonFrame.origin.y = reloadButtonFrame.origin.y;
    homeButtonFrame.size = toolbarButtonSize;
    [homeButton_ setFrame:homeButtonFrame];

    // Replace the app button from the nib with an AppToolbarButton instance for
    // Material Design.
    AppToolbarButton* newMenuButton =
        [[[AppToolbarButton alloc] initWithFrame:[appMenuButton_ frame]]
            autorelease];
    [newMenuButton setAutoresizingMask:[appMenuButton_ autoresizingMask]];
    [[appMenuButton_ superview] addSubview:newMenuButton];
    [appMenuButton_ removeFromSuperview];
    appMenuButton_ = newMenuButton;

    // Adjust the menu button's position.
    NSRect menuButtonFrame = [appMenuButton_ frame];
    CGFloat menuButtonFrameMaxX =
        NSMaxX(toolbarBounds) - [ToolbarController appMenuLeftPadding];
    menuButtonFrame.origin.x =
        menuButtonFrameMaxX - kMaterialDesignButtonInset -
            toolbarButtonSize.width;
    menuButtonFrame.origin.y = homeButtonFrame.origin.y;
    menuButtonFrame.size = toolbarButtonSize;
    [appMenuButton_ setFrame:menuButtonFrame];

    // Adjust the size and location on the location bar to take up the
    // space between the reload and menu buttons.
    NSRect locationBarFrame = [locationBar_ frame];
    locationBarFrame.origin.x = NSMaxX(homeButtonFrame) +
        kMaterialDesignButtonInset;
    if (![homeButton_ isHidden]) {
      // Ensure proper spacing between the home button and the location bar.
      locationBarFrame.origin.x += kMaterialDesignElementPadding;
    }
    locationBarFrame.origin.y = NSMaxY(toolbarBounds) -
        kMaterialDesignLocationBarPadding - kMaterialDesignLocationBarHeight;
    locationBarFrame.size.width =
        menuButtonFrame.origin.x -
            locationBarFrame.origin.x;
    locationBarFrame.size.height = kMaterialDesignLocationBarHeight;
    [locationBar_ setFrame:locationBarFrame];

    // Correctly position the extension buttons' container view.
    NSRect containerFrame = [browserActionsContainerView_ frame];
    containerFrame.size.width += kMaterialDesignButtonInset;
    containerFrame.origin.y =
        locationBarFrame.origin.y + kMaterialDesignContainerYOffset;
    containerFrame.size.height = toolbarButtonSize.height;
    [browserActionsContainerView_ setFrame:containerFrame];
  } else {
    [[backButton_ cell] setImageID:IDR_BACK
                    forButtonState:image_button_cell::kDefaultState];
    [[backButton_ cell] setImageID:IDR_BACK_H
                    forButtonState:image_button_cell::kHoverState];
    [[backButton_ cell] setImageID:IDR_BACK_P
                    forButtonState:image_button_cell::kPressedState];
    [[backButton_ cell] setImageID:IDR_BACK_D
                    forButtonState:image_button_cell::kDisabledState];

    [[forwardButton_ cell] setImageID:IDR_FORWARD
                       forButtonState:image_button_cell::kDefaultState];
    [[forwardButton_ cell] setImageID:IDR_FORWARD_H
                       forButtonState:image_button_cell::kHoverState];
    [[forwardButton_ cell] setImageID:IDR_FORWARD_P
                       forButtonState:image_button_cell::kPressedState];
    [[forwardButton_ cell] setImageID:IDR_FORWARD_D
                       forButtonState:image_button_cell::kDisabledState];

    [[reloadButton_ cell] setImageID:IDR_RELOAD
                      forButtonState:image_button_cell::kDefaultState];
    [[reloadButton_ cell] setImageID:IDR_RELOAD_H
                      forButtonState:image_button_cell::kHoverState];
    [[reloadButton_ cell] setImageID:IDR_RELOAD_P
                      forButtonState:image_button_cell::kPressedState];

    [[homeButton_ cell] setImageID:IDR_HOME
                    forButtonState:image_button_cell::kDefaultState];
    [[homeButton_ cell] setImageID:IDR_HOME_H
                    forButtonState:image_button_cell::kHoverState];
    [[homeButton_ cell] setImageID:IDR_HOME_P
                    forButtonState:image_button_cell::kPressedState];

    [[appMenuButton_ cell] setImageID:IDR_TOOLS
                       forButtonState:image_button_cell::kDefaultState];
    [[appMenuButton_ cell] setImageID:IDR_TOOLS_H
                       forButtonState:image_button_cell::kHoverState];
    [[appMenuButton_ cell] setImageID:IDR_TOOLS_P
                       forButtonState:image_button_cell::kPressedState];

    // Adjust the toolbar height if running on Retina - see the comment in
    // -baseToolbarHeight.
    CGFloat toolbarHeight = [self baseToolbarHeight];
    ToolbarView* toolbarView = [self toolbarView];
    NSRect toolbarFrame = [toolbarView frame];
    if (toolbarFrame.size.height != toolbarHeight) {
      toolbarFrame.size.height = toolbarHeight;
      [toolbarView setFrame:toolbarFrame];
    }
  }

  notificationBridge_.reset(
      new ToolbarControllerInternal::NotificationBridge(self));
  notificationBridge_->UpdateSeverity();

  [appMenuButton_ setOpenMenuOnClick:YES];

  [backButton_ setOpenMenuOnRightClick:YES];
  [forwardButton_ setOpenMenuOnRightClick:YES];

  [backButton_ setHandleMiddleClick:YES];
  [forwardButton_ setHandleMiddleClick:YES];
  [reloadButton_ setHandleMiddleClick:YES];
  [homeButton_ setHandleMiddleClick:YES];

  [self initCommandStatus:commands_];
  [reloadButton_ setCommandUpdater:commands_];

  locationBarView_.reset(new LocationBarViewMac(locationBar_, commands_,
                                                profile_, browser_));
  [locationBar_ setFont:[NSFont systemFontOfSize:14]];

  // Add the location bar's accessibility views as direct subviews of the
  // toolbar. They are logical children of the location bar, but the location
  // bar's actual Cocoa control is an NSCell, so it cannot have child views.
  // The |locationBarView_| is responsible for positioning the accessibility
  // views.
  std::vector<NSView*> accessibility_views =
      locationBarView_->GetDecorationAccessibilityViews();
  for (const auto& view : accessibility_views) {
    [[self toolbarView] addSubview:view
                        positioned:NSWindowAbove
                        relativeTo:locationBar_];
  }

  if (!isModeMaterial) {
    [locationBar_ setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
  }

  // Register pref observers for the optional home and page/options buttons
  // and then add them to the toolbar based on those prefs.
  PrefService* prefs = profile_->GetPrefs();
  showHomeButton_.Init(
      prefs::kShowHomeButton, prefs,
      base::Bind(
          &ToolbarControllerInternal::NotificationBridge::OnPreferenceChanged,
          base::Unretained(notificationBridge_.get())));
  [self showOptionalHomeButton];
  [self installAppMenu];

  [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:NO];

  // Create the controllers for the back/forward menus.
  backMenuController_.reset([[BackForwardMenuController alloc]
          initWithBrowser:browser_
                modelType:BACK_FORWARD_MENU_TYPE_BACK
                   button:backButton_]);
  forwardMenuController_.reset([[BackForwardMenuController alloc]
          initWithBrowser:browser_
                modelType:BACK_FORWARD_MENU_TYPE_FORWARD
                   button:forwardButton_]);

  trackingArea_.reset(
      [[CrTrackingArea alloc] initWithRect:NSZeroRect // Ignored
                                   options:NSTrackingMouseMoved |
                                           NSTrackingInVisibleRect |
                                           NSTrackingMouseEnteredAndExited |
                                           NSTrackingActiveAlways
                                     owner:self
                                  userInfo:nil]);
  NSView* toolbarView = [self view];
  [toolbarView addTrackingArea:trackingArea_.get()];

  // If the user has any Browser Actions installed, the container view for them
  // may have to be resized depending on the width of the toolbar frame.
  [toolbarView setPostsFrameChangedNotifications:YES];
  [[NSNotificationCenter defaultCenter]
      addObserver:self
         selector:@selector(toolbarFrameChanged)
             name:NSViewFrameDidChangeNotification
           object:toolbarView];

  // Set ViewIDs for toolbar elements which don't have their dedicated class.
  // ViewIDs of |toolbarView|, |reloadButton_|, |locationBar_| and
  // |browserActionsContainerView_| are handled by themselves.
  view_id_util::SetID(backButton_, VIEW_ID_BACK_BUTTON);
  view_id_util::SetID(forwardButton_, VIEW_ID_FORWARD_BUTTON);
  view_id_util::SetID(homeButton_, VIEW_ID_HOME_BUTTON);
  view_id_util::SetID(appMenuButton_, VIEW_ID_APP_MENU);

  [self addAccessibilityDescriptions];
}

- (void)dealloc {
  [self cleanUp];
  [super dealloc];
}

- (void)browserWillBeDestroyed {
  // Clear resize delegate so it doesn't get called during stopAnimation, and
  // stop any in-flight animation.
  [[self toolbarView] setResizeDelegate:nil];
  [[self toolbarView] stopAnimation];

  // Pass this call onto other reference counted objects.
  [backMenuController_ browserWillBeDestroyed];
  [forwardMenuController_ browserWillBeDestroyed];
  [browserActionsController_ browserWillBeDestroyed];
  [appMenuController_ browserWillBeDestroyed];

  [self cleanUp];
}

- (void)cleanUp {
  // Unset ViewIDs of toolbar elements.
  // ViewIDs of |toolbarView|, |reloadButton_|, |locationBar_| and
  // |browserActionsContainerView_| are handled by themselves.
  view_id_util::UnsetID(backButton_);
  view_id_util::UnsetID(forwardButton_);
  view_id_util::UnsetID(homeButton_);
  view_id_util::UnsetID(appMenuButton_);

  // Make sure any code in the base class which assumes [self view] is
  // the "parent" view continues to work.
  hasToolbar_ = YES;
  hasLocationBar_ = YES;

  [[NSNotificationCenter defaultCenter] removeObserver:self];

  if (trackingArea_.get()) {
    [[self view] removeTrackingArea:trackingArea_.get()];
    [trackingArea_.get() clearOwner];
    trackingArea_.reset();
  }

  // Destroy owned objects that hold a weak Browser*.
  locationBarView_.reset();
  browserActionsContainerDelegate_.reset();
  browser_ = nullptr;
}

- (void)addAccessibilityDescriptions {
  // Set accessibility descriptions. http://openradar.appspot.com/7496255
  NSString* description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_BACK);
  [[backButton_ cell]
      accessibilitySetOverrideValue:description
                       forAttribute:NSAccessibilityDescriptionAttribute];
  NSString* helpTag = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_TOOLTIP_BACK);
  [[backButton_ cell]
      accessibilitySetOverrideValue:helpTag
                       forAttribute:NSAccessibilityHelpAttribute];

  description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_FORWARD);
  [[forwardButton_ cell]
      accessibilitySetOverrideValue:description
                       forAttribute:NSAccessibilityDescriptionAttribute];
  helpTag = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_TOOLTIP_FORWARD);
  [[forwardButton_ cell]
      accessibilitySetOverrideValue:helpTag
                       forAttribute:NSAccessibilityHelpAttribute];

  description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_RELOAD);
  [[reloadButton_ cell]
      accessibilitySetOverrideValue:description
                       forAttribute:NSAccessibilityDescriptionAttribute];
  description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_HOME);
  [[homeButton_ cell]
      accessibilitySetOverrideValue:description
                       forAttribute:NSAccessibilityDescriptionAttribute];
  description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_LOCATION);
  [[locationBar_ cell]
      accessibilitySetOverrideValue:description
                       forAttribute:NSAccessibilityDescriptionAttribute];
  description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_APP);
  [[appMenuButton_ cell]
      accessibilitySetOverrideValue:description
                       forAttribute:NSAccessibilityDescriptionAttribute];
}

- (void)mouseExited:(NSEvent*)theEvent {
  [[hoveredButton_ cell] setIsMouseInside:NO];
  [hoveredButton_ release];
  hoveredButton_ = nil;
}

- (NSButton*)hoverButtonForEvent:(NSEvent*)theEvent {
  NSButton* targetView = (NSButton*)[[self view]
                                     hitTest:[theEvent locationInWindow]];

  // Only interpret the view as a hoverButton_ if it's both button and has a
  // button cell that cares.  GradientButtonCell derived cells care.
  if (([targetView isKindOfClass:[NSButton class]]) &&
      ([[targetView cell]
         respondsToSelector:@selector(setIsMouseInside:)]))
    return targetView;
  return nil;
}

- (void)mouseMoved:(NSEvent*)theEvent {
  NSButton* targetView = [self hoverButtonForEvent:theEvent];
  if (hoveredButton_ != targetView) {
    [[hoveredButton_ cell] setIsMouseInside:NO];
    [[targetView cell] setIsMouseInside:YES];
    [hoveredButton_ release];
    hoveredButton_ = [targetView retain];
  }
}

- (void)mouseEntered:(NSEvent*)event {
  [self mouseMoved:event];
}

- (LocationBarViewMac*)locationBarBridge {
  return locationBarView_.get();
}

- (void)locationBarWasAddedToWindow {
  // Allow the |locationBarView_| to update itself to match the browser window
  // theme.
  locationBarView_->OnAddedToWindow();
}

- (void)focusLocationBar:(BOOL)selectAll {
  if (locationBarView_.get()) {
    locationBarView_->FocusLocation(selectAll ? true : false);
  }
}

// Called when the state for a command changes to |enabled|. Update the
// corresponding UI element.
- (void)enabledStateChangedForCommand:(int)command enabled:(bool)enabled {
  NSButton* button = nil;
  switch (command) {
    case IDC_BACK:
      button = backButton_;
      break;
    case IDC_FORWARD:
      button = forwardButton_;
      break;
    case IDC_HOME:
      button = homeButton_;
      break;
  }
  [button setEnabled:enabled];
}

// Init the enabled state of the buttons on the toolbar to match the state in
// the controller.
- (void)initCommandStatus:(CommandUpdater*)commands {
  [backButton_ setEnabled:commands->IsCommandEnabled(IDC_BACK) ? YES : NO];
  [forwardButton_
      setEnabled:commands->IsCommandEnabled(IDC_FORWARD) ? YES : NO];
  [reloadButton_ setEnabled:YES];
  [homeButton_ setEnabled:commands->IsCommandEnabled(IDC_HOME) ? YES : NO];
}

- (void)updateToolbarWithContents:(WebContents*)tab {
  locationBarView_->Update(tab);

  [locationBar_ updateMouseTracking];

  if (browserActionsController_.get()) {
    [browserActionsController_ update];
  }

  BOOL needReloadMenu = chrome::IsDebuggerAttachedToCurrentTab(browser_);
  [reloadButton_ setMenuEnabled:needReloadMenu];
}

- (void)resetTabState:(WebContents*)tab {
  locationBarView_->ResetTabState(tab);
}

- (void)setStarredState:(BOOL)isStarred {
  locationBarView_->SetStarred(isStarred);
}

- (void)setTranslateIconLit:(BOOL)on {
  locationBarView_->SetTranslateIconLit(on);
}

- (void)zoomChangedForActiveTab:(BOOL)canShowBubble {
  locationBarView_->ZoomChangedForActiveTab(
      canShowBubble && ![appMenuController_ isMenuOpen]);
}

- (void)setIsLoading:(BOOL)isLoading force:(BOOL)force {
  [reloadButton_ setIsLoading:isLoading force:force];
}

- (void)setHasToolbar:(BOOL)toolbar hasLocationBar:(BOOL)locBar {
  [self view];  // Force nib loading.

  hasToolbar_ = toolbar;

  // If there's a toolbar, there must be a location bar.
  DCHECK((toolbar && locBar) || !toolbar);
  hasLocationBar_ = toolbar ? YES : locBar;

  // Decide whether to hide/show based on whether there's a location bar.
  [[self view] setHidden:!hasLocationBar_];

  // Make location bar not editable when in a pop-up or an app window.
  locationBarView_->SetEditable(toolbar);

  // If necessary, resize the location bar and hide the toolbar icons to display
  // the toolbar with only the location bar inside it.
  if (!hasToolbar_ && hasLocationBar_)
    [self showLocationBarOnly];
}

// (Private) Returns the backdrop to the toolbar as a ToolbarView.
- (ToolbarView*)toolbarView{
  return base::mac::ObjCCastStrict<ToolbarView>([self view]);
}

- (id)customFieldEditorForObject:(id)obj {
  if (obj == locationBar_) {
    // Lazilly construct Field editor, Cocoa UI code always runs on the
    // same thread, so there shoudn't be a race condition here.
    if (autocompleteTextFieldEditor_.get() == nil) {
      autocompleteTextFieldEditor_.reset(
          [[AutocompleteTextFieldEditor alloc] init]);
    }

    // This needs to be called every time, otherwise notifications
    // aren't sent correctly.
    DCHECK(autocompleteTextFieldEditor_.get());
    [autocompleteTextFieldEditor_.get() setFieldEditor:YES];
    return autocompleteTextFieldEditor_.get();
  }
  return nil;
}

// Returns an array of views in the order of the outlets above.
- (NSArray*)toolbarViews {
  return [NSArray arrayWithObjects:backButton_, forwardButton_, reloadButton_,
                                   homeButton_, appMenuButton_, locationBar_,
                                   browserActionsContainerView_, nil];
}

// Moves |rect| to the right by |delta|, keeping the right side fixed by
// shrinking the width to compensate. Passing a negative value for |deltaX|
// moves to the left and increases the width.
- (NSRect)adjustRect:(NSRect)rect byAmount:(CGFloat)deltaX {
  NSRect frame = NSOffsetRect(rect, deltaX, 0);
  frame.size.width -= deltaX;
  return frame;
}

// Show or hide the home button based on the pref.
- (void)showOptionalHomeButton {
  // Ignore this message if only showing the URL bar.
  if (!hasToolbar_)
    return;
  BOOL hide = showHomeButton_.GetValue() ? NO : YES;
  if (hide == [homeButton_ isHidden])
    return;  // Nothing to do, view state matches pref state.

  // Always shift the text field by the width of the home button minus one pixel
  // since the frame edges of each button are right on top of each other. When
  // hiding the button, reverse the direction of the movement (to the left).
  CGFloat moveX = [homeButton_ frame].size.width;
  if (!ui::MaterialDesignController::IsModeMaterial()) {
    moveX -= 1.0;
  } else {
    // Ensure proper spacing between the home button and the location bar.
    moveX += kMaterialDesignElementPadding;
  }
  if (hide)
    moveX *= -1;  // Reverse the direction of the move.

  [locationBar_ setFrame:[self adjustRect:[locationBar_ frame]
                                 byAmount:moveX]];
  [homeButton_ setHidden:hide];
}

// Install the app menu buttons. Calling this repeatedly is inexpensive so it
// can be done every time the buttons are shown.
- (void)installAppMenu {
  if (appMenuController_.get())
    return;

  appMenuController_.reset(
      [[AppMenuController alloc] initWithBrowser:browser_]);
  [appMenuController_ setUseWithPopUpButtonCell:YES];
  [appMenuButton_ setAttachedMenu:[appMenuController_ menu]];
}

- (void)updateAppMenuButtonSeverity:(AppMenuIconPainter::Severity)severity
                           iconType:(AppMenuIconController::IconType)iconType
                            animate:(BOOL)animate {
  if (!ui::MaterialDesignController::IsModeMaterial()) {
    AppToolbarButtonCell* cell =
        base::mac::ObjCCastStrict<AppToolbarButtonCell>([appMenuButton_ cell]);
    [cell setSeverity:severity shouldAnimate:animate];
    return;
  }
  AppToolbarButton* appMenuButton =
      base::mac::ObjCCastStrict<AppToolbarButton>(appMenuButton_);
  [appMenuButton setSeverity:severity iconType:iconType shouldAnimate:animate];
}

- (void)prefChanged:(const std::string&)prefName {
  if (prefName == prefs::kShowHomeButton) {
    [self showOptionalHomeButton];
  }
}

- (void)createBrowserActionButtons {
  if (!browserActionsController_.get()) {
    browserActionsContainerDelegate_.reset(
        new BrowserActionsContainerDelegate(locationBar_,
                                            browserActionsContainerView_));
    browserActionsController_.reset([[BrowserActionsController alloc]
            initWithBrowser:browser_
              containerView:browserActionsContainerView_
             mainController:nil]);
    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(browserActionsContainerDragged:)
               name:kBrowserActionGrippyDraggingNotification
             object:browserActionsContainerView_];
    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(browserActionsVisibilityChanged:)
               name:kBrowserActionVisibilityChangedNotification
             object:browserActionsController_];
    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(browserActionsContainerWillAnimate:)
               name:kBrowserActionsContainerWillAnimate
             object:browserActionsContainerView_];
    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(adjustBrowserActionsContainerForNewWindow:)
               name:NSWindowDidBecomeKeyNotification
             object:[[self view] window]];
  }
  if (![browserActionsContainerView_ isHidden])
    [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:NO];
}

- (void)updateVisibility:(BOOL)visible withAnimation:(BOOL)animate {
  CGFloat newHeight = visible ? [ToolbarController locationBarHeight] : 0;

  // Perform the animation, which will cause the BrowserWindowController to
  // resize this view in the browser layout as required.
  if (animate) {
    [[self toolbarView] animateToNewHeight:newHeight
                                  duration:kToolBarAnimationDuration];
  } else {
    [[self toolbarView] setHeight:newHeight];
  }
}

- (void)adjustBrowserActionsContainerForNewWindow:
    (NSNotification*)notification {
  [self toolbarFrameChanged];
  [[NSNotificationCenter defaultCenter]
      removeObserver:self
                name:NSWindowDidBecomeKeyNotification
              object:[[self view] window]];
}

- (void)browserActionsContainerDragged:(NSNotification*)notification {
  [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:NO];
}

- (void)browserActionsVisibilityChanged:(NSNotification*)notification {
  [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:NO];
}

- (void)browserActionsContainerWillAnimate:(NSNotification*)notification {
  [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:YES];
}

- (void)pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:(BOOL)animate {
  CGFloat locationBarXPos = NSMaxX([locationBar_ frame]);
  CGFloat leftDistance = 0.0;

  if ([browserActionsContainerView_ isHidden]) {
    CGFloat edgeXPos = [appMenuButton_ frame].origin.x;
    leftDistance = edgeXPos - locationBarXPos -
        [ToolbarController appMenuLeftPadding];
  } else {
    leftDistance = NSMinX([browserActionsContainerView_ animationEndFrame]) -
        locationBarXPos;
    // Equalize the distance between the location bar and the first extension
    // button, and the distance between the location bar and home/reload button.
    if (ui::MaterialDesignController::IsModeMaterial()) {
      leftDistance -= kMaterialDesignButtonInset;
    }
  }
  if (leftDistance != 0.0)
    [self adjustLocationSizeBy:leftDistance animate:animate];
  else
    [locationBar_ stopAnimation];
}

- (void)maintainMinimumLocationBarWidth {
  CGFloat locationBarWidth = NSWidth([locationBar_ frame]);
  locationBarAtMinSize_ = locationBarWidth <= kMinimumLocationBarWidth;
  if (locationBarAtMinSize_) {
    CGFloat dX = kMinimumLocationBarWidth - locationBarWidth;
    [self adjustLocationSizeBy:dX animate:NO];
  }
}

- (void)toolbarFrameChanged {
  // Do nothing if the frame changes but no Browser Action Controller is
  // present.
  if (!browserActionsController_.get())
    return;

  if ([browserActionsContainerView_ isAnimating]) {
    // If the browser actions container is animating, we need to stop it first,
    // because the frame it's animating for could be incorrect with the new
    // bounds (if, for instance, the bookmark bar was added).
    // This will advance to the end of the animation, so we also need to adjust
    // it afterwards.
    [browserActionsContainerView_ stopAnimation];
    NSRect containerFrame = [browserActionsContainerView_ frame];
    if (!ui::MaterialDesignController::IsModeMaterial()) {
      CGFloat elementTopPadding =
          kMaterialDesignElementPadding + kMaterialDesignButtonInset;
      // Pre-Material Design, this value is calculated from the values in
      // Toolbar.xib: the height of the toolbar (35) minus the height of the
      // child elements (29) minus the y-origin of the elements (4).
      elementTopPadding = 2;
      containerFrame.origin.y =
          NSHeight([[self view] frame]) - NSHeight(containerFrame) -
          elementTopPadding;
    } else {
      containerFrame.origin.y =
          [locationBar_ frame].origin.y + kMaterialDesignContainerYOffset;
    }
    [browserActionsContainerView_ setFrame:containerFrame];
    [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:NO];
  }

  [self maintainMinimumLocationBarWidth];

  if (locationBarAtMinSize_) {
    // Once the grippy is pinned, leave it until it is explicity un-pinned.
    [browserActionsContainerView_ setGrippyPinned:YES];
    NSRect containerFrame = [browserActionsContainerView_ frame];
    // Determine how much the container needs to move in case it's overlapping
    // with the location bar.
    CGFloat dX = NSMaxX([locationBar_ frame]) - containerFrame.origin.x;
    containerFrame = NSOffsetRect(containerFrame, dX, 0);
    containerFrame.size.width -= dX;
    [browserActionsContainerView_ setFrame:containerFrame];
  } else if (!locationBarAtMinSize_ &&
      [browserActionsContainerView_ grippyPinned]) {
    // Expand out the container until it hits the saved size, then unpin the
    // grippy.
    // Add 0.1 pixel so that it doesn't hit the minimum width codepath above.
    CGFloat dX = NSWidth([locationBar_ frame]) -
        (kMinimumLocationBarWidth + 0.1);
    NSRect containerFrame = [browserActionsContainerView_ frame];
    containerFrame = NSOffsetRect(containerFrame, -dX, 0);
    containerFrame.size.width += dX;
    CGFloat savedContainerWidth =
        [browserActionsController_ preferredSize].width();
    if (NSWidth(containerFrame) >= savedContainerWidth) {
      containerFrame = NSOffsetRect(containerFrame,
          NSWidth(containerFrame) - savedContainerWidth, 0);
      containerFrame.size.width = savedContainerWidth;
      [browserActionsContainerView_ setGrippyPinned:NO];
    }
    [browserActionsContainerView_ setFrame:containerFrame];
    [self pinLocationBarToLeftOfBrowserActionsContainerAndAnimate:NO];
  }
}

// Hide the back, forward, reload, home, and app menu buttons of the toolbar.
// This allows the location bar to occupy the entire width. There is no way to
// undo this operation, and once it is called, no other programmatic changes
// to the toolbar or location bar width should be made. This message is
// invalid if the toolbar is shown or the location bar is hidden.
- (void)showLocationBarOnly {
  // -showLocationBarOnly is only ever called once, shortly after
  // initialization, so the regular buttons should all be visible.
  DCHECK(!hasToolbar_ && hasLocationBar_);
  DCHECK(![backButton_ isHidden]);

  // Ensure the location bar fills the toolbar.
  NSRect toolbarFrame = [[self view] frame];
  toolbarFrame.size.height = [ToolbarController locationBarHeight];
  [[self view] setFrame:toolbarFrame];

  [locationBar_ setFrame:NSMakeRect(0, 0, NSWidth([[self view] frame]),
                                    [ToolbarController locationBarHeight])];

  [backButton_ setHidden:YES];
  [forwardButton_ setHidden:YES];
  [reloadButton_ setHidden:YES];
  [appMenuButton_ setHidden:YES];
  [homeButton_ setHidden:YES];
}

- (void)adjustLocationSizeBy:(CGFloat)dX animate:(BOOL)animate {
  // Ensure that the location bar is in its proper place.
  NSRect locationFrame = [locationBar_ frame];
  locationFrame.size.width += dX;

  [locationBar_ stopAnimation];

  if (animate)
    [locationBar_ animateToFrame:locationFrame];
  else
    [locationBar_ setFrame:locationFrame];
}

- (NSPoint)bookmarkBubblePoint {
  if (locationBarView_->IsStarEnabled())
    return locationBarView_->GetBookmarkBubblePoint();

  // Grab bottom middle of hotdogs.
  NSRect frame = appMenuButton_.frame;
  NSPoint point = NSMakePoint(NSMidX(frame), NSMinY(frame));
  // Inset to account for the whitespace around the hotdogs.
  point.y += app_menu_controller::kAppMenuBubblePointOffsetY;
  return [self.view convertPoint:point toView:nil];
}

- (NSPoint)managePasswordsBubblePoint {
  return locationBarView_->GetManagePasswordsBubblePoint();
}

- (NSPoint)saveCreditCardBubblePoint {
  return locationBarView_->GetSaveCreditCardBubblePoint();
}

- (NSPoint)translateBubblePoint {
  return locationBarView_->GetTranslateBubblePoint();
}

- (CGFloat)baseToolbarHeight {
  // Height of the toolbar in pixels when the bookmark bar is closed.
  const bool kIsModeMaterial = ui::MaterialDesignController::IsModeMaterial();
  const CGFloat kBaseToolbarHeightNormal = kIsModeMaterial ? 37 : 35;

  // Not all lines are drawn at 2x normal height when running on Retina, which
  // causes the toolbar controls to be visually 1pt too high within the toolbar
  // area. It's not possible to adjust the control y-positions by 0.5pt and have
  // them appear 0.5pt lower (they are still drawn at their original locations),
  // so instead shave off 1pt from the bottom of the toolbar. Note that there's
  // an offsetting change in -[BookmarkBarController preferredHeight] to
  // maintain the proper spacing between bookmark icons and toolbar items. See
  // https://crbug.com/326245 .
  const CGFloat kLineWidth = [[self view] cr_lineWidth];
  const BOOL kIsRetina = (kLineWidth < 1);
  BOOL reduceHeight = NO;

  // Only adjust the height if Retina and not Material Design.
  reduceHeight = kIsRetina && !kIsModeMaterial;

  return reduceHeight ? kBaseToolbarHeightNormal - 1
                      : kBaseToolbarHeightNormal;
}

- (CGFloat)desiredHeightForCompression:(CGFloat)compressByHeight {
  // With no toolbar, just ignore the compression.
  if (!hasToolbar_)
    return NSHeight([locationBar_ frame]);

  return [self baseToolbarHeight] - compressByHeight;
}

- (void)setDividerOpacity:(CGFloat)opacity {
  ToolbarView* toolbarView = [self toolbarView];
  [toolbarView setShowsDivider:(opacity > 0 ? YES : NO)];
  [toolbarView setDividerOpacity:opacity];
  [toolbarView setNeedsDisplay:YES];
}

- (BrowserActionsController*)browserActionsController {
  return browserActionsController_.get();
}

- (NSView*)appMenuButton {
  return appMenuButton_;
}

- (AppMenuController*)appMenuController {
  return appMenuController_.get();
}

- (BOOL)isLocationBarFocused {
  OmniboxEditModel* model = locationBarView_->GetOmniboxView()->model();
  return model->has_focus();
}

// (URLDropTargetController protocol)
- (void)dropURLs:(NSArray*)urls inView:(NSView*)view at:(NSPoint)point {
  // TODO(viettrungluu): This code is more or less copied from the code in
  // |TabStripController|. I'll refactor this soon to make it common and expand
  // its capabilities (e.g., allow text DnD).
  if ([urls count] < 1) {
    NOTREACHED();
    return;
  }

  // TODO(viettrungluu): dropping multiple URLs?
  if ([urls count] > 1)
    NOTIMPLEMENTED();

  // Get the first URL and fix it up.
  GURL url(url_formatter::FixupURL(
      base::SysNSStringToUTF8([urls objectAtIndex:0]), std::string()));

  // Security: Sanitize text to prevent self-XSS.
  if (url.SchemeIs(url::kJavaScriptScheme)) {
    browser_->window()->GetLocationBar()->GetOmniboxView()->SetUserText(
          OmniboxView::StripJavascriptSchemas(base::UTF8ToUTF16(url.spec())));
    return;
  }

  OpenURLParams params(url, Referrer(), WindowOpenDisposition::CURRENT_TAB,
                       ui::PAGE_TRANSITION_TYPED, false);
  browser_->tab_strip_model()->GetActiveWebContents()->OpenURL(params);
}

// (URLDropTargetController protocol)
- (void)dropText:(NSString*)text inView:(NSView*)view at:(NSPoint)point {
  // TODO(viettrungluu): This code is more or less copied from the code in
  // |TabStripController|. I'll refactor this soon to make it common and expand
  // its capabilities (e.g., allow text DnD).

  // If the input is plain text, classify the input and make the URL.
  AutocompleteMatch match;
  AutocompleteClassifierFactory::GetForProfile(browser_->profile())->Classify(
      base::SysNSStringToUTF16(text), false, false,
      metrics::OmniboxEventProto::BLANK, &match, NULL);
  GURL url(match.destination_url);

  // Security: Block JavaScript to prevent self-XSS.
  if (url.SchemeIs(url::kJavaScriptScheme))
    return;

  OpenURLParams params(url, Referrer(), WindowOpenDisposition::CURRENT_TAB,
                       ui::PAGE_TRANSITION_TYPED, false);
  browser_->tab_strip_model()->GetActiveWebContents()->OpenURL(params);
}

// (URLDropTargetController protocol)
- (void)indicateDropURLsInView:(NSView*)view at:(NSPoint)point {
  // Do nothing.
}

// (URLDropTargetController protocol)
- (void)hideDropURLsIndicatorInView:(NSView*)view {
  // Do nothing.
}

// (URLDropTargetController protocol)
- (BOOL)isUnsupportedDropData:(id<NSDraggingInfo>)info {
  return drag_util::IsUnsupportedDropData(profile_, info);
}

@end
