// 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/notifications/balloon_view_views.h"

#include <algorithm>
#include <vector>

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/notifications/balloon_collection.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/notifications/notification_options_menu_model.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/path.h"
#include "ui/views/bubble/bubble_border.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/controls/button/text_button.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/menu/menu_item_view.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/widget/widget.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/notifications/balloon_view_host_chromeos.h"
#else
#include "chrome/browser/ui/views/notifications/balloon_view_host.h"
#endif

namespace {

const int kTopMargin = 2;
const int kBottomMargin = 0;
const int kLeftMargin = 4;
const int kRightMargin = 4;

// Margin between various shelf buttons/label and the shelf border.
const int kShelfMargin = 2;

// Spacing between the options and close buttons.
const int kOptionsDismissSpacing = 4;

// Spacing between the options button and label text.
const int kLabelOptionsSpacing = 4;

// Margin between shelf border and title label.
const int kLabelLeftMargin = 6;

// Size of the drop shadow.  The shadow is provided by BubbleBorder,
// not this class.
const int kLeftShadowWidth = 0;
const int kRightShadowWidth = 0;
const int kTopShadowWidth = 0;
const int kBottomShadowWidth = 6;

// Optional animation.
const bool kAnimateEnabled = true;

// Menu commands
const int kRevokePermissionCommand = 0;

// Colors
const SkColor kControlBarBackgroundColor = SkColorSetRGB(245, 245, 245);
const SkColor kControlBarTextColor = SkColorSetRGB(125, 125, 125);
const SkColor kControlBarSeparatorLineColor = SkColorSetRGB(180, 180, 180);

}  // namespace

// static
int BalloonView::GetHorizontalMargin() {
  return kLeftMargin + kRightMargin + kLeftShadowWidth + kRightShadowWidth;
}

BalloonViewImpl::BalloonViewImpl(BalloonCollection* collection)
    : balloon_(NULL),
      collection_(collection),
      frame_container_(NULL),
      html_container_(NULL),
      close_button_(NULL),
      options_menu_button_(NULL),
      enable_web_ui_(false),
      closed_by_user_(false),
      closed_(false) {
  // We're owned by Balloon and don't want to be deleted by our parent View.
  set_owned_by_client();

  set_border(new views::BubbleBorder(views::BubbleBorder::FLOAT,
      views::BubbleBorder::NO_SHADOW, SK_ColorWHITE));
}

BalloonViewImpl::~BalloonViewImpl() {
}

void BalloonViewImpl::Close(bool by_user) {
  if (closed_)
    return;

  closed_ = true;
  animation_->Stop();
  html_contents_->Shutdown();
  // Detach contents from the widget before they close.
  // This is necessary because a widget may be deleted
  // after this when chrome is shutting down.
  html_container_->GetRootView()->RemoveAllChildViews(true);
  html_container_->Close();
  frame_container_->GetRootView()->RemoveAllChildViews(true);
  frame_container_->Close();
  closed_by_user_ = by_user;
  // |frame_container_->::Close()| is async. When processed it'll call back to
  // DeleteDelegate() and we'll cleanup.
}

gfx::Size BalloonViewImpl::GetSize() const {
  // BalloonView has no size if it hasn't been shown yet (which is when
  // balloon_ is set).
  if (!balloon_)
    return gfx::Size(0, 0);

  return gfx::Size(GetTotalWidth(), GetTotalHeight());
}

BalloonHost* BalloonViewImpl::GetHost() const {
  return html_contents_.get();
}

void BalloonViewImpl::OnMenuButtonClicked(views::View* source,
                                          const gfx::Point& point) {
  CreateOptionsMenu();

  menu_runner_.reset(new views::MenuRunner(options_menu_model_.get()));

  gfx::Point screen_location;
  views::View::ConvertPointToScreen(options_menu_button_, &screen_location);
  if (menu_runner_->RunMenuAt(
          source->GetWidget()->GetTopLevelWidget(),
          options_menu_button_,
          gfx::Rect(screen_location, options_menu_button_->size()),
          views::MenuItemView::TOPRIGHT,
          ui::MENU_SOURCE_NONE,
          views::MenuRunner::HAS_MNEMONICS) == views::MenuRunner::MENU_DELETED)
    return;
}

