// Copyright 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/browser_window_controller.h"

#include <cmath>
#include <numeric>
#include <utility>

#include "base/command_line.h"
#include "base/mac/bundle_locations.h"
#import "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#import "base/mac/sdk_forward_declarations.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"  // IDC_*
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/bookmarks/managed_bookmark_service_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/extensions/extension_commands_global_registry.h"
#include "chrome/browser/fullscreen.h"
#include "chrome/browser/profiles/avatar_menu.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/translate/chrome_translate_client.h"
#include "chrome/browser/ui/bookmarks/bookmark_editor.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_instant_controller.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window_state.h"
#import "chrome/browser/ui/cocoa/background_gradient_view.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_observer_cocoa.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h"
#import "chrome/browser/ui/cocoa/browser_window_cocoa.h"
#import "chrome/browser/ui/cocoa/browser_window_command_handler.h"
#import "chrome/browser/ui/cocoa/browser_window_controller_private.h"
#import "chrome/browser/ui/cocoa/browser_window_layout.h"
#import "chrome/browser/ui/cocoa/browser_window_utils.h"
#import "chrome/browser/ui/cocoa/dev_tools_controller.h"
#import "chrome/browser/ui/cocoa/download/download_shelf_controller.h"
#include "chrome/browser/ui/cocoa/extensions/extension_keybinding_registry_cocoa.h"
#import "chrome/browser/ui/cocoa/fast_resize_view.h"
#import "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h"
#import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h"
#import "chrome/browser/ui/cocoa/framed_browser_window.h"
#import "chrome/browser/ui/cocoa/fullscreen_window.h"
#import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h"
#include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h"
#import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h"
#import "chrome/browser/ui/cocoa/presentation_mode_controller.h"
#import "chrome/browser/ui/cocoa/profiles/avatar_base_controller.h"
#import "chrome/browser/ui/cocoa/profiles/avatar_button_controller.h"
#import "chrome/browser/ui/cocoa/profiles/avatar_icon_controller.h"
#import "chrome/browser/ui/cocoa/status_bubble_mac.h"
#import "chrome/browser/ui/cocoa/tab_contents/overlayable_contents_controller.h"
#import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h"
#import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h"
#import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h"
#import "chrome/browser/ui/cocoa/tabs/tab_view.h"
#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
#import "chrome/browser/ui/cocoa/translate/translate_bubble_controller.h"
#include "chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
#include "chrome/browser/ui/translate/translate_bubble_model_impl.h"
#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
#include "chrome/browser/ui/window_sizer/window_sizer.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/command.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/locale_settings.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/managed/managed_bookmark_service.h"
#include "components/signin/core/common/profile_management_switches.h"
#include "components/translate/core/browser/translate_manager.h"
#include "components/translate/core/browser/translate_ui_delegate.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#import "ui/base/cocoa/cocoa_base_utils.h"
#import "ui/base/cocoa/nsview_additions.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_mac.h"
#import "ui/gfx/mac/coordinate_conversion.h"
#include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h"
#include "ui/gfx/screen.h"

using bookmarks::BookmarkModel;
using bookmarks::BookmarkNode;
using l10n_util::GetStringUTF16;
using l10n_util::GetNSStringWithFixup;
using l10n_util::GetNSStringFWithFixup;

// ORGANIZATION: This is a big file. It is (in principle) organized as follows
// (in order):
// 1. Interfaces. Very short, one-time-use classes may include an implementation
//    immediately after their interface.
// 2. The general implementation section, ordered as follows:
//      i. Public methods and overrides.
//     ii. Overrides/implementations of undocumented methods.
//    iii. Delegate methods for various protocols, formal and informal, to which
//        |BrowserWindowController| conforms.
// 3. (temporary) Implementation sections for various categories.
//
// Private methods are defined and implemented separately in
// browser_window_controller_private.{h,mm}.
//
// Not all of the above guidelines are followed and more (re-)organization is
// needed. BUT PLEASE TRY TO KEEP THIS FILE ORGANIZED. I'd rather re-organize as
// little as possible, since doing so messes up the file's history.
//
// TODO(viettrungluu): [crbug.com/35543] on-going re-organization, splitting
// things into multiple files -- the plan is as follows:
// - in general, everything stays in browser_window_controller.h, but is split
//   off into categories (see below)
// - core stuff stays in browser_window_controller.mm
// - ... overrides also stay (without going into a category, in particular)
// - private stuff which everyone needs goes into
//   browser_window_controller_private.{h,mm}; if no one else needs them, they
//   can go in individual files (see below)
// - area/task-specific stuff go in browser_window_controller_<area>.mm
// - ... in categories called "(<Area>)" or "(<PrivateArea>)"
// Plan of action:
// - first re-organize into categories
// - then split into files

// Notes on self-inflicted (not user-inflicted) window resizing and moving:
//
// When the bookmark bar goes from hidden to shown (on a non-NTP) page, or when
// the download shelf goes from hidden to shown, we grow the window downwards in
// order to maintain a constant content area size. When either goes from shown
// to hidden, we consequently shrink the window from the bottom, also to keep
// the content area size constant. To keep things simple, if the window is not
// entirely on-screen, we don't grow/shrink the window.
//
// The complications come in when there isn't enough room (on screen) below the
// window to accomodate the growth. In this case, we grow the window first
// downwards, and then upwards. So, when it comes to shrinking, we do the
// opposite: shrink from the top by the amount by which we grew at the top, and
// then from the bottom -- unless the user moved/resized/zoomed the window, in
// which case we "reset state" and just shrink from the bottom.
//
// A further complication arises due to the way in which "zoom" ("maximize")
// works on Mac OS X. Basically, for our purposes, a window is "zoomed" whenever
// it occupies the full available vertical space. (Note that the green zoom
// button does not track zoom/unzoomed state per se, but basically relies on
// this heuristic.) We don't, in general, want to shrink the window if the
// window is zoomed (scenario: window is zoomed, download shelf opens -- which
// doesn't cause window growth, download shelf closes -- shouldn't cause the
// window to become unzoomed!). However, if we grew the window
// (upwards/downwards) to become zoomed in the first place, we *should* shrink
// the window by the amounts by which we grew (scenario: window occupies *most*
// of vertical space, download shelf opens causing growth so that window
// occupies all of vertical space -- i.e., window is effectively zoomed,
// download shelf closes -- should return the window to its previous state).
//
// A major complication is caused by the way grows/shrinks are handled and
// animated. Basically, the BWC doesn't see the global picture, but it sees
// grows and shrinks in small increments (as dictated by the animation). Thus
// window growth/shrinkage (at the top/bottom) have to be tracked incrementally.
// Allowing shrinking from the zoomed state also requires tracking: We check on
// any shrink whether we're both zoomed and have previously grown -- if so, we
// set a flag, and constrain any resize by the allowed amounts. On further
// shrinks, we check the flag (since the size/position of the window will no
// longer indicate that the window is shrinking from an apparent zoomed state)
// and if it's set we continue to constrain the resize.

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

namespace {

void SetUpBrowserWindowCommandHandler(NSWindow* window) {
  // Make the window handle browser window commands.
  [base::mac::ObjCCastStrict<ChromeEventProcessingWindow>(window)
      setCommandHandler:[[[BrowserWindowCommandHandler alloc] init]
                            autorelease]];
}

}  // namespace

@interface NSWindow (NSPrivateApis)
// Note: These functions are private, use -[NSObject respondsToSelector:]
// before calling them.

- (void)setBottomCornerRounded:(BOOL)rounded;

- (NSRect)_growBoxRect;

@end

@implementation BrowserWindowController

+ (BrowserWindowController*)browserWindowControllerForWindow:(NSWindow*)window {
  while (window) {
    id controller = [window windowController];
    if ([controller isKindOfClass:[BrowserWindowController class]])
      return (BrowserWindowController*)controller;
    window = [window parentWindow];
  }
  return nil;
}

+ (BrowserWindowController*)browserWindowControllerForView:(NSView*)view {
  NSWindow* window = [view window];
  return [BrowserWindowController browserWindowControllerForWindow:window];
}

// Load the browser window nib and do any Cocoa-specific initialization.
// Takes ownership of |browser|. Note that the nib also sets this controller
// up as the window's delegate.
- (id)initWithBrowser:(Browser*)browser {
  return [self initWithBrowser:browser takeOwnership:YES];
}

