// 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_attributes_storage.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/exclusive_access_controller_views.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]);

    // 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));
    }

    // Creates the manager for fullscreen and fullscreen bubbles.
    exclusiveAccessController_.reset(
        new ExclusiveAccessController(self, browser_.get()));

    // 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]);
    // This call triggers an -awakeFromNib for ToolbarView.xib.
    [[bookmarkBarController_ controlledView] setResizeDelegate: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);

    // 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();
    shouldShowFullscreenToolbar_ =
        prefs->GetBoolean(prefs::kShowFullscreenToolbar);
    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();

  // Explicitly release |fullscreenTransition_| here since it may call back to
  // this BWC in |-dealloc|. Reset the fullscreen variables.
  if (fullscreenTransition_) {
    [fullscreenTransition_ browserWillBeDestroyed];
    [self resetCustomAppKitFullscreenVariables];
  }

  // 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 have been minimized.
- (void)windowDidMiniaturize:(NSNotification *)notification {
  [self saveWindowPositionIfNeeded];
}

// 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];
}

// 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 = ui::ConvertPointFromWindowToScreen([dragController window],
                                                     tabOrigin);
      tabOrigin = ui::ConvertPointFromScreenToWindow([self window], 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;

  ProfileAttributesEntry* entry;
  if (!g_browser_process->profile_manager()->GetProfileAttributesStorage().
          GetProfileAttributesWithPath(browser_->profile()->GetPath(),
                                       &entry)) {
    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(ui::ConvertPointFromWindowToScreen(
            [self window], [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();
  }

  // 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];
}

// 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)
- (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)setAlertState:(TabAlertState)alertState {
  static_cast<BrowserWindowCocoa*>([self browserWindow])
      ->UpdateAlertState(alertState);
}

- (TabAlertState)alertState {
  return static_cast<BrowserWindowCocoa*>([self browserWindow])->alert_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)updateFullscreenExitBubble {
  [self layoutSubviews];
  [self showFullscreenExitBubbleIfNecessary];
}

- (BOOL)exitExtensionFullscreenIfPossible {
  if (browser_->exclusive_access_manager()
          ->fullscreen_controller()
          ->IsExtensionFullscreenOrPending()) {
    browser_->extension_window_controller()->SetFullscreenMode(NO, GURL());
    return YES;
  }
  return NO;
}

- (void)setFullscreenToolbarVisible:(BOOL)visible {
  if (shouldShowFullscreenToolbar_ == visible)
    return;

  [presentationModeController_ setToolbarFraction:0.0];
  shouldShowFullscreenToolbar_ = visible;
  if ([self isInAppKitFullscreen])
    [self updateFullscreenWithToolbar:shouldShowFullscreenToolbar_];
}

- (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)enterExtensionFullscreen {
  if (chrome::mac::SupportsSystemFullscreen()) {
    [self enterBrowserFullscreenWithToolbar:NO];
  } else {
    [self enterImmersiveFullscreen];
    DCHECK(!exclusiveAccessController_->url().is_empty());
    [self updateFullscreenExitBubble];
  }
}

- (void)enterWebContentFullscreen {
  // 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 (!exclusiveAccessController_->url().is_empty())
    [self updateFullscreenExitBubble];
}

- (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)shouldShowFullscreenToolbar {
  return shouldShowFullscreenToolbar_;
}

- (void)exitFullscreenAnimationFinished {
  if (appKitDidExitFullscreen_) {
    [self windowDidExitFullScreen:nil];
    appKitDidExitFullscreen_ = NO;
  }
}

- (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]];
}

- (ExclusiveAccessController*)exclusiveAccessController {
  return exclusiveAccessController_.get();
}

@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();
}

- (NSRect)savedRegularWindowFrame {
  return savedRegularWindowFrame_;
}

@end  // @implementation BrowserWindowController(WindowType)
