// 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/location_bar/zoom_bubble_view.h"

#include <cmath>

#include "base/auto_reset.h"
#include "base/i18n/number_formatting.h"
#include "base/i18n/rtl.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/toolbar_button_provider.h"
#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h"
#include "chrome/browser/ui/views/page_action/page_action_icon_container_view.h"
#include "chrome/browser/ui/views/page_action/zoom_view.h"
#include "chrome/browser/ui/views_mode_controller.h"
#include "chrome/common/extensions/api/extension_action/action_info.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h"
#include "components/zoom/page_zoom.h"
#include "components/zoom/zoom_controller.h"
#include "content/public/browser/notification_source.h"
#include "extensions/browser/extension_zoom_request_client.h"
#include "extensions/common/manifest_handlers/icons_handler.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/base/ui_features.h"
#include "ui/gfx/favicon_size.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/text_utils.h"
#include "ui/gfx/vector_icon_types.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/button/image_button_factory.h"
#include "ui/views/controls/button/md_text_button.h"
#include "ui/views/controls/separator.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/view_properties.h"
#include "ui/views/widget/widget.h"

namespace {

// The default time that the bubble should stay on the screen if it will close
// automatically.
constexpr base::TimeDelta kBubbleCloseDelayDefault =
    base::TimeDelta::FromMilliseconds(1500);

// A longer timeout used for how long the bubble should stay on the screen
// before it will close automatically after + or - buttons have been used.
constexpr base::TimeDelta kBubbleCloseDelayLong =
    base::TimeDelta::FromMilliseconds(5000);

// Creates an ImageButton using vector |icon|, sets a tooltip with |tooltip_id|.
// Returns the button.
std::unique_ptr<views::Button> CreateZoomButton(views::ButtonListener* listener,
                                                const gfx::VectorIcon& icon,
                                                int tooltip_id) {
  std::unique_ptr<views::ImageButton> button(
      views::CreateVectorImageButton(listener));
  views::SetImageFromVectorIcon(button.get(), icon);
  button->SetFocusForPlatform();
  button->SetTooltipText(l10n_util::GetStringUTF16(tooltip_id));
  return std::move(button);
}

class ZoomValue : public views::Label {
 public:
  explicit ZoomValue(const content::WebContents* web_contents)
      : Label(base::string16(),
              views::style::CONTEXT_LABEL,
              views::style::STYLE_PRIMARY),
        max_width_(GetLabelMaxWidth(web_contents)) {
    SetHorizontalAlignment(gfx::ALIGN_LEFT);
  }
  ~ZoomValue() override {}

  // views::Label:
  gfx::Size CalculatePreferredSize() const override {
    return gfx::Size(max_width_, GetHeightForWidth(max_width_));
  }

 private:
  int GetLabelMaxWidth(const content::WebContents* web_contents) const {
    const int border_width = border() ? border()->GetInsets().width() : 0;
    int max_w = 0;
    auto* zoom_controller = zoom::ZoomController::FromWebContents(web_contents);
    DCHECK(zoom_controller);
    // Enumerate all zoom factors that can be used in PageZoom::Zoom.
    std::vector<double> zoom_factors =
        zoom::PageZoom::PresetZoomFactors(zoom_controller->GetZoomPercent());
    for (auto zoom : zoom_factors) {
      int w = gfx::GetStringWidth(
          base::FormatPercent(static_cast<int>(std::round(zoom * 100))),
          font_list());
      max_w = std::max(w, max_w);
    }
    return max_w + border_width;
  }

  const int max_width_;

