// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/frame/glass_browser_frame_view.h"

#include <dwmapi.h>
#include <utility>

#include "base/trace_event/common/trace_event_common.h"
#include "base/win/windows_version.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/hosted_app_button_container.h"
#include "chrome/browser/ui/views/tabs/new_tab_button.h"
#include "chrome/browser/ui/views/tabs/tab.h"
#include "chrome/browser/ui/views/tabs/tab_strip.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/browser/win/titlebar_config.h"
#include "content/public/browser/web_contents.h"
#include "skia/ext/image_operations.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle_win.h"
#include "ui/base/theme_provider.h"
#include "ui/base/win/hwnd_metrics.h"
#include "ui/display/win/dpi.h"
#include "ui/display/win/screen_win.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/icon_util.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/scoped_canvas.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/win/hwnd_util.h"
#include "ui/views/window/client_view.h"

HICON GlassBrowserFrameView::throbber_icons_[
    GlassBrowserFrameView::kThrobberIconCount];

namespace {

// Converts the |image| to a Windows icon and returns the corresponding HICON
// handle. |image| is resized to desired |width| and |height| if needed.
base::win::ScopedHICON CreateHICONFromSkBitmapSizedTo(
    const gfx::ImageSkia& image,
    int width,
    int height) {
  return IconUtil::CreateHICONFromSkBitmap(
      width == image.width() && height == image.height()
          ? *image.bitmap()
          : skia::ImageOperations::Resize(*image.bitmap(),
                                          skia::ImageOperations::RESIZE_BEST,
                                          width, height));
}

}  // namespace

///////////////////////////////////////////////////////////////////////////////
// GlassBrowserFrameView, public:

constexpr char GlassBrowserFrameView::kClassName[];

SkColor GlassBrowserFrameView::GetReadableFeatureColor(
    SkColor background_color) {
  // color_utils::GetColorWithMaxContrast()/IsDark() aren't used here because
  // they switch based on the Chrome light/dark endpoints, while we want to use
  // the system native behavior below.
  return color_utils::GetLuma(background_color) < 128 ? SK_ColorWHITE
                                                      : SK_ColorBLACK;
}

GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame,
                                             BrowserView* browser_view)
    : BrowserNonClientFrameView(frame, browser_view),
      window_icon_(nullptr),
      window_title_(nullptr),
      minimize_button_(nullptr),
      maximize_button_(nullptr),
      restore_button_(nullptr),
      close_button_(nullptr),
      throbber_running_(false),
      throbber_frame_(0) {
  // We initialize all fields despite some of them being unused in some modes,
  // since it's possible for modes to flip dynamically (e.g. if the user enables
  // a high-contrast theme). Throbber icons are only used when ShowSystemIcon()
  // is true. Everything else here is only used when
  // ShouldCustomDrawSystemTitlebar() is true.

  if (browser_view->ShouldShowWindowIcon()) {
    InitThrobberIcons();

    window_icon_ = new TabIconView(this, nullptr);
    window_icon_->set_is_light(true);
    window_icon_->SetID(VIEW_ID_WINDOW_ICON);
    // Stop the icon from intercepting clicks intended for the HTSYSMENU region
    // of the window. Even though it does nothing on click, it will still
    // prevent us from giving the event back to Windows to handle properly.
    window_icon_->set_can_process_events_within_subtree(false);
    AddChildView(window_icon_);
  }

  if (browser_view->ShouldShowWindowTitle()) {
    window_title_ = new views::Label(browser_view->GetWindowTitle());
    window_title_->SetSubpixelRenderingEnabled(false);
    window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    window_title_->SetID(VIEW_ID_WINDOW_TITLE);
    AddChildView(window_title_);
  }

  web_app::AppBrowserController* controller =
      browser_view->browser()->app_controller();
  if (controller && controller->ShouldShowHostedAppButtonContainer()) {
    // TODO(alancutter): Avoid snapshotting GetCaptionColor() values here and
    // call it on demand in HostedAppButtonContainer::UpdateIconsColor() via a
    // delegate interface.
    set_hosted_app_button_container(new HostedAppButtonContainer(
        frame, browser_view, GetCaptionColor(kActive),
        GetCaptionColor(kInactive)));
    AddChildView(hosted_app_button_container());
  }

  minimize_button_ =
      CreateCaptionButton(VIEW_ID_MINIMIZE_BUTTON, IDS_APP_ACCNAME_MINIMIZE);
  maximize_button_ =
      CreateCaptionButton(VIEW_ID_MAXIMIZE_BUTTON, IDS_APP_ACCNAME_MAXIMIZE);
  restore_button_ =
      CreateCaptionButton(VIEW_ID_RESTORE_BUTTON, IDS_APP_ACCNAME_RESTORE);
  close_button_ =
      CreateCaptionButton(VIEW_ID_CLOSE_BUTTON, IDS_APP_ACCNAME_CLOSE);
}

