#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h> //includes memset?
#include <png.h>

#include <amscimglib4/amscimglib4.h>
#include <amscimglib4/amscimglib4_intl.h>

#ifdef __cplusplus
extern "C" {  
#endif


/*
* 1) Declare a 'png_image' structure (see below) on the stack, set the
*    version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL
*    (this is REQUIRED, your program may crash if you don't do it.)
* 2) Call the appropriate png_image_begin_read... function.
* 3) Set the png_image 'format' member to the required sample format.
* 4) Allocate a buffer for the image and, if required, the color-map.
* 5) Call png_image_finish_read to read the image and, if required, the
*    color-map into your buffers.

* To write a PNG file using the simplified API:
*
* 1) Declare a 'png_image' structure on the stack and memset() it to all zero.
* 2) Initialize the members of the structure that describe the image, setting
*    the 'format' member to the format of the image samples.
* 3) Call the appropriate png_image_write... function with a pointer to the
*    image and, if necessary, the color-map to write the PNG data.

*/

/* Initialize to NULL, free with png_image_free */



AMSCIMGLIB4_API void amscimglib4_readimage_png(const char *fname, amscimglib4_image *img)
{
  int I,J;
  //FILE *fp;
  png_image image; //the control structure used by libpng
  //png_image has height, width, format, flags...
  //
  //format = PNG_FORMAT_RGBA
  //          PNG_FORMAT_
  memset(&image,0,sizeof(image)); //fills memory with zeros
  image.version = PNG_IMAGE_VERSION;

  if(png_image_begin_read_from_file(&image, fname) != 0)
  {
    png_bytep buffer; //presumably this is a pointer to bytes
    unsigned char *bf2;
    int z;
    unsigned char R,G,B,A;
    //set the format in which to read the PNG file: This code chooses RGBA
    image.format = PNG_FORMAT_RGBA;
    buffer = (png_bytep) malloc(PNG_IMAGE_SIZE(image));
    if(buffer!=NULL &&
      png_image_finish_read(&image,
                            NULL /*background*/,
                            buffer,
                            0 /*row stride*/,
                            NULL /*colormap*/) != 0
      );
    {
       // the example code now uses a writing function to write it to another file
       //png_image_write_to_file(&image, fname, 0 /*convert_to_8bit*/, buffer, 0/*row_stride*/,NULL/*colormap*/)
       //I want to convert and translate the image into my struct

      //this function must make some sort of assumption about the contents of the buffer? I might have to try to blit output to see what?
      // fp = fopen("testbufferoutput.csv","w+");
      // //assuming RGBARGBARGBA
      // for(I=0;I<image.width;I++)
      // {
      //   for(J=0;J<image.height;J++)
      //   {
      //     bf2 = (unsigned char *)buffer;
      //     z = (I+J*image.width)*4;
      //     fprintf(fp,"%d,%d,%d,%d,",bf2[z+0],bf2[z+1],bf2[z+2],bf2[z+3]);
      //   }
      //   fprintf(fp,"\n");
      // }
      // fclose(fp);
      amscimglib4_image_resize(img,image.width,image.height);
      bf2 = (unsigned char *) buffer;
      for(I=0;I<image.width;I++)
      {
        for(J=0;J<image.height;J++)
        {
          z = (I+J*image.width)*4;
          R = bf2[z+0];
          G = bf2[z+1];
          B = bf2[z+2];
          A = bf2[z+3];
          amscimglib4_set_pixel_RGBA(img,I,J,R,G,B,A);
        }
      }

      //clean up
      png_image_free(&image);
      free(buffer);

    }

  }
  else
  {
    //something went wrong?
    printf("readimage_png: error: %s\n", image.message);
    amscimglib4_image_resize(img,0,0);
  }

  return;
}

AMSCIMGLIB4_API void amscimglib4_writeimage_png(const char *fname, amscimglib4_image *img)
{
  png_image image;

  unsigned char *bb2 = NULL;
  bb2 = (unsigned char*)malloc(img->sizex*img->sizey*4*sizeof(unsigned char));
  memcpy(bb2,img->data,img->sizex*img->sizey*4*sizeof(unsigned char));

  memset(&image,0,sizeof(image)); //fills memory with zeros
  image.version = PNG_IMAGE_VERSION;
  image.format = PNG_FORMAT_RGBA;
  image.width = img->sizex;
  image.height = img->sizey;

  png_image_write_to_file(&image, fname, 0 /*convert_to_8bit*/, (png_bytep) bb2, 0/*row_stride*/,NULL/*colormap*/);

  free(bb2); //weird - png-writer causes memory leaks if {I operate directly on img->bytebuf
  return;
}


#ifdef __cplusplus
}; //end extern "C"
#endif