#ifndef _SER_H_
#define _SER_H_

/*
  Example usage of the class:
  ---------------------------

  SER *ser = new SER();
  ser->setWidth(640);
  ser->setHeight(480);
  ser->setColorID(SER_COLORID_RGB);
  ser->setPixelDepth(8);
  ser->setFile((char *)"test.ser");
  ser->setObserver((char *)"Steffen Pohle");
  ser->setTelescope((char *)"Sky-Watcher EVOSTAR 102");
  ser->setInstrument((char *)"Svbony SV305");
  ser->setNumberOfFrames(1);
  ser->writeHeader();
  uint8_t * data = (uint8_t *) ser->allocFrame();
  memset(data, 0, ser->getFrameSize());
  for(int y = 0; y < ser->getHeight()/3; y++) {
    for(int x = 0; x < ser->getWidth(); x++) {
      data[y*ser->getWidth()*3 + x*3 + 0] = 0xff;
    }
  }
  for(int y = ser->getHeight()/3; y < 2*ser->getHeight()/3; y++) {
    for(int x = 0; x < ser->getWidth(); x++) {
      data[y*ser->getWidth()*3 + x*3 + 1] = 0xff;
    }
  }
  for(int y = 2*ser->getHeight()/3; y < 3*ser->getHeight()/3; y++) {
    for(int x = 0; x < ser->getWidth(); x++) {
      data[y*ser->getWidth()*3 + x*3 + 2] = 0xff;
    }
  }
  ser->appendFrame(data);
  delete ser;

 */

int ser_convert_type_to_ser (int v4l2_fmt, int *pixeldepth, int *serformat);


enum {
  SER_COLORID_MONO = 0,
  SER_COLORID_BAYER_RGGB = 8,
  SER_COLORID_BAYER_GRBG = 9,
  SER_COLORID_BAYER_GBRG = 10,
  SER_COLORID_BAYER_BGGR = 11,
  SER_COLORID_BAYER_CYYM = 16,
  SER_COLORID_BAYER_YCMY = 17,
  SER_COLORID_BAYER_YMCY = 18,
  SER_COLORID_BAYER_MYYC = 19,
  SER_COLORID_RGB = 100,
  SER_COLORID_BGR = 101
};

struct __attribute__((__packed__)) SER_Header {
  char FileID[14];              /* "LUCAM-RECORDER" (fix) */
  int32_t LuID;                 /* Lumenera camera series ID (currently unused; default = 0) */
  int32_t ColorID;              /* see SER_COLORID_* */
  int32_t LittleEndian;         /* 0 (FALSE) for big-endian, 1 (TRUE) for little-endian */
  int32_t ImageWidth;           /* Width of every image in pixel */
  int32_t ImageHeight;          /* Height of every image in pixel */
  int32_t PixelDepthPerPlane;   /* True bit depth per pixel per plane */
  int32_t FrameCount;           /* Number of image frames in SER file */
  char Observer[40];            /* Name of observer */
  char Instrument[40];          /* Name of used camera */
  char Telescope[40];           /* Name of used telescope */
  int64_t DateTime;             /* Start time of image stream (local time) */
  int64_t DateTimeUTC;          /* Start time of image stream in UTC */
};

class SER {

 private:
  /* header data */
  struct SER_Header header;

  /* internal data */
  FILE * FileDesc;
  int NumberOfPlanes;
  int BytesPerPixel;
  size_t FrameSize;
  void * Frame;
  int FramePointer;
  int Reading;
  int64_t * TimeStamps;
  int NumberOfTimeStamps;
  
  void updateHeaderData(void);
  int64_t differenceLocalUTC(void);

 public:
  SER();
  ~SER();

  int setObserver(char *);
  int setInstrument(char *);
  int setTelescope(char *);
  int setWidth(int);
  int setHeight(int);
  int getWidth(void);
  int getHeight(void);
  int setColorID(int);
  int setPixelDepth(int);
  int getPixelDepth(void);
  int32_t getNumberOfFrames(void);
  void setNumberOfFrames(int32_t);
  int64_t setDateTime(void);
  int64_t currentDateTimeUTC(void);
  size_t getFrameSize(void);
  
  int setFile(char *);
  int writeHeader(void);
  int readHeader(void);
  int appendFrame(void *);
  int readFrame(void *);
  int readFrame(void *, int);
  void * allocFrame(void);
};

#endif