GlassBrowserFrameView::~GlassBrowserFrameView() {
}

///////////////////////////////////////////////////////////////////////////////
// GlassBrowserFrameView, BrowserNonClientFrameView implementation:

bool GlassBrowserFrameView::CaptionButtonsOnLeadingEdge() const {
  // Because we don't set WS_EX_LAYOUTRTL (which would conflict with Chrome's
  // own RTL layout logic), Windows always draws the caption buttons on the
  // right, even when we want to be RTL. See crbug.com/560619.
  return !ShouldCustomDrawSystemTitlebar() && base::i18n::IsRTL();
}

gfx::Rect GlassBrowserFrameView::GetBoundsForTabStripRegion(
    const views::View* tabstrip) const {
  const int x = CaptionButtonsOnLeadingEdge()
                    ? (width() - frame()->GetMinimizeButtonOffset())
                    : 0;
  int end_x = width();
  if (!CaptionButtonsOnLeadingEdge())
    end_x = std::min(MinimizeButtonX(), end_x);
  return gfx::Rect(x, TopAreaHeight(false), std::max(0, end_x - x),
                   tabstrip->GetPreferredSize().height());
}

int GlassBrowserFrameView::GetTopInset(bool restored) const {
  if (browser_view()->IsTabStripVisible())
    return TopAreaHeight(restored);
  return ShouldCustomDrawSystemTitlebar() ? TitlebarHeight(restored) : 0;
}

int GlassBrowserFrameView::GetThemeBackgroundXInset() const {
  return 0;
}

bool GlassBrowserFrameView::HasVisibleBackgroundTabShapes(
    ActiveState active_state) const {
  // Pre-Win 8, tabs never match the glass frame appearance.
  if (base::win::GetVersion() < base::win::Version::WIN8)
    return true;

  // Enabling high contrast mode disables the custom-drawn titlebar (so the
  // system-drawn frame will respect the native frame colors) and enables the
  // IncreasedContrastThemeSupplier (which does not respect the native frame
  // colors).
  // TODO(pkasting): https://crbug.com/831769  Change the architecture of the
  // high contrast support to respect system colors, then remove this.
  if (ui::NativeTheme::GetInstanceForNativeUi()->UsesHighContrastColors())
    return true;

  return BrowserNonClientFrameView::HasVisibleBackgroundTabShapes(active_state);
}

bool GlassBrowserFrameView::CanDrawStrokes() const {
  // On Win 7, the tabs are drawn as flat shapes against the glass frame, so
  // the active tab always has a visible shape and strokes are unnecessary.
  if (base::win::GetVersion() < base::win::Version::WIN8)
    return false;

  return BrowserNonClientFrameView::CanDrawStrokes();
}

SkColor GlassBrowserFrameView::GetCaptionColor(ActiveState active_state) const {
  const SkAlpha title_alpha = ShouldPaintAsActive(active_state)
                                  ? SK_AlphaOPAQUE
                                  : kInactiveTitlebarFeatureAlpha;
  return SkColorSetA(GetReadableFeatureColor(GetFrameColor(active_state)),
                     title_alpha);
}

