// Copyright 2015 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/controls/button/md_text_button.h"

#include "base/i18n/case_conversion.h"
#include "base/memory/ptr_util.h"
#include "build/build_config.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
#include "ui/views/animation/ink_drop_highlight.h"
#include "ui/views/animation/ink_drop_impl.h"
#include "ui/views/animation/ink_drop_painted_layer_delegates.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
#include "ui/views/controls/focus_ring.h"
#include "ui/views/layout/layout_provider.h"
#include "ui/views/painter.h"
#include "ui/views/style/platform_style.h"
#include "ui/views/style/typography.h"

namespace views {

// static
LabelButton* MdTextButton::CreateSecondaryUiButton(ButtonListener* listener,
                                                   const base::string16& text) {
  return MdTextButton::Create(listener, text, style::CONTEXT_BUTTON_MD);
}

// static
LabelButton* MdTextButton::CreateSecondaryUiBlueButton(
    ButtonListener* listener,
    const base::string16& text) {
  MdTextButton* md_button =
      MdTextButton::Create(listener, text, style::CONTEXT_BUTTON_MD);
  md_button->SetProminent(true);
  return md_button;
}

// static
MdTextButton* MdTextButton::Create(ButtonListener* listener,
                                   const base::string16& text,
                                   int button_context) {
  MdTextButton* button = new MdTextButton(listener, button_context);
  button->SetText(text);
  button->SetFocusForPlatform();

  return button;
}

MdTextButton::~MdTextButton() {}

void MdTextButton::SetProminent(bool is_prominent) {
  if (is_prominent_ == is_prominent)
    return;

  is_prominent_ = is_prominent;
  UpdateColors();
}

void MdTextButton::SetBgColorOverride(const base::Optional<SkColor>& color) {
  bg_color_override_ = color;
  UpdateColors();
}

void MdTextButton::set_corner_radius(float radius) {
  corner_radius_ = radius;
  set_ink_drop_corner_radii(corner_radius_, corner_radius_);
}

void MdTextButton::OnPaintBackground(gfx::Canvas* canvas) {
  LabelButton::OnPaintBackground(canvas);
  if (hover_animation().is_animating() || state() == STATE_HOVERED) {
    bool is_dark_mode = GetNativeTheme()->SystemDarkModeEnabled();
    int hover_alpha = is_prominent_ ? 0x0C : 0x05;
    if (is_dark_mode)
      hover_alpha = 0x0A;
    const SkColor hover_color =
        is_dark_mode && !is_prominent_ ? gfx::kGoogleBlue300 : SK_ColorBLACK;
    SkScalar alpha = hover_animation().CurrentValueBetween(0, hover_alpha);
    cc::PaintFlags flags;
    flags.setColor(SkColorSetA(hover_color, alpha));
    flags.setStyle(cc::PaintFlags::kFill_Style);
    flags.setAntiAlias(true);
    canvas->DrawRoundRect(gfx::RectF(GetLocalBounds()), corner_radius_, flags);
  }
}

void MdTextButton::OnNativeThemeChanged(const ui::NativeTheme* theme) {
  LabelButton::OnNativeThemeChanged(theme);
  UpdateColors();
}

SkColor MdTextButton::GetInkDropBaseColor() const {
  return color_utils::DeriveDefaultIconColor(label()->enabled_color());
}

std::unique_ptr<InkDrop> MdTextButton::CreateInkDrop() {
  return CreateDefaultFloodFillInkDropImpl();
}

std::unique_ptr<views::InkDropRipple> MdTextButton::CreateInkDropRipple()
    const {
  return std::unique_ptr<views::InkDropRipple>(
      new views::FloodFillInkDropRipple(
          size(), GetInkDropCenterBasedOnLastEvent(), GetInkDropBaseColor(),
          ink_drop_visible_opacity()));
}

void MdTextButton::StateChanged(ButtonState old_state) {
  LabelButton::StateChanged(old_state);
  UpdateColors();
}

void MdTextButton::OnFocus() {
  LabelButton::OnFocus();
  UpdateColors();
}

void MdTextButton::OnBlur() {
  LabelButton::OnBlur();
  UpdateColors();
}

std::unique_ptr<views::InkDropHighlight> MdTextButton::CreateInkDropHighlight()
    const {
  bool is_dark_mode = GetNativeTheme()->SystemDarkModeEnabled();
  // The prominent button hover effect is a shadow.
  const int kYOffset = 1;
  const int kSkiaBlurRadius = 2;
  const int shadow_alpha = is_prominent_ ? 0x3D : 0x1A;
  const SkColor shadow_color =
      is_dark_mode && is_prominent_ ? gfx::kGoogleBlue300 : SK_ColorBLACK;
  std::vector<gfx::ShadowValue> shadows;
  // The notion of blur that gfx::ShadowValue uses is twice the Skia/CSS value.
  // Skia counts the number of pixels outside the mask area whereas
  // gfx::ShadowValue counts together the number of pixels inside and outside
  // the mask bounds.
  shadows.push_back(gfx::ShadowValue(
      gfx::Vector2d(0, kYOffset), 2 * kSkiaBlurRadius,
      SkColorSetA(shadow_color, is_dark_mode ? 0x7F : shadow_alpha)));
  const SkColor fill_color =
      SkColorSetA(SK_ColorWHITE, is_prominent_ ? 0x0D : 0x05);
  return std::make_unique<InkDropHighlight>(
      gfx::RectF(GetLocalBounds()).CenterPoint(),
      base::WrapUnique(new BorderShadowLayerDelegate(
          shadows, GetLocalBounds(), fill_color, corner_radius_)));
}

void MdTextButton::SetEnabledTextColors(SkColor color) {
  LabelButton::SetEnabledTextColors(color);
  UpdateColors();
}

void MdTextButton::SetText(const base::string16& text) {
  LabelButton::SetText(text);
  UpdatePadding();
}

void MdTextButton::UpdateStyleToIndicateDefaultStatus() {
  is_prominent_ = is_prominent_ || is_default();
  UpdateColors();
}

MdTextButton::MdTextButton(ButtonListener* listener, int button_context)
    : LabelButton(listener, base::string16(), button_context),
      is_prominent_(false) {
  SetInkDropMode(InkDropMode::ON);
  set_has_ink_drop_action_on_click(true);
  set_corner_radius(LayoutProvider::Get()->GetCornerRadiusMetric(EMPHASIS_LOW));
  SetHorizontalAlignment(gfx::ALIGN_CENTER);
  SetFocusForPlatform();
  const int minimum_width = LayoutProvider::Get()->GetDistanceMetric(
      DISTANCE_DIALOG_BUTTON_MINIMUM_WIDTH);
  SetMinSize(gfx::Size(minimum_width, 0));
  SetInstallFocusRingOnFocus(true);
  label()->SetAutoColorReadabilityEnabled(false);
  set_request_focus_on_press(false);

  set_animate_on_state_change(true);

  // Paint to a layer so that the canvas is snapped to pixel boundaries (useful
  // for fractional DSF).
  SetPaintToLayer();
  layer()->SetFillsBoundsOpaquely(false);
}

void MdTextButton::UpdatePadding() {
  // Don't use font-based padding when there's no text visible.
  if (GetText().empty()) {
    SetBorder(NullBorder());
    return;
  }

  // Text buttons default to 28dp in height on all platforms when the base font
  // is in use, but should grow or shrink if the font size is adjusted up or
  // down. When the system font size has been adjusted, the base font will be
  // larger than normal such that 28dp might not be enough, so also enforce a
  // minimum height of twice the font size.
  // Example 1:
  // * Normal button on ChromeOS, 12pt Roboto. Button height of 28dp.
  // * Button on ChromeOS that has been adjusted to 14pt Roboto. Button height
  // of 28 + 2 * 2 = 32dp.
  // * Linux user sets base system font size to 17dp. For a normal button, the
  // |size_delta| will be zero, so to adjust upwards we double 17 to get 34.
  int size_delta =
      label()->font_list().GetFontSize() -
      style::GetFont(style::CONTEXT_BUTTON_MD, style::STYLE_PRIMARY)
          .GetFontSize();
  // TODO(tapted): This should get |target_height| using LayoutProvider::
  // GetControlHeightForFont().
  constexpr int kBaseHeight = 32;
  int target_height = std::max(kBaseHeight + size_delta * 2,
                               label()->font_list().GetFontSize() * 2);

  int label_height = label()->GetPreferredSize().height();
  int top_padding = (target_height - label_height) / 2;
  int bottom_padding = (target_height - label_height + 1) / 2;
  DCHECK_EQ(target_height, label_height + top_padding + bottom_padding);

  // TODO(estade): can we get rid of the platform style border hoopla if
  // we apply the MD treatment to all buttons, even GTK buttons?
  const int horizontal_padding = LayoutProvider::Get()->GetDistanceMetric(
      DISTANCE_BUTTON_HORIZONTAL_PADDING);
  SetBorder(CreateEmptyBorder(top_padding, horizontal_padding, bottom_padding,
                              horizontal_padding));
}

void MdTextButton::UpdateColors() {
  bool is_disabled = state() == STATE_DISABLED;
  SkColor enabled_text_color =
      style::GetColor(*this, label()->text_context(),
                      is_prominent_ ? style::STYLE_DIALOG_BUTTON_DEFAULT
                                    : style::STYLE_PRIMARY);
  if (!explicitly_set_normal_color()) {
    const auto colors = explicitly_set_colors();
    LabelButton::SetEnabledTextColors(enabled_text_color);
    // Non-prominent, disabled buttons need the disabled color explicitly set.
    // This ensures that label()->enabled_color() returns the correct color as
    // the basis for calculating the stroke color. enabled_text_color isn't used
    // since a descendant could have overridden the label enabled color.
    if (is_disabled && !is_prominent_) {
      LabelButton::SetTextColor(STATE_DISABLED,
                                style::GetColor(*this, label()->text_context(),
                                                style::STYLE_DISABLED));
    }
    set_explicitly_set_colors(colors);
  }

  // Prominent buttons keep their enabled text color; disabled state is conveyed
  // by shading the background instead.
  if (is_prominent_)
    SetTextColor(STATE_DISABLED, enabled_text_color);

  ui::NativeTheme* theme = GetNativeTheme();
  SkColor text_color = label()->enabled_color();
  SkColor bg_color =
      theme->GetSystemColor(ui::NativeTheme::kColorId_DialogBackground);

  if (bg_color_override_) {
    bg_color = *bg_color_override_;
  } else if (is_prominent_) {
    bg_color = theme->GetSystemColor(
        HasFocus() ? ui::NativeTheme::kColorId_ProminentButtonFocusedColor
                   : ui::NativeTheme::kColorId_ProminentButtonColor);
    if (is_disabled) {
      bg_color = color_utils::BlendTowardOppositeLuma(
          bg_color, gfx::kDisabledControlAlpha);
    }
  }

  if (state() == STATE_PRESSED) {
    SkColor shade =
        theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonPressedShade);
    bg_color = color_utils::GetResultingPaintColor(shade, bg_color);
  }

