#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

#include <gdk-pixbuf/gdk-pixbuf.h>

struct test_case
{
  const char *out_image_path;
  GdkInterpType interp_type;
};

int main(int argc, char *argv[])
{
  GError *err = NULL;

  const char *image_path = "apple-red.png";

  GdkPixbuf *src = gdk_pixbuf_new_from_file (image_path, &err);
  if (NULL != err) {
    fprintf(stderr, "Unable to read `%s': %s\n", image_path, err->message);
    g_error_free (err);
    return EXIT_FAILURE;
  }

  {
    GdkPixbuf *tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
                                     TRUE,
                                     gdk_pixbuf_get_bits_per_sample (src),
                                     gdk_pixbuf_get_width (src),
                                     gdk_pixbuf_get_height (src));
    gdk_pixbuf_fill (tmp, 0x00ccccff);
    gdk_pixbuf_composite (src, tmp,
                          0, 0, gdk_pixbuf_get_width (tmp), gdk_pixbuf_get_height (tmp),
                          0., 0., 1., 1.,
                          GDK_INTERP_NEAREST, 255);
    g_object_unref (src);
    src = tmp;
  }

  guchar *pixels = gdk_pixbuf_get_pixels (src);
  guchar *tl_pixel = pixels;
  tl_pixel[0] = 0xff;
  tl_pixel[1] = 0x00;
  tl_pixel[2] = 0xff;
  guchar *br_pixel = pixels + (gsize)((gdk_pixbuf_get_height (src) - 1) * gdk_pixbuf_get_rowstride (src)) + (gsize)((gdk_pixbuf_get_width (src) - 1) * gdk_pixbuf_get_n_channels (src));
  br_pixel[0] = 0xff;
  br_pixel[1] = 0xff;
  br_pixel[2] = 0x00;

  const struct test_case test_cases[] = {
    {
      .out_image_path = "out-NEAREST.png",
      .interp_type = GDK_INTERP_NEAREST
    },
    {
      .out_image_path = "out-TILES.png",
      .interp_type = GDK_INTERP_TILES
    },
    {
      .out_image_path = "out-BILINEAR.png",
      .interp_type = GDK_INTERP_BILINEAR
    },
    {
      .out_image_path = "out-HYPER.png",
      .interp_type = GDK_INTERP_HYPER
    }
  };

  for (size_t i = 0; i < (sizeof test_cases) / (sizeof test_cases[0]); ++i) {
    GdkPixbuf *dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, gdk_pixbuf_get_bits_per_sample (src), 128, 128);
    gdk_pixbuf_fill (dest, 0xffffffff);
    gdk_pixbuf_composite (src, dest,
                          0, 0, gdk_pixbuf_get_width (dest), gdk_pixbuf_get_height (dest),
                          10., 10., 1., 1.,
                          test_cases[i].interp_type, 255);

    image_path = test_cases[i].out_image_path;
    gdk_pixbuf_save (dest, image_path, "png", &err, NULL);
    if (NULL != err) {
      fprintf(stderr, "Unable to write to `%s': %s\n", image_path, err->message);
      g_error_free (err);
      g_object_unref (dest);
      g_object_unref (src);
      return EXIT_FAILURE;
    }

    g_object_unref (dest);
  }

  g_object_unref (src);

  return EXIT_SUCCESS;
}
