// 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 "ui/views/painter.h"

#include "base/logging.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_delegate.h"
#include "ui/compositor/layer_owner.h"
#include "ui/compositor/paint_recorder.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/insets_f.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/nine_image_painter.h"
#include "ui/gfx/scoped_canvas.h"
#include "ui/views/view.h"

namespace views {

namespace {

// SolidRoundRectPainter -------------------------------------------------------

// Creates a round rect painter with a 1 pixel border. The border paints on top
// of the background.
class SolidRoundRectPainter : public Painter {
 public:
  SolidRoundRectPainter(SkColor bg_color,
                        SkColor stroke_color,
                        float radius,
                        const gfx::Insets& insets,
                        SkBlendMode blend_mode,
                        bool antialias);
  ~SolidRoundRectPainter() override;

  // Painter:
  gfx::Size GetMinimumSize() const override;
  void Paint(gfx::Canvas* canvas, const gfx::Size& size) override;

 private:
  const SkColor bg_color_;
  const SkColor stroke_color_;
  const float radius_;
  const gfx::Insets insets_;
  const SkBlendMode blend_mode_;
  const bool antialias_;

  DISALLOW_COPY_AND_ASSIGN(SolidRoundRectPainter);
};

SolidRoundRectPainter::SolidRoundRectPainter(SkColor bg_color,
                                             SkColor stroke_color,
                                             float radius,
                                             const gfx::Insets& insets,
                                             SkBlendMode blend_mode,
                                             bool antialias)
    : bg_color_(bg_color),
      stroke_color_(stroke_color),
      radius_(radius),
      insets_(insets),
      blend_mode_(blend_mode),
      antialias_(antialias) {}

SolidRoundRectPainter::~SolidRoundRectPainter() {}

gfx::Size SolidRoundRectPainter::GetMinimumSize() const {
  return gfx::Size();
}

void SolidRoundRectPainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) {
  gfx::ScopedCanvas scoped_canvas(canvas);
  const float scale = canvas->UndoDeviceScaleFactor();

  gfx::Rect inset_rect(size);
  inset_rect.Inset(insets_);
  gfx::RectF fill_rect(gfx::ScaleToEnclosingRect(inset_rect, scale));
  gfx::RectF stroke_rect = fill_rect;
  float scaled_radius = radius_ * scale;

  cc::PaintFlags flags;
  flags.setBlendMode(blend_mode_);
  if (antialias_)
    flags.setAntiAlias(true);
  flags.setStyle(cc::PaintFlags::kFill_Style);
  flags.setColor(bg_color_);
  canvas->DrawRoundRect(fill_rect, scaled_radius, flags);

  if (stroke_color_ != SK_ColorTRANSPARENT) {
    constexpr float kStrokeWidth = 1.0f;
    stroke_rect.Inset(gfx::InsetsF(kStrokeWidth / 2));
    scaled_radius -= kStrokeWidth / 2;
    flags.setStyle(cc::PaintFlags::kStroke_Style);
    flags.setStrokeWidth(kStrokeWidth);
    flags.setColor(stroke_color_);
    canvas->DrawRoundRect(stroke_rect, scaled_radius, flags);
  }
}

// SolidFocusPainter -----------------------------------------------------------

class SolidFocusPainter : public Painter {
 public:
  SolidFocusPainter(SkColor color, int thickness, const gfx::InsetsF& insets);
  ~SolidFocusPainter() override;

  // Painter:
  gfx::Size GetMinimumSize() const override;
  void Paint(gfx::Canvas* canvas, const gfx::Size& size) override;

 private:
  const SkColor color_;
  const int thickness_;
  const gfx::InsetsF insets_;

  DISALLOW_COPY_AND_ASSIGN(SolidFocusPainter);
};

SolidFocusPainter::SolidFocusPainter(SkColor color,
                                     int thickness,
                                     const gfx::InsetsF& insets)
    : color_(color), thickness_(thickness), insets_(insets) {}

SolidFocusPainter::~SolidFocusPainter() {
}

gfx::Size SolidFocusPainter::GetMinimumSize() const {
  return gfx::Size();
}

void SolidFocusPainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) {
  gfx::RectF rect((gfx::Rect(size)));
  rect.Inset(insets_);
  canvas->DrawSolidFocusRect(rect, color_, thickness_);
}

// ImagePainter ---------------------------------------------------------------

// ImagePainter stores and paints nine images as a scalable grid.
class ImagePainter : public Painter {
 public:
  // Constructs an ImagePainter with the specified image resource ids.
  // See CreateImageGridPainter()'s comment regarding image ID count and order.
  explicit ImagePainter(const int image_ids[]);

  // Constructs an ImagePainter with the specified image and insets.
  ImagePainter(const gfx::ImageSkia& image, const gfx::Insets& insets);

  ~ImagePainter() override;

  // Painter:
  gfx::Size GetMinimumSize() const override;
  void Paint(gfx::Canvas* canvas, const gfx::Size& size) override;

