// 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/chrome_layout_provider.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/page_action/page_action_icon_container_view.h"
#include "chrome/browser/ui/views/page_action/zoom_view.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/resource/resource_bundle.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_class_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();
}

PageActionIconContainerView* GetAnchorViewForBrowser(Browser* browser,
                                                     bool is_fullscreen) {
  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
  if (!is_fullscreen ||
      browser_view->immersive_mode_controller()->IsRevealed()) {
    return browser_view->toolbar_button_provider()
        ->GetPageActionIconContainerView();
  }
  return nullptr;
}

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

ImmersiveModeController* GetImmersiveModeControllerForBrowser(
    Browser* browser) {
  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
  return browser_view->immersive_mode_controller();
}

void ParentToViewsBrowser(Browser* browser,
                          ZoomBubbleView* zoom_bubble,
                          views::View* anchor_view,
                          content::WebContents* web_contents) {
  // If the anchor view exists the zoom icon should be highlighed.
  if (anchor_view) {
    zoom_bubble->SetHighlightedButton(
        BrowserView::GetBrowserViewForBrowser(browser)
            ->toolbar_button_provider()
            ->GetPageActionIconContainerView()
            ->GetPageActionIconView(PageActionIconType::kZoom));
  } else {
    // If we do not have an anchor view, parent the bubble to the content area.
    zoom_bubble->set_parent_window(web_contents->GetNativeView());
  }

  views::BubbleDialogDelegateView::CreateBubble(zoom_bubble);
}

void ParentToBrowser(Browser* browser,
                     ZoomBubbleView* zoom_bubble,
                     views::View* anchor_view,
                     content::WebContents* web_contents) {
  ParentToViewsBrowser(browser, zoom_bubble, anchor_view, web_contents);
}

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

  // Do not announce hotkey for refocusing inactive Zoom bubble as it
  // disappears after a short timeout.
  zoom_bubble_->ShowForReason(reason, /* allow_refocus_alert */ false);
  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) {
  // Can't refresh when there's not already a bubble for this tab.
  if (!zoom_bubble_ || (zoom_bubble_->web_contents() != web_contents))
    return false;

  Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
  if (!browser ||
      (zoom_bubble_->GetAnchorView() != GetAnchorViewForBrowser(browser)))
    return false;

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

  // Allow refreshes when the client won't create its own bubble; otherwise
  // the existing bubble would show the wrong zoom value.
  if (client && client->ShouldSuppressBubble())
    return true;

  // Allow refreshes when the existing bubble has the same attribution for
  // the zoom change, so only the label needs updating.
  return zoom_bubble_->extension_info_.id ==
         (client ? client->extension()->id() : std::string());
}

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

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

void ZoomBubbleView::Refresh() {
  UpdateZoomPercent();
  GetWidget()->GetRootView()->NotifyAccessibilityEvent(ax::mojom::Event::kAlert,
                                                       true);
  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);
}

base::string16 ZoomBubbleView::GetAccessibleWindowTitle() const {
  Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
  PageActionIconContainerView* page_action_icon_container_view =
      GetAnchorViewForBrowser(browser);
  if (!page_action_icon_container_view)
    return base::string16();

  PageActionIconView* zoom_view =
      page_action_icon_container_view->GetPageActionIconView(
          PageActionIconType::kZoom);
  return zoom_view->GetTextForTooltipAndAccessibleName();
}

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

void ZoomBubbleView::OnFocus() {
  LocationBarBubbleDelegateView::OnFocus();
  StopTimer();
}

void ZoomBubbleView::OnBlur() {
  LocationBarBubbleDelegateView::OnBlur();

  const views::FocusManager* focus_manager = GetFocusManager();
  if (focus_manager && Contains(focus_manager->GetFocusedView()))
    return;

  StartTimerIfNecessary();
}

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::OnKeyEvent(ui::KeyEvent* event) {
  if (!zoom_bubble_ || !zoom_bubble_->auto_close_)
    return;

  const views::FocusManager* focus_manager = GetFocusManager();
  if (focus_manager && Contains(focus_manager->GetFocusedView()))
    StopTimer();
  else
    StartTimerIfNecessary();
}

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::Layout() {
  View::Layout();

  for (auto* button : {zoom_in_button_, zoom_out_button_}) {
    constexpr int kCircleDiameterDp = 24;
    auto highlight_path = std::make_unique<SkPath>();
    // Use a centered circular shape for inkdrops and focus rings.
    gfx::Rect circle_rect(button->GetLocalBounds());
    circle_rect.ClampToCenteredSize(
        gfx::Size(kCircleDiameterDp, kCircleDiameterDp));
    highlight_path->addOval(gfx::RectToSkRect(circle_rect));
    button->SetProperty(views::kHighlightPathKey, highlight_path.release());
  }
}

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

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;

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

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

ZoomBubbleView::ZoomBubbleExtensionInfo::ZoomBubbleExtensionInfo() {}

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