  SkColor stroke_color;
  if (is_prominent_) {
    stroke_color = SK_ColorTRANSPARENT;
  } else {
    int stroke_alpha;
    if (is_disabled) {
      // Disabled, non-prominent buttons need a lighter stroke. This alpha
      // value will take the disabled button colors, a1a192 @ 1.0 alpha for
      // non-Harmony, 9e9e9e @ 1.0 alpha for Harmony and turn it into
      // e6e6e6 @ 1.0 alpha (or very close to it) or an effective 000000 @ 0.1
      // alpha for the stroke color. The same alpha value will work with both
      // Harmony and non-Harmony colors.
      stroke_alpha = 0x43;
    } else {
      // These alpha values will take the enabled button colors, 757575 @ 1.0
      // alpha turn it into an effective b2b2b2 @ 1.0 alpha or 000000 @ 0.3 for
      // the stroke_color.
      stroke_alpha = 0x8f;
    }
    stroke_color = SkColorSetA(text_color, stroke_alpha);
  }

  DCHECK_EQ(SK_AlphaOPAQUE, static_cast<int>(SkColorGetA(bg_color)));
  SetBackground(
      CreateBackgroundFromPainter(Painter::CreateRoundRectWith1PxBorderPainter(
          bg_color, stroke_color, corner_radius_)));
  SchedulePaint();
}

}  // namespace views