  DISALLOW_COPY_AND_ASSIGN(ZoomValue);
};

bool IsBrowserFullscreen(Browser* browser) {
  DCHECK(browser->window() &&
         browser->exclusive_access_manager()->fullscreen_controller());
  return browser->window()->IsFullscreen();
}

views::View* GetAnchorViewForBrowser(Browser* browser, bool is_fullscreen) {
#if !defined(OS_MACOSX) || BUILDFLAG(MAC_VIEWS_BROWSER)
#if BUILDFLAG(MAC_VIEWS_BROWSER)
  if (views_mode_controller::IsViewsBrowserCocoa())
    return nullptr;  // Cocoa browsers always use anchor rects instead of views.
#endif
  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
  if (!is_fullscreen ||
      browser_view->immersive_mode_controller()->IsRevealed()) {
    PageActionIconContainerView* container =
        browser_view->toolbar_button_provider()
            ->GetPageActionIconContainerView();
    return ui::MaterialDesignController::IsSecondaryUiMaterial()
               ? static_cast<views::View*>(container)
               : static_cast<views::View*>(container->GetPageActionIconView(
                     PageActionIconType::kZoom));
  }
  return nullptr;
#else  // OS_MACOSX && !MAC_VIEWS_BROWSER
  return nullptr;
#endif
}

views::View* GetAnchorViewForBrowser(Browser* browser) {
  const bool is_fullscreen = IsBrowserFullscreen(browser);
  return GetAnchorViewForBrowser(browser, is_fullscreen);
}

ImmersiveModeController* GetImmersiveModeControllerForBrowser(
    Browser* browser) {
#if !defined(OS_MACOSX) || BUILDFLAG(MAC_VIEWS_BROWSER)
#if BUILDFLAG(MAC_VIEWS_BROWSER)
  if (views_mode_controller::IsViewsBrowserCocoa())
    return nullptr;
#endif
  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
  return browser_view->immersive_mode_controller();
#else
  return nullptr;
#endif
}

#if !defined(OS_MACOSX) || BUILDFLAG(MAC_VIEWS_BROWSER)
void ParentToViewsBrowser(Browser* browser,
                          ZoomBubbleView* zoom_bubble,
                          views::View* anchor_view,
                          content::WebContents* web_contents) {
  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
  // If we do not have an anchor view, parent the bubble to the content area.
  if (!anchor_view)
    zoom_bubble->set_parent_window(web_contents->GetNativeView());

  views::Widget* zoom_bubble_widget =
      views::BubbleDialogDelegateView::CreateBubble(zoom_bubble);
  if (zoom_bubble_widget && anchor_view) {
    browser_view->toolbar_button_provider()
        ->GetPageActionIconContainerView()
        ->GetPageActionIconView(PageActionIconType::kZoom)
        ->OnBubbleWidgetCreated(zoom_bubble_widget);
  }
}
#endif

#if defined(OS_MACOSX)
void ParentToCocoaBrowser(Browser* browser, ZoomBubbleView* zoom_bubble) {
  gfx::NativeView parent =
      platform_util::GetViewForWindow(browser->window()->GetNativeWindow());
  DCHECK(parent);
  zoom_bubble->set_arrow(views::BubbleBorder::TOP_RIGHT);
  zoom_bubble->set_parent_window(parent);
  views::BubbleDialogDelegateView::CreateBubble(zoom_bubble);
}
#endif

void ParentToBrowser(Browser* browser,
                     ZoomBubbleView* zoom_bubble,
                     views::View* anchor_view,
                     content::WebContents* web_contents) {
#if defined(OS_MACOSX) && BUILDFLAG(MAC_VIEWS_BROWSER)
  if (views_mode_controller::IsViewsBrowserCocoa())
    ParentToCocoaBrowser(browser, zoom_bubble);
  else
    ParentToViewsBrowser(browser, zoom_bubble, anchor_view, web_contents);
#elif defined(OS_MACOSX)
  ParentToCocoaBrowser(browser, zoom_bubble);
#else
  ParentToViewsBrowser(browser, zoom_bubble, anchor_view, web_contents);
#endif
}

// Find the extension that initiated the zoom change, if any.
const extensions::ExtensionZoomRequestClient* GetExtensionZoomRequestClient(
    const content::WebContents* web_contents) {
  const zoom::ZoomController* zoom_controller =
      zoom::ZoomController::FromWebContents(web_contents);
  const zoom::ZoomRequestClient* client = zoom_controller->last_client();
  return static_cast<const extensions::ExtensionZoomRequestClient*>(client);
}

}  // namespace

// static
ZoomBubbleView* ZoomBubbleView::zoom_bubble_ = nullptr;

// static
void ZoomBubbleView::ShowBubble(content::WebContents* web_contents,
                                const gfx::Point& anchor_point,
                                DisplayReason reason) {
  Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
  // |web_contents| could have been unloaded if a tab gets closed and a mouse
  // event arrives before the zoom icon gets hidden.
  if (!browser)
    return;

  if (RefreshBubbleIfShowing(web_contents))
    return;

  // If the bubble is already showing but in a different tab, the current
  // bubble must be closed and a new one created.
  CloseCurrentBubble();

  const bool is_fullscreen = IsBrowserFullscreen(browser);
  views::View* anchor_view = GetAnchorViewForBrowser(browser, is_fullscreen);
  ImmersiveModeController* immersive_mode_controller =
      GetImmersiveModeControllerForBrowser(browser);

  zoom_bubble_ = new ZoomBubbleView(anchor_view, anchor_point, web_contents,
                                    reason, immersive_mode_controller);

  const extensions::ExtensionZoomRequestClient* client =
      GetExtensionZoomRequestClient(web_contents);

  // If the zoom change was initiated by an extension, capture the relevent
  // information from it.
  if (client)
    zoom_bubble_->SetExtensionInfo(client->extension());

  ParentToBrowser(browser, zoom_bubble_, anchor_view, web_contents);

  // Adjust for fullscreen after creation as it relies on the content size.
  if (is_fullscreen)
    zoom_bubble_->AdjustForFullscreen(browser->window()->GetBounds());

  zoom_bubble_->ShowForReason(reason);
  zoom_bubble_->UpdateZoomIconVisibility();
}

