// Copyright 2013 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/window/frame_caption_button.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "ui/base/hit_test.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/rrect_f.h"
#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
#include "ui/views/animation/ink_drop.h"
#include "ui/views/animation/ink_drop_highlight.h"
#include "ui/views/animation/ink_drop_impl.h"
#include "ui/views/animation/ink_drop_ripple.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/window/hit_test_utils.h"

namespace views {

namespace {

// Ink drop parameters.
constexpr float kInkDropVisibleOpacity = 0.06f;

// The duration of the fade out animation of the old icon during a crossfade
// animation as a ratio of the duration of |swap_images_animation_|.
constexpr float kFadeOutRatio = 0.5f;

// The ratio applied to the button's alpha when the button is disabled.
constexpr float kDisabledButtonAlphaRatio = 0.5f;

}  // namespace

// Custom highlight path generator for clipping ink drops and drawing focus
// rings.
class FrameCaptionButton::HighlightPathGenerator
    : public views::HighlightPathGenerator {
 public:
  explicit HighlightPathGenerator(FrameCaptionButton* frame_caption_button)
      : frame_caption_button_(frame_caption_button) {}
  HighlightPathGenerator(const HighlightPathGenerator&) = delete;
  HighlightPathGenerator& operator=(const HighlightPathGenerator&) = delete;
  ~HighlightPathGenerator() override = default;

  // views::HighlightPathGenerator:
  absl::optional<gfx::RRectF> GetRoundRect(const gfx::RectF& rect) override {
    gfx::Rect bounds = gfx::ToRoundedRect(rect);
    bounds.Inset(frame_caption_button_->GetInkdropInsets(bounds.size()));
    return gfx::RRectF(gfx::RectF(bounds),
                       frame_caption_button_->GetInkDropCornerRadius());
  }

 private:
  FrameCaptionButton* const frame_caption_button_;
};

FrameCaptionButton::FrameCaptionButton(PressedCallback callback,
                                       CaptionButtonIcon icon,
                                       int hit_test_type)
    : Button(std::move(callback)),
      icon_(icon),
      swap_images_animation_(std::make_unique<gfx::SlideAnimation>(this)) {
  views::SetHitTestComponent(this, hit_test_type);
  // Not focusable by default, only for accessibility.
  SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);

  SetAnimateOnStateChange(true);
  swap_images_animation_->Reset(1);

  SetHasInkDropActionOnClick(true);
  InkDrop::Get(this)->SetMode(views::InkDropHost::InkDropMode::ON);
  InkDrop::Get(this)->SetVisibleOpacity(kInkDropVisibleOpacity);
  UpdateInkDropBaseColor();
  InkDrop::UseInkDropWithoutAutoHighlight(InkDrop::Get(this),
                                          /*highlight_on_hover=*/false);
  InkDrop::Get(this)->SetCreateRippleCallback(base::BindRepeating(
      [](FrameCaptionButton* host) -> std::unique_ptr<views::InkDropRipple> {
        return std::make_unique<views::FloodFillInkDropRipple>(
            host->size(), host->GetInkdropInsets(host->size()),
            InkDrop::Get(host)->GetInkDropCenterBasedOnLastEvent(),
            InkDrop::Get(host)->GetBaseColor(),
            InkDrop::Get(host)->GetVisibleOpacity());
      },
      this));

  views::HighlightPathGenerator::Install(
      this, std::make_unique<HighlightPathGenerator>(this));

  // Do not flip the gfx::Canvas passed to the OnPaint() method. The snap left
  // and snap right button icons should not be flipped. The other icons are
  // horizontally symmetrical.
}

FrameCaptionButton::~FrameCaptionButton() = default;

