// 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/gfx/nine_image_painter.h"

#include "base/base64.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
#include "ui/gfx/image/image_skia.h"

namespace gfx {

static std::string GetPNGDataUrl(const SkBitmap& bitmap) {
  std::vector<unsigned char> png_data;
  gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &png_data);
  std::string data_url;
  data_url.insert(data_url.end(), png_data.begin(), png_data.end());
  base::Base64Encode(data_url, &data_url);
  data_url.insert(0, "data:image/png;base64,");

  return data_url;
}

void ExpectRedWithGreenRect(const SkBitmap& bitmap,
                            const Rect& outer_rect,
                            const Rect& green_rect) {
  for (int y = outer_rect.y(); y < outer_rect.bottom(); y++) {
    SCOPED_TRACE(y);
    for (int x = outer_rect.x(); x < outer_rect.right(); x++) {
      SCOPED_TRACE(x);
      if (green_rect.Contains(x, y)) {
        ASSERT_EQ(SK_ColorGREEN, bitmap.getColor(x, y))
            << "Output image:\n" << GetPNGDataUrl(bitmap);
      } else {
        ASSERT_EQ(SK_ColorRED, bitmap.getColor(x, y)) << "Output image:\n"
                                                      << GetPNGDataUrl(bitmap);
      }
    }
  }
}

TEST(NineImagePainterTest, GetSubsetRegions) {
  SkBitmap src;
  src.allocN32Pixels(40, 50);
  const ImageSkia image_skia(ImageSkiaRep(src, 1.0));
  const Insets insets(1, 2, 3, 4);
  std::vector<Rect> rects;
  NineImagePainter::GetSubsetRegions(image_skia, insets, &rects);
  ASSERT_EQ(9u, rects.size());
  EXPECT_EQ(gfx::Rect(0, 0, 2, 1), rects[0]);
  EXPECT_EQ(gfx::Rect(2, 0, 34, 1), rects[1]);
  EXPECT_EQ(gfx::Rect(36, 0, 4, 1), rects[2]);
  EXPECT_EQ(gfx::Rect(0, 1, 2, 46), rects[3]);
  EXPECT_EQ(gfx::Rect(2, 1, 34, 46), rects[4]);
  EXPECT_EQ(gfx::Rect(36, 1, 4, 46), rects[5]);
  EXPECT_EQ(gfx::Rect(0, 47, 2, 3), rects[6]);
  EXPECT_EQ(gfx::Rect(2, 47, 34, 3), rects[7]);
  EXPECT_EQ(gfx::Rect(36, 47, 4, 3), rects[8]);
}

TEST(NineImagePainterTest, PaintHighDPI) {
  SkBitmap src;
  src.allocN32Pixels(100, 100);
  src.eraseColor(SK_ColorRED);
  src.eraseArea(SkIRect::MakeXYWH(10, 10, 80, 80), SK_ColorGREEN);

  float image_scale = 2.f;

  gfx::ImageSkia image = gfx::ImageSkia::CreateFromBitmap(src, image_scale);
  gfx::Insets insets(10, 10, 10, 10);
  gfx::NineImagePainter painter(image, insets);

  bool is_opaque = true;
  gfx::Canvas canvas(gfx::Size(100, 100), image_scale, is_opaque);

  gfx::Vector2d offset(20, 10);
  canvas.Translate(offset);

  gfx::Rect bounds(0, 0, 50, 50);
  painter.Paint(&canvas, bounds);

  SkBitmap result = canvas.GetBitmap();

  gfx::Vector2d paint_offset =
      gfx::ToFlooredVector2d(gfx::ScaleVector2d(offset, image_scale));
  gfx::Rect green_rect = gfx::Rect(10, 10, 80, 80) + paint_offset;
  gfx::Rect outer_rect = gfx::Rect(100, 100) + paint_offset;
  ExpectRedWithGreenRect(result, outer_rect, green_rect);
}

TEST(NineImagePainterTest, PaintStaysInBounds) {
  // In this test the bounds rect is 1x1 but each image is 2x2.
  // The NineImagePainter should not paint outside the bounds.
  // The border images should be cropped, but still painted.

  SkBitmap src;
  src.allocN32Pixels(6, 6);
  src.eraseColor(SK_ColorGREEN);
  src.erase(SK_ColorRED, SkIRect::MakeXYWH(2, 2, 2, 2));

  gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(src);
  gfx::Insets insets(2, 2, 2, 2);
  gfx::NineImagePainter painter(image, insets);

  int image_scale = 1;
  bool is_opaque = true;
  gfx::Canvas canvas(gfx::Size(3, 3), image_scale, is_opaque);
  canvas.DrawColor(SK_ColorBLACK);

  gfx::Rect bounds(1, 1, 1, 1);
  painter.Paint(&canvas, bounds);

  SkBitmap result = canvas.GetBitmap();

  EXPECT_EQ(SK_ColorGREEN, result.getColor(1, 1));

  EXPECT_EQ(SK_ColorBLACK, result.getColor(0, 0));
  EXPECT_EQ(SK_ColorBLACK, result.getColor(0, 1));
  EXPECT_EQ(SK_ColorBLACK, result.getColor(0, 2));
  EXPECT_EQ(SK_ColorBLACK, result.getColor(1, 0));
  EXPECT_EQ(SK_ColorBLACK, result.getColor(1, 2));
  EXPECT_EQ(SK_ColorBLACK, result.getColor(2, 0));
  EXPECT_EQ(SK_ColorBLACK, result.getColor(2, 1));
  EXPECT_EQ(SK_ColorBLACK, result.getColor(2, 2));
}

