/* Data organisation on disk:

                      Board 1      Board 2      ...     Board 1      Board 2      ...
   RH  BS1 BS2 ... EH C1 C2 C3 ... C1 C2 C3 ... ...  EH C1 C2 C3 ... C1 C2 C3 ... ...
                   --------------------------------  --------------------------------
                   Event 1                           Event 2

  RH Run header   BSx Board structures   EV Event header   Cx Channel (0-19 for 2 chips)
  Channel data are written as shorts, lenght of channel data is in the run header

  Structures are defined using #pragma pack (1) to not include any padding. Note that
  using the gcc attribute __attribute__((__packed__)) is incompatible with root.
*/

#ifndef RAWDATACTX_H_SEEN
#define RAWDATACTX_H_SEEN

#include <stdio.h>

#define DATA_FORMAT 1

#define I8      char
#define U8      unsigned char
#define I16     short
#define U16     unsigned short
#define I32     int
#define U32     unsigned int
#define F32     float

#define MAGICNUM_FILE_OPEN 0xe0e1    // Magic number for run header while file open
#define MAGICNUM_FILE_CLOSED 0xe0e0  //    ... and when file is closed

// Error codes
enum CTX_ErrCode {CTX_OK, CTX_FOPEN, CTX_FCLOSE, CTX_NOTOPEN, CTX_RHEADER,
    	    	  CTX_BSTRUCT, CTX_EHEADER, CTX_DATA, CTX_SEEK, CTX_EOF};

#pragma pack (1)  // Switch padding off

// Run header
typedef struct {
  U16 MagicNum;
  U16 DataFormat;       // Increasing whenever header format changes
  I8  DAQVersion[12]; 	// contains result of __DATE__ macro
  I8  Source[16];
  I8  Type;          // run type (char): pedestal, data, ...
  U32 RunNumber;
  
  U16 StartYear;
  U8  StartMonth;
  U8  StartDay;
  U8  StartHour;
  U8  StartMinute;
  U8  StartSecond;
  
  U16 EndYear;
  U8  EndMonth;
  U8  EndDay;
  U8  EndHour;
  U8  EndMinute;
  U8  EndSecond;

  F32 SourceRA;
  F32 SourceDEC;
  F32 TelescopeRA;
  F32 TelescopeDEC;
  
  U32 Events;                     // Number of events in the run 
  U32 NCMCBoards;                 // Number of used boards
  U32 NChips;			  // Number of DRS chips per board
  U32 NChannels;		  // Number of channels per chip
  U32 Samples;                    // Number of samples
  I32 Offset;                     // Offset from first sample
} RunHeader;

// Board structure
typedef struct {
  I32 Index; 	   // Index number (data written in this order)
  I32 SerialNo;    // Board serial number
  F32 NomFreq;     // Nominal sampling frequency [GHz]
  F32 BoardTemp;   // Board temperature [deg C]
  F32 ScaleFactor; // Factor for conversion to mV 
} BoardStructure;

// Event header
typedef struct {
  I8  Name[5];          // "EVTH", NULL-terminated
  U32 EventNumber;
  F32 TimeSec;          // event time stamp in seconds, ms precision
  U16 TriggerType;
} EventHeader;

#pragma pack ()     // Set default padding

// Class definition
class RawDataCTX {
    FILE *Rawfile;
    bool FileOpen;
    bool Silent;
    
  public:
    RunHeader   *RHeader; 
    EventHeader *EHeader;
    BoardStructure *BStruct;
    short *Data; 

    RawDataCTX(bool = false);
    ~RawDataCTX();
    
    CTX_ErrCode OpenDataFile(char*, FILE* = NULL);
    CTX_ErrCode CloseDataFile();
    CTX_ErrCode ReadEvent(int = 0, FILE* = NULL);
    bool IsFileOpen();
};
#endif