// static
SkColor FrameCaptionButton::GetButtonColor(SkColor background_color) {
  // Use IsDark() to change target colors instead of PickContrastingColor(), so
  // that DefaultFrameHeader::GetTitleColor() (which uses different target
  // colors) can change between light/dark targets at the same time.  It looks
  // bad when the title and caption buttons disagree about whether to be light
  // or dark.
  const SkColor default_foreground = color_utils::IsDark(background_color)
                                         ? gfx::kGoogleGrey200
                                         : gfx::kGoogleGrey700;
  const SkColor high_contrast_foreground =
      color_utils::GetColorWithMaxContrast(background_color);
  return color_utils::BlendForMinContrast(
             default_foreground, background_color, high_contrast_foreground,
             color_utils::kMinimumVisibleContrastRatio)
      .color;
}

// static
float FrameCaptionButton::GetInactiveButtonColorAlphaRatio() {
  return 0.38f;
}

void FrameCaptionButton::SetImage(CaptionButtonIcon icon,
                                  Animate animate,
                                  const gfx::VectorIcon& icon_definition) {
  gfx::ImageSkia new_icon_image =
      gfx::CreateVectorIcon(icon_definition, GetButtonColor(background_color_));

  // The early return is dependent on |animate| because callers use SetImage()
  // with Animate::kNo to progress the crossfade animation to the end.
  if (icon == icon_ &&
      (animate == Animate::kYes || !swap_images_animation_->is_animating()) &&
      new_icon_image.BackedBySameObjectAs(icon_image_)) {
    return;
  }

  if (animate == Animate::kYes)
    crossfade_icon_image_ = icon_image_;

  icon_ = icon;
  icon_definition_ = &icon_definition;
  icon_image_ = new_icon_image;

  if (animate == Animate::kYes) {
    swap_images_animation_->Reset(0);
    swap_images_animation_->SetSlideDuration(
        base::TimeDelta::FromMilliseconds(200));
    swap_images_animation_->Show();
  } else {
    swap_images_animation_->Reset(1);
  }

  SchedulePaint();
}

bool FrameCaptionButton::IsAnimatingImageSwap() const {
  return swap_images_animation_->is_animating();
}

void FrameCaptionButton::SetAlpha(int alpha) {
  if (alpha_ != alpha) {
    alpha_ = alpha;
    SchedulePaint();
  }
}

void FrameCaptionButton::OnGestureEvent(ui::GestureEvent* event) {
  // Button does not become pressed when the user drags off and then back
  // onto the button. Make FrameCaptionButton pressed in this case because this
  // behavior is more consistent with AlternateFrameSizeButton.
  if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
      event->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
    if (HitTestPoint(event->location())) {
      SetState(STATE_PRESSED);
      RequestFocus();
      event->StopPropagation();
    } else {
      SetState(STATE_NORMAL);
    }
  } else if (event->type() == ui::ET_GESTURE_SCROLL_END) {
    if (HitTestPoint(event->location())) {
      SetState(STATE_HOVERED);
      NotifyClick(*event);
      event->StopPropagation();
    }
  }

  if (!event->handled())
    Button::OnGestureEvent(event);
}

views::PaintInfo::ScaleType FrameCaptionButton::GetPaintScaleType() const {
  return views::PaintInfo::ScaleType::kUniformScaling;
}

void FrameCaptionButton::SetBackgroundColor(SkColor background_color) {
  if (background_color_ == background_color)
    return;

  background_color_ = background_color;
  // Refresh the icon since the color may have changed.
  if (icon_definition_)
    SetImage(icon_, Animate::kNo, *icon_definition_);
  UpdateInkDropBaseColor();

  OnPropertyChanged(&background_color_, kPropertyEffectsPaint);
}

SkColor FrameCaptionButton::GetBackgroundColor() const {
  return background_color_;
}

void FrameCaptionButton::SetInkDropCornerRadius(int ink_drop_corner_radius) {
  ink_drop_corner_radius_ = ink_drop_corner_radius;
  // Changes to |ink_drop_corner_radius| will affect the ink drop. Therefore
  // this effect is handled by the ink drop.
  OnPropertyChanged(&ink_drop_corner_radius_, kPropertyEffectsNone);
}

int FrameCaptionButton::GetInkDropCornerRadius() const {
  return ink_drop_corner_radius_;
}