void BalloonViewImpl::OnDisplayChanged() {
  collection_->DisplayChanged();
}

void BalloonViewImpl::OnWorkAreaChanged() {
  collection_->DisplayChanged();
}

void BalloonViewImpl::DeleteDelegate() {
  balloon_->OnClose(closed_by_user_);
}

void BalloonViewImpl::ButtonPressed(views::Button* sender, const ui::Event&) {
  // The only button currently is the close button.
  DCHECK_EQ(close_button_, sender);
  Close(true);
}

gfx::Size BalloonViewImpl::GetPreferredSize() {
  return gfx::Size(1000, 1000);
}

void BalloonViewImpl::SizeContentsWindow() {
  if (!html_container_ || !frame_container_)
    return;

  gfx::Rect contents_rect = GetContentsRectangle();
  html_container_->SetBounds(contents_rect);
  html_container_->StackAboveWidget(frame_container_);

  gfx::Path path;
  GetContentsMask(contents_rect, &path);
  html_container_->SetShape(path.CreateNativeRegion());

  close_button_->SetBoundsRect(GetCloseButtonBounds());
  options_menu_button_->SetBoundsRect(GetOptionsButtonBounds());
  source_label_->SetBoundsRect(GetLabelBounds());
}

void BalloonViewImpl::RepositionToBalloon() {
  if (closed_)
    return;

  DCHECK(frame_container_);
  DCHECK(html_container_);
  DCHECK(balloon_);

  if (!kAnimateEnabled) {
    frame_container_->SetBounds(GetBoundsForFrameContainer());
    gfx::Rect contents_rect = GetContentsRectangle();
    html_container_->SetBounds(contents_rect);
    html_contents_->SetPreferredSize(contents_rect.size());
    content::RenderWidgetHostView* view =
        html_contents_->web_contents()->GetRenderWidgetHostView();
    if (view)
      view->SetSize(contents_rect.size());
    return;
  }

  anim_frame_end_ = GetBoundsForFrameContainer();
  anim_frame_start_ = frame_container_->GetClientAreaBoundsInScreen();
  animation_.reset(new gfx::SlideAnimation(this));
  animation_->Show();
}

void BalloonViewImpl::Update() {
  if (closed_)
    return;

  // Tls might get called before html_contents_ is set in Show() if more than
  // one update with the same replace_id occurs, or if an update occurs after
  // the ballon has been closed (e.g. during shutdown) but before this has been
  // destroyed.
  if (!html_contents_.get() || !html_contents_->web_contents())
    return;
  html_contents_->web_contents()->GetController().LoadURL(
      balloon_->notification().content_url(), content::Referrer(),
      content::PAGE_TRANSITION_LINK, std::string());
}

void BalloonViewImpl::AnimationProgressed(const gfx::Animation* animation) {
  DCHECK_EQ(animation_.get(), animation);

  // Linear interpolation from start to end position.
  gfx::Rect frame_position(animation_->CurrentValueBetween(
                               anim_frame_start_, anim_frame_end_));
  frame_container_->SetBounds(frame_position);

  gfx::Path path;
  gfx::Rect contents_rect = GetContentsRectangle();
  html_container_->SetBounds(contents_rect);
  GetContentsMask(contents_rect, &path);
  html_container_->SetShape(path.CreateNativeRegion());

  html_contents_->SetPreferredSize(contents_rect.size());
  content::RenderWidgetHostView* view =
      html_contents_->web_contents()->GetRenderWidgetHostView();
  if (view)
    view->SetSize(contents_rect.size());
}