// Private(TestingAPI) init routine with testing options.
- (id)initWithBrowser:(Browser*)browser takeOwnership:(BOOL)ownIt {
  bool hasTabStrip = browser->SupportsWindowFeature(Browser::FEATURE_TABSTRIP);
  if ((self = [super initTabWindowControllerWithTabStrip:hasTabStrip])) {
    DCHECK(browser);
    initializing_ = YES;
    browser_.reset(browser);
    ownsBrowser_ = ownIt;
    NSWindow* window = [self window];
    SetUpBrowserWindowCommandHandler(window);

    // Make the content view for the window have a layer. This will make all
    // sub-views have layers. This is necessary to ensure correct layer
    // ordering of all child views and their layers.
    [[window contentView] setWantsLayer:YES];
    windowShim_.reset(new BrowserWindowCocoa(browser, self));

    // Set different minimum sizes on tabbed windows vs non-tabbed, e.g. popups.
    // This has to happen before -enforceMinWindowSize: is called further down.
    NSSize minSize = [self isTabbedWindow] ?
      NSMakeSize(400, 272) : NSMakeSize(100, 122);
    [[self window] setMinSize:minSize];

    // Create the bar visibility lock set; 10 is arbitrary, but should hopefully
    // be big enough to hold all locks that'll ever be needed.
    barVisibilityLocks_.reset([[NSMutableSet setWithCapacity:10] retain]);

    // Set the window to not have rounded corners, which prevents the resize
    // control from being inset slightly and looking ugly. Only bother to do
    // this on Snow Leopard; on Lion and later all windows have rounded bottom
    // corners, and this won't work anyway.
    if (base::mac::IsOSSnowLeopard() &&
        [window respondsToSelector:@selector(setBottomCornerRounded:)])
      [window setBottomCornerRounded:NO];

    // Lion will attempt to automagically save and restore the UI. This
    // functionality appears to be leaky (or at least interacts badly with our
    // architecture) and thus BrowserWindowController never gets released. This
    // prevents the browser from being able to quit <http://crbug.com/79113>.
    if ([window respondsToSelector:@selector(setRestorable:)])
      [window setRestorable:NO];

    // Get the windows to swish in on Lion.
    if ([window respondsToSelector:@selector(setAnimationBehavior:)])
      [window setAnimationBehavior:NSWindowAnimationBehaviorDocumentWindow];

    // Get the most appropriate size for the window, then enforce the
    // minimum width and height. The window shim will handle flipping
    // the coordinates for us so we can use it to save some code.
    // Note that this may leave a significant portion of the window
    // offscreen, but there will always be enough window onscreen to
    // drag the whole window back into view.
    ui::WindowShowState show_state = ui::SHOW_STATE_DEFAULT;
    gfx::Rect desiredContentRect;
    chrome::GetSavedWindowBoundsAndShowState(browser_.get(),
                                             &desiredContentRect,
                                             &show_state);
    gfx::Rect windowRect = desiredContentRect;
    windowRect = [self enforceMinWindowSize:windowRect];

    // When we are given x/y coordinates of 0 on a created popup window, assume
    // none were given by the window.open() command.
    if (browser_->is_type_popup() &&
        windowRect.x() == 0 && windowRect.y() == 0) {
      gfx::Size size = windowRect.size();
      windowRect.set_origin(
          WindowSizer::GetDefaultPopupOrigin(size,
                                             browser_->host_desktop_type()));
    }

    // Size and position the window.  Note that it is not yet onscreen.  Popup
    // windows may get resized later on in this function, once the actual size
    // of the toolbar/tabstrip is known.
    windowShim_->SetBounds(windowRect);

    // Puts the incognito badge on the window frame, if necessary.
    [self installAvatar];

    // Create a sub-controller for the docked devTools and add its view to the
    // hierarchy.
    devToolsController_.reset([[DevToolsController alloc] init]);
    [[devToolsController_ view] setFrame:[[self tabContentArea] bounds]];
    [[self tabContentArea] addSubview:[devToolsController_ view]];

    // Create the overlayable contents controller.  This provides the switch
    // view that TabStripController needs.
    overlayableContentsController_.reset(
        [[OverlayableContentsController alloc] init]);
    [[overlayableContentsController_ view]
        setFrame:[[devToolsController_ view] bounds]];
    [[devToolsController_ view]
        addSubview:[overlayableContentsController_ view]];

    // Create a controller for the tab strip, giving it the model object for
    // this window's Browser and the tab strip view. The controller will handle
    // registering for the appropriate tab notifications from the back-end and
    // managing the creation of new tabs.
    [self createTabStripController];

    // Create a controller for the toolbar, giving it the toolbar model object
    // and the toolbar view from the nib. The controller will handle
    // registering for the appropriate command state changes from the back-end.
    // Adds the toolbar to the content area.
    toolbarController_.reset([[ToolbarController alloc]
        initWithCommands:browser->command_controller()->command_updater()
                 profile:browser->profile()
                 browser:browser
          resizeDelegate:self]);
    [toolbarController_ setHasToolbar:[self hasToolbar]
                       hasLocationBar:[self hasLocationBar]];

    // Create a sub-controller for the bookmark bar.
    bookmarkBarController_.reset(
        [[BookmarkBarController alloc]
            initWithBrowser:browser_.get()
               initialWidth:NSWidth([[[self window] contentView] frame])
                   delegate:self
             resizeDelegate:self]);
    [bookmarkBarController_ setBookmarkBarEnabled:[self supportsBookmarkBar]];

    // Create the infobar container view, so we can pass it to the
    // ToolbarController.
    infoBarContainerController_.reset(
        [[InfoBarContainerController alloc] initWithResizeDelegate:self]);
    [self updateInfoBarTipVisibility];

    // We don't want to try and show the bar before it gets placed in its parent
    // view, so this step shoudn't be inside the bookmark bar controller's
    // |-awakeFromNib|.
    windowShim_->BookmarkBarStateChanged(
        BookmarkBar::DONT_ANIMATE_STATE_CHANGE);

    // Allow bar visibility to be changed.
    [self enableBarVisibilityUpdates];

    // Set the window to participate in Lion Fullscreen mode.  Setting this flag
    // has no effect on Snow Leopard or earlier.  Panels can share a fullscreen
    // space with a tabbed window, but they can not be primary fullscreen
    // windows.
    // This ensures the fullscreen button is appropriately positioned. It must
    // be done before calling layoutSubviews because the new avatar button's
    // position depends on the fullscreen button's position, as well as
    // TabStripController's rightIndentForControls.
    // The fullscreen button's position may depend on the old avatar button's
    // width, but that does not require calling layoutSubviews first.
    NSUInteger collectionBehavior = [window collectionBehavior];
    collectionBehavior |=
       browser_->type() == Browser::TYPE_TABBED ||
           browser_->type() == Browser::TYPE_POPUP ?
               NSWindowCollectionBehaviorFullScreenPrimary :
               NSWindowCollectionBehaviorFullScreenAuxiliary;
    [window setCollectionBehavior:collectionBehavior];

    [self layoutSubviews];

    // For non-trusted, non-app popup windows, |desiredContentRect| contains the
    // desired height of the content, not of the whole window.  Now that all the
    // views are laid out, measure the current content area size and grow if
    // needed. The window has not been placed onscreen yet, so this extra resize
    // will not cause visible jank.
    if (chrome::SavedBoundsAreContentBounds(browser_.get())) {
      CGFloat deltaH = desiredContentRect.height() -
                       NSHeight([[self tabContentArea] frame]);
      // Do not shrink the window, as that may break minimum size invariants.
      if (deltaH > 0) {
        // Convert from tabContentArea coordinates to window coordinates.
        NSSize convertedSize =
            [[self tabContentArea] convertSize:NSMakeSize(0, deltaH)
                                        toView:nil];
        NSRect frame = [[self window] frame];
        frame.size.height += convertedSize.height;
        frame.origin.y -= convertedSize.height;
        [[self window] setFrame:frame display:NO];
      }
    }

    // Create the bridge for the status bubble.
    statusBubble_ = new StatusBubbleMac([self window], self);

    // Register for application hide/unhide notifications.
    [[NSNotificationCenter defaultCenter]
         addObserver:self
            selector:@selector(applicationDidHide:)
                name:NSApplicationDidHideNotification
              object:nil];
    [[NSNotificationCenter defaultCenter]
         addObserver:self
            selector:@selector(applicationDidUnhide:)
                name:NSApplicationDidUnhideNotification
              object:nil];

    // This must be done after the view is added to the window since it relies
    // on the window bounds to determine whether to show buttons or not.
    if ([self hasToolbar])  // Do not create the buttons in popups.
      [toolbarController_ createBrowserActionButtons];

    extension_keybinding_registry_.reset(
        new ExtensionKeybindingRegistryCocoa(browser_->profile(),
            [self window],
            extensions::ExtensionKeybindingRegistry::ALL_EXTENSIONS,
            windowShim_.get()));

    PrefService* prefs = browser_->profile()->GetPrefs();
    shouldHideFullscreenToolbar_ =
        prefs->GetBoolean(prefs::kHideFullscreenToolbar);

    blockLayoutSubviews_ = NO;

    // We are done initializing now.
    initializing_ = NO;
  }
  return self;
}

- (void)dealloc {
  browser_->tab_strip_model()->CloseAllTabs();

  // Explicitly release |presentationModeController_| here, as it may call back
  // to this BWC in |-dealloc|.  We are required to call |-exitPresentationMode|
  // before releasing the controller.
  [presentationModeController_ exitPresentationMode];
  presentationModeController_.reset();

  // Under certain testing configurations we may not actually own the browser.
  if (ownsBrowser_ == NO)
    ignore_result(browser_.release());

  [[NSNotificationCenter defaultCenter] removeObserver:self];

  // Inform reference counted objects that the Browser will be destroyed. This
  // ensures they invalidate their weak Browser* to prevent use-after-free.
  // These may outlive the Browser if they are retained by something else. For
  // example, since 10.10, the Nib loader internally creates an NSDictionary
  // that retains NSViewControllers and is autoreleased, so there is no way to
  // guarantee that the [super dealloc] call below will also call dealloc on the
  // controllers.
  [toolbarController_ browserWillBeDestroyed];
  [tabStripController_ browserWillBeDestroyed];
  [findBarCocoaController_ browserWillBeDestroyed];
  [downloadShelfController_ browserWillBeDestroyed];
  [bookmarkBarController_ browserWillBeDestroyed];
  [avatarButtonController_ browserWillBeDestroyed];
  [bookmarkBubbleController_ browserWillBeDestroyed];

  [super dealloc];
}

- (gfx::Rect)enforceMinWindowSize:(gfx::Rect)bounds {
  gfx::Rect checkedBounds = bounds;

  NSSize minSize = [[self window] minSize];
  if (bounds.width() < minSize.width)
      checkedBounds.set_width(minSize.width);
  if (bounds.height() < minSize.height)
      checkedBounds.set_height(minSize.height);

  return checkedBounds;
}

- (BrowserWindow*)browserWindow {
  return windowShim_.get();
}

- (ToolbarController*)toolbarController {
  return toolbarController_.get();
}

- (TabStripController*)tabStripController {
  return tabStripController_.get();
}

- (FindBarCocoaController*)findBarCocoaController {
  return findBarCocoaController_.get();
}

- (InfoBarContainerController*)infoBarContainerController {
  return infoBarContainerController_.get();
}

- (StatusBubbleMac*)statusBubble {
  return statusBubble_;
}

- (LocationBarViewMac*)locationBarBridge {
  return [toolbarController_ locationBarBridge];
}

- (NSView*)floatingBarBackingView {
  return floatingBarBackingView_;
}

- (OverlayableContentsController*)overlayableContentsController {
  return overlayableContentsController_;
}

- (Profile*)profile {
  return browser_->profile();
}

- (AvatarBaseController*)avatarButtonController {
  return avatarButtonController_.get();
}

- (void)destroyBrowser {
  [NSApp removeWindowsItem:[self window]];

  // We need the window to go away now.
  // We can't actually use |-autorelease| here because there's an embedded
  // run loop in the |-performClose:| which contains its own autorelease pool.
  // Instead call it after a zero-length delay, which gets us back to the main
  // event loop.
  [self performSelector:@selector(autorelease)
             withObject:nil
             afterDelay:0];
}