base::CallbackListSubscription
FrameCaptionButton::AddBackgroundColorChangedCallback(
    PropertyChangedCallback callback) {
  return AddPropertyChangedCallback(&background_color_, callback);
}

void FrameCaptionButton::SetPaintAsActive(bool paint_as_active) {
  if (paint_as_active == paint_as_active_)
    return;
  paint_as_active_ = paint_as_active;
  OnPropertyChanged(&paint_as_active_, kPropertyEffectsPaint);
}

bool FrameCaptionButton::GetPaintAsActive() const {
  return paint_as_active_;
}

void FrameCaptionButton::DrawHighlight(gfx::Canvas* canvas,
                                       cc::PaintFlags flags) {
  const gfx::Point center(GetMirroredRect(GetContentsBounds()).CenterPoint());
  canvas->DrawCircle(center, ink_drop_corner_radius_, flags);
}

void FrameCaptionButton::DrawIconContents(gfx::Canvas* canvas,
                                          gfx::ImageSkia image,
                                          int x,
                                          int y,
                                          cc::PaintFlags flags) {
  canvas->DrawImageInt(image, x, y, flags);
}

gfx::Size FrameCaptionButton::GetInkDropSize() const {
  return gfx::Size(2 * GetInkDropCornerRadius(), 2 * GetInkDropCornerRadius());
}

gfx::Insets FrameCaptionButton::GetInkdropInsets(
    const gfx::Size& button_size) const {
  return gfx::Insets((button_size.height() - GetInkDropSize().height()) / 2,
                     (button_size.width() - GetInkDropSize().width()) / 2);
}

void FrameCaptionButton::PaintButtonContents(gfx::Canvas* canvas) {
  constexpr SkAlpha kHighlightVisibleOpacity = 0x14;
  SkAlpha highlight_alpha = SK_AlphaTRANSPARENT;
  if (hover_animation().is_animating()) {
    highlight_alpha = hover_animation().CurrentValueBetween(
        SK_AlphaTRANSPARENT, kHighlightVisibleOpacity);
  } else if (GetState() == STATE_HOVERED || GetState() == STATE_PRESSED) {
    // Painting a circular highlight in both "hovered" and "pressed" states
    // simulates and ink drop highlight mode of
    // AutoHighlightMode::SHOW_ON_RIPPLE.
    highlight_alpha = kHighlightVisibleOpacity;
  }

  if (highlight_alpha != SK_AlphaTRANSPARENT) {
    // We paint the highlight manually here rather than relying on the ink drop
    // highlight as it doesn't work well when the button size is changing while
    // the window is moving as a result of the animation from normal to
    // maximized state or vice versa. https://crbug.com/840901.
    cc::PaintFlags flags;
    flags.setColor(InkDrop::Get(this)->GetBaseColor());
    flags.setAlpha(highlight_alpha);
    DrawHighlight(canvas, flags);
  }

  int icon_alpha = swap_images_animation_->CurrentValueBetween(0, 255);
  int crossfade_icon_alpha = 0;
  if (icon_alpha < static_cast<int>(kFadeOutRatio * 255))
    crossfade_icon_alpha = static_cast<int>(255 - icon_alpha / kFadeOutRatio);

  int centered_origin_x = (width() - icon_image_.width()) / 2;
  int centered_origin_y = (height() - icon_image_.height()) / 2;

  if (crossfade_icon_alpha > 0 && !crossfade_icon_image_.isNull()) {
    canvas->SaveLayerAlpha(GetAlphaForIcon(alpha_));
    cc::PaintFlags flags;
    flags.setAlpha(icon_alpha);
    DrawIconContents(canvas, icon_image_, centered_origin_x, centered_origin_y,
                     flags);

    flags.setAlpha(crossfade_icon_alpha);
    flags.setBlendMode(SkBlendMode::kPlus);
    DrawIconContents(canvas, crossfade_icon_image_, centered_origin_x,
                     centered_origin_y, flags);
    canvas->Restore();
  } else {
    if (!swap_images_animation_->is_animating())
      icon_alpha = alpha_;
    cc::PaintFlags flags;
    flags.setAlpha(GetAlphaForIcon(icon_alpha));
    DrawIconContents(canvas, icon_image_, centered_origin_x, centered_origin_y,
                     flags);
  }
}