gfx::Rect BalloonViewImpl::GetCloseButtonBounds() const {
  gfx::Rect bounds(GetContentsBounds());
  bounds.set_height(GetShelfHeight());
  const gfx::Size& pref_size(close_button_->GetPreferredSize());
  bounds.Inset(bounds.width() - kShelfMargin - pref_size.width(), 0,
      kShelfMargin, 0);
  bounds.ClampToCenteredSize(pref_size);
  return bounds;
}

gfx::Rect BalloonViewImpl::GetOptionsButtonBounds() const {
  gfx::Rect bounds(GetContentsBounds());
  bounds.set_height(GetShelfHeight());
  const gfx::Size& pref_size(options_menu_button_->GetPreferredSize());
  bounds.set_x(GetCloseButtonBounds().x() - kOptionsDismissSpacing -
      pref_size.width());
  bounds.set_width(pref_size.width());
  bounds.ClampToCenteredSize(pref_size);
  return bounds;
}

gfx::Rect BalloonViewImpl::GetLabelBounds() const {
  gfx::Rect bounds(GetContentsBounds());
  bounds.set_height(GetShelfHeight());
  gfx::Size pref_size(source_label_->GetPreferredSize());
  bounds.Inset(kLabelLeftMargin, 0, bounds.width() -
      GetOptionsButtonBounds().x() + kLabelOptionsSpacing, 0);
  pref_size.set_width(bounds.width());
  bounds.ClampToCenteredSize(pref_size);
  return bounds;
}

void BalloonViewImpl::Show(Balloon* balloon) {
  if (closed_)
    return;

  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();

  balloon_ = balloon;

  const string16 source_label_text = l10n_util::GetStringFUTF16(
      IDS_NOTIFICATION_BALLOON_SOURCE_LABEL,
      balloon->notification().display_source());

  source_label_ = new views::Label(source_label_text);
  AddChildView(source_label_);
  options_menu_button_ = new views::MenuButton(NULL, string16(), this, false);
  AddChildView(options_menu_button_);
#if defined(OS_CHROMEOS)
  // Disable and hide the options menu on ChromeOS. This is a short term fix
  // for a crash (long term we're redesigning notifications).
  options_menu_button_->SetEnabled(false);
  options_menu_button_->SetVisible(false);
#endif
  close_button_ = new views::ImageButton(this);
  close_button_->SetTooltipText(l10n_util::GetStringUTF16(
      IDS_NOTIFICATION_BALLOON_DISMISS_LABEL));
  AddChildView(close_button_);

  // We have to create two windows: one for the contents and one for the
  // frame.  Why?
  // * The contents is an html window which cannot be a
  //   layered window (because it may have child windows for instance).
  // * The frame is a layered window so that we can have nicely rounded
  //   corners using alpha blending (and we may do other alpha blending
  //   effects).
  // Unfortunately, layered windows cannot have child windows. (Well, they can
  // but the child windows don't render).
  //
  // We carefully keep these two windows in sync to present the illusion of
  // one window to the user.
  //
  // We don't let the OS manage the RTL layout of these widgets, because
  // this code is already taking care of correctly reversing the layout.
#if defined(OS_CHROMEOS) && defined(USE_AURA)
  html_contents_.reset(new chromeos::BalloonViewHost(balloon));
#else
  html_contents_.reset(new BalloonViewHost(balloon));
#endif
  html_contents_->SetPreferredSize(gfx::Size(10000, 10000));
  if (enable_web_ui_)
    html_contents_->EnableWebUI();

  html_container_ = new views::Widget;
  views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
  html_container_->Init(params);
  html_container_->SetContentsView(html_contents_->view());

  frame_container_ = new views::Widget;
  params.delegate = this;
  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
  params.bounds = GetBoundsForFrameContainer();
  frame_container_->Init(params);
  frame_container_->SetContentsView(this);
  frame_container_->StackAboveWidget(html_container_);

  // GetContentsRectangle() is calculated relative to |frame_container_|. Make
  // sure |frame_container_| has bounds before we ask for
  // GetContentsRectangle().
  html_container_->SetBounds(GetContentsRectangle());

  // SetAlwaysOnTop should be called after StackAboveWidget because otherwise
  // the top-most flag will be removed.
  html_container_->SetAlwaysOnTop(true);
  frame_container_->SetAlwaysOnTop(true);

  close_button_->SetImage(views::CustomButton::STATE_NORMAL,
                          rb.GetImageSkiaNamed(IDR_CLOSE_1));
  close_button_->SetImage(views::CustomButton::STATE_HOVERED,
                          rb.GetImageSkiaNamed(IDR_CLOSE_1_H));
  close_button_->SetImage(views::CustomButton::STATE_PRESSED,
                          rb.GetImageSkiaNamed(IDR_CLOSE_1_P));
  close_button_->SetBoundsRect(GetCloseButtonBounds());
  close_button_->SetBackground(SK_ColorBLACK,
                               rb.GetImageSkiaNamed(IDR_CLOSE_1),
                               rb.GetImageSkiaNamed(IDR_CLOSE_1_MASK));

  options_menu_button_->SetIcon(*rb.GetImageSkiaNamed(IDR_BALLOON_WRENCH));
  options_menu_button_->SetHoverIcon(
      *rb.GetImageSkiaNamed(IDR_BALLOON_WRENCH_H));
  options_menu_button_->SetPushedIcon(*rb.GetImageSkiaNamed(
      IDR_BALLOON_WRENCH_P));
  options_menu_button_->set_alignment(views::TextButton::ALIGN_CENTER);
  options_menu_button_->set_border(NULL);
  options_menu_button_->SetBoundsRect(GetOptionsButtonBounds());

  source_label_->SetFont(rb.GetFont(ui::ResourceBundle::SmallFont));
  source_label_->SetBackgroundColor(kControlBarBackgroundColor);
  source_label_->SetEnabledColor(kControlBarTextColor);
  source_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
  source_label_->SetBoundsRect(GetLabelBounds());

  SizeContentsWindow();
  html_container_->Show();
  frame_container_->Show();

  notification_registrar_.Add(
    this, chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED,
    content::Source<Balloon>(balloon));
}