// Called when the window meets the criteria to be closed (ie,
// |-windowShouldClose:| returns YES). We must be careful to preserve the
// semantics of BrowserWindow::Close() and not call the Browser's dtor directly
// from this method.
- (void)windowWillClose:(NSNotification*)notification {
  DCHECK_EQ([notification object], [self window]);
  DCHECK(browser_->tab_strip_model()->empty());
  [savedRegularWindow_ close];
  // We delete statusBubble here because we need to kill off the dependency
  // that its window has on our window before our window goes away.
  delete statusBubble_;
  statusBubble_ = NULL;
  // We can't actually use |-autorelease| here because there's an embedded
  // run loop in the |-performClose:| which contains its own autorelease pool.
  // Instead call it after a zero-length delay, which gets us back to the main
  // event loop.
  [self performSelector:@selector(autorelease)
             withObject:nil
             afterDelay:0];
}

- (void)updateDevToolsForContents:(WebContents*)contents {
  BOOL layout_changed =
      [devToolsController_ updateDevToolsForWebContents:contents
                                            withProfile:browser_->profile()];
  if (layout_changed && [findBarCocoaController_ isFindBarVisible])
    [self layoutSubviews];
}

// Called when the user wants to close a window or from the shutdown process.
// The Browser object is in control of whether or not we're allowed to close. It
// may defer closing due to several states, such as onUnload handlers needing to
// be fired. If closing is deferred, the Browser will handle the processing
// required to get us to the closing state and (by watching for all the tabs
// going away) will again call to close the window when it's finally ready.
- (BOOL)windowShouldClose:(id)sender {
  // Disable updates while closing all tabs to avoid flickering.
  gfx::ScopedCocoaDisableScreenUpdates disabler;
  // Give beforeunload handlers the chance to cancel the close before we hide
  // the window below.
  if (!browser_->ShouldCloseWindow())
    return NO;

  // saveWindowPositionIfNeeded: only works if we are the last active
  // window, but orderOut: ends up activating another window, so we
  // have to save the window position before we call orderOut:.
  [self saveWindowPositionIfNeeded];

  bool fast_tab_closing_enabled =
      base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableFastUnload);

  if (!browser_->tab_strip_model()->empty()) {
    // Tab strip isn't empty.  Hide the frame (so it appears to have closed
    // immediately) and close all the tabs, allowing the renderers to shut
    // down. When the tab strip is empty we'll be called back again.
    [[self window] orderOut:self];
    browser_->OnWindowClosing();
    if (fast_tab_closing_enabled)
      browser_->tab_strip_model()->CloseAllTabs();
    return NO;
  } else if (fast_tab_closing_enabled &&
        !browser_->HasCompletedUnloadProcessing()) {
    // The browser needs to finish running unload handlers.
    // Hide the window (so it appears to have closed immediately), and
    // the browser will call us back again when it is ready to close.
    [[self window] orderOut:self];
    return NO;
  }

  // the tab strip is empty, it's ok to close the window
  return YES;
}

// Called right after our window became the main window.
- (void)windowDidBecomeMain:(NSNotification*)notification {
  if (chrome::GetLastActiveBrowser() != browser_.get()) {
    BrowserList::SetLastActive(browser_.get());
  }
  // Always saveWindowPositionIfNeeded when becoming main, not just
  // when |browser_| is not the last active browser. See crbug.com/536280 .
  [self saveWindowPositionIfNeeded];

  NSView* rootView = [[[self window] contentView] superview];
  [rootView cr_recursivelyInvokeBlock:^(id view) {
      if ([view conformsToProtocol:@protocol(ThemedWindowDrawing)])
        [view windowDidChangeActive];
  }];

  extensions::ExtensionCommandsGlobalRegistry::Get(browser_->profile())
      ->set_registry_for_active_window(extension_keybinding_registry_.get());
}

- (void)windowDidResignMain:(NSNotification*)notification {
  NSView* rootView = [[[self window] contentView] superview];
  [rootView cr_recursivelyInvokeBlock:^(id view) {
      if ([view conformsToProtocol:@protocol(ThemedWindowDrawing)])
        [view windowDidChangeActive];
  }];

  extensions::ExtensionCommandsGlobalRegistry::Get(browser_->profile())
      ->set_registry_for_active_window(nullptr);
}

// Called when we are activated (when we gain focus).
- (void)windowDidBecomeKey:(NSNotification*)notification {
  // We need to activate the controls (in the "WebView"). To do this, get the
  // selected WebContents's RenderWidgetHostView and tell it to activate.
  if (WebContents* contents = [self webContents]) {
    WebContents* devtools = DevToolsWindow::GetInTabWebContents(
        contents, NULL);
    if (devtools) {
      RenderWidgetHostView* devtoolsView = devtools->GetRenderWidgetHostView();
      if (devtoolsView && devtoolsView->HasFocus()) {
        devtoolsView->SetActive(true);
        return;
      }
    }

    if (RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView())
      rwhv->SetActive(true);
  }
}

// Called when we are deactivated (when we lose focus).
- (void)windowDidResignKey:(NSNotification*)notification {
  // If our app is still active and we're still the key window, ignore this
  // message, since it just means that a menu extra (on the "system status bar")
  // was activated; we'll get another |-windowDidResignKey| if we ever really
  // lose key window status.
  if ([NSApp isActive] && ([NSApp keyWindow] == [self window]))
    return;

  // We need to deactivate the controls (in the "WebView"). To do this, get the
  // selected WebContents's RenderWidgetHostView and tell it to deactivate.
  if (WebContents* contents = [self webContents]) {
    WebContents* devtools = DevToolsWindow::GetInTabWebContents(
        contents, NULL);
    if (devtools) {
      RenderWidgetHostView* devtoolsView = devtools->GetRenderWidgetHostView();
      if (devtoolsView && devtoolsView->HasFocus()) {
        devtoolsView->SetActive(false);
        return;
      }
    }

    if (RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView())
      rwhv->SetActive(false);
  }
}

// Called when we have been minimized.
- (void)windowDidMiniaturize:(NSNotification *)notification {
  [self saveWindowPositionIfNeeded];

  // Let the selected RenderWidgetHostView know, so that it can tell plugins.
  if (WebContents* contents = [self webContents]) {
    if (RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView())
      rwhv->SetWindowVisibility(false);
  }
}

// Called when we have been unminimized.
- (void)windowDidDeminiaturize:(NSNotification *)notification {
  // Make sure the window's show_state (which is now ui::SHOW_STATE_NORMAL)
  // gets saved.
  [self saveWindowPositionIfNeeded];

  // Let the selected RenderWidgetHostView know, so that it can tell plugins.
  if (WebContents* contents = [self webContents]) {
    if (RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView())
      rwhv->SetWindowVisibility(true);
  }
}

// Called when the application has been hidden.
- (void)applicationDidHide:(NSNotification *)notification {
  // Let the selected RenderWidgetHostView know, so that it can tell plugins
  // (unless we are minimized, in which case nothing has really changed).
  if (![[self window] isMiniaturized]) {
    if (WebContents* contents = [self webContents]) {
      if (RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView())
        rwhv->SetWindowVisibility(false);
    }
  }
}

// Called when the application has been unhidden.
- (void)applicationDidUnhide:(NSNotification *)notification {
  // Let the selected RenderWidgetHostView know, so that it can tell plugins
  // (unless we are minimized, in which case nothing has really changed).
  if (![[self window] isMiniaturized]) {
    if (WebContents* contents = [self webContents]) {
      if (RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView())
        rwhv->SetWindowVisibility(true);
    }
  }
}

// Called when the user clicks the zoom button (or selects it from the Window
// menu) to determine the "standard size" of the window, based on the content
// and other factors. If the current size/location differs nontrivally from the
// standard size, Cocoa resizes the window to the standard size, and saves the
// current size as the "user size". If the current size/location is the same (up
// to a fudge factor) as the standard size, Cocoa resizes the window to the
// saved user size. (It is possible for the two to coincide.) In this way, the
// zoom button acts as a toggle. We determine the standard size based on the
// content, but enforce a minimum width (calculated using the dimensions of the
// screen) to ensure websites with small intrinsic width (such as google.com)
// don't end up with a wee window. Moreover, we always declare the standard
// width to be at least as big as the current width, i.e., we never want zooming
// to the standard width to shrink the window. This is consistent with other
// browsers' behaviour, and is desirable in multi-tab situations. Note, however,
// that the "toggle" behaviour means that the window can still be "unzoomed" to
// the user size.
// Note: this method is also called from -isZoomed. If the returned zoomed rect
// equals the current window's frame, -isZoomed returns YES.
- (NSRect)windowWillUseStandardFrame:(NSWindow*)window
                        defaultFrame:(NSRect)frame {
  // Forget that we grew the window up (if we in fact did).
  [self resetWindowGrowthState];

  // |frame| already fills the current screen. Never touch y and height since we
  // always want to fill vertically.

  // If the shift key is down, maximize. Hopefully this should make the
  // "switchers" happy.
  if ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) {
    return frame;
  }

  // To prevent strange results on portrait displays, the basic minimum zoomed
  // width is the larger of: 60% of available width, 60% of available height
  // (bounded by available width).
  const CGFloat kProportion = 0.6;
  CGFloat zoomedWidth =
      std::max(kProportion * NSWidth(frame),
               std::min(kProportion * NSHeight(frame), NSWidth(frame)));

  WebContents* contents = browser_->tab_strip_model()->GetActiveWebContents();
  if (contents) {
    // If the intrinsic width is bigger, then make it the zoomed width.
    const int kScrollbarWidth = 16;  // TODO(viettrungluu): ugh.
    CGFloat intrinsicWidth = static_cast<CGFloat>(
        contents->GetPreferredSize().width() + kScrollbarWidth);
    zoomedWidth = std::max(zoomedWidth,
                           std::min(intrinsicWidth, NSWidth(frame)));
  }

  // Never shrink from the current size on zoom (see above).
  NSRect currentFrame = [[self window] frame];
  zoomedWidth = std::max(zoomedWidth, NSWidth(currentFrame));

  // |frame| determines our maximum extents. We need to set the origin of the
  // frame -- and only move it left if necessary.
  if (currentFrame.origin.x + zoomedWidth > NSMaxX(frame))
    frame.origin.x = NSMaxX(frame) - zoomedWidth;
  else
    frame.origin.x = currentFrame.origin.x;

  // Set the width. Don't touch y or height.
  frame.size.width = zoomedWidth;

  return frame;
}