void GlassBrowserFrameView::UpdateThrobber(bool running) {
  if (ShowCustomIcon())
    window_icon_->Update();

  if (!ShowSystemIcon())
    return;

  if (throbber_running_) {
    if (running) {
      DisplayNextThrobberFrame();
    } else {
      StopThrobber();
    }
  } else if (running) {
    StartThrobber();
  }
}

gfx::Size GlassBrowserFrameView::GetMinimumSize() const {
  gfx::Size min_size(browser_view()->GetMinimumSize());
  min_size.Enlarge(0, GetTopInset(false));

  return min_size;
}

///////////////////////////////////////////////////////////////////////////////
// GlassBrowserFrameView, views::NonClientFrameView implementation:

gfx::Rect GlassBrowserFrameView::GetBoundsForClientView() const {
  return client_view_bounds_;
}

gfx::Rect GlassBrowserFrameView::GetWindowBoundsForClientBounds(
    const gfx::Rect& client_bounds) const {
  HWND hwnd = views::HWNDForWidget(frame());
  if (!browser_view()->IsTabStripVisible() && hwnd) {
    // If we don't have a tabstrip, we're either a popup or an app window, in
    // which case we have a standard size non-client area and can just use
    // AdjustWindowRectEx to obtain it. We check for a non-null window handle in
    // case this gets called before the window is actually created.
    RECT rect = client_bounds.ToRECT();
    AdjustWindowRectEx(&rect, GetWindowLong(hwnd, GWL_STYLE), FALSE,
                       GetWindowLong(hwnd, GWL_EXSTYLE));
    return gfx::Rect(rect);
  }

  const int top_inset = GetTopInset(false);
  return gfx::Rect(client_bounds.x(),
                   std::max(0, client_bounds.y() - top_inset),
                   client_bounds.width(), client_bounds.height() + top_inset);
}

namespace {

bool HitTestCaptionButton(Windows10CaptionButton* button,
                          const gfx::Point& point) {
  return button && button->GetVisible() &&
         button->GetMirroredBounds().Contains(point);
}

}  // namespace

int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
  int super_component = BrowserNonClientFrameView::NonClientHitTest(point);
  if (super_component != HTNOWHERE)
    return super_component;

  // For app windows and popups without a custom titlebar we haven't customized
  // the frame at all so Windows can figure it out.
  if (!ShouldCustomDrawSystemTitlebar() &&
      !browser_view()->IsBrowserTypeNormal())
    return HTNOWHERE;

  // If the point isn't within our bounds, then it's in the native portion of
  // the frame so again Windows can figure it out.
  if (!bounds().Contains(point))
    return HTNOWHERE;

  int frame_component = frame()->client_view()->NonClientHitTest(point);

  // See if we're in the sysmenu region.  We still have to check the tabstrip
  // first so that clicks in a tab don't get treated as sysmenu clicks.
  if (browser_view()->ShouldShowWindowIcon() && frame_component != HTCLIENT) {
    gfx::Rect sys_menu_region(
        0, display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYSIZEFRAME),
        display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXSMICON),
        display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYSMICON));
    if (sys_menu_region.Contains(point))
      return HTSYSMENU;
  }

  if (frame_component != HTNOWHERE)
    return frame_component;

  // Then see if the point is within any of the window controls.
  if (HitTestCaptionButton(minimize_button_, point))
    return HTMINBUTTON;
  if (HitTestCaptionButton(maximize_button_, point))
    return HTMAXBUTTON;
  if (HitTestCaptionButton(restore_button_, point))
    return HTMAXBUTTON;
  if (HitTestCaptionButton(close_button_, point))
    return HTCLOSE;

  // On Windows 8+, the caption buttons are almost butted up to the top right
  // corner of the window. This code ensures the mouse isn't set to a size
  // cursor while hovering over the caption buttons, thus giving the incorrect
  // impression that the user can resize the window.
  if (base::win::GetVersion() >= base::win::Version::WIN8) {
    RECT button_bounds = {0};
    if (SUCCEEDED(DwmGetWindowAttribute(views::HWNDForWidget(frame()),
                                        DWMWA_CAPTION_BUTTON_BOUNDS,
                                        &button_bounds,
                                        sizeof(button_bounds)))) {
      gfx::Rect buttons = gfx::ConvertRectToDIP(display::win::GetDPIScale(),
                                                gfx::Rect(button_bounds));

      // There is a small one-pixel strip right above the caption buttons in
      // which the resize border "peeks" through.
      constexpr int kCaptionButtonTopInset = 1;
      // The sizing region at the window edge above the caption buttons is
      // 1 px regardless of scale factor. If we inset by 1 before converting
      // to DIPs, the precision loss might eliminate this region entirely. The
      // best we can do is to inset after conversion. This guarantees we'll
      // show the resize cursor when resizing is possible. The cost of which
      // is also maybe showing it over the portion of the DIP that isn't the
      // outermost pixel.
      buttons.Inset(0, kCaptionButtonTopInset, 0, 0);
      if (buttons.Contains(point))
        return HTNOWHERE;
    }
  }

  int top_border_thickness = FrameTopBorderThickness(false);
  // At the window corners the resize area is not actually bigger, but the 16
  // pixels at the end of the top and bottom edges trigger diagonal resizing.
  constexpr int kResizeCornerWidth = 16;
  int window_component = GetHTComponentForFrame(
      point, top_border_thickness, 0, top_border_thickness,
      kResizeCornerWidth - FrameBorderThickness(),
      frame()->widget_delegate()->CanResize());
  // Fall back to the caption if no other component matches.
  return (window_component == HTNOWHERE) ? HTCAPTION : window_component;
}