// static
bool ZoomBubbleView::RefreshBubbleIfShowing(
    const content::WebContents* web_contents) {
  if (!CanRefresh(web_contents))
    return false;

  DCHECK_EQ(web_contents, zoom_bubble_->web_contents());
  zoom_bubble_->Refresh();

  return true;
}

// static
bool ZoomBubbleView::CanRefresh(const content::WebContents* web_contents) {
  Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
  if (!browser)
    return false;

  const views::View* anchor_view = GetAnchorViewForBrowser(browser);
  const extensions::ExtensionZoomRequestClient* client =
      GetExtensionZoomRequestClient(web_contents);

  // If the bubble is already showing in this window and the zoom change was not
  // initiated by an extension that needs attribution in the zoom bubble, then
  // the bubble can be reused and only the label text needs to be updated.
  return zoom_bubble_ && zoom_bubble_->web_contents() == web_contents &&
         zoom_bubble_->GetAnchorView() == anchor_view &&
         (!client || client->ShouldSuppressBubble());
}

// static
void ZoomBubbleView::CloseCurrentBubble() {
  if (zoom_bubble_)
    zoom_bubble_->CloseBubble();
}

// static
ZoomBubbleView* ZoomBubbleView::GetZoomBubble() {
  return zoom_bubble_;
}

void ZoomBubbleView::Refresh() {
  UpdateZoomPercent();
  StartTimerIfNecessary();
}

ZoomBubbleView::ZoomBubbleView(
    views::View* anchor_view,
    const gfx::Point& anchor_point,
    content::WebContents* web_contents,
    DisplayReason reason,
    ImmersiveModeController* immersive_mode_controller)
    : LocationBarBubbleDelegateView(anchor_view, anchor_point, web_contents),
      auto_close_duration_(kBubbleCloseDelayDefault),
      image_button_(nullptr),
      label_(nullptr),
      zoom_out_button_(nullptr),
      zoom_in_button_(nullptr),
      reset_button_(nullptr),
      auto_close_(reason == AUTOMATIC),
      ignore_close_bubble_(false),
      immersive_mode_controller_(immersive_mode_controller),
      session_id_(
          chrome::FindBrowserWithWebContents(web_contents)->session_id()) {
  set_notify_enter_exit_on_child(true);
  if (immersive_mode_controller_)
    immersive_mode_controller_->AddObserver(this);
  UseCompactMargins();
  chrome::RecordDialogCreation(chrome::DialogIdentifier::ZOOM);
}

ZoomBubbleView::~ZoomBubbleView() {
  if (immersive_mode_controller_)
    immersive_mode_controller_->RemoveObserver(this);
}

int ZoomBubbleView::GetDialogButtons() const {
  return ui::DIALOG_BUTTON_NONE;
}

void ZoomBubbleView::OnGestureEvent(ui::GestureEvent* event) {
  if (!zoom_bubble_ || !zoom_bubble_->auto_close_ ||
      event->type() != ui::ET_GESTURE_TAP) {
    return;
  }

  auto_close_ = false;
  StopTimer();
  event->SetHandled();
}

void ZoomBubbleView::OnMouseEntered(const ui::MouseEvent& event) {
  StopTimer();
}

void ZoomBubbleView::OnMouseExited(const ui::MouseEvent& event) {
  StartTimerIfNecessary();
}