- (void)activate {
  [BrowserWindowUtils activateWindowForController:self];
}

// Determine whether we should let a window zoom/unzoom to the given |newFrame|.
// We avoid letting unzoom move windows between screens, because it's really
// strange and unintuitive.
- (BOOL)windowShouldZoom:(NSWindow*)window toFrame:(NSRect)newFrame {
  // Figure out which screen |newFrame| is on.
  NSScreen* newScreen = nil;
  CGFloat newScreenOverlapArea = 0.0;
  for (NSScreen* screen in [NSScreen screens]) {
    NSRect overlap = NSIntersectionRect(newFrame, [screen frame]);
    CGFloat overlapArea = NSWidth(overlap) * NSHeight(overlap);
    if (overlapArea > newScreenOverlapArea) {
      newScreen = screen;
      newScreenOverlapArea = overlapArea;
    }
  }
  // If we're somehow not on any screen, allow the zoom.
  if (!newScreen)
    return YES;

  // If the new screen is the current screen, we can return a definitive YES.
  // Note: This check is not strictly necessary, but just short-circuits in the
  // "no-brainer" case. To test the complicated logic below, comment this out!
  NSScreen* curScreen = [window screen];
  if (newScreen == curScreen)
    return YES;

  // Worry a little: What happens when a window is on two (or more) screens?
  // E.g., what happens in a 50-50 scenario? Cocoa may reasonably elect to zoom
  // to the other screen rather than staying on the officially current one. So
  // we compare overlaps with the current window frame, and see if Cocoa's
  // choice was reasonable (allowing a small rounding error). This should
  // hopefully avoid us ever erroneously denying a zoom when a window is on
  // multiple screens.
  NSRect curFrame = [window frame];
  NSRect newScrIntersectCurFr = NSIntersectionRect([newScreen frame], curFrame);
  NSRect curScrIntersectCurFr = NSIntersectionRect([curScreen frame], curFrame);
  if (NSWidth(newScrIntersectCurFr) * NSHeight(newScrIntersectCurFr) >=
      (NSWidth(curScrIntersectCurFr) * NSHeight(curScrIntersectCurFr) - 1.0)) {
    return YES;
  }

  // If it wasn't reasonable, return NO.
  return NO;
}

// Adjusts the window height by the given amount.
- (BOOL)adjustWindowHeightBy:(CGFloat)deltaH {
  // By not adjusting the window height when initializing, we can ensure that
  // the window opens with the same size that was saved on close.
  if (initializing_ || [self isInAnyFullscreenMode] || deltaH == 0)
    return NO;

  NSWindow* window = [self window];
  NSRect windowFrame = [window frame];
  NSRect workarea = [[window screen] visibleFrame];

  // Prevent the window from growing smaller than its minimum height:
  // http://crbug.com/230400 .
  if (deltaH < 0) {
    CGFloat minWindowHeight = [window minSize].height;
    if (windowFrame.size.height + deltaH < minWindowHeight) {
      // |deltaH| + |windowFrame.size.height| = |minWindowHeight|.
      deltaH = minWindowHeight - windowFrame.size.height;
    }
    if (deltaH == 0) {
      return NO;
    }
  }

  // If the window is not already fully in the workarea, do not adjust its frame
  // at all.
  if (!NSContainsRect(workarea, windowFrame))
    return NO;

  // Record the position of the top/bottom of the window, so we can easily check
  // whether we grew the window upwards/downwards.
  CGFloat oldWindowMaxY = NSMaxY(windowFrame);
  CGFloat oldWindowMinY = NSMinY(windowFrame);

  // We are "zoomed" if we occupy the full vertical space.
  bool isZoomed = (windowFrame.origin.y == workarea.origin.y &&
                   NSHeight(windowFrame) == NSHeight(workarea));

  // If we're shrinking the window....
  if (deltaH < 0) {
    bool didChange = false;

    // Don't reset if not currently zoomed since shrinking can take several
    // steps!
    if (isZoomed)
      isShrinkingFromZoomed_ = YES;

    // If we previously grew at the top, shrink as much as allowed at the top
    // first.
    if (windowTopGrowth_ > 0) {
      CGFloat shrinkAtTopBy = MIN(-deltaH, windowTopGrowth_);
      windowFrame.size.height -= shrinkAtTopBy;  // Shrink the window.
      deltaH += shrinkAtTopBy;            // Update the amount left to shrink.
      windowTopGrowth_ -= shrinkAtTopBy;  // Update the growth state.
      didChange = true;
    }

    // Similarly for the bottom (not an "else if" since we may have to
    // simultaneously shrink at both the top and at the bottom). Note that
    // |deltaH| may no longer be nonzero due to the above.
    if (deltaH < 0 && windowBottomGrowth_ > 0) {
      CGFloat shrinkAtBottomBy = MIN(-deltaH, windowBottomGrowth_);
      windowFrame.origin.y += shrinkAtBottomBy;     // Move the window up.
      windowFrame.size.height -= shrinkAtBottomBy;  // Shrink the window.
      deltaH += shrinkAtBottomBy;               // Update the amount left....
      windowBottomGrowth_ -= shrinkAtBottomBy;  // Update the growth state.
      didChange = true;
    }

    // If we're shrinking from zoomed but we didn't change the top or bottom
    // (since we've reached the limits imposed by |window...Growth_|), then stop
    // here. Don't reset |isShrinkingFromZoomed_| since we might get called
    // again for the same shrink.
    if (isShrinkingFromZoomed_ && !didChange)
      return NO;
  } else {
    isShrinkingFromZoomed_ = NO;

    // Don't bother with anything else.
    if (isZoomed)
      return NO;
  }

  // Shrinking from zoomed is handled above (and is constrained by
  // |window...Growth_|).
  if (!isShrinkingFromZoomed_) {
    // Resize the window down until it hits the bottom of the workarea, then if
    // needed continue resizing upwards.  Do not resize the window to be taller
    // than the current workarea.
    // Resize the window as requested, keeping the top left corner fixed.
    windowFrame.origin.y -= deltaH;
    windowFrame.size.height += deltaH;

    // If the bottom left corner is now outside the visible frame, move the
    // window up to make it fit, but make sure not to move the top left corner
    // out of the visible frame.
    if (windowFrame.origin.y < workarea.origin.y) {
      windowFrame.origin.y = workarea.origin.y;
      windowFrame.size.height =
          std::min(NSHeight(windowFrame), NSHeight(workarea));
    }

    // Record (if applicable) how much we grew the window in either direction.
    // (N.B.: These only record growth, not shrinkage.)
    if (NSMaxY(windowFrame) > oldWindowMaxY)
      windowTopGrowth_ += NSMaxY(windowFrame) - oldWindowMaxY;
    if (NSMinY(windowFrame) < oldWindowMinY)
      windowBottomGrowth_ += oldWindowMinY - NSMinY(windowFrame);
  }

  // Disable subview resizing while resizing the window, or else we will get
  // unwanted renderer resizes.  The calling code must call layoutSubviews to
  // make things right again.
  NSView* chromeContentView = [self chromeContentView];
  BOOL autoresizesSubviews = [chromeContentView autoresizesSubviews];
  [chromeContentView setAutoresizesSubviews:NO];

  // On Yosemite the toolbar can flicker when hiding or showing the bookmarks
  // bar. Here, |chromeContentView| is set to not autoresize its subviews during
  // the window resize. Because |chromeContentView| is not flipped, if the
  // window is getting shorter, the toolbar will move up within the window.
  // Soon after, a call to layoutSubviews corrects its position. Passing NO to
  // setFrame:display: should keep the toolbarView's intermediate position
  // hidden, as should the prior call to disable screen updates. For some
  // reason, neither prevents the toolbarView's intermediate position from
  // becoming visible. Its subsequent appearance in its correct location causes
  // the flicker. It may be that the Appkit assumes that updating the window
  // immediately is not a big deal given that everything in it is layer-backed.
  // Indeed, turning off layer backing for all ancestors of the toolbarView
  // causes the flicker to go away.
  //
  // By shifting the toolbarView enough so that it's in its correct location
  // immediately after the call to setFrame:display:, the toolbar will be in
  // the right spot when the Appkit prematurely flushes the window contents to
  // the screen. http://crbug.com/444080 .
  if ([self hasToolbar]) {
    NSView* toolbarView = [toolbarController_ view];
    NSRect currentWindowFrame = [window frame];
    NSRect toolbarViewFrame = [toolbarView frame];
    toolbarViewFrame.origin.y += windowFrame.size.height -
        currentWindowFrame.size.height;
    [toolbarView setFrame:toolbarViewFrame];
  }

  [window setFrame:windowFrame display:NO];
  [chromeContentView setAutoresizesSubviews:autoresizesSubviews];
  return YES;
}