void GlassBrowserFrameView::UpdateWindowIcon() {
  if (ShowCustomIcon() && !frame()->IsFullscreen())
    window_icon_->SchedulePaint();
}

void GlassBrowserFrameView::UpdateWindowTitle() {
  if (ShowCustomTitle() && !frame()->IsFullscreen()) {
    LayoutTitleBar();
    window_title_->SchedulePaint();
  }
}

void GlassBrowserFrameView::ResetWindowControls() {
  BrowserNonClientFrameView::ResetWindowControls();
  minimize_button_->SetState(views::Button::STATE_NORMAL);
  maximize_button_->SetState(views::Button::STATE_NORMAL);
  restore_button_->SetState(views::Button::STATE_NORMAL);
  close_button_->SetState(views::Button::STATE_NORMAL);
}

void GlassBrowserFrameView::ButtonPressed(views::Button* sender,
                                          const ui::Event& event) {
  if (sender == minimize_button_)
    frame()->Minimize();
  else if (sender == maximize_button_)
    frame()->Maximize();
  else if (sender == restore_button_)
    frame()->Restore();
  else if (sender == close_button_)
    frame()->CloseWithReason(views::Widget::ClosedReason::kCloseButtonClicked);
}

bool GlassBrowserFrameView::ShouldTabIconViewAnimate() const {
  DCHECK(ShowCustomIcon());
  content::WebContents* current_tab = browser_view()->GetActiveWebContents();
  return current_tab && current_tab->IsLoading();
}

gfx::ImageSkia GlassBrowserFrameView::GetFaviconForTabIconView() {
  DCHECK(ShowCustomIcon());
  return frame()->widget_delegate()->GetWindowIcon();
}

bool GlassBrowserFrameView::IsMaximized() const {
  return frame()->IsMaximized();
}

///////////////////////////////////////////////////////////////////////////////
// GlassBrowserFrameView, views::View overrides:

const char* GlassBrowserFrameView::GetClassName() const {
  return kClassName;
}

void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) {
  TRACE_EVENT0("views.frame", "GlassBrowserFrameView::OnPaint");
  if (ShouldCustomDrawSystemTitlebar())
    PaintTitlebar(canvas);
}