int FrameCaptionButton::GetAlphaForIcon(int base_alpha) const {
  if (!GetEnabled())
    return base_alpha * kDisabledButtonAlphaRatio;

  if (paint_as_active_)
    return base_alpha;

  // Paint icons as active when they are hovered over or pressed.
  double inactive_alpha = GetInactiveButtonColorAlphaRatio();

  if (hover_animation().is_animating()) {
    inactive_alpha =
        hover_animation().CurrentValueBetween(inactive_alpha, 1.0f);
  } else if (GetState() == STATE_PRESSED || GetState() == STATE_HOVERED) {
    inactive_alpha = 1.0f;
  }
  return base_alpha * inactive_alpha;
}

void FrameCaptionButton::UpdateInkDropBaseColor() {
  using color_utils::GetColorWithMaxContrast;
  // A typical implementation would simply do
  // GetColorWithMaxContrast(background_color_).  However, this could look odd
  // if we use a light button glyph and dark ink drop or vice versa.  So
  // instead, use the lightest/darkest color in the same direction as the button
  // glyph color.
  // TODO(pkasting): It would likely be better to make the button glyph always
  // be an alpha-blended version of GetColorWithMaxContrast(background_color_).
  const SkColor button_color = GetButtonColor(background_color_);
  InkDrop::Get(this)->SetBaseColor(
      GetColorWithMaxContrast(GetColorWithMaxContrast(button_color)));
}

BEGIN_METADATA(FrameCaptionButton, Button)
ADD_PROPERTY_METADATA(SkColor, BackgroundColor, ui::metadata::SkColorConverter)
ADD_PROPERTY_METADATA(int, InkDropCornerRadius)
ADD_READONLY_PROPERTY_METADATA(CaptionButtonIcon, Icon)
ADD_PROPERTY_METADATA(bool, PaintAsActive)
END_METADATA

}  // namespace views

DEFINE_ENUM_CONVERTERS(
    views::CaptionButtonIcon,
    {views::CaptionButtonIcon::CAPTION_BUTTON_ICON_MINIMIZE,
     u"CAPTION_BUTTON_ICON_MINIMIZE"},
    {views::CaptionButtonIcon::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE,
     u"CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE"},
    {views::CaptionButtonIcon::CAPTION_BUTTON_ICON_CLOSE,
     u"CAPTION_BUTTON_ICON_CLOSE"},
    {views::CaptionButtonIcon::CAPTION_BUTTON_ICON_LEFT_SNAPPED,
     u"CAPTION_BUTTON_ICON_LEFT_SNAPPED"},
    {views::CaptionButtonIcon::CAPTION_BUTTON_ICON_RIGHT_SNAPPED,
     u"CAPTION_BUTTON_ICON_RIGHT_SNAPPED"},
    {views::CaptionButtonIcon::CAPTION_BUTTON_ICON_BACK,
     u"CAPTION_BUTTON_ICON_BACK"},
    {views::CaptionButtonIcon::CAPTION_BUTTON_ICON_LOCATION,
     u"CAPTION_BUTTON_ICON_LOCATION"},
    {views::CaptionButtonIcon::CAPTION_BUTTON_ICON_MENU,
     u"CAPTION_BUTTON_ICON_MENU"},
    {views::CaptionButtonIcon::CAPTION_BUTTON_ICON_ZOOM,
     u"CAPTION_BUTTON_ICON_ZOOM"},
    {views::CaptionButtonIcon::CAPTION_BUTTON_ICON_CENTER,
     u"CAPTION_BUTTON_ICON_CENTER"},
    {views::CaptionButtonIcon::CAPTION_BUTTON_ICON_CUSTOM,
     u"CAPTION_BUTTON_ICON_CUSTOM"},
    {views::CaptionButtonIcon::CAPTION_BUTTON_ICON_COUNT,
     u"CAPTION_BUTTON_ICON_COUNT"})