// Main method to resize browser window subviews.  This method should be called
// when resizing any child of the content view, rather than resizing the views
// directly.  If the view is already the correct height, does not force a
// relayout.
- (void)resizeView:(NSView*)view newHeight:(CGFloat)height {
  // We should only ever be called for one of the following four views.
  // |downloadShelfController_| may be nil. If we are asked to size the bookmark
  // bar directly, its superview must be this controller's content view.
  DCHECK(view);
  DCHECK(view == [toolbarController_ view] ||
         view == [infoBarContainerController_ view] ||
         view == [downloadShelfController_ view] ||
         view == [bookmarkBarController_ view]);

  // The infobar has insufficient information to determine its new height. It
  // knows the total height of all of the info bars (which is what it passes
  // into this method), but knows nothing about the maximum arrow height, which
  // is determined by this class.
  if (view == [infoBarContainerController_ view]) {
    base::scoped_nsobject<BrowserWindowLayout> layout(
        [[BrowserWindowLayout alloc] init]);
    [self updateLayoutParameters:layout];
    // Use the new height for the info bar.
    [layout setInfoBarHeight:height];

    chrome::LayoutOutput output = [layout computeLayout];

    height = NSHeight(output.infoBarFrame);
  }

  // Change the height of the view and call |-layoutSubViews|. We set the height
  // here without regard to where the view is on the screen or whether it needs
  // to "grow up" or "grow down."  The below call to |-layoutSubviews| will
  // position each view correctly.
  NSRect frame = [view frame];
  if (NSHeight(frame) == height)
    return;

  // Disable screen updates to prevent flickering.
  gfx::ScopedCocoaDisableScreenUpdates disabler;

  // Grow or shrink the window by the amount of the height change.  We adjust
  // the window height only in two cases:
  // 1) We are adjusting the height of the bookmark bar and it is currently
  // animating either open or closed.
  // 2) We are adjusting the height of the download shelf.
  //
  // We do not adjust the window height for bookmark bar changes on the NTP.
  BOOL shouldAdjustBookmarkHeight =
      [bookmarkBarController_ isAnimatingBetweenState:BookmarkBar::HIDDEN
                                             andState:BookmarkBar::SHOW];

  BOOL resizeRectDirty = NO;
  if ((shouldAdjustBookmarkHeight && view == [bookmarkBarController_ view]) ||
      view == [downloadShelfController_ view]) {
    CGFloat deltaH = height - NSHeight(frame);
    if ([self adjustWindowHeightBy:deltaH] &&
        view == [downloadShelfController_ view]) {
      // If the window height didn't change, the download shelf will change the
      // size of the contents. If the contents size doesn't change, send it
      // an explicit grow box invalidation (else, the resize message does that.)
      resizeRectDirty = YES;
    }
  }

  frame.size.height = height;
  // TODO(rohitrao): Determine if calling setFrame: twice is bad.
  [view setFrame:frame];
  [self layoutSubviews];

  if (resizeRectDirty) {
    // Send new resize rect to foreground tab.
    if (WebContents* contents = [self webContents]) {
      if (content::RenderViewHost* rvh = contents->GetRenderViewHost()) {
        rvh->GetWidget()->ResizeRectChanged(
            windowShim_->GetRootWindowResizerRect());
      }
    }
  }
}

- (BOOL)handledByExtensionCommand:(NSEvent*)event
    priority:(ui::AcceleratorManager::HandlerPriority)priority {
  return extension_keybinding_registry_->ProcessKeyEvent(
      content::NativeWebKeyboardEvent(event), priority);
}

// StatusBubble delegate method: tell the status bubble the frame it should
// position itself in.
- (NSRect)statusBubbleBaseFrame {
  NSView* view = [overlayableContentsController_ view];
  return [view convertRect:[view bounds] toView:nil];
}

- (void)updateToolbarWithContents:(WebContents*)tab {
  [toolbarController_ updateToolbarWithContents:tab];
}

- (void)resetTabState:(WebContents*)tab {
  [toolbarController_ resetTabState:tab];
}

- (void)setStarredState:(BOOL)isStarred {
  [toolbarController_ setStarredState:isStarred];
}

- (void)setCurrentPageIsTranslated:(BOOL)on {
  [toolbarController_ setTranslateIconLit:on];
}

- (void)onActiveTabChanged:(content::WebContents*)oldContents
                        to:(content::WebContents*)newContents {
  // No need to remove previous bubble. It will close itself.
  PermissionBubbleManager* manager(nullptr);
  if (oldContents) {
    manager = PermissionBubbleManager::FromWebContents(oldContents);
    if (manager)
      manager->HideBubble();
  }

  if (newContents) {
    manager = PermissionBubbleManager::FromWebContents(newContents);
    if (manager)
      manager->DisplayPendingRequests();
  }
}

- (void)zoomChangedForActiveTab:(BOOL)canShowBubble {
  [toolbarController_ zoomChangedForActiveTab:canShowBubble];
}

// Return the rect, in WebKit coordinates (flipped), of the window's grow box
// in the coordinate system of the content area of the currently selected tab.
// |windowGrowBox| needs to be in the window's coordinate system.
- (NSRect)selectedTabGrowBoxRect {
  NSWindow* window = [self window];
  if (![window respondsToSelector:@selector(_growBoxRect)])
    return NSZeroRect;

  // Before we return a rect, we need to convert it from window coordinates
  // to tab content area coordinates and flip the coordinate system.
  NSRect growBoxRect =
      [[self tabContentArea] convertRect:[window _growBoxRect] fromView:nil];
  growBoxRect.origin.y =
      NSHeight([[self tabContentArea] frame]) - NSMaxY(growBoxRect);
  return growBoxRect;
}

// Accept tabs from a BrowserWindowController with the same Profile.
- (BOOL)canReceiveFrom:(TabWindowController*)source {
  BrowserWindowController* realSource =
      base::mac::ObjCCast<BrowserWindowController>(source);
  if (!realSource || browser_->profile() != realSource->browser_->profile()) {
    return NO;
  }

  // Can't drag a tab from a normal browser to a pop-up
  if (browser_->type() != realSource->browser_->type()) {
    return NO;
  }

  return YES;
}

// Move a given tab view to the location of the current placeholder. If there is
// no placeholder, it will go at the end. |controller| is the window controller
// of a tab being dropped from a different window. It will be nil if the drag is
// within the window, otherwise the tab is removed from that window before being
// placed into this one. The implementation will call |-removePlaceholder| since
// the drag is now complete.  This also calls |-layoutTabs| internally so
// clients do not need to call it again.
- (void)moveTabViews:(NSArray*)views
      fromController:(TabWindowController*)dragController {
  if (dragController) {
    // Moving between windows.
    NSView* activeTabView = [dragController activeTabView];
    BrowserWindowController* dragBWC =
        base::mac::ObjCCastStrict<BrowserWindowController>(dragController);

    // We will drop the tabs starting at indexOfPlaceholder, and increment from
    // there. We remove the placehoder before dropping the tabs, so that the
    // new tab animation's destination frame is correct.
    int tabIndex = [tabStripController_ indexOfPlaceholder];
    [self removePlaceholder];

    for (NSView* view in views) {
      // Figure out the WebContents to drop into our tab model from the source
      // window's model.
      int index = [dragBWC->tabStripController_ modelIndexForTabView:view];
      WebContents* contents =
          dragBWC->browser_->tab_strip_model()->GetWebContentsAt(index);
      // The tab contents may have gone away if given a window.close() while it
      // is being dragged. If so, bail, we've got nothing to drop.
      if (!contents)
        continue;

      // Convert |view|'s frame (which starts in the source tab strip's
      // coordinate system) to the coordinate system of the destination tab
      // strip. This needs to be done before being detached so the window
      // transforms can be performed.
      NSRect destinationFrame = [view frame];
      NSPoint tabOrigin = destinationFrame.origin;
      tabOrigin = [[dragController tabStripView] convertPoint:tabOrigin
                                                       toView:nil];
      tabOrigin = [[dragController window] convertBaseToScreen:tabOrigin];
      tabOrigin = [[self window] convertScreenToBase:tabOrigin];
      tabOrigin = [[self tabStripView] convertPoint:tabOrigin fromView:nil];
      destinationFrame.origin = tabOrigin;

      // Before the tab is detached from its originating tab strip, store the
      // pinned state so that it can be maintained between the windows.
      bool isPinned = dragBWC->browser_->tab_strip_model()->IsTabPinned(index);

      // Now that we have enough information about the tab, we can remove it
      // from the dragging window. We need to do this *before* we add it to the
      // new window as this will remove the WebContents' delegate.
      [dragController detachTabView:view];

      // Deposit it into our model at the appropriate location (it already knows
      // where it should go from tracking the drag). Doing this sets the tab's
      // delegate to be the Browser.
      [tabStripController_ dropWebContents:contents
                                   atIndex:tabIndex++
                                 withFrame:destinationFrame
                               asPinnedTab:isPinned
                                  activate:view == activeTabView];
    }
  } else {
    // Moving within a window.
    for (NSView* view in views) {
      int index = [tabStripController_ modelIndexForTabView:view];
      [tabStripController_ moveTabFromIndex:index];
    }
    [self removePlaceholder];
  }
}

// Tells the tab strip to forget about this tab in preparation for it being
// put into a different tab strip, such as during a drop on another window.
- (void)detachTabView:(NSView*)view {
  int index = [tabStripController_ modelIndexForTabView:view];
  browser_->tab_strip_model()->DetachWebContentsAt(index);
}

- (NSArray*)tabViews {
  return [tabStripController_ tabViews];
}

- (NSView*)activeTabView {
  return [tabStripController_ activeTabView];
}

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

// Make the location bar the first responder, if possible.
- (void)focusLocationBar:(BOOL)selectAll {
  [toolbarController_ focusLocationBar:selectAll];
}

- (void)focusTabContents {
  content::WebContents* const activeWebContents =
      browser_->tab_strip_model()->GetActiveWebContents();
  if (activeWebContents)
    activeWebContents->Focus();
}

- (void)layoutTabs {
  [tabStripController_ layoutTabs];
}