void BalloonViewImpl::CreateOptionsMenu() {
  if (options_menu_model_.get())
    return;
  options_menu_model_.reset(new NotificationOptionsMenuModel(balloon_));
}

void BalloonViewImpl::GetContentsMask(const gfx::Rect& rect,
                                      gfx::Path* path) const {
  // This rounds the corners, and we also cut out a circle for the close
  // button, since we can't guarantee the ordering of two top-most windows.
  SkScalar radius = SkIntToScalar(views::BubbleBorder::GetCornerRadius());
  SkScalar spline_radius = radius -
      SkScalarMul(radius, (SK_ScalarSqrt2 - SK_Scalar1) * 4 / 3);
  SkScalar left = SkIntToScalar(0);
  SkScalar top = SkIntToScalar(0);
  SkScalar right = SkIntToScalar(rect.width());
  SkScalar bottom = SkIntToScalar(rect.height());

  path->moveTo(left, top);
  path->lineTo(right, top);
  path->lineTo(right, bottom - radius);
  path->cubicTo(right, bottom - spline_radius,
                right - spline_radius, bottom,
                right - radius, bottom);
  path->lineTo(left + radius, bottom);
  path->cubicTo(left + spline_radius, bottom,
                left, bottom - spline_radius,
                left, bottom - radius);
  path->lineTo(left, top);
  path->close();
}

