#include "SkImage.h"
#include "SkPixmap.h"
#include "SkStream.h"
#include "image_cmp.hpp"

#include <algorithm>
#include <assert.h>
#include <cstdint>
#include <vector>

static int byte0(uint32_t p) { return (p >> 0) & 0xFF; }
static int byte1(uint32_t p) { return (p >> 8) & 0xFF; }
static int byte2(uint32_t p) { return (p >> 16) & 0xFF; }
static int byte3(uint32_t p) { return (p >> 24) & 0xFF; }

static uint32_t pack(unsigned a, unsigned b, unsigned c, unsigned d)
{
  return (a << 24) | (b << 16) | (c << 8) | (d << 0);
}

static ImageCmp pixmap_cmp(const SkPixmap& pa, const SkPixmap& pb)
{
  assert(pa.width() == pb.width());
  assert(pa.height() == pb.height());

  size_t pixcount = pa.width() * pa.height();
  int maxdiff = 0;
  size_t rgb_diffcount = 0;
  size_t pixel_diffcount = 0;

  for (int y = 0; y < pa.height(); ++y)
  {
    const uint32_t* row0 = pa.addr32(0, y);
    const uint32_t* row1 = pb.addr32(0, y);

    for (int x = 0; x < pa.width(); ++x)
    {
      const uint32_t p0 = row0[x];
      const uint32_t p1 = row1[x];
      if (p0 == p1)
      {
        continue;
      }
      // Find the max diff in this pixel's r,g,b,a.
      int rgb_diff = std::abs(byte0(p0) - byte0(p1));
      rgb_diff = std::max(rgb_diff, std::abs(byte1(p0) - byte1(p1)));
      rgb_diff = std::max(rgb_diff, std::abs(byte2(p0) - byte2(p1)));
      rgb_diff = std::max(rgb_diff, std::abs(byte3(p0) - byte3(p1)));
      maxdiff = std::max(maxdiff, rgb_diff);
      rgb_diffcount += rgb_diff;
      if (rgb_diff != 0)
      {
        ++pixel_diffcount;
      }
    }
  }

  return ImageCmp::diff(
      maxdiff,
      (float)rgb_diffcount / (pixcount * 255),
      pixel_diffcount);
}

ImageCmp image_cmp(sk_sp<SkImage> a, sk_sp<SkImage> b)
{
  if (a->width() != b->width() || a->height() != b->height())
  {
    return ImageCmp::dimensionMismatch();
  }

  // ensure we can peek at the pixels
  a = a->makeRasterImage();
  b = b->makeRasterImage();

  SkPixmap pa, pb;
  if (!a->peekPixels(&pa) || !b->peekPixels(&pb))
  {
    return ImageCmp::failedToLoad();
  }

  return pixmap_cmp(pa, pb);
}

uint32_t compute_diff0(uint32_t p0, uint32_t p1)
{
  auto a = std::abs(byte0(p0) - byte0(p1));
  auto b = std::abs(byte1(p0) - byte1(p1));
  auto c = std::abs(byte2(p0) - byte2(p1));
  return pack(0xFF, a, b, c);
}

uint32_t compute_diff1(uint32_t p0, uint32_t p1)
{
  auto d = p0 == p1 ? 0 : 0xFF;
  return pack(0xFF, d, d, d);
}

sk_sp<SkImage> make_diff_image(
    sk_sp<SkImage> a,
    sk_sp<SkImage> b,
    uint32_t (*compute_diff)(uint32_t a, uint32_t b))
{
  // ensure we can peek at the pixels
  a = a->makeRasterImage();
  b = b->makeRasterImage();

  SkPixmap pa, pb;
  if (!a->peekPixels(&pa) || !b->peekPixels(&pb))
  {
    throw "failed to peek";
  }

  const auto info = SkImageInfo::MakeN32Premul(pa.width(), pa.height());
  std::vector<uint32_t> pixels(pa.width() * pa.height());
  auto df = SkPixmap(info, pixels.data(), pa.width() * sizeof(uint32_t));

  for (int y = 0; y < df.height(); ++y)
  {
    for (int x = 0; x < df.width(); ++x)
    {
      *df.writable_addr32(x, y) = compute_diff(
          *pa.addr32(x, y),
          *pb.addr32(x, y));
    }
  }

  return SkImage::MakeRasterCopy(df);
}
