// 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 <Cocoa/Cocoa.h>

#include "base/logging.h"
#include "base/mac/scoped_nsobject.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_png_rep.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_util_mac.h"
#include "ui/gfx/image/image_unittest_util.h"

namespace {

// Returns true if the structure of |ns_image| matches the structure
// described by |width|, |height|, and |scales|.
// The structure matches if:
// - |ns_image| is not nil.
// - |ns_image| has NSImageReps of |scales|.
// - Each of the NSImageReps has a pixel size of [|ns_image| size] *
//   scale.
bool NSImageStructureMatches(
    NSImage* ns_image,
    int width,
    int height,
    const std::vector<float>& scales) {
  if (!ns_image ||
      [ns_image size].width != width ||
      [ns_image size].height != height ||
      [ns_image representations].count != scales.size()) {
    return false;
  }

  for (size_t i = 0; i < scales.size(); ++i) {
    float scale = scales[i];
    bool found_match = false;
    for (size_t j = 0; j < [ns_image representations].count; ++j) {
      NSImageRep* ns_image_rep = [[ns_image representations] objectAtIndex:j];
      if (ns_image_rep &&
          [ns_image_rep pixelsWide] == width * scale &&
          [ns_image_rep pixelsHigh] == height * scale) {
        found_match = true;
        break;
      }
    }
    if (!found_match)
      return false;
  }
  return true;
}

void BitmapImageRep(int width, int height,
     NSBitmapImageRep** image_rep) {
  *image_rep = [[[NSBitmapImageRep alloc]
      initWithBitmapDataPlanes:NULL
                    pixelsWide:width
                   pixelsHigh:height
                bitsPerSample:8
              samplesPerPixel:3
                     hasAlpha:NO
                     isPlanar:NO
               colorSpaceName:NSDeviceRGBColorSpace
                 bitmapFormat:0
                  bytesPerRow:0
                 bitsPerPixel:0]
      autorelease];
  unsigned char* image_rep_data = [*image_rep bitmapData];
  for (int i = 0; i < width * height * 3; ++i)
    image_rep_data[i] = 255;
}

class ImageMacTest : public testing::Test {
 public:
  ImageMacTest() {
    gfx::ImageSkia::SetSupportedScales(gfx::test::Get1xAnd2xScales());
  }