- (TabWindowController*)detachTabsToNewWindow:(NSArray*)tabViews
                                   draggedTab:(NSView*)draggedTab {
  DCHECK_GT([tabViews count], 0U);

  // Disable screen updates so that this appears as a single visual change.
  gfx::ScopedCocoaDisableScreenUpdates disabler;

  // Set the window size. Need to do this before we detach the tab so it's
  // still in the window. We have to flip the coordinates as that's what
  // is expected by the Browser code.
  NSWindow* sourceWindow = [draggedTab window];
  NSRect windowRect = [sourceWindow frame];
  NSScreen* screen = [sourceWindow screen];
  windowRect.origin.y = NSHeight([screen frame]) - NSMaxY(windowRect);
  gfx::Rect browserRect(windowRect.origin.x, windowRect.origin.y,
                        NSWidth(windowRect), NSHeight(windowRect));

  std::vector<TabStripModelDelegate::NewStripContents> contentses;
  TabStripModel* model = browser_->tab_strip_model();

  for (TabView* tabView in tabViews) {
    // Fetch the tab contents for the tab being dragged.
    int index = [tabStripController_ modelIndexForTabView:tabView];
    bool isPinned = model->IsTabPinned(index);
    bool isActive = (index == model->active_index());

    TabStripModelDelegate::NewStripContents item;
    item.web_contents = model->GetWebContentsAt(index);
    item.add_types =
        (isActive ? TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE) |
        (isPinned ? TabStripModel::ADD_PINNED : TabStripModel::ADD_NONE);
    contentses.push_back(item);
  }

  for (TabView* tabView in tabViews) {
    int index = [tabStripController_ modelIndexForTabView:tabView];
    // Detach it from the source window, which just updates the model without
    // deleting the tab contents. This needs to come before creating the new
    // Browser because it clears the WebContents' delegate, which gets hooked
    // up during creation of the new window.
    model->DetachWebContentsAt(index);
  }

  // Create a new window with the dragged tabs in its model.
  Browser* newBrowser = browser_->tab_strip_model()->delegate()->
      CreateNewStripWithContents(contentses, browserRect, false);

  // Get the new controller by asking the new window for its delegate.
  BrowserWindowController* controller =
      reinterpret_cast<BrowserWindowController*>(
          [newBrowser->window()->GetNativeWindow() delegate]);
  DCHECK(controller && [controller isKindOfClass:[TabWindowController class]]);

  // And make sure we use the correct frame in the new view.
  TabStripController* tabStripController = [controller tabStripController];
  NSView* tabStrip = [self tabStripView];
  NSEnumerator* tabEnumerator = [tabViews objectEnumerator];
  for (NSView* newView in [tabStripController tabViews]) {
    NSView* oldView = [tabEnumerator nextObject];
    if (oldView) {
      // Pushes tabView's frame back inside the tabstrip.
      NSRect sourceTabRect = [oldView frame];
      NSSize tabOverflow =
          [self overflowFrom:[tabStrip convertRect:sourceTabRect toView:nil]
                          to:[tabStrip frame]];
      NSRect tabRect =
          NSOffsetRect(sourceTabRect, -tabOverflow.width, -tabOverflow.height);
      // Force the added tab to the right size (remove stretching.)
      tabRect.size.height = [TabStripController defaultTabHeight];

      [tabStripController setFrame:tabRect ofTabView:newView];
    }
  }

  return controller;
}

- (void)insertPlaceholderForTab:(TabView*)tab
                          frame:(NSRect)frame {
  [super insertPlaceholderForTab:tab frame:frame];
  [tabStripController_ insertPlaceholderForTab:tab frame:frame];
}

- (void)removePlaceholder {
  [super removePlaceholder];
  [tabStripController_ insertPlaceholderForTab:nil frame:NSZeroRect];
}

- (BOOL)isDragSessionActive {
  // The tab can be dragged within the existing tab strip or detached
  // into its own window (then the overlay window will be present).
  return [[self tabStripController] isDragSessionActive] ||
         [self overlayWindow] != nil;
}

- (BOOL)tabDraggingAllowed {
  return [tabStripController_ tabDraggingAllowed];
}

- (BOOL)tabTearingAllowed {
  return ![self isInAnyFullscreenMode];
}

- (BOOL)windowMovementAllowed {
  return ![self isInAnyFullscreenMode];
}

- (BOOL)isTabFullyVisible:(TabView*)tab {
  return [tabStripController_ isTabFullyVisible:tab];
}

- (void)showNewTabButton:(BOOL)show {
  [tabStripController_ showNewTabButton:show];
}

- (BOOL)shouldShowAvatar {
  if (![self hasTabStrip])
    return NO;
  if (browser_->profile()->IsOffTheRecord())
    return YES;

  ProfileInfoCache& cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  if (cache.GetIndexOfProfileWithPath(browser_->profile()->GetPath()) ==
      std::string::npos) {
    return NO;
  }

  return AvatarMenu::ShouldShowAvatarMenu();
}

- (BOOL)shouldUseNewAvatarButton {
  return profiles::IsRegularOrGuestSession(browser_.get());
}

- (BOOL)isBookmarkBarVisible {
  return [bookmarkBarController_ isVisible];
}

- (BOOL)isBookmarkBarAnimating {
  return [bookmarkBarController_ isAnimationRunning];
}

- (BookmarkBarController*)bookmarkBarController {
  return bookmarkBarController_;
}

- (DevToolsController*)devToolsController {
  return devToolsController_;
}

- (BOOL)isDownloadShelfVisible {
  return downloadShelfController_ != nil &&
      [downloadShelfController_ isVisible];
}

- (void)createAndAddDownloadShelf {
  if (!downloadShelfController_.get()) {
    downloadShelfController_.reset([[DownloadShelfController alloc]
        initWithBrowser:browser_.get() resizeDelegate:self]);
    [self.chromeContentView addSubview:[downloadShelfController_ view]];
  }
}

- (DownloadShelfController*)downloadShelf {
  return downloadShelfController_;
}

- (void)addFindBar:(FindBarCocoaController*)findBarCocoaController {
  // Shouldn't call addFindBar twice.
  DCHECK(!findBarCocoaController_.get());

  // Create a controller for the findbar.
  findBarCocoaController_.reset([findBarCocoaController retain]);
  [self layoutSubviews];
  [self updateSubviewZOrder];
}

- (NSWindow*)createFullscreenWindow {
  NSWindow* window = [[[FullscreenWindow alloc]
      initForScreen:[[self window] screen]] autorelease];
  SetUpBrowserWindowCommandHandler(window);
  return window;
}

- (NSInteger)numberOfTabs {
  // count() includes pinned tabs.
  return browser_->tab_strip_model()->count();
}

- (BOOL)hasLiveTabs {
  return !browser_->tab_strip_model()->empty();
}

- (NSString*)activeTabTitle {
  WebContents* contents = browser_->tab_strip_model()->GetActiveWebContents();
  return base::SysUTF16ToNSString(contents->GetTitle());
}

- (NSRect)regularWindowFrame {
  return [self isInAnyFullscreenMode] ? savedRegularWindowFrame_
                                      : [[self window] frame];
}

// (Override of |TabWindowController| method.)
- (BOOL)hasTabStrip {
  return [self supportsWindowFeature:Browser::FEATURE_TABSTRIP];
}

- (BOOL)isTabDraggable:(NSView*)tabView {
  // TODO(avi, thakis): ConstrainedWindowSheetController has no api to move
  // tabsheets between windows. Until then, we have to prevent having to move a
  // tabsheet between windows, e.g. no tearing off of tabs.
  int index = [tabStripController_ modelIndexForTabView:tabView];
  WebContents* contents = browser_->tab_strip_model()->GetWebContentsAt(index);
  if (!contents)
    return NO;

  const web_modal::WebContentsModalDialogManager* manager =
      web_modal::WebContentsModalDialogManager::FromWebContents(contents);
  return !manager || !manager->IsDialogActive();
}

// TabStripControllerDelegate protocol.
- (void)onActivateTabWithContents:(WebContents*)contents {
  // Update various elements that are interested in knowing the current
  // WebContents.

  // Update all the UI bits.
  windowShim_->UpdateTitleBar();

  // Update the bookmark bar.
  // TODO(viettrungluu): perhaps update to not terminate running animations (if
  // applicable)?
  windowShim_->BookmarkBarStateChanged(
      BookmarkBar::DONT_ANIMATE_STATE_CHANGE);

  [infoBarContainerController_ changeWebContents:contents];

  // Must do this after bookmark and infobar updates to avoid
  // unnecesary resize in contents.
  [devToolsController_ updateDevToolsForWebContents:contents
                                        withProfile:browser_->profile()];
}

- (void)onTabChanged:(TabStripModelObserver::TabChangeType)change
        withContents:(WebContents*)contents {
  // Update titles if this is the currently selected tab and if it isn't just
  // the loading state which changed.
  if (change != TabStripModelObserver::LOADING_ONLY)
    windowShim_->UpdateTitleBar();

  // Update the bookmark bar if this is the currently selected tab and if it
  // isn't just the title which changed. This for transitions between the NTP
  // (showing its floating bookmark bar) and normal web pages (showing no
  // bookmark bar).
  // TODO(viettrungluu): perhaps update to not terminate running animations?
  if (change != TabStripModelObserver::TITLE_NOT_LOADING) {
    windowShim_->BookmarkBarStateChanged(
        BookmarkBar::DONT_ANIMATE_STATE_CHANGE);
  }
}

- (void)onTabDetachedWithContents:(WebContents*)contents {
  [infoBarContainerController_ tabDetachedWithContents:contents];
}

- (void)userChangedTheme {
  NSView* rootView = [[[self window] contentView] superview];
  [rootView cr_recursivelyInvokeBlock:^(id view) {
      if ([view conformsToProtocol:@protocol(ThemedWindowDrawing)])
        [view windowDidChangeTheme];

      // TODO(andresantoso): Remove this once all themed views respond to
      // windowDidChangeTheme above.
      [view setNeedsDisplay:YES];
  }];
}

- (const ui::ThemeProvider*)themeProvider {
  return &ThemeService::GetThemeProviderForProfile(browser_->profile());
}

- (ThemedWindowStyle)themedWindowStyle {
  ThemedWindowStyle style = 0;
  if (browser_->profile()->IsOffTheRecord())
    style |= THEMED_INCOGNITO;

  if (browser_->is_devtools())
    style |= THEMED_DEVTOOLS;
  if (browser_->is_type_popup())
    style |= THEMED_POPUP;

  return style;
}

- (NSPoint)themeImagePositionForAlignment:(ThemeImageAlignment)alignment {
  NSView* windowChromeView = [[[self window] contentView] superview];
  NSView* tabStripView = nil;
  if ([self hasTabStrip])
    tabStripView = [self tabStripView];
  return [BrowserWindowUtils themeImagePositionFor:windowChromeView
                                      withTabStrip:tabStripView
                                         alignment:alignment];
}

- (NSPoint)bookmarkBubblePoint {
  return [toolbarController_ bookmarkBubblePoint];
}

