// 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 "base/i18n/rtl.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chrome_page_zoom.h"
#include "chrome/browser/ui/browser.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/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/location_bar/zoom_view.h"
#include "chrome/browser/ui/zoom/zoom_controller.h"
#include "chrome/common/extensions/api/extension_action/action_info.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/notification_source.h"
#include "extensions/common/manifest_handlers/icons_handler.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/favicon_size.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/separator.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/layout/layout_constants.h"
#include "ui/views/widget/widget.h"

namespace {

// The number of milliseconds the bubble should stay on the screen if it will
// close automatically.
const int kBubbleCloseDelay = 1500;

// The bubble's padding from the screen edge, used in fullscreen.
const int kFullscreenPaddingEnd = 20;

}  // namespace

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

// static
void ZoomBubbleView::ShowBubble(content::WebContents* web_contents,
                                bool auto_close) {
  Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
  DCHECK(browser && browser->window() && browser->fullscreen_controller());

  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
  bool is_fullscreen = browser_view->IsFullscreen();
  bool anchor_to_view = !is_fullscreen ||
      browser_view->immersive_mode_controller()->IsRevealed();
  views::View* anchor_view = anchor_to_view ?
      browser_view->GetLocationBarView()->zoom_view() : NULL;

  // Find the extension that initiated the zoom change, if any.
  ZoomController* zoom_controller =
      ZoomController::FromWebContents(web_contents);
  const extensions::Extension* extension = zoom_controller->last_extension();

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

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

  zoom_bubble_ = new ZoomBubbleView(anchor_view,
                                    web_contents,
                                    auto_close,
                                    browser_view->immersive_mode_controller(),
                                    browser->fullscreen_controller());

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

  // If we do not have an anchor view, parent the bubble to the content area.
  if (!anchor_to_view)
    zoom_bubble_->set_parent_window(web_contents->GetTopLevelNativeWindow());

  views::BubbleDelegateView::CreateBubble(zoom_bubble_);

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

  if (auto_close)
    zoom_bubble_->GetWidget()->ShowInactive();
  else
    zoom_bubble_->GetWidget()->Show();
}

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

// static
bool ZoomBubbleView::IsShowing() {
  // The bubble is considered showing while closing.
  return zoom_bubble_ != NULL && (zoom_bubble_->GetWidget()->IsVisible() ||
                                  zoom_bubble_->GetWidget()->IsClosed());
}

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

ZoomBubbleView::ZoomBubbleView(
    views::View* anchor_view,
    content::WebContents* web_contents,
    bool auto_close,
    ImmersiveModeController* immersive_mode_controller,
    FullscreenController* fullscreen_controller)
    : BubbleDelegateView(anchor_view, anchor_view ?
          views::BubbleBorder::TOP_RIGHT : views::BubbleBorder::NONE),
      image_button_(NULL),
      label_(NULL),
      web_contents_(web_contents),
      auto_close_(auto_close),
      immersive_mode_controller_(immersive_mode_controller) {
  // Compensate for built-in vertical padding in the anchor view's image.
  set_anchor_view_insets(gfx::Insets(5, 0, 5, 0));
  set_notify_enter_exit_on_child(true);

  // Add observers to close the bubble if the fullscreen state or immersive
  // fullscreen revealed state changes.
  registrar_.Add(this,
                 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
                 content::Source<FullscreenController>(fullscreen_controller));
  immersive_mode_controller_->AddObserver(this);
}

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

void ZoomBubbleView::AdjustForFullscreen(const gfx::Rect& screen_bounds) {
  if (GetAnchorView())
    return;

  // TODO(dbeam): should RTL logic be done in views::BubbleDelegateView?
  const size_t bubble_half_width = width() / 2;
  const int x_pos = base::i18n::IsRTL() ?
      screen_bounds.x() + bubble_half_width + kFullscreenPaddingEnd :
      screen_bounds.right() - bubble_half_width - kFullscreenPaddingEnd;
  SetAnchorRect(gfx::Rect(x_pos, screen_bounds.y(), 0, 0));
}

void ZoomBubbleView::Refresh() {
  ZoomController* zoom_controller =
      ZoomController::FromWebContents(web_contents_);
  int zoom_percent = zoom_controller->GetZoomPercent();
  label_->SetText(
      l10n_util::GetStringFUTF16Int(IDS_TOOLTIP_ZOOM, zoom_percent));
  StartTimerIfNecessary();
}

void ZoomBubbleView::Close() {
  // 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_ = NULL;
  web_contents_ = NULL;
  GetWidget()->Close();
}

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

  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::StartTimerIfNecessary() {
  if (auto_close_) {
    if (timer_.IsRunning()) {
      timer_.Reset();
    } else {
      timer_.Start(
          FROM_HERE,
          base::TimeDelta::FromMilliseconds(kBubbleCloseDelay),
          this,
          &ZoomBubbleView::Close);
    }
  }
}

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

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

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

void ZoomBubbleView::OnMouseExited(const ui::MouseEvent& event) {
  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::ButtonPressed(views::Button* sender,
                                   const ui::Event& event) {
  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 {
    chrome_page_zoom::Zoom(web_contents_, content::PAGE_ZOOM_RESET);
  }
}

void ZoomBubbleView::Init() {
  // Set up the layout of the zoom bubble. A grid layout is used because
  // sometimes an extension icon is shown next to the zoom label.
  views::GridLayout* grid_layout = new views::GridLayout(this);
  SetLayoutManager(grid_layout);
  views::ColumnSet* columns = grid_layout->AddColumnSet(0);
  // First row.
  if (extension_info_.icon_image) {
    columns->AddColumn(views::GridLayout::CENTER,views::GridLayout::CENTER, 2,
                       views::GridLayout::USE_PREF, 0, 0);
  }
  columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
                     views::GridLayout::USE_PREF, 0, 0);
  grid_layout->StartRow(0, 0);

  // 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());
    grid_layout->AddView(image_button_);
  }

  // Add zoom label with the new zoom percent.
  ZoomController* zoom_controller =
      ZoomController::FromWebContents(web_contents_);
  int zoom_percent = zoom_controller->GetZoomPercent();
  label_ = new views::Label(
      l10n_util::GetStringFUTF16Int(IDS_TOOLTIP_ZOOM, zoom_percent));
  label_->SetFontList(
      ui::ResourceBundle::GetSharedInstance().GetFontList(
          ui::ResourceBundle::MediumFont));
  grid_layout->AddView(label_);

  // Second row.
  grid_layout->AddPaddingRow(0, 8);
  columns = grid_layout->AddColumnSet(1);
  columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
                     views::GridLayout::USE_PREF, 0, 0);
  grid_layout->StartRow(0, 1);

  // Add "Reset to Default" button.
  views::LabelButton* set_default_button = new views::LabelButton(
      this, l10n_util::GetStringUTF16(IDS_ZOOM_SET_DEFAULT));
  set_default_button->SetStyle(views::Button::STYLE_BUTTON);
  set_default_button->SetHorizontalAlignment(gfx::ALIGN_CENTER);
  grid_layout->AddView(set_default_button);

  StartTimerIfNecessary();
}

void ZoomBubbleView::Observe(int type,
                             const content::NotificationSource& source,
                             const content::NotificationDetails& details) {
  DCHECK_EQ(type, chrome::NOTIFICATION_FULLSCREEN_CHANGED);
  CloseBubble();
}

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

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

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

ZoomBubbleView::ZoomBubbleExtensionInfo::ZoomBubbleExtensionInfo() {}

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