void ZoomBubbleView::Init() {
  // Set up the layout of the zoom bubble.
  const ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
  const int spacing =
      provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_HORIZONTAL);
  auto box_layout = std::make_unique<views::BoxLayout>(
      views::BoxLayout::kHorizontal,
      provider->GetInsetsMetric(INSETS_TOAST) - margins(), spacing);
  box_layout->set_main_axis_alignment(
      views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
  box_layout->set_cross_axis_alignment(
      views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
  SetLayoutManager(std::move(box_layout));

  // Calculate child views margins in |this| client view.
  const int label_vertical_spacing =
      provider->GetDistanceMetric(DISTANCE_TOAST_LABEL_VERTICAL);
  const gfx::Insets label_vertical_margin(
      label_vertical_spacing - margins().top(), 0,
      label_vertical_spacing - margins().bottom(), 0);

  // Account for the apparent margins that vector buttons have around icons.
  const int control_vertical_spacing =
      provider->GetDistanceMetric(DISTANCE_TOAST_CONTROL_VERTICAL);
  const gfx::Insets control_vertical_margin(
      control_vertical_spacing - margins().top(), 0,
      control_vertical_spacing - margins().bottom(), 0);
  const gfx::Insets vector_button_margin(
      control_vertical_margin -
      provider->GetInsetsMetric(views::INSETS_VECTOR_IMAGE_BUTTON));

  // If this zoom change was initiated by an extension, that extension will be
  // attributed by showing its icon in the zoom bubble.
  if (extension_info_.icon_image) {
    image_button_ = new views::ImageButton(this);
    image_button_->SetTooltipText(
        l10n_util::GetStringFUTF16(IDS_TOOLTIP_ZOOM_EXTENSION_ICON,
                                   base::UTF8ToUTF16(extension_info_.name)));
    image_button_->SetImage(views::Button::STATE_NORMAL,
                            &extension_info_.icon_image->image_skia());
    AddChildView(image_button_);
  }

  // Add zoom label with the new zoom percent.
  label_ = new ZoomValue(web_contents());
  UpdateZoomPercent();
  label_->SetProperty(views::kMarginsKey,
                      new gfx::Insets(label_vertical_margin));
  AddChildView(label_);

  // Add extra padding between the zoom percent label and the buttons.
  constexpr int kPercentLabelPadding = 64;
  auto* label_padding_view = new views::View();
  label_padding_view->SetPreferredSize(gfx::Size(
      kPercentLabelPadding - spacing * 2, label_->GetPreferredSize().height()));
  AddChildView(label_padding_view);

  // Add Zoom Out ("-") button.
  std::unique_ptr<views::Button> zoom_out_button =
      CreateZoomButton(this, kRemoveIcon, IDS_ACCNAME_ZOOM_MINUS2);
  zoom_out_button_ = zoom_out_button.get();
  zoom_out_button_->SetProperty(views::kMarginsKey,
                                new gfx::Insets(vector_button_margin));
  AddChildView(zoom_out_button.release());

  // Add Zoom In ("+") button.
  std::unique_ptr<views::Button> zoom_in_button =
      CreateZoomButton(this, kAddIcon, IDS_ACCNAME_ZOOM_PLUS2);
  zoom_in_button_ = zoom_in_button.get();
  zoom_in_button_->SetProperty(views::kMarginsKey,
                               new gfx::Insets(vector_button_margin));
  AddChildView(zoom_in_button.release());

  // Add "Reset" button.
  reset_button_ = views::MdTextButton::CreateSecondaryUiButton(
      this, l10n_util::GetStringUTF16(IDS_ZOOM_SET_DEFAULT));
  reset_button_->SetTooltipText(
      l10n_util::GetStringUTF16(IDS_ACCNAME_ZOOM_SET_DEFAULT));
  AddChildView(reset_button_);

  StartTimerIfNecessary();
}

void ZoomBubbleView::WindowClosing() {
  // |zoom_bubble_| can be a new bubble by this point (as Close(); doesn't
  // call this right away). Only set to nullptr when it's this bubble.
  bool this_bubble = zoom_bubble_ == this;
  if (this_bubble)
    zoom_bubble_ = nullptr;

  UpdateZoomIconVisibility();
}

void ZoomBubbleView::CloseBubble() {
  if (ignore_close_bubble_)
    return;

  // Widget's Close() is async, but we don't want to use zoom_bubble_ after
  // this. Additionally web_contents() may have been destroyed.
  zoom_bubble_ = nullptr;
  LocationBarBubbleDelegateView::CloseBubble();
}

void ZoomBubbleView::ButtonPressed(views::Button* sender,
                                   const ui::Event& event) {
  // No button presses in this dialog should cause the dialog to close,
  // including when the zoom level is set to 100% as a result of a button press.
  base::AutoReset<bool> auto_ignore_close_bubble(&ignore_close_bubble_, true);

  // Extend the timer to give a user more time after any button is pressed.
  auto_close_duration_ = kBubbleCloseDelayLong;
  StartTimerIfNecessary();

  if (sender == image_button_) {
    DCHECK(extension_info_.icon_image) << "Invalid button press.";
    Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
    chrome::AddSelectedTabWithURL(
        browser, GURL(base::StringPrintf("chrome://extensions?id=%s",
                                         extension_info_.id.c_str())),
        ui::PAGE_TRANSITION_FROM_API);
  } else if (sender == zoom_out_button_) {
    zoom::PageZoom::Zoom(web_contents(), content::PAGE_ZOOM_OUT);
  } else if (sender == zoom_in_button_) {
    zoom::PageZoom::Zoom(web_contents(), content::PAGE_ZOOM_IN);
  } else if (sender == reset_button_) {
    zoom::PageZoom::Zoom(web_contents(), content::PAGE_ZOOM_RESET);
  } else {
    NOTREACHED();
  }
}

void ZoomBubbleView::OnImmersiveRevealStarted() {
  CloseBubble();
}

void ZoomBubbleView::OnImmersiveModeControllerDestroyed() {
  immersive_mode_controller_ = nullptr;
}

void ZoomBubbleView::OnExtensionIconImageChanged(
    extensions::IconImage* /* image */) {
  image_button_->SetImage(views::Button::STATE_NORMAL,
                          &extension_info_.icon_image->image_skia());
  image_button_->SchedulePaint();
}

void ZoomBubbleView::SetExtensionInfo(const extensions::Extension* extension) {
  DCHECK(extension);
  extension_info_.id = extension->id();
  extension_info_.name = extension->name();

  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  const gfx::ImageSkia& default_extension_icon_image =
      *rb.GetImageSkiaNamed(IDR_EXTENSIONS_FAVICON);
  int icon_size = gfx::kFaviconSize;

  // We give first preference to an icon from the extension's icon set that
  // matches the size of the default. But not all extensions will declare an
  // icon set, or may not have an icon of the default size (we don't want the
  // bubble to display, for example, a very large icon). In that case, if there
  // is a browser-action icon (size-19) this is an acceptable alternative.
  const ExtensionIconSet& icons = extensions::IconsInfo::GetIcons(extension);
  bool has_default_sized_icon =
      !icons.Get(gfx::kFaviconSize, ExtensionIconSet::MATCH_EXACTLY).empty();
  if (has_default_sized_icon) {
    extension_info_.icon_image.reset(new extensions::IconImage(
        web_contents()->GetBrowserContext(), extension, icons, icon_size,
        default_extension_icon_image, this));
    return;
  }

  const extensions::ActionInfo* browser_action =
      extensions::ActionInfo::GetBrowserActionInfo(extension);
  if (!browser_action || browser_action->default_icon.empty())
    return;

  icon_size = browser_action->default_icon.map().begin()->first;
  extension_info_.icon_image.reset(
      new extensions::IconImage(web_contents()->GetBrowserContext(), extension,
                                browser_action->default_icon, icon_size,
                                default_extension_icon_image, this));
}

void ZoomBubbleView::UpdateZoomPercent() {
  label_->SetText(base::FormatPercent(
      zoom::ZoomController::FromWebContents(web_contents())->GetZoomPercent()));
  label_->NotifyAccessibilityEvent(ax::mojom::Event::kTextChanged, true);
}

void ZoomBubbleView::UpdateZoomIconVisibility() {
  // Note that we can't rely on web_contents() here, as it may have been
  // destroyed by the time we get this call. Also note parent_window() (if set)
  // may also be destroyed: the call to WindowClosing() may be triggered by
  // parent window destruction tearing down its child windows.
  Browser* browser = chrome::FindBrowserWithID(session_id_);
  if (browser && browser->window() &&
      browser->window()->GetPageActionIconContainer()) {
    browser->window()->GetPageActionIconContainer()->UpdatePageActionIcon(
        PageActionIconType::kZoom);
  }
}

void ZoomBubbleView::StartTimerIfNecessary() {
  if (!auto_close_)
    return;

  timer_.Start(FROM_HERE, auto_close_duration_, this,
               &ZoomBubbleView::CloseBubble);
}

void ZoomBubbleView::StopTimer() {
  timer_.Stop();
}

ZoomBubbleView::ZoomBubbleExtensionInfo::ZoomBubbleExtensionInfo() {}

ZoomBubbleView::ZoomBubbleExtensionInfo::~ZoomBubbleExtensionInfo() {}