// Show the bookmark bubble (e.g. user just clicked on the STAR).
- (void)showBookmarkBubbleForURL:(const GURL&)url
               alreadyBookmarked:(BOOL)alreadyMarked {
  if (bookmarkBubbleObserver_.get())
    return;

  bookmarkBubbleObserver_.reset(new BookmarkBubbleObserverCocoa(self));

  if (chrome::ToolkitViewsDialogsEnabled()) {
    chrome::ShowBookmarkBubbleViewsAtPoint(
        gfx::ScreenPointFromNSPoint(
            [[self window] convertBaseToScreen:[self bookmarkBubblePoint]]),
        [[self window] contentView], bookmarkBubbleObserver_.get(),
        browser_.get(), url, alreadyMarked);
  } else {
    BookmarkModel* model =
        BookmarkModelFactory::GetForProfile(browser_->profile());
    bookmarks::ManagedBookmarkService* managed =
        ManagedBookmarkServiceFactory::GetForProfile(browser_->profile());
    const BookmarkNode* node = model->GetMostRecentlyAddedUserNodeForURL(url);
    bookmarkBubbleController_ = [[BookmarkBubbleController alloc]
        initWithParentWindow:[self window]
              bubbleObserver:bookmarkBubbleObserver_.get()
                     managed:managed
                       model:model
                        node:node
           alreadyBookmarked:alreadyMarked];
    [bookmarkBubbleController_ showWindow:self];
  }
  DCHECK(bookmarkBubbleObserver_);
}

- (void)bookmarkBubbleClosed {
  // Nil out the weak bookmark bubble controller reference.
  bookmarkBubbleController_ = nil;
  bookmarkBubbleObserver_.reset();
}

// Handle the editBookmarkNode: action sent from bookmark bubble controllers.
- (void)editBookmarkNode:(id)sender {
  BOOL responds = [sender respondsToSelector:@selector(node)];
  DCHECK(responds);
  if (responds) {
    const BookmarkNode* node = [sender node];
    if (node)
      BookmarkEditor::Show([self window], browser_->profile(),
          BookmarkEditor::EditDetails::EditNode(node),
          BookmarkEditor::SHOW_TREE);
  }
}

- (void)showTranslateBubbleForWebContents:(content::WebContents*)contents
                                     step:(translate::TranslateStep)step
                                errorType:(translate::TranslateErrors::Type)
                                errorType {
  // TODO(hajimehoshi): The similar logic exists at TranslateBubbleView::
  // ShowBubble. This should be unified.
  if (translateBubbleController_) {
    // When the user reads the advanced setting panel, the bubble should not be
    // changed because they are focusing on the bubble.
    if (translateBubbleController_.webContents == contents &&
        translateBubbleController_.model->GetViewState() ==
        TranslateBubbleModel::VIEW_STATE_ADVANCED) {
      return;
    }
    if (step != translate::TRANSLATE_STEP_TRANSLATE_ERROR) {
      TranslateBubbleModel::ViewState viewState =
          TranslateBubbleModelImpl::TranslateStepToViewState(step);
      [translateBubbleController_ switchView:viewState];
    } else {
      [translateBubbleController_ switchToErrorView:errorType];
    }
    return;
  }

  std::string sourceLanguage;
  std::string targetLanguage;
  ChromeTranslateClient::GetTranslateLanguages(
      contents, &sourceLanguage, &targetLanguage);

  scoped_ptr<translate::TranslateUIDelegate> uiDelegate(
      new translate::TranslateUIDelegate(
          ChromeTranslateClient::GetManagerFromWebContents(contents)
              ->GetWeakPtr(),
          sourceLanguage,
          targetLanguage));
  scoped_ptr<TranslateBubbleModel> model(
      new TranslateBubbleModelImpl(step, std::move(uiDelegate)));
  translateBubbleController_ =
      [[TranslateBubbleController alloc] initWithParentWindow:self
                                                        model:std::move(model)
                                                  webContents:contents];
  [translateBubbleController_ showWindow:nil];

  NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
  [center addObserver:self
             selector:@selector(translateBubbleWindowWillClose:)
                 name:NSWindowWillCloseNotification
               object:[translateBubbleController_ window]];
}

- (void)dismissPermissionBubble {
  PermissionBubbleManager* manager = [self permissionBubbleManager];
  if (manager)
    manager->HideBubble();
}

// Nil out the weak translate bubble controller reference.
- (void)translateBubbleWindowWillClose:(NSNotification*)notification {
  DCHECK_EQ([notification object], [translateBubbleController_ window]);

  NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
  [center removeObserver:self
                    name:NSWindowWillCloseNotification
                  object:[translateBubbleController_ window]];
  translateBubbleController_ = nil;
}

// If the browser is in incognito mode or has multi-profiles, install the image
// view to decorate the window at the upper right. Use the same base y
// coordinate as the tab strip.
- (void)installAvatar {
  // Install the image into the badge view. Hide it for now; positioning and
  // sizing will be done by the layout code. The AvatarIcon will choose which
  // image to display based on the browser. The AvatarButton will display
  // the browser profile's name unless the browser is incognito.
  NSView* view;
  if ([self shouldUseNewAvatarButton]) {
    avatarButtonController_.reset(
      [[AvatarButtonController alloc] initWithBrowser:browser_.get()]);
  } else {
    avatarButtonController_.reset(
      [[AvatarIconController alloc] initWithBrowser:browser_.get()]);
  }
  view = [avatarButtonController_ view];
  [view setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin];
  [view setHidden:![self shouldShowAvatar]];

  // Install the view.
  [[[self window] contentView] addSubview:view];
}

// Called when we get a three-finger swipe.
- (void)swipeWithEvent:(NSEvent*)event {
  CGFloat deltaX = [event deltaX];
  CGFloat deltaY = [event deltaY];

  // Map forwards and backwards to history; left is positive, right is negative.
  unsigned int command = 0;
  if (deltaX > 0.5) {
    command = IDC_BACK;
  } else if (deltaX < -0.5) {
    command = IDC_FORWARD;
  } else if (deltaY > 0.5) {
    // TODO(pinkerton): figure out page-up, http://crbug.com/16305
  } else if (deltaY < -0.5) {
    // TODO(pinkerton): figure out page-down, http://crbug.com/16305
  }

  // Ensure the command is valid first (ExecuteCommand() won't do that) and
  // then make it so.
  if (chrome::IsCommandEnabled(browser_.get(), command)) {
    chrome::ExecuteCommandWithDisposition(
        browser_.get(),
        command,
        ui::WindowOpenDispositionFromNSEvent(event));
  }
}

// Delegate method called when window is resized.
- (void)windowDidResize:(NSNotification*)notification {
  [self saveWindowPositionIfNeeded];

  // Resize (and possibly move) the status bubble. Note that we may get called
  // when the status bubble does not exist.
  if (statusBubble_) {
    statusBubble_->UpdateSizeAndPosition();
  }

  // Let the selected RenderWidgetHostView know, so that it can tell plugins.
  if (WebContents* contents = [self webContents]) {
    if (RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView())
      rwhv->WindowFrameChanged();
  }

  // The FindBar needs to know its own position to properly detect overlaps
  // with find results. The position changes whenever the window is resized,
  // and |layoutSubviews| computes the FindBar's position.
  // TODO: calling |layoutSubviews| here is a waste, find a better way to
  // do this.
  if ([findBarCocoaController_ isFindBarVisible])
    [self layoutSubviews];
}

// Handle the openLearnMoreAboutCrashLink: action from SadTabView when
// "Learn more" link in "Aw snap" page (i.e. crash page or sad tab) is
// clicked. Decoupling the action from its target makes unit testing possible.
- (void)openLearnMoreAboutCrashLink:(id)sender {
  if (WebContents* contents = [self webContents]) {
    OpenURLParams params(GURL(chrome::kCrashReasonURL), Referrer(), CURRENT_TAB,
                         ui::PAGE_TRANSITION_LINK, false);
    contents->OpenURL(params);
  }
}

// Delegate method called when window did move. (See below for why we don't use
// |-windowWillMove:|, which is called less frequently than |-windowDidMove|
// instead.)
- (void)windowDidMove:(NSNotification*)notification {
  [self saveWindowPositionIfNeeded];

  NSWindow* window = [self window];
  NSRect windowFrame = [window frame];
  NSRect workarea = [[window screen] visibleFrame];

  // We reset the window growth state whenever the window is moved out of the
  // work area or away (up or down) from the bottom or top of the work area.
  // Unfortunately, Cocoa sends |-windowWillMove:| too frequently (including
  // when clicking on the title bar to activate), and of course
  // |-windowWillMove| is called too early for us to apply our heuristic. (The
  // heuristic we use for detecting window movement is that if |windowTopGrowth_
  // > 0|, then we should be at the bottom of the work area -- if we're not,
  // we've moved. Similarly for the other side.)
  if (!NSContainsRect(workarea, windowFrame) ||
      (windowTopGrowth_ > 0 && NSMinY(windowFrame) != NSMinY(workarea)) ||
      (windowBottomGrowth_ > 0 && NSMaxY(windowFrame) != NSMaxY(workarea)))
    [self resetWindowGrowthState];

  // Let the selected RenderWidgetHostView know, so that it can tell plugins.
  if (WebContents* contents = [self webContents]) {
    if (RenderWidgetHostView* rwhv = contents->GetRenderWidgetHostView())
      rwhv->WindowFrameChanged();
  }
}