void BalloonViewImpl::GetFrameMask(const gfx::Rect& rect,
                                   gfx::Path* path) const {
  SkScalar radius = SkIntToScalar(views::BubbleBorder::GetCornerRadius());
  SkScalar spline_radius = radius -
      SkScalarMul(radius, (SK_ScalarSqrt2 - SK_Scalar1) * 4 / 3);
  SkScalar left = SkIntToScalar(rect.x());
  SkScalar top = SkIntToScalar(rect.y());
  SkScalar right = SkIntToScalar(rect.right());
  SkScalar bottom = SkIntToScalar(rect.bottom());

  path->moveTo(left, bottom);
  path->lineTo(left, top + radius);
  path->cubicTo(left, top + spline_radius,
                left + spline_radius, top,
                left + radius, top);
  path->lineTo(right - radius, top);
  path->cubicTo(right - spline_radius, top,
                right, top + spline_radius,
                right, top + radius);
  path->lineTo(right, bottom);
  path->lineTo(left, bottom);
  path->close();
}

gfx::Point BalloonViewImpl::GetContentsOffset() const {
  return gfx::Point(kLeftShadowWidth + kLeftMargin,
                    kTopShadowWidth + kTopMargin);
}

gfx::Rect BalloonViewImpl::GetBoundsForFrameContainer() const {
  return gfx::Rect(balloon_->GetPosition().x(), balloon_->GetPosition().y(),
                   GetTotalWidth(), GetTotalHeight());
}

int BalloonViewImpl::GetShelfHeight() const {
  // TODO(johnnyg): add scaling here.
  int max_button_height = std::max(std::max(
      close_button_->GetPreferredSize().height(),
      options_menu_button_->GetPreferredSize().height()),
      source_label_->GetPreferredSize().height());
  return max_button_height + kShelfMargin * 2;
}

int BalloonViewImpl::GetBalloonFrameHeight() const {
  return GetTotalHeight() - GetShelfHeight();
}

int BalloonViewImpl::GetTotalWidth() const {
  return balloon_->content_size().width() +
      kLeftMargin + kRightMargin + kLeftShadowWidth + kRightShadowWidth;
}

int BalloonViewImpl::GetTotalHeight() const {
  return balloon_->content_size().height() +
      kTopMargin + kBottomMargin + kTopShadowWidth + kBottomShadowWidth +
      GetShelfHeight();
}

gfx::Rect BalloonViewImpl::GetContentsRectangle() const {
  if (!frame_container_)
    return gfx::Rect();

  gfx::Size content_size = balloon_->content_size();
  gfx::Point offset = GetContentsOffset();
  gfx::Rect frame_rect = frame_container_->GetWindowBoundsInScreen();
  return gfx::Rect(frame_rect.x() + offset.x(),
                   frame_rect.y() + GetShelfHeight() + offset.y(),
                   content_size.width(),
                   content_size.height());
}

void BalloonViewImpl::OnPaint(gfx::Canvas* canvas) {
  DCHECK(canvas);
  // Paint the menu bar area white, with proper rounded corners.
  gfx::Path path;
  gfx::Rect rect = GetContentsBounds();
  rect.set_height(GetShelfHeight());
  GetFrameMask(rect, &path);

  SkPaint paint;
  paint.setAntiAlias(true);
  paint.setColor(kControlBarBackgroundColor);
  canvas->DrawPath(path, paint);

  // Draw a 1-pixel gray line between the content and the menu bar.
  int line_width = GetTotalWidth() - kLeftMargin - kRightMargin;
  canvas->FillRect(gfx::Rect(kLeftMargin, rect.bottom(), line_width, 1),
                   kControlBarSeparatorLineColor);
  View::OnPaint(canvas);
  OnPaintBorder(canvas);
}

void BalloonViewImpl::OnBoundsChanged(const gfx::Rect& previous_bounds) {
  SizeContentsWindow();
}

void BalloonViewImpl::Observe(int type,
                              const content::NotificationSource& source,
                              const content::NotificationDetails& details) {
  if (type != chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED) {
    NOTREACHED();
    return;
  }

  // If the renderer process attached to this balloon is disconnected
  // (e.g., because of a crash), we want to close the balloon.
  notification_registrar_.Remove(
      this, chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED,
      content::Source<Balloon>(balloon_));
  Close(false);
}
