#ifndef FACT_Fits
#define FACT_Fits

#include <CCfits/CCfits>
#include <vector>

#include "Description.h"

class Converter;
class MessageImp;

using namespace std;

class Fits
{
	private:
		///The CCfits object to the FITS file
        CCfits::FITS* fFile;
		///Flag indicating whether the FITS object should be managed internally or not.
		bool fOwner;
		///The CCfits Table
		CCfits::Table* fTable;
		///The current number of Rows in the table
		int fNumRows;
		///Name of the "standard", i.e. data found in every fits file
		///TODO make these variable static so that they are shared by every object.
		///TODO add also a static boolean to initialize these only once
		vector<Description> fStandardColDesc;
		///Format of the standard columns.
		vector<string> fStandardFormats;
		///the pointers to the standard variables
		vector<void*> fStandardPointers;
		///the number of bytes taken by each standard variable
		vector<int> fStandardNumBytes;
		///the vector of data column names
		vector<Description> fDataColDesc;
		///the data format of the data columns
		vector<string> fDataFormats;
		///the pointer to the contiguous memory location where the data is stored (i.e. the dim data pointer)
		void* fDataPointer;
		///the size of the data, in bytes.
		int fDataNumBytes;
		///the copy buffer. Required to put the standard and data variable in contguous memory 
		unsigned char* fCopyBuffer;
		///the total number of bytes per FITS row
		int fTotalNumBytes;
		///to keep track of the time of the latest written entry (to update the header when closing the file)
		double fEndMjD;
		///to keep track of the reference MjD
		double fRefMjD;
		///Write the FITS header keys
		bool WriteHeaderKeys();
public:
		///Name of the openned file. For querying stats
		string fFileName;
private:
		///Keep track of number of opened fits
		int* fNumOpenFitsFiles;
		///were to log the errors
		MessageImp* fMess;		
public:
        ///current run number being logged
		uint32_t fRunNumber;
		
		Fits() :  fFile(NULL),
				  fOwner(false),
				  fTable(NULL), 
					 fNumRows(0), 
					 fDataPointer(NULL), 
					 fDataNumBytes(0), 
					 fCopyBuffer(NULL), 
					 fTotalNumBytes(0),
					 fEndMjD(0.0),
					 fRefMjD(0.0),
					 fFileName(""),
					 fNumOpenFitsFiles(NULL),
					 fMess(NULL),
					 fRunNumber(0)
		 {}
		
		virtual ~Fits() 
		{
			if (IsOpen())
				Close();
		}
		///returns wether or not the file is currently open or not
		bool IsOpen() const {return fFile != NULL;}
		
		///Adds a column that exists in all FITS files
		void AddStandardColumn(const Description& desc, const string &dataFormat, void* dataPointer, long unsigned int numDataBytes);
		
		///Adds columns specific to the service being logged.
		void InitDataColumns(const vector<Description> &desc, vector<string>& dataFormat, void* dataPointer, int numDataBytes);

		///Opens a FITS file
        bool Open(const string& fileName, const string& tableName, CCfits::FITS* file, int* fitsCounter, MessageImp* out, int runNumber);//ostream& out);

		///Write one line of data. Use the given converter.
		bool Write(Converter* conv);
		
		///Close the currently opened file.
		void Close();
		
		///Get the size currently written on the disk
		int GetWrittenSize() const;
private:
		template <typename T>
		bool WriteSingleHeaderKey(const string &name, const T &value, const string &comment);
		CCfits::Table* findSuitableTableInFitsFile(const string& tableName,const vector<string>& allNames, const vector<string>& allDataTypes, const vector<string>& allUnits);

};//Fits


#endif /*FITS_H_*/