TEST(NineImagePainterTest, PaintWithBoundOffset) {
  SkBitmap src;
  src.allocN32Pixels(10, 10);
  src.eraseColor(SK_ColorRED);
  src.eraseArea(SkIRect::MakeXYWH(1, 1, 8, 8), SK_ColorGREEN);

  gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(src);
  gfx::Insets insets(1, 1, 1, 1);
  gfx::NineImagePainter painter(image, insets);

  bool is_opaque = true;
  gfx::Canvas canvas(gfx::Size(10, 10), 1, is_opaque);

  gfx::Rect bounds(1, 1, 10, 10);
  painter.Paint(&canvas, bounds);

  SkBitmap result = canvas.GetBitmap();

  SkIRect green_rect = SkIRect::MakeLTRB(2, 2, 10, 10);
  for (int y = 1; y < 10; y++) {
    for (int x = 1; x < 10; x++) {
      if (green_rect.contains(x, y)) {
        ASSERT_EQ(SK_ColorGREEN, result.getColor(x, y));
      } else {
        ASSERT_EQ(SK_ColorRED, result.getColor(x, y));
      }
    }
  }
}

TEST(NineImagePainterTest, PaintWithScale) {
  SkBitmap src;
  src.allocN32Pixels(100, 100);
  src.eraseColor(SK_ColorRED);
  src.eraseArea(SkIRect::MakeXYWH(10, 10, 80, 80), SK_ColorGREEN);

  float image_scale = 2.f;

  gfx::ImageSkia image = gfx::ImageSkia::CreateFromBitmap(src, image_scale);
  gfx::Insets insets(10, 10, 10, 10);
  gfx::NineImagePainter painter(image, insets);

  bool is_opaque = true;
  gfx::Canvas canvas(gfx::Size(400, 400), image_scale, is_opaque);

  gfx::Vector2d offset(20, 10);
  canvas.Translate(offset);
  canvas.Scale(2, 1);

  gfx::Rect bounds(0, 0, 50, 50);
  painter.Paint(&canvas, bounds);

  SkBitmap result = canvas.GetBitmap();

  gfx::Vector2d paint_offset =
      gfx::ToFlooredVector2d(gfx::ScaleVector2d(offset, image_scale));
  gfx::Rect green_rect = gfx::Rect(20, 10, 160, 80) + paint_offset;
  gfx::Rect outer_rect = gfx::Rect(200, 100) + paint_offset;
  ExpectRedWithGreenRect(result, outer_rect, green_rect);
}

TEST(NineImagePainterTest, PaintWithNegativeScale) {
  SkBitmap src;
  src.allocN32Pixels(100, 100);
  src.eraseColor(SK_ColorRED);
  src.eraseArea(SkIRect::MakeXYWH(10, 10, 80, 80), SK_ColorGREEN);

  float image_scale = 2.f;

  gfx::ImageSkia image = gfx::ImageSkia::CreateFromBitmap(src, image_scale);
  gfx::Insets insets(10, 10, 10, 10);
  gfx::NineImagePainter painter(image, insets);

  bool is_opaque = true;
  gfx::Canvas canvas(gfx::Size(400, 400), image_scale, is_opaque);
  canvas.Translate(gfx::Vector2d(70, 60));
  canvas.Scale(-1, -1);

  gfx::Rect bounds(0, 0, 50, 50);
  painter.Paint(&canvas, bounds);

  SkBitmap result = canvas.GetBitmap();

  // The painting space is 50x50 and the scale of -1,-1 means an offset of 50,50
  // would put the output in the top left corner. Since the offset is 70,60 it
  // moves by 20,10. Since the output is 2x DPI it will become offset by 40,20.
  gfx::Vector2d paint_offset(40, 20);
  gfx::Rect green_rect = gfx::Rect(10, 10, 80, 80) + paint_offset;
  gfx::Rect outer_rect = gfx::Rect(100, 100) + paint_offset;
  ExpectRedWithGreenRect(result, outer_rect, green_rect);
}

}  // namespace gfx
