// 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 "ui/views/bubble/bubble_frame_view.h"

#include <algorithm>
#include <utility>

#include "build/build_config.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/base/default_style.h"
#include "ui/base/hit_test.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/paint_recorder.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/path.h"
#include "ui/gfx/skia_util.h"
#include "ui/native_theme/native_theme.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/bubble/bubble_border.h"
#include "ui/views/bubble/bubble_dialog_delegate.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/button/image_button_factory.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/layout_provider.h"
#include "ui/views/paint_info.h"
#include "ui/views/resources/grit/views_resources.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/window/client_view.h"
#include "ui/views/window/dialog_delegate.h"

namespace views {

namespace {

// Get the |vertical| or horizontal amount that |available_bounds| overflows
// |window_bounds|.
int GetOffScreenLength(const gfx::Rect& available_bounds,
                       const gfx::Rect& window_bounds,
                       bool vertical) {
  if (available_bounds.IsEmpty() || available_bounds.Contains(window_bounds))
    return 0;

  //  window_bounds
  //  +---------------------------------+
  //  |             top                 |
  //  |      +------------------+       |
  //  | left | available_bounds | right |
  //  |      +------------------+       |
  //  |            bottom               |
  //  +---------------------------------+
  if (vertical)
    return std::max(0, available_bounds.y() - window_bounds.y()) +
           std::max(0, window_bounds.bottom() - available_bounds.bottom());
  return std::max(0, available_bounds.x() - window_bounds.x()) +
         std::max(0, window_bounds.right() - available_bounds.right());
}

}  // namespace

// A container that changes visibility with its contents.
class FootnoteContainerView : public View {
 public:
  FootnoteContainerView() {}

