#ifndef _GRABPNG_H
#define _GRABPNG_H 1

class PngGrabber 
{
  
private:

  struct ImageSize
  {
    int width;
    int height;
    ImageSize() { width=height=0; }
  };

public:

  PngGrabber(){ isOpen=false; imageData = 0; dataSize = 0;}
  ~PngGrabber(){ if (imageData) delete imageData; }

  struct PngInfo  // for ui and maybe a list command for console
  {
    int w;  // width
    int h;  // height
    int x;  // grab x
    int y;  // grab y
    int alph; // 0 or 1
    int ok; // 0 or 1
    PngInfo(){w=h=x=y=alph=ok=0;}
  };
  
  PngInfo pngInfo;
  
  static PngInfo getInfo(const char *pngpath);
  static void staticGrab(const char *pngpath, int x, int y);
  static void staticAlph(const char *pngpath, int alph);
  
  bool open (const char *pngpath);
  void close ();
  bool grab (const char *outpath, int x, int y);
  bool setAlph (const char *outpath, int alph);
  
  
  int getWidth() {return imageSize.width;}
  int getHeight() {return imageSize.height;}
  void getSize(int &w, int &h){w=imageSize.width; h=imageSize.height;}

private:
  
  bool isOpen;
  ImageSize imageSize;  // dimensions of image
  char *imageData; // pointer to png data
  unsigned dataSize;

  struct grabChunk
  {
    char size[4];
    char name[4];
    long xoff;
    long yoff;
    unsigned long crc;
  };
  
  struct alphChunk
  {
    char size[4];
    char name[4];
    char crc[4];
  };
  
  // swap bytes for big endian format
  static inline unsigned long byteSwapULong(unsigned long nLongNumber);
  static inline unsigned long byteSwapLong(long value);

  // CRC stuff for PNG.
  static unsigned long crc_table[256];
  static int crc_table_computed; // = 0;
  static void make_crc_table(void);
  static unsigned long update_crc(unsigned long crc, unsigned char *buf, int len);
  static unsigned long crc(unsigned char *buf, int len);

};

#endif