 private:
  std::unique_ptr<gfx::NineImagePainter> nine_painter_;

  DISALLOW_COPY_AND_ASSIGN(ImagePainter);
};

ImagePainter::ImagePainter(const int image_ids[])
    : nine_painter_(ui::CreateNineImagePainter(image_ids)) {
}

ImagePainter::ImagePainter(const gfx::ImageSkia& image,
                           const gfx::Insets& insets)
    : nine_painter_(new gfx::NineImagePainter(image, insets)) {
}

ImagePainter::~ImagePainter() {
}

gfx::Size ImagePainter::GetMinimumSize() const {
  return nine_painter_->GetMinimumSize();
}

void ImagePainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) {
  nine_painter_->Paint(canvas, gfx::Rect(size));
}

class PaintedLayer : public ui::LayerOwner, public ui::LayerDelegate {
 public:
  explicit PaintedLayer(std::unique_ptr<Painter> painter);
  ~PaintedLayer() override;

  // LayerDelegate:
  void OnPaintLayer(const ui::PaintContext& context) override;
  void OnDeviceScaleFactorChanged(float old_device_scale_factor,
                                  float new_device_scale_factor) override;

 private:
  std::unique_ptr<Painter> painter_;

  DISALLOW_COPY_AND_ASSIGN(PaintedLayer);
};

PaintedLayer::PaintedLayer(std::unique_ptr<Painter> painter)
    : painter_(std::move(painter)) {
  SetLayer(std::make_unique<ui::Layer>(ui::LAYER_TEXTURED));
  layer()->set_delegate(this);
}

PaintedLayer::~PaintedLayer() {}

void PaintedLayer::OnPaintLayer(const ui::PaintContext& context) {
  ui::PaintRecorder recorder(context, layer()->size());
  painter_->Paint(recorder.canvas(), layer()->size());
}

void PaintedLayer::OnDeviceScaleFactorChanged(float old_device_scale_factor,
                                              float new_device_scale_factor) {}

}  // namespace


// Painter --------------------------------------------------------------------

Painter::Painter() {
}

Painter::~Painter() {
}

// static
void Painter::PaintPainterAt(gfx::Canvas* canvas,
                             Painter* painter,
                             const gfx::Rect& rect) {
  DCHECK(canvas);
  DCHECK(painter);
  canvas->Save();
  canvas->Translate(rect.OffsetFromOrigin());
  painter->Paint(canvas, rect.size());
  canvas->Restore();
}

// static
void Painter::PaintFocusPainter(View* view,
                                gfx::Canvas* canvas,
                                Painter* focus_painter) {
  if (focus_painter && view->HasFocus())
    PaintPainterAt(canvas, focus_painter, view->GetLocalBounds());
}

// static
std::unique_ptr<Painter> Painter::CreateSolidRoundRectPainter(
    SkColor color,
    float radius,
    const gfx::Insets& insets,
    SkBlendMode blend_mode,
    bool antialias) {
  return std::make_unique<SolidRoundRectPainter>(
      color, SK_ColorTRANSPARENT, radius, insets, blend_mode, antialias);
}

// static
std::unique_ptr<Painter> Painter::CreateRoundRectWith1PxBorderPainter(
    SkColor bg_color,
    SkColor stroke_color,
    float radius,
    SkBlendMode blend_mode,
    bool antialias) {
  return std::make_unique<SolidRoundRectPainter>(
      bg_color, stroke_color, radius, gfx::Insets(), blend_mode, antialias);
}

// static
std::unique_ptr<Painter> Painter::CreateImagePainter(
    const gfx::ImageSkia& image,
    const gfx::Insets& insets) {
  return std::make_unique<ImagePainter>(image, insets);
}

// static
std::unique_ptr<Painter> Painter::CreateImageGridPainter(
    const int image_ids[]) {
  return std::make_unique<ImagePainter>(image_ids);
}

// static
std::unique_ptr<Painter> Painter::CreateSolidFocusPainter(
    SkColor color,
    const gfx::Insets& insets) {
  // Before Canvas::DrawSolidFocusRect correctly inset the rect's bounds based
  // on the thickness, callers had to add 1 to the bottom and right insets.
  // Subtract that here so it works the same way with the new
  // Canvas::DrawSolidFocusRect.
  const gfx::Insets corrected_insets = insets - gfx::Insets(0, 0, 1, 1);
  return std::make_unique<SolidFocusPainter>(color, 1, corrected_insets);
}

// static
std::unique_ptr<Painter> Painter::CreateSolidFocusPainter(
    SkColor color,
    int thickness,
    const gfx::InsetsF& insets) {
  return std::make_unique<SolidFocusPainter>(color, thickness, insets);
}

// static
std::unique_ptr<ui::LayerOwner> Painter::CreatePaintedLayer(
    std::unique_ptr<Painter> painter) {
  return std::make_unique<PaintedLayer>(std::move(painter));
}

}  // namespace views