  virtual ~ImageMacTest() {
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ImageMacTest);
};

namespace gt = gfx::test;

TEST_F(ImageMacTest, MultiResolutionNSImageToImageSkia) {
  const int kWidth1x = 10;
  const int kHeight1x = 12;
  const int kWidth2x = 20;
  const int kHeight2x = 24;

  NSBitmapImageRep* ns_image_rep1;
  BitmapImageRep(kWidth1x, kHeight1x, &ns_image_rep1);
  NSBitmapImageRep* ns_image_rep2;
  BitmapImageRep(kWidth2x, kHeight2x, &ns_image_rep2);
  base::scoped_nsobject<NSImage> ns_image(
      [[NSImage alloc] initWithSize:NSMakeSize(kWidth1x, kHeight1x)]);
  [ns_image addRepresentation:ns_image_rep1];
  [ns_image addRepresentation:ns_image_rep2];

  gfx::Image image(ns_image.release());

  EXPECT_EQ(1u, image.RepresentationCount());

  const gfx::ImageSkia* image_skia = image.ToImageSkia();

  std::vector<float> scales;
  scales.push_back(1.0f);
  scales.push_back(2.0f);
  EXPECT_TRUE(gt::ImageSkiaStructureMatches(*image_skia, kWidth1x, kHeight1x,
                                            scales));

  // ToImageSkia should create a second representation.
  EXPECT_EQ(2u, image.RepresentationCount());
}

// Test that convertng to an ImageSkia from an NSImage with scale factors
// other than 1x and 2x results in an ImageSkia with scale factors 1x and
// 2x;
TEST_F(ImageMacTest, UnalignedMultiResolutionNSImageToImageSkia) {
  const int kWidth1x = 10;
  const int kHeight1x= 12;
  const int kWidth4x = 40;
  const int kHeight4x = 48;

  NSBitmapImageRep* ns_image_rep4;
  BitmapImageRep(kWidth4x, kHeight4x, &ns_image_rep4);
  base::scoped_nsobject<NSImage> ns_image(
      [[NSImage alloc] initWithSize:NSMakeSize(kWidth1x, kHeight1x)]);
  [ns_image addRepresentation:ns_image_rep4];

  gfx::Image image(ns_image.release());

  EXPECT_EQ(1u, image.RepresentationCount());

  const gfx::ImageSkia* image_skia = image.ToImageSkia();

  std::vector<float> scales;
  scales.push_back(1.0f);
  scales.push_back(2.0f);
  EXPECT_TRUE(gt::ImageSkiaStructureMatches(*image_skia, kWidth1x, kHeight1x,
                                            scales));

  // ToImageSkia should create a second representation.
  EXPECT_EQ(2u, image.RepresentationCount());
}

TEST_F(ImageMacTest, MultiResolutionImageSkiaToNSImage) {
  const int kWidth1x = 10;
  const int kHeight1x= 12;
  const int kWidth2x = 20;
  const int kHeight2x = 24;

  gfx::ImageSkia image_skia;
  image_skia.AddRepresentation(gfx::ImageSkiaRep(
      gt::CreateBitmap(kWidth1x, kHeight1x), 1.0f));
  image_skia.AddRepresentation(gfx::ImageSkiaRep(
      gt::CreateBitmap(kWidth2x, kHeight2x), 2.0f));

  gfx::Image image(image_skia);

  EXPECT_EQ(1u, image.RepresentationCount());
  EXPECT_EQ(2u, image.ToImageSkia()->image_reps().size());

  NSImage* ns_image = image.ToNSImage();

  std::vector<float> scales;
  scales.push_back(1.0f);
  scales.push_back(2.0f);
  EXPECT_TRUE(NSImageStructureMatches(ns_image, kWidth1x, kHeight1x, scales));

  // Request for NSImage* should create a second representation.
  EXPECT_EQ(2u, image.RepresentationCount());
}

TEST_F(ImageMacTest, MultiResolutionPNGToNSImage) {
  const int kSize1x = 25;
  const int kSize2x = 50;

  scoped_refptr<base::RefCountedMemory> bytes1x = gt::CreatePNGBytes(kSize1x);
  scoped_refptr<base::RefCountedMemory> bytes2x = gt::CreatePNGBytes(kSize2x);
  std::vector<gfx::ImagePNGRep> image_png_reps;
  image_png_reps.push_back(gfx::ImagePNGRep(bytes1x, 1.0f));
  image_png_reps.push_back(gfx::ImagePNGRep(bytes2x, 2.0f));

  gfx::Image image(image_png_reps);

  NSImage* ns_image = image.ToNSImage();
  std::vector<float> scales;
  scales.push_back(1.0f);
  scales.push_back(2.0f);
  EXPECT_TRUE(NSImageStructureMatches(ns_image, kSize1x, kSize1x, scales));

  // Converting from PNG to NSImage should not go through ImageSkia.
  EXPECT_FALSE(image.HasRepresentation(gfx::Image::kImageRepSkia));

  // Convert to ImageSkia to check pixel contents of NSImageReps.
  gfx::ImageSkia image_skia = gfx::ImageSkiaFromNSImage(ns_image);
  EXPECT_TRUE(gt::IsEqual(bytes1x,
      image_skia.GetRepresentation(1.0f).sk_bitmap()));
  EXPECT_TRUE(gt::IsEqual(bytes2x,
      image_skia.GetRepresentation(2.0f).sk_bitmap()));
}

} // namespace