void GlassBrowserFrameView::Layout() {
  TRACE_EVENT0("views.frame", "GlassBrowserFrameView::Layout");
  if (ShouldCustomDrawSystemTitlebar())
    LayoutCaptionButtons();

  if (ShouldCustomDrawSystemTitlebar())
    LayoutTitleBar();

  LayoutClientView();
}

///////////////////////////////////////////////////////////////////////////////
// GlassBrowserFrameView, private:

int GlassBrowserFrameView::FrameBorderThickness() const {
  return (IsMaximized() || frame()->IsFullscreen())
             ? 0
             : display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXSIZEFRAME);
}

int GlassBrowserFrameView::FrameTopBorderThickness(bool restored) const {
  // Restored windows have a smaller top resize handle than the system default.
  // When maximized, the OS sizes the window such that the border extends beyond
  // the screen edges. In that case, we must return the default value.
  if ((!frame()->IsFullscreen() && !IsMaximized()) || restored) {
    constexpr int kTopResizeFrameArea = 5;
    return kTopResizeFrameArea;
  }

  // Mouse and touch locations are floored but GetSystemMetricsInDIP is rounded,
  // so we need to floor instead or else the difference will cause the hittest
  // to fail when it ought to succeed.
  return std::floor(
      FrameTopBorderThicknessPx(restored) /
      display::win::ScreenWin::GetScaleFactorForHWND(HWNDForView(this)));
}

int GlassBrowserFrameView::FrameTopBorderThicknessPx(bool restored) const {
  // Distinct from FrameBorderThickness() because Windows gives maximized
  // windows an offscreen region around the edges. The left/right/bottom edges
  // don't worry about this because we cancel them out in
  // BrowserDesktopWindowTreeHostWin::GetClientAreaInsets() so the offscreen
  // area is non-client as far as Windows is concerned. However we can't do this
  // with the top inset because otherwise Windows will give us a standard
  // titlebar. Thus we must compensate here to avoid having UI elements drift
  // off the top of the screen.
  if (frame()->IsFullscreen() && !restored)
    return 0;

  // Note that this method assumes an equal resize handle thickness on all
  // sides of the window.
  // TODO(dfried): Consider having it return a gfx::Insets object instead.
  return ui::GetFrameThickness(
      MonitorFromWindow(HWNDForView(this), MONITOR_DEFAULTTONEAREST));
}

int GlassBrowserFrameView::TopAreaHeight(bool restored) const {
  if (frame()->IsFullscreen() && !restored)
    return 0;

  int top = FrameTopBorderThickness(restored);
  if (IsMaximized() && !restored)
    return top;

  // Besides the frame border, there's empty space atop the window in restored
  // mode, to use to drag the window around.
  constexpr int kNonClientRestoredExtraThickness = 4;
  int thickness = kNonClientRestoredExtraThickness;
  if (EverHasVisibleBackgroundTabShapes()) {
    thickness =
        std::max(thickness, BrowserNonClientFrameView::kMinimumDragHeight);
  }
  return top + thickness;
}

int GlassBrowserFrameView::TitlebarMaximizedVisualHeight() const {
  int maximized_height =
      display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYCAPTION);
  if (hosted_app_button_container()) {
    // Adding 2px of vertical padding puts at least 1 px of space on the top and
    // bottom of the element.
    constexpr int kVerticalPadding = 2;
    maximized_height =
        std::max(maximized_height,
                 hosted_app_button_container()->GetPreferredSize().height() +
                     kVerticalPadding);
  }
  return maximized_height;
}

int GlassBrowserFrameView::TitlebarHeight(bool restored) const {
  if (frame()->IsFullscreen() && !restored)
    return 0;
  // The titlebar's actual height is the same in restored and maximized, but
  // some of it is above the screen in maximized mode. See the comment in
  // FrameTopBorderThicknessPx().
  return TitlebarMaximizedVisualHeight() + FrameTopBorderThickness(false);
}