  // View:
  void ChildVisibilityChanged(View* child) override {
    DCHECK_EQ(child_count(), 1);
    SetVisible(child->visible());
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(FootnoteContainerView);
};

// static
const char BubbleFrameView::kViewClassName[] = "BubbleFrameView";

BubbleFrameView::BubbleFrameView(const gfx::Insets& title_margins,
                                 const gfx::Insets& content_margins)
    : bubble_border_(nullptr),
      title_margins_(title_margins),
      content_margins_(content_margins),
      footnote_margins_(content_margins_),
      title_icon_(new views::ImageView()),
      default_title_(CreateDefaultTitleLabel(base::string16()).release()),
      custom_title_(nullptr),
      close_(nullptr),
      footnote_container_(nullptr),
      close_button_clicked_(false) {
  AddChildView(title_icon_);

  default_title_->SetVisible(false);
  AddChildView(default_title_);

  close_ = CreateCloseButton(this);
  close_->SetVisible(false);
#if defined(OS_WIN)
  // Windows will automatically create a tooltip for the close button based on
  // the HTCLOSE result from NonClientHitTest().
  close_->SetTooltipText(base::string16());
#endif
  AddChildView(close_);
}

BubbleFrameView::~BubbleFrameView() {}

// static
std::unique_ptr<Label> BubbleFrameView::CreateDefaultTitleLabel(
    const base::string16& title_text) {
  auto title = std::make_unique<Label>(title_text, style::CONTEXT_DIALOG_TITLE);
  title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
  title->set_collapse_when_hidden(true);
  title->SetMultiLine(true);
  return title;
}

// static
Button* BubbleFrameView::CreateCloseButton(ButtonListener* listener) {
  ImageButton* close_button = nullptr;
  if (ui::MaterialDesignController::IsSecondaryUiMaterial()) {
    close_button = CreateVectorImageButton(listener);
    SetImageFromVectorIcon(close_button, vector_icons::kCloseRoundedIcon);
  } else {
    ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
    close_button = new ImageButton(listener);
    close_button->SetImage(Button::STATE_NORMAL,
                           *rb->GetImageNamed(IDR_CLOSE_DIALOG).ToImageSkia());
    close_button->SetImage(
        Button::STATE_HOVERED,
        *rb->GetImageNamed(IDR_CLOSE_DIALOG_H).ToImageSkia());
    close_button->SetImage(
        Button::STATE_PRESSED,
        *rb->GetImageNamed(IDR_CLOSE_DIALOG_P).ToImageSkia());
  }
  close_button->SetTooltipText(l10n_util::GetStringUTF16(IDS_APP_CLOSE));
  close_button->SizeToPreferredSize();

  // Remove the close button from tab traversal on all platforms. Note this does
  // not affect screen readers' ability to focus the close button. Keyboard
  // access to the close button when not using a screen reader is done via the
  // ESC key handler in DialogClientView.
  close_button->SetFocusBehavior(View::FocusBehavior::NEVER);
  return close_button;
}

gfx::Rect BubbleFrameView::GetBoundsForClientView() const {
  // When NonClientView asks for this, the size of the frame view has been set
  // (i.e. |this|), but not the client view bounds.
  gfx::Rect client_bounds = GetContentsBounds();
  client_bounds.Inset(GetClientInsetsForFrameWidth(client_bounds.width()));
  // Only account for footnote_container_'s height if it's visible, because
  // content_margins_ adds extra padding even if all child views are invisible.
  if (footnote_container_ && footnote_container_->visible()) {
    client_bounds.set_height(client_bounds.height() -
                             footnote_container_->height());
  }
  return client_bounds;
}

gfx::Rect BubbleFrameView::GetWindowBoundsForClientBounds(
    const gfx::Rect& client_bounds) const {
  gfx::Size size(GetFrameSizeForClientSize(client_bounds.size()));
  return bubble_border_->GetBounds(gfx::Rect(), size);
}

bool BubbleFrameView::GetClientMask(const gfx::Size& size,
                                    gfx::Path* path) const {
  // NonClientView calls this after setting the client view size from the return
  // of GetBoundsForClientView(); feeding it back in |size|.
  DCHECK(GetBoundsForClientView().size() == size);
  DCHECK(GetWidget()->client_view()->size() == size);

  const int radius = bubble_border_->GetBorderCornerRadius();
  gfx::Insets content_insets = GetInsets();
  // If the client bounds don't touch the edges, no need to mask.
  if (std::min({content_insets.top(), content_insets.left(),
                content_insets.bottom(), content_insets.right()}) > radius) {
    return false;
  }
  gfx::RectF rect((gfx::Rect(size)));
  path->addRoundRect(gfx::RectFToSkRect(rect), radius, radius);
  return true;
}

int BubbleFrameView::NonClientHitTest(const gfx::Point& point) {
  if (!bounds().Contains(point))
    return HTNOWHERE;
  if (close_->visible() && close_->GetMirroredBounds().Contains(point))
    return HTCLOSE;

  // Allow dialogs to show the system menu and be dragged.
  if (GetWidget()->widget_delegate()->AsDialogDelegate() &&
      !GetWidget()->widget_delegate()->AsBubbleDialogDelegate()) {
    gfx::Rect bounds(GetContentsBounds());
    bounds.Inset(title_margins_);
    gfx::Rect sys_rect(0, 0, bounds.x(), bounds.y());
    sys_rect.set_origin(gfx::Point(GetMirroredXForRect(sys_rect), 0));
    if (sys_rect.Contains(point))
      return HTSYSMENU;
    if (point.y() < title()->bounds().bottom())
      return HTCAPTION;
  }

  return GetWidget()->client_view()->NonClientHitTest(point);
}

void BubbleFrameView::GetWindowMask(const gfx::Size& size,
                                    gfx::Path* window_mask) {
  if (bubble_border_->shadow() != BubbleBorder::SMALL_SHADOW &&
      bubble_border_->shadow() != BubbleBorder::NO_SHADOW_OPAQUE_BORDER &&
      bubble_border_->shadow() != BubbleBorder::NO_ASSETS)
    return;

  // We don't return a mask for windows with arrows unless they use
  // BubbleBorder::NO_ASSETS.
  if (bubble_border_->shadow() != BubbleBorder::NO_ASSETS &&
      bubble_border_->arrow() != BubbleBorder::NONE &&
      bubble_border_->arrow() != BubbleBorder::FLOAT)
    return;

  // Use a window mask roughly matching the border in the image assets.
  const int kBorderStrokeSize =
      bubble_border_->shadow() == BubbleBorder::NO_ASSETS ? 0 : 1;
  const SkScalar kCornerRadius =
      SkIntToScalar(bubble_border_->GetBorderCornerRadius());
  const gfx::Insets border_insets = bubble_border_->GetInsets();
  SkRect rect = {
      SkIntToScalar(border_insets.left() - kBorderStrokeSize),
      SkIntToScalar(border_insets.top() - kBorderStrokeSize),
      SkIntToScalar(size.width() - border_insets.right() + kBorderStrokeSize),
      SkIntToScalar(size.height() - border_insets.bottom() +
                    kBorderStrokeSize)};

  if (bubble_border_->shadow() == BubbleBorder::NO_SHADOW_OPAQUE_BORDER ||
      bubble_border_->shadow() == BubbleBorder::NO_ASSETS) {
    window_mask->addRoundRect(rect, kCornerRadius, kCornerRadius);
  } else {
    static const int kBottomBorderShadowSize = 2;
    rect.fBottom += SkIntToScalar(kBottomBorderShadowSize);
    window_mask->addRect(rect);
  }
  gfx::Path arrow_path;
  if (bubble_border_->GetArrowPath(gfx::Rect(size), &arrow_path))
    window_mask->addPath(arrow_path, 0, 0);
}

void BubbleFrameView::ResetWindowControls() {
  close_->SetVisible(GetWidget()->widget_delegate()->ShouldShowCloseButton());
}

void BubbleFrameView::UpdateWindowIcon() {
  gfx::ImageSkia image;
  if (GetWidget()->widget_delegate()->ShouldShowWindowIcon())
    image = GetWidget()->widget_delegate()->GetWindowIcon();
  title_icon_->SetImage(&image);
}

void BubbleFrameView::UpdateWindowTitle() {
  if (default_title_) {
    const WidgetDelegate* delegate = GetWidget()->widget_delegate();
    default_title_->SetVisible(delegate->ShouldShowWindowTitle() &&
                               !delegate->GetWindowTitle().empty());
    default_title_->SetText(delegate->GetWindowTitle());
  }  // custom_title_'s updates are handled by its creator.
  Layout();
}

void BubbleFrameView::SizeConstraintsChanged() {}

void BubbleFrameView::SetTitleView(std::unique_ptr<View> title_view) {
  DCHECK(title_view);
  delete default_title_;
  default_title_ = nullptr;
  delete custom_title_;
  custom_title_ = title_view.get();
  // Keep the title after the icon for focus order.
  AddChildViewAt(title_view.release(), 1);
}

const char* BubbleFrameView::GetClassName() const {
  return kViewClassName;
}

gfx::Insets BubbleFrameView::GetInsets() const {
  return GetClientInsetsForFrameWidth(GetContentsBounds().width());
}

gfx::Size BubbleFrameView::CalculatePreferredSize() const {
  // Get the preferred size of the client area.
  gfx::Size client_size = GetWidget()->client_view()->GetPreferredSize();
  // Expand it to include the bubble border and space for the arrow.
  return GetWindowBoundsForClientBounds(gfx::Rect(client_size)).size();
}

gfx::Size BubbleFrameView::GetMinimumSize() const {
  // Get the minimum size of the client area.
  gfx::Size client_size = GetWidget()->client_view()->GetMinimumSize();
  // Expand it to include the bubble border and space for the arrow.
  return GetWindowBoundsForClientBounds(gfx::Rect(client_size)).size();
}

gfx::Size BubbleFrameView::GetMaximumSize() const {
#if defined(OS_WIN)
  // On Windows, this causes problems, so do not set a maximum size (it doesn't
  // take the drop shadow area into account, resulting in a too-small window;
  // see http://crbug.com/506206). This isn't necessary on Windows anyway, since
  // the OS doesn't give the user controls to resize a bubble.
  return gfx::Size();
#else
#if defined(OS_MACOSX)
  // Allow BubbleFrameView dialogs to be resizable on Mac.
  if (GetWidget()->widget_delegate()->CanResize()) {
    gfx::Size client_size = GetWidget()->client_view()->GetMaximumSize();
    if (client_size.IsEmpty())
      return client_size;
    return GetWindowBoundsForClientBounds(gfx::Rect(client_size)).size();
  }
#endif  // OS_MACOSX
  // Non-dialog bubbles should be non-resizable, so its max size is its
  // preferred size.
  return GetPreferredSize();
#endif
}

void BubbleFrameView::Layout() {
  // The title margins may not be set, but make sure that's only the case when
  // there's no title.
  DCHECK(!title_margins_.IsEmpty() ||
         (!custom_title_ && !default_title_->visible()));

  const gfx::Rect contents_bounds = GetContentsBounds();
  gfx::Rect bounds = contents_bounds;
  bounds.Inset(title_margins_);
  if (bounds.IsEmpty())
    return;

  int title_label_right = bounds.right();
  if (close_->visible()) {
    // The close button is positioned somewhat closer to the edge of the bubble.
    const int close_margin =
        LayoutProvider::Get()->GetDistanceMetric(DISTANCE_CLOSE_BUTTON_MARGIN);
    close_->SetPosition(
        gfx::Point(contents_bounds.right() - close_margin - close_->width(),
                   contents_bounds.y() + close_margin));
    title_label_right = std::min(title_label_right, close_->x() - close_margin);
  }

  gfx::Size title_icon_pref_size(title_icon_->GetPreferredSize());
  const int title_icon_padding =
      title_icon_pref_size.width() > 0 ? title_margins_.left() : 0;
  const int title_label_x =
      bounds.x() + title_icon_pref_size.width() + title_icon_padding;

  // TODO(tapted): Layout() should skip more surrounding code when !HasTitle().
  // Currently DCHECKs fail since title_insets is 0 when there is no title.
  if (DCHECK_IS_ON() && HasTitle()) {
    gfx::Insets title_insets = GetTitleLabelInsetsFromFrame();
    if (border())
      title_insets += border()->GetInsets();
    DCHECK_EQ(title_insets.left(), title_label_x);
    DCHECK_EQ(title_insets.right(), width() - title_label_right);
  }

  const int title_available_width =
      std::max(1, title_label_right - title_label_x);
  const int title_preferred_height =
      title()->GetHeightForWidth(title_available_width);
  const int title_height =
      std::max(title_icon_pref_size.height(), title_preferred_height);
  title()->SetBounds(title_label_x,
                     bounds.y() + (title_height - title_preferred_height) / 2,
                     title_available_width, title_preferred_height);

  title_icon_->SetBounds(bounds.x(), bounds.y(), title_icon_pref_size.width(),
                         title_height);

  // Only account for footnote_container_'s height if it's visible, because
  // content_margins_ adds extra padding even if all child views are invisible.
  if (footnote_container_ && footnote_container_->visible()) {
    const int width = contents_bounds.width();
    const int height = footnote_container_->GetHeightForWidth(width);
    footnote_container_->SetBounds(
        contents_bounds.x(), contents_bounds.bottom() - height, width, height);
  }
}

void BubbleFrameView::OnThemeChanged() {
  UpdateWindowTitle();
  ResetWindowControls();
  UpdateWindowIcon();
}

void BubbleFrameView::OnNativeThemeChanged(const ui::NativeTheme* theme) {
  if (bubble_border_ && bubble_border_->use_theme_background_color()) {
    bubble_border_->set_background_color(GetNativeTheme()->
        GetSystemColor(ui::NativeTheme::kColorId_DialogBackground));
    SchedulePaint();
  }
}

void BubbleFrameView::ViewHierarchyChanged(
    const ViewHierarchyChangedDetails& details) {
  if (details.is_add && details.child == this)
    OnThemeChanged();

  if (!details.is_add && details.parent == footnote_container_ &&
      footnote_container_->child_count() == 1 &&
      details.child == footnote_container_->child_at(0)) {
    // Setting the footnote_container_ to be hidden and null it. This will
    // remove update the bubble to have no placeholder for the footnote and
    // enable the destructor to delete the footnote_container_ later.
    footnote_container_->SetVisible(false);
    footnote_container_ = nullptr;
  }
}

void BubbleFrameView::OnPaint(gfx::Canvas* canvas) {
  OnPaintBackground(canvas);
  // Border comes after children.
}

void BubbleFrameView::PaintChildren(const PaintInfo& paint_info) {
  NonClientFrameView::PaintChildren(paint_info);

  ui::PaintCache paint_cache;
  ui::PaintRecorder recorder(
      paint_info.context(), paint_info.paint_recording_size(),
      paint_info.paint_recording_scale_x(),
      paint_info.paint_recording_scale_y(), &paint_cache);
  OnPaintBorder(recorder.canvas());
}

void BubbleFrameView::ButtonPressed(Button* sender, const ui::Event& event) {
  if (sender == close_) {
    close_button_clicked_ = true;
    GetWidget()->Close();
  }
}

void BubbleFrameView::SetBubbleBorder(std::unique_ptr<BubbleBorder> border) {
  bubble_border_ = border.get();
  SetBorder(std::move(border));

  // Update the background, which relies on the border.
  SetBackground(std::make_unique<views::BubbleBackground>(bubble_border_));
}

void BubbleFrameView::SetFootnoteView(View* view) {
  if (!view)
    return;

  DCHECK(!footnote_container_);
  footnote_container_ = new FootnoteContainerView();
  footnote_container_->SetLayoutManager(
      std::make_unique<BoxLayout>(BoxLayout::kVertical, footnote_margins_, 0));
  footnote_container_->SetBackground(
      CreateSolidBackground(gfx::kGoogleGrey050));
  footnote_container_->SetBorder(
      CreateSolidSidedBorder(1, 0, 0, 0, gfx::kGoogleGrey200));
  footnote_container_->AddChildView(view);
  footnote_container_->SetVisible(view->visible());
  AddChildView(footnote_container_);
}

gfx::Rect BubbleFrameView::GetUpdatedWindowBounds(const gfx::Rect& anchor_rect,
                                                  const gfx::Size& client_size,
                                                  bool adjust_if_offscreen) {
  gfx::Size size(GetFrameSizeForClientSize(client_size));

  const BubbleBorder::Arrow arrow = bubble_border_->arrow();
  if (adjust_if_offscreen && BubbleBorder::has_arrow(arrow)) {
    // Try to mirror the anchoring if the bubble does not fit on the screen.
    if (!bubble_border_->is_arrow_at_center(arrow)) {
      MirrorArrowIfOffScreen(true, anchor_rect, size);
      MirrorArrowIfOffScreen(false, anchor_rect, size);
    } else {
      const bool mirror_vertical = BubbleBorder::is_arrow_on_horizontal(arrow);
      MirrorArrowIfOffScreen(mirror_vertical, anchor_rect, size);
      OffsetArrowIfOffScreen(anchor_rect, size);
    }
  }

  // Calculate the bounds with the arrow in its updated location and offset.
  return bubble_border_->GetBounds(anchor_rect, size);
}

gfx::Rect BubbleFrameView::GetAvailableScreenBounds(
    const gfx::Rect& rect) const {
  // The bubble attempts to fit within the current screen bounds.
  return display::Screen::GetScreen()
      ->GetDisplayNearestPoint(rect.CenterPoint())
      .work_area();
}

bool BubbleFrameView::ExtendClientIntoTitle() const {
  return false;
}

bool BubbleFrameView::IsCloseButtonVisible() const {
  return close_->visible();
}

gfx::Rect BubbleFrameView::GetCloseButtonMirroredBounds() const {
  return close_->GetMirroredBounds();
}

void BubbleFrameView::MirrorArrowIfOffScreen(
    bool vertical,
    const gfx::Rect& anchor_rect,
    const gfx::Size& client_size) {
  // Check if the bounds don't fit on screen.
  gfx::Rect available_bounds(GetAvailableScreenBounds(anchor_rect));
  gfx::Rect window_bounds(bubble_border_->GetBounds(anchor_rect, client_size));
  if (GetOffScreenLength(available_bounds, window_bounds, vertical) > 0) {
    BubbleBorder::Arrow arrow = bubble_border()->arrow();
    // Mirror the arrow and get the new bounds.
    bubble_border_->set_arrow(
        vertical ? BubbleBorder::vertical_mirror(arrow) :
                   BubbleBorder::horizontal_mirror(arrow));
    gfx::Rect mirror_bounds =
        bubble_border_->GetBounds(anchor_rect, client_size);
    // Restore the original arrow if mirroring doesn't show more of the bubble.
    // Otherwise it should invoke parent's Layout() to layout the content based
    // on the new bubble border.
    if (GetOffScreenLength(available_bounds, mirror_bounds, vertical) >=
        GetOffScreenLength(available_bounds, window_bounds, vertical)) {
      bubble_border_->set_arrow(arrow);
    } else {
      if (parent())
        parent()->Layout();
      SchedulePaint();
    }
  }
}

void BubbleFrameView::OffsetArrowIfOffScreen(const gfx::Rect& anchor_rect,
                                             const gfx::Size& client_size) {
  BubbleBorder::Arrow arrow = bubble_border()->arrow();
  DCHECK(BubbleBorder::is_arrow_at_center(arrow));

  // Get the desired bubble bounds without adjustment.
  bubble_border_->set_arrow_offset(0);
  gfx::Rect window_bounds(bubble_border_->GetBounds(anchor_rect, client_size));

  gfx::Rect available_bounds(GetAvailableScreenBounds(anchor_rect));
  if (available_bounds.IsEmpty() || available_bounds.Contains(window_bounds))
    return;

  // Calculate off-screen adjustment.
  const bool is_horizontal = BubbleBorder::is_arrow_on_horizontal(arrow);
  int offscreen_adjust = 0;
  if (is_horizontal) {
    if (window_bounds.x() < available_bounds.x())
      offscreen_adjust = available_bounds.x() - window_bounds.x();
    else if (window_bounds.right() > available_bounds.right())
      offscreen_adjust = available_bounds.right() - window_bounds.right();
  } else {
    if (window_bounds.y() < available_bounds.y())
      offscreen_adjust = available_bounds.y() - window_bounds.y();
    else if (window_bounds.bottom() > available_bounds.bottom())
      offscreen_adjust = available_bounds.bottom() - window_bounds.bottom();
  }

  // For center arrows, arrows are moved in the opposite direction of
  // |offscreen_adjust|, e.g. positive |offscreen_adjust| means bubble
  // window needs to be moved to the right and that means we need to move arrow
  // to the left, and that means negative offset.
  bubble_border_->set_arrow_offset(
      bubble_border_->GetArrowOffset(window_bounds.size()) - offscreen_adjust);
  if (offscreen_adjust)
    SchedulePaint();
}

int BubbleFrameView::GetFrameWidthForClientWidth(int client_width) const {
  // Note that GetMinimumSize() for multiline Labels is typically 0.
  const int title_bar_width = title()->GetMinimumSize().width() +
                              GetTitleLabelInsetsFromFrame().width();
  const int client_area_width = client_width + content_margins_.width();
  const int frame_width = std::max(title_bar_width, client_area_width);
  DialogDelegate* dialog_delegate =
      GetWidget()->widget_delegate()->AsDialogDelegate();
  return dialog_delegate && dialog_delegate->ShouldSnapFrameWidth()
             ? LayoutProvider::Get()->GetSnappedDialogWidth(frame_width)
             : frame_width;
}

gfx::Size BubbleFrameView::GetFrameSizeForClientSize(
    const gfx::Size& client_size) const {
  const int frame_width = GetFrameWidthForClientWidth(client_size.width());
  const gfx::Insets client_insets = GetClientInsetsForFrameWidth(frame_width);
  DCHECK_GE(frame_width, client_size.width());
  gfx::Size size(frame_width, client_size.height() + client_insets.height());

  // Only account for footnote_container_'s height if it's visible, because
  // content_margins_ adds extra padding even if all child views are invisible.
  if (footnote_container_ && footnote_container_->visible())
    size.Enlarge(0, footnote_container_->GetHeightForWidth(size.width()));

  return size;
}

bool BubbleFrameView::HasTitle() const {
  return (custom_title_ != nullptr &&
          GetWidget()->widget_delegate()->ShouldShowWindowTitle()) ||
         (default_title_ != nullptr &&
          default_title_->GetPreferredSize().height() > 0) ||
         title_icon_->GetPreferredSize().height() > 0;
}

gfx::Insets BubbleFrameView::GetTitleLabelInsetsFromFrame() const {
  int insets_right = 0;
  if (GetWidget()->widget_delegate()->ShouldShowCloseButton()) {
    const int close_margin =
        LayoutProvider::Get()->GetDistanceMetric(DISTANCE_CLOSE_BUTTON_MARGIN);
    insets_right = 2 * close_margin + close_->width();
  }
  if (!HasTitle())
    return gfx::Insets(0, 0, 0, insets_right);

  insets_right = std::max(insets_right, title_margins_.right());
  const gfx::Size title_icon_pref_size = title_icon_->GetPreferredSize();
  const int title_icon_padding =
      title_icon_pref_size.width() > 0 ? title_margins_.left() : 0;
  const int insets_left =
      title_margins_.left() + title_icon_pref_size.width() + title_icon_padding;
  return gfx::Insets(title_margins_.top(), insets_left, title_margins_.bottom(),
                     insets_right);
}

gfx::Insets BubbleFrameView::GetClientInsetsForFrameWidth(
    int frame_width) const {
  int close_height = 0;
  if (!ExtendClientIntoTitle() &&
      GetWidget()->widget_delegate()->ShouldShowCloseButton()) {
    const int close_margin =
        LayoutProvider::Get()->GetDistanceMetric(DISTANCE_CLOSE_BUTTON_MARGIN);
    // Note: |close_margin| is not applied on the bottom of the icon.
    close_height = close_margin + close_->height();
  }
  if (!HasTitle())
    return content_margins_ + gfx::Insets(close_height, 0, 0, 0);

  const int icon_height = title_icon_->GetPreferredSize().height();
  const int label_height = title()->GetHeightForWidth(
      frame_width - GetTitleLabelInsetsFromFrame().width());
  const int title_height =
      std::max(icon_height, label_height) + title_margins_.height();
  return content_margins_ +
         gfx::Insets(std::max(title_height, close_height), 0, 0, 0);
}

}  // namespace views
