//This file contains structures and functions used for processing the HIT2017 files
#include <fstream>
#include <iostream>

using namespace std;

#define DATA_SAMPLES_PER_SENSOR     64
#define DATA_SENSORS_PER_BOARD      2

//**** Structure definitions ****

typedef struct SyncFrame
{
    //unsigned short channel_id;
  unsigned short local_ctr;// local counter // 16 bits, possibly different for each board
  unsigned short global_ctr; //global counter same for all board up to 512
  unsigned short sma_state; //external signal input (external timestamper)
        //these files are additional compared to STM side
    unsigned short dummy = 0xFFFF;  //spacer for nice structure packing
  int device_nr; //device number
  int data_ok; //0 = not ok, anything else is ok
} SyncFrame;

typedef struct BufferData
{
    SyncFrame sync_frame;
    unsigned short sensor_data[DATA_SENSORS_PER_BOARD * DATA_SAMPLES_PER_SENSOR];
} BufferData;

//**** Interface functions ****

//Read some data from a binary HIT2017 file
// The data are grouped in block of BufferData type. Each block is a single frame 
// from one detector board. If there are more than 1 board, the data is ordered sequentially:
// B1F1 B2F1 .. BmF1 B1F2 B2F2 .. BmF2 .. B1Fn B2Fn .. BmFn 
// where Bx stands for board x (1..m) and Fx stands for frame x (1..n)
// User can read files in smaller blocks by specifying the first block and the number of blocks
// to be read. The function will return the number of correctly read blocks.
// The user must allocate memory for the data before running the function.
// If smaller number of blocks was read than specified, the remaining data in the
// allocated memory should be considered invalid.
//Parameters:
// filename:	name of the file to read (with extension)
// first:		number of first data record (starting with 0)
// nr:		number of data records to be read (one record is one board!
// dataptr:	a pointer to an allocaced memory block with min size = sizeof(BufferData)*nr
//Returned value: number of records read.
int hit_read_binary_file(const char* file, int first, int nr, BufferData* dataptr);





//**** Function bodies ****

int hit_read_binary_file(const char* filename, int first, int nr, BufferData* dataptr)
{
	
    ifstream file(filename, ifstream::in | ifstream::binary);

    if (!file.is_open()){
      return -1;	//file could not be opened
    }
    //seek to right position
    file.seekg(first*sizeof(BufferData));
    
    //read data
      file.read((char*)dataptr, nr*sizeof(BufferData));
     int blocks_read = file.gcount() / sizeof(BufferData);
 
      // //close the file
    file.close();
    
    return blocks_read;
}

int getFileSize(const char* filename)
{
    ifstream file(filename, ifstream::in | ifstream::binary);

    if(!file.is_open())
    {
        return -1;
    }

    file.seekg(0, ios::end);
    int fileSize = file.tellg();
    file.close();

    return fileSize;
}

int getBlock(const char* filename,int block)
{
    ifstream file(filename, ifstream::in | ifstream::binary);

    if(!file.is_open())
    {
        return -1;
    }
    file.seekg (block*sizeof(BufferData));

    BufferData* dataptr = new BufferData();
    file.read ((char*)dataptr ,sizeof(BufferData));
    file.close();
    cout <<  dataptr->sync_frame.device_nr << endl;
    cout << dataptr->sensor_data[127] << endl;
    
    return 0;
}