int GlassBrowserFrameView::WindowTopY() const {
  // The window top is SM_CYSIZEFRAME pixels when maximized (see the comment in
  // FrameTopBorderThickness()) and floor(system dsf) pixels when restored.
  // Unfortunately we can't represent either of those at hidpi without using
  // non-integral dips, so we return the closest reasonable values instead.
  return IsMaximized() ? FrameTopBorderThickness(false) : 1;
}

int GlassBrowserFrameView::MinimizeButtonX() const {
  // When CaptionButtonsOnLeadingEdge() is true call
  // frame()->GetMinimizeButtonOffset() directly, because minimize_button_->x()
  // will give the wrong edge of the button.
  DCHECK(!CaptionButtonsOnLeadingEdge());
  // If we're drawing the button we can query the layout directly, otherwise we
  // need to ask Windows where the minimize button is.
  // TODO(bsep): Ideally these would always be the same. When we're always
  // custom drawing the caption buttons, remove GetMinimizeButtonOffset().
  return ShouldCustomDrawSystemTitlebar() ? minimize_button_->x()
                                          : frame()->GetMinimizeButtonOffset();
}

bool GlassBrowserFrameView::IsToolbarVisible() const {
  return browser_view()->IsToolbarVisible() &&
      !browser_view()->toolbar()->GetPreferredSize().IsEmpty();
}

bool GlassBrowserFrameView::ShowCustomIcon() const {
  // Hosted app windows don't include the window icon as per UI mocks.
  return !hosted_app_button_container() && ShouldCustomDrawSystemTitlebar() &&
         browser_view()->ShouldShowWindowIcon();
}

bool GlassBrowserFrameView::ShowCustomTitle() const {
  return ShouldCustomDrawSystemTitlebar() &&
         browser_view()->ShouldShowWindowTitle();
}

bool GlassBrowserFrameView::ShowSystemIcon() const {
  return !ShouldCustomDrawSystemTitlebar() &&
         browser_view()->ShouldShowWindowIcon();
}

SkColor GlassBrowserFrameView::GetTitlebarColor() const {
  return GetFrameColor();
}

Windows10CaptionButton* GlassBrowserFrameView::CreateCaptionButton(
    ViewID button_type,
    int accessible_name_resource_id) {
  Windows10CaptionButton* button = new Windows10CaptionButton(
      this, button_type,
      l10n_util::GetStringUTF16(accessible_name_resource_id));
  AddChildView(button);
  return button;
}