// Delegate method called when window will be resized; not called for
// |-setFrame:display:|.
- (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize {
  [self resetWindowGrowthState];
  return frameSize;
}

// Delegate method: see |NSWindowDelegate| protocol.
- (id)windowWillReturnFieldEditor:(NSWindow*)sender toObject:(id)obj {
  // Ask the toolbar controller if it wants to return a custom field editor
  // for the specific object.
  return [toolbarController_ customFieldEditorForObject:obj];
}

// (Needed for |BookmarkBarControllerDelegate| protocol.)
- (void)bookmarkBar:(BookmarkBarController*)controller
 didChangeFromState:(BookmarkBar::State)oldState
            toState:(BookmarkBar::State)newState {
  [toolbarController_ setDividerOpacity:[self toolbarDividerOpacity]];
  [self adjustToolbarAndBookmarkBarForCompression:
          [controller getDesiredToolbarHeightCompression]];
}

// (Needed for |BookmarkBarControllerDelegate| protocol.)
- (void)bookmarkBar:(BookmarkBarController*)controller
willAnimateFromState:(BookmarkBar::State)oldState
            toState:(BookmarkBar::State)newState {
  [toolbarController_ setDividerOpacity:[self toolbarDividerOpacity]];
  [self adjustToolbarAndBookmarkBarForCompression:
          [controller getDesiredToolbarHeightCompression]];
}

// (Private/TestingAPI)
- (void)resetWindowGrowthState {
  windowTopGrowth_ = 0;
  windowBottomGrowth_ = 0;
  isShrinkingFromZoomed_ = NO;
}

- (NSSize)overflowFrom:(NSRect)source
                    to:(NSRect)target {
  // If |source|'s boundary is outside of |target|'s, set its distance
  // to |x|.  Note that |source| can overflow to both side, but we
  // have nothing to do for such case.
  CGFloat x = 0;
  if (NSMaxX(target) < NSMaxX(source)) // |source| overflows to right
    x = NSMaxX(source) - NSMaxX(target);
  else if (NSMinX(source) < NSMinX(target)) // |source| overflows to left
    x = NSMinX(source) - NSMinX(target);

  // Same as |x| above.
  CGFloat y = 0;
  if (NSMaxY(target) < NSMaxY(source))
    y = NSMaxY(source) - NSMaxY(target);
  else if (NSMinY(source) < NSMinY(target))
    y = NSMinY(source) - NSMinY(target);

  return NSMakeSize(x, y);
}

// (Private/TestingAPI)
- (ExclusiveAccessBubbleWindowController*)
        exclusiveAccessBubbleWindowController {
  return exclusiveAccessBubbleWindowController_.get();
}

- (NSRect)omniboxPopupAnchorRect {
  // Start with toolbar rect.
  NSView* toolbarView = [toolbarController_ view];
  NSRect anchorRect = [toolbarView frame];

  // Adjust to account for height and possible bookmark bar. Compress by 1
  // to account for the separator.
  anchorRect.origin.y =
      NSMaxY(anchorRect) - [toolbarController_ desiredHeightForCompression:1];

  // Shift to window base coordinates.
  return [[toolbarView superview] convertRect:anchorRect toView:nil];
}

- (BOOL)isLayoutSubviewsBlocked {
  return blockLayoutSubviews_;
}

- (BOOL)isActiveTabContentsControllerResizeBlocked {
  return
      [[tabStripController_ activeTabContentsController] blockFullscreenResize];
}

- (void)sheetDidEnd:(NSWindow*)sheet
         returnCode:(NSInteger)code
            context:(void*)context {
  [sheet orderOut:self];
}

- (PresentationModeController*)presentationModeController {
  return presentationModeController_.get();
}

- (void)executeExtensionCommand:(const std::string&)extension_id
                        command:(const extensions::Command&)command {
  // Global commands are handled by the ExtensionCommandsGlobalRegistry
  // instance.
  DCHECK(!command.global());
  extension_keybinding_registry_->ExecuteCommand(extension_id,
                                                 command.accelerator());
}

- (void)setMediaState:(TabMediaState)mediaState {
  static_cast<BrowserWindowCocoa*>([self browserWindow])
      ->UpdateMediaState(mediaState);
}

- (TabMediaState)mediaState {
  return static_cast<BrowserWindowCocoa*>([self browserWindow])->media_state();
}

@end  // @implementation BrowserWindowController

@implementation BrowserWindowController(Fullscreen)

- (void)handleLionToggleFullscreen {
  DCHECK(base::mac::IsOSLionOrLater());
  chrome::ExecuteCommand(browser_.get(), IDC_FULLSCREEN);
}

- (void)enterBrowserFullscreenWithToolbar:(BOOL)withToolbar {
  if (!chrome::mac::SupportsSystemFullscreen()) {
    if (![self isInImmersiveFullscreen])
      [self enterImmersiveFullscreen];
    return;
  }

  if ([self isInAppKitFullscreen]) {
    [self updateFullscreenWithToolbar:withToolbar];
  } else {
    // Need to invoke AppKit Fullscreen API. Presentation mode (if set) will
    // automatically be enabled in |-windowWillEnterFullScreen:|.
    enteringPresentationMode_ = !withToolbar;
    [self enterAppKitFullscreen];
  }
}

- (void)updateFullscreenWithToolbar:(BOOL)withToolbar {
  [self adjustUIForSlidingFullscreenStyle:
            withToolbar ? fullscreen_mac::OMNIBOX_TABS_PRESENT
                        : fullscreen_mac::OMNIBOX_TABS_HIDDEN];
}

- (void)updateFullscreenExitBubbleURL:(const GURL&)url
                           bubbleType:(ExclusiveAccessBubbleType)bubbleType {
  fullscreenUrl_ = url;
  exclusiveAccessBubbleType_ = bubbleType;
  [self layoutSubviews];
  [self showFullscreenExitBubbleIfNecessary];
}

- (void)setFullscreenToolbarHidden:(BOOL)shouldHide {
  if (shouldHideFullscreenToolbar_ == shouldHide)
    return;

  [presentationModeController_ setToolbarFraction:0.0];
  shouldHideFullscreenToolbar_ = shouldHide;
  if ([self isInAppKitFullscreen])
    [self updateFullscreenWithToolbar:!shouldHideFullscreenToolbar_];
}

- (BOOL)isInAnyFullscreenMode {
  return [self isInImmersiveFullscreen] || [self isInAppKitFullscreen];
}

- (BOOL)isInImmersiveFullscreen {
  return fullscreenWindow_.get() != nil || enteringImmersiveFullscreen_;
}

- (BOOL)isInAppKitFullscreen {
  return !exitingAppKitFullscreen_ &&
         (([[self window] styleMask] & NSFullScreenWindowMask) ==
              NSFullScreenWindowMask ||
          enteringAppKitFullscreen_);
}

- (void)enterExtensionFullscreenForURL:(const GURL&)url
                            bubbleType:(ExclusiveAccessBubbleType)bubbleType {
  if (chrome::mac::SupportsSystemFullscreen()) {
    fullscreenUrl_ = url;
    exclusiveAccessBubbleType_ = bubbleType;
    [self enterBrowserFullscreenWithToolbar:NO];
  } else {
    [self enterImmersiveFullscreen];
    DCHECK(!url.is_empty());
    [self updateFullscreenExitBubbleURL:url bubbleType:bubbleType];
  }
}

- (void)enterWebContentFullscreenForURL:(const GURL&)url
                             bubbleType:(ExclusiveAccessBubbleType)bubbleType {
  // HTML5 Fullscreen should only use AppKit fullscreen in 10.10+.
  // However, if the user is using multiple monitors and turned off
  // "Separate Space in Each Display", use Immersive Fullscreen so
  // that the other monitors won't blank out.
  gfx::Screen* screen = gfx::Screen::GetScreen();
  BOOL hasMultipleMonitors = screen && screen->GetNumDisplays() > 1;
  if (chrome::mac::SupportsSystemFullscreen() &&
      base::mac::IsOSYosemiteOrLater() &&
      !(hasMultipleMonitors && ![NSScreen screensHaveSeparateSpaces])) {
    [self enterAppKitFullscreen];
  } else {
    [self enterImmersiveFullscreen];
  }

  if (!url.is_empty())
    [self updateFullscreenExitBubbleURL:url bubbleType:bubbleType];
}

- (void)exitAnyFullscreen {
  // TODO(erikchen): Fullscreen modes should stack. Should be able to exit
  // Immersive Fullscreen and still be in AppKit Fullscreen.
  if ([self isInAppKitFullscreen])
    [self exitAppKitFullscreen];
  if ([self isInImmersiveFullscreen])
    [self exitImmersiveFullscreen];
}

- (BOOL)inPresentationMode {
  return presentationModeController_.get() &&
         [presentationModeController_ inPresentationMode] &&
         presentationModeController_.get().slidingStyle ==
             fullscreen_mac::OMNIBOX_TABS_HIDDEN;
}

- (BOOL)shouldHideFullscreenToolbar {
  return shouldHideFullscreenToolbar_;
}

- (void)resizeFullscreenWindow {
  DCHECK([self isInAnyFullscreenMode]);
  if (![self isInAnyFullscreenMode])
    return;

  NSWindow* window = [self window];
  [window setFrame:[[window screen] frame] display:YES];
  [self layoutSubviews];
}

- (BOOL)isBarVisibilityLockedForOwner:(id)owner {
  DCHECK(owner);
  DCHECK(barVisibilityLocks_);
  return [barVisibilityLocks_ containsObject:owner];
}

- (void)lockBarVisibilityForOwner:(id)owner
                    withAnimation:(BOOL)animate
                            delay:(BOOL)delay {
  if (![self isBarVisibilityLockedForOwner:owner]) {
    [barVisibilityLocks_ addObject:owner];

    // If enabled, show the overlay if necessary (and if in presentation mode).
    if (barVisibilityUpdatesEnabled_) {
      [presentationModeController_ ensureOverlayShownWithAnimation:animate
                                                             delay:delay];
    }
  }
}

- (void)releaseBarVisibilityForOwner:(id)owner
                       withAnimation:(BOOL)animate
                               delay:(BOOL)delay {
  if ([self isBarVisibilityLockedForOwner:owner]) {
    [barVisibilityLocks_ removeObject:owner];

    // If enabled, hide the overlay if necessary (and if in presentation mode).
    if (barVisibilityUpdatesEnabled_ &&
        ![barVisibilityLocks_ count]) {
      [presentationModeController_ ensureOverlayHiddenWithAnimation:animate
                                                              delay:delay];
    }
  }
}

- (BOOL)floatingBarHasFocus {
  NSResponder* focused = [[self window] firstResponder];
  return [focused isKindOfClass:[AutocompleteTextFieldEditor class]];
}

@end  // @implementation BrowserWindowController(Fullscreen)


@implementation BrowserWindowController(WindowType)

- (BOOL)supportsWindowFeature:(int)feature {
  return browser_->SupportsWindowFeature(
      static_cast<Browser::WindowFeature>(feature));
}

- (BOOL)hasTitleBar {
  return [self supportsWindowFeature:Browser::FEATURE_TITLEBAR];
}

- (BOOL)hasToolbar {
  return [self supportsWindowFeature:Browser::FEATURE_TOOLBAR];
}

- (BOOL)hasLocationBar {
  return [self supportsWindowFeature:Browser::FEATURE_LOCATIONBAR];
}

- (BOOL)supportsBookmarkBar {
  return [self supportsWindowFeature:Browser::FEATURE_BOOKMARKBAR];
}

- (BOOL)isTabbedWindow {
  return browser_->is_type_tabbed();
}

@end  // @implementation BrowserWindowController(WindowType)
