/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "platform/DragImage.h"

#include <memory>
#include "base/memory/scoped_refptr.h"
#include "platform/fonts/FontDescription.h"
#include "platform/geometry/IntSize.h"
#include "platform/graphics/BitmapImage.h"
#include "platform/graphics/Image.h"
#include "platform/graphics/skia/SkiaUtils.h"
#include "platform/weborigin/KURL.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPixelRef.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace blink {

class TestImage : public Image {
 public:
  static scoped_refptr<TestImage> Create(sk_sp<SkImage> image) {
    return base::AdoptRef(new TestImage(image));
  }

  static scoped_refptr<TestImage> Create(const IntSize& size) {
    return base::AdoptRef(new TestImage(size));
  }

  IntSize Size() const override {
    DCHECK(image_);

    return IntSize(image_->width(), image_->height());
  }

  bool CurrentFrameKnownToBeOpaque(
      MetadataMode = kUseCurrentMetadata) override {
    return false;
  }

  void DestroyDecodedData() override {
    // Image pure virtual stub.
  }

  void Draw(PaintCanvas*,
            const PaintFlags&,
            const FloatRect&,
            const FloatRect&,
            RespectImageOrientationEnum,
            ImageClampingMode,
            ImageDecodingMode) override {
    // Image pure virtual stub.
  }

  PaintImage PaintImageForCurrentFrame() override {
    return CreatePaintImageBuilder()
        .set_image(image_, cc::PaintImage::GetNextContentId())
        .TakePaintImage();
  }

 private:
  explicit TestImage(sk_sp<SkImage> image) : image_(image) {}

  explicit TestImage(IntSize size) : image_(nullptr) {
    sk_sp<SkSurface> surface = CreateSkSurface(size);
    if (!surface)
      return;

    surface->getCanvas()->clear(SK_ColorTRANSPARENT);
    image_ = surface->makeImageSnapshot();
  }

  static sk_sp<SkSurface> CreateSkSurface(IntSize size) {
    return SkSurface::MakeRaster(
        SkImageInfo::MakeN32(size.Width(), size.Height(), kPremul_SkAlphaType));
  }

  sk_sp<SkImage> image_;
};

TEST(DragImageTest, NullHandling) {
  EXPECT_FALSE(DragImage::Create(nullptr));

  scoped_refptr<TestImage> null_test_image(TestImage::Create(IntSize()));
  EXPECT_FALSE(DragImage::Create(null_test_image.get()));
}

TEST(DragImageTest, NonNullHandling) {
  scoped_refptr<TestImage> test_image(TestImage::Create(IntSize(2, 2)));
  std::unique_ptr<DragImage> drag_image = DragImage::Create(test_image.get());
  ASSERT_TRUE(drag_image);

  drag_image->Scale(0.5, 0.5);
  IntSize size = drag_image->Size();
  EXPECT_EQ(1, size.Width());
  EXPECT_EQ(1, size.Height());
}

TEST(DragImageTest, CreateDragImage) {
  // Tests that the DrageImage implementation doesn't choke on null values
  // of imageForCurrentFrame().
  // FIXME: how is this test any different from test NullHandling?
  scoped_refptr<TestImage> test_image(TestImage::Create(IntSize()));
  EXPECT_FALSE(DragImage::Create(test_image.get()));
}

TEST(DragImageTest, TrimWhitespace) {
  KURL url("http://www.example.com/");
  String test_label = "          Example Example Example      \n    ";
  String expected_label = "Example Example Example";
  float device_scale_factor = 1.0f;

  FontDescription font_description;
  font_description.FirstFamily().SetFamily("Arial");
  font_description.SetSpecifiedSize(16);
  font_description.SetIsAbsoluteSize(true);
  font_description.SetGenericFamily(FontDescription::kNoFamily);
  font_description.SetWeight(NormalWeightValue());
  font_description.SetStyle(NormalSlopeValue());

  std::unique_ptr<DragImage> test_image =
      DragImage::Create(url, test_label, font_description, device_scale_factor);
  std::unique_ptr<DragImage> expected_image = DragImage::Create(
      url, expected_label, font_description, device_scale_factor);

  EXPECT_EQ(test_image->Size().Width(), expected_image->Size().Width());
}

TEST(DragImageTest, InterpolationNone) {
  SkBitmap expected_bitmap;
  expected_bitmap.allocN32Pixels(4, 4);
  expected_bitmap.eraseArea(SkIRect::MakeXYWH(0, 0, 2, 2), 0xFFFFFFFF);
  expected_bitmap.eraseArea(SkIRect::MakeXYWH(0, 2, 2, 2), 0xFF000000);
  expected_bitmap.eraseArea(SkIRect::MakeXYWH(2, 0, 2, 2), 0xFF000000);
  expected_bitmap.eraseArea(SkIRect::MakeXYWH(2, 2, 2, 2), 0xFFFFFFFF);

  SkBitmap test_bitmap;
  test_bitmap.allocN32Pixels(2, 2);
  test_bitmap.eraseArea(SkIRect::MakeXYWH(0, 0, 1, 1), 0xFFFFFFFF);
  test_bitmap.eraseArea(SkIRect::MakeXYWH(0, 1, 1, 1), 0xFF000000);
  test_bitmap.eraseArea(SkIRect::MakeXYWH(1, 0, 1, 1), 0xFF000000);
  test_bitmap.eraseArea(SkIRect::MakeXYWH(1, 1, 1, 1), 0xFFFFFFFF);

  scoped_refptr<TestImage> test_image =
      TestImage::Create(SkImage::MakeFromBitmap(test_bitmap));
  std::unique_ptr<DragImage> drag_image = DragImage::Create(
      test_image.get(), kDoNotRespectImageOrientation, 1, kInterpolationNone);
  ASSERT_TRUE(drag_image);
  drag_image->Scale(2, 2);
  const SkBitmap& drag_bitmap = drag_image->Bitmap();
  for (int x = 0; x < drag_bitmap.width(); ++x)
    for (int y = 0; y < drag_bitmap.height(); ++y)
      EXPECT_EQ(expected_bitmap.getColor(x, y), drag_bitmap.getColor(x, y));
}

}  // namespace blink