void GlassBrowserFrameView::PaintTitlebar(gfx::Canvas* canvas) const {
  TRACE_EVENT0("views.frame", "GlassBrowserFrameView::PaintTitlebar");

  cc::PaintFlags flags;
  gfx::ScopedCanvas scoped_canvas(canvas);
  float scale = canvas->UndoDeviceScaleFactor();
  // This is the pixel-accurate version of WindowTopY(). Scaling the DIP values
  // here compounds precision error, which exposes unpainted client area. When
  // restored it uses the system dsf instead of the per-monitor dsf to match
  // Windows' behavior.
  const int y = IsMaximized() ? FrameTopBorderThicknessPx(false)
                              : std::floor(display::win::GetDPIScale());

  // Draw the top of the accent border.
  //
  // We let the DWM do this for the other sides of the window by insetting the
  // client area to leave nonclient area available. However, along the top
  // window edge, we have to have zero nonclient area or the DWM will draw a
  // full native titlebar outside our client area. See
  // BrowserDesktopWindowTreeHostWin::GetClientAreaInsets().
  //
  // We could ask the DWM to draw the top accent border in the client area (by
  // calling DwmExtendFrameIntoClientArea() in
  // BrowserDesktopWindowTreeHostWin::UpdateDWMFrame()), but this requires
  // that we leave part of the client surface transparent. If we draw this
  // ourselves, we can make the client surface fully opaque and avoid the
  // power consumption needed for DWM to blend the window contents.
  //
  // So the accent border also has to be opaque. Native inactive borders are
  // #555555 with 50% alpha. We can blend the titlebar color with this to
  // approximate the native effect.
  const SkColor titlebar_color = GetTitlebarColor();
  flags.setColor(
      ShouldPaintAsActive()
          ? GetThemeProvider()->GetColor(ThemeProperties::COLOR_ACCENT_BORDER)
          : color_utils::AlphaBlend(SkColorSetRGB(0x55, 0x55, 0x55),
                                    titlebar_color, 0.5f));
  canvas->DrawRect(gfx::RectF(0, 0, width() * scale, y), flags);

  const int titlebar_height =
      browser_view()->IsTabStripVisible()
          ? GetBoundsForTabStripRegion(browser_view()->tabstrip()).bottom()
          : TitlebarHeight(false);
  const gfx::Rect titlebar_rect = gfx::ToEnclosingRect(
      gfx::RectF(0, y, width() * scale, titlebar_height * scale - y));
  // Paint the titlebar first so we have a background if an area isn't covered
  // by the theme image.
  flags.setColor(titlebar_color);
  canvas->DrawRect(titlebar_rect, flags);
  const gfx::ImageSkia frame_image = GetFrameImage();
  if (!frame_image.isNull()) {
    canvas->TileImageInt(frame_image, 0,
                         ThemeProperties::kFrameHeightAboveTabs -
                             GetTopInset(false) + titlebar_rect.y(),
                         titlebar_rect.x(), titlebar_rect.y(),
                         titlebar_rect.width(), titlebar_rect.height(), scale,
                         SkTileMode::kRepeat, SkTileMode::kMirror);
  }
  const gfx::ImageSkia frame_overlay_image = GetFrameOverlayImage();
  if (!frame_overlay_image.isNull()) {
    canvas->DrawImageInt(frame_overlay_image, 0, 0, frame_overlay_image.width(),
                         frame_overlay_image.height(), titlebar_rect.x(),
                         titlebar_rect.y(), frame_overlay_image.width() * scale,
                         frame_overlay_image.height() * scale, true);
  }

  if (ShowCustomTitle())
    window_title_->SetEnabledColor(GetCaptionColor(kUseCurrent));
}

void GlassBrowserFrameView::LayoutTitleBar() {
  TRACE_EVENT0("views.frame", "GlassBrowserFrameView::LayoutTitleBar");
  if (!ShowCustomIcon() && !ShowCustomTitle())
    return;

  gfx::Rect window_icon_bounds;
  const int icon_size =
      display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYSMICON);
  const int titlebar_visual_height =
      IsMaximized() ? TitlebarMaximizedVisualHeight() : TitlebarHeight(false);
  // Don't include the area above the screen when maximized. However it only
  // looks centered if we start from y=0 when restored.
  const int window_top = IsMaximized() ? WindowTopY() : 0;
  int next_leading_x =
      display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXSIZEFRAME);
  constexpr int kMaximizedLeftMargin = 2;
  if (IsMaximized())
    next_leading_x += kMaximizedLeftMargin;
  int next_trailing_x = MinimizeButtonX();

  const int y = window_top + (titlebar_visual_height - icon_size) / 2;
  window_icon_bounds = gfx::Rect(next_leading_x, y, icon_size, icon_size);

  constexpr int kIconTitleSpacing = 5;
  if (ShowCustomIcon()) {
    window_icon_->SetBoundsRect(window_icon_bounds);
    next_leading_x = window_icon_bounds.right() + kIconTitleSpacing;
  }

  if (hosted_app_button_container()) {
    next_trailing_x = hosted_app_button_container()->LayoutInContainer(
        next_leading_x, next_trailing_x, window_top, titlebar_visual_height);
  }

  if (ShowCustomTitle()) {
    if (!ShowCustomIcon()) {
      // This matches native Windows 10 UWP apps that don't have window icons.
      constexpr int kMinimumTitleLeftBorderMargin = 11;
      DCHECK_LE(next_leading_x, kMinimumTitleLeftBorderMargin);
      next_leading_x = kMinimumTitleLeftBorderMargin;
    }
    window_title_->SetText(browser_view()->GetWindowTitle());
    const int max_text_width = std::max(0, next_trailing_x - next_leading_x);
    window_title_->SetBounds(next_leading_x, window_icon_bounds.y(),
                             max_text_width, window_icon_bounds.height());
    window_title_->SetAutoColorReadabilityEnabled(false);
  }
}

void GlassBrowserFrameView::LayoutCaptionButton(Windows10CaptionButton* button,
                                                int previous_button_x) {
  TRACE_EVENT0("views.frame", "GlassBrowserFrameView::LayoutCaptionButton");
  gfx::Size button_size = button->GetPreferredSize();
  button->SetBounds(previous_button_x - button_size.width(), WindowTopY(),
                    button_size.width(), button_size.height());
}

void GlassBrowserFrameView::LayoutCaptionButtons() {
  TRACE_EVENT0("views.frame", "GlassBrowserFrameView::LayoutCaptionButtons");
  LayoutCaptionButton(close_button_, width());

  LayoutCaptionButton(restore_button_, close_button_->x());
  restore_button_->SetVisible(IsMaximized());

  LayoutCaptionButton(maximize_button_, close_button_->x());
  maximize_button_->SetVisible(!IsMaximized());

  LayoutCaptionButton(minimize_button_, maximize_button_->x());
}

void GlassBrowserFrameView::LayoutClientView() {
  client_view_bounds_ = GetLocalBounds();
  client_view_bounds_.Inset(0, GetTopInset(false), 0, 0);
}

void GlassBrowserFrameView::StartThrobber() {
  DCHECK(ShowSystemIcon());
  if (!throbber_running_) {
    throbber_running_ = true;
    throbber_frame_ = 0;
    InitThrobberIcons();
    SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
                static_cast<WPARAM>(ICON_SMALL),
                reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_]));
  }
}

void GlassBrowserFrameView::StopThrobber() {
  DCHECK(ShowSystemIcon());
  if (throbber_running_) {
    throbber_running_ = false;

    base::win::ScopedHICON previous_small_icon;
    base::win::ScopedHICON previous_big_icon;
    HICON small_icon = nullptr;
    HICON big_icon = nullptr;

    gfx::ImageSkia icon = browser_view()->GetWindowIcon();
    if (!icon.isNull()) {
      // Keep previous icons alive as long as they are referenced by the HWND.
      previous_small_icon = std::move(small_window_icon_);
      previous_big_icon = std::move(big_window_icon_);

      // Take responsibility for eventually destroying the created icons.
      small_window_icon_ = CreateHICONFromSkBitmapSizedTo(
          icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
      big_window_icon_ = CreateHICONFromSkBitmapSizedTo(
          icon, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));

      small_icon = small_window_icon_.get();
      big_icon = big_window_icon_.get();
    }

    // Fallback to class icon.
    if (!small_icon) {
      small_icon = reinterpret_cast<HICON>(
          GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICONSM));
    }
    if (!big_icon) {
      big_icon = reinterpret_cast<HICON>(
          GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICON));
    }

    // This will reset the icon which we set in the throbber code.
    // WM_SETICON with null icon restores the icon for title bar but not
    // for taskbar. See http://crbug.com/29996
    SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
                static_cast<WPARAM>(ICON_SMALL),
                reinterpret_cast<LPARAM>(small_icon));

    SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
                static_cast<WPARAM>(ICON_BIG),
                reinterpret_cast<LPARAM>(big_icon));
  }
}

void GlassBrowserFrameView::DisplayNextThrobberFrame() {
  throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount;
  SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
              static_cast<WPARAM>(ICON_SMALL),
              reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_]));
}

// static
void GlassBrowserFrameView::InitThrobberIcons() {
  static bool initialized = false;
  if (!initialized) {
    for (int i = 0; i < kThrobberIconCount; ++i) {
      throbber_icons_[i] =
          ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i);
      DCHECK(throbber_icons_[i]);
    }
    initialized = true;
  }
}
