#ifndef MARS_MDataFormat
#define MARS_MDataFormat


#ifndef ROOT_Rtypes
#include <Rtypes.h>
#endif


#include <iosfwd>

#include "MLog.h"


class MCorsikaFormat
{
protected:
   MLog           * fLog;
   std::istream   * fIn;

   std::streampos fPrevPos; // file position before previous read
   std::streampos fPos;

public:
   MCorsikaFormat(MLog * log, std::istream * in)
        : fIn(in) {fLog = log;} 
   virtual ~MCorsikaFormat();

   virtual Bool_t SeekNextBlock(const char * id, unsigned short type) = 0;
   virtual void   UnreadLastHeader() = 0;

   virtual Bool_t ReadData(Int_t numValues, Float_t * buffer, 
	                        Int_t minSeekValues = 272);
   virtual void   UnreadLastData();

   virtual Bool_t SeekEvtEnd() = 0;
   virtual void   StorePos();
   virtual void   ResetPos();

   virtual Bool_t GetNextEvent(Float_t ** buffer, Bool_t & readError) = 0;
   virtual Bool_t IsEventioFormat() = 0;

	virtual Bool_t Eof()   {return fIn->eof();}


	std::streampos GetCurrPos()  {return fIn->tellg();}
};


class MCorsikaFormatRaw : public MCorsikaFormat
{
private:

public:
   MCorsikaFormatRaw(MLog * log, std::istream * in)
        : MCorsikaFormat(log, in) {} 

   Bool_t SeekNextBlock(const char * id, unsigned short type);
   void   UnreadLastHeader();

   Bool_t SeekEvtEnd();

   Bool_t GetNextEvent(Float_t ** buffer, Bool_t & readError);
   Bool_t IsEventioFormat()   {return kFALSE;}
};


class MCorsikaFormatEventIO : public MCorsikaFormat
{
private:

public:
   MCorsikaFormatEventIO(MLog * log, std::istream * in)
        : MCorsikaFormat(log, in) {} 

   Bool_t SeekNextBlock(const char * id, unsigned short type);
   void   UnreadLastHeader();

   Bool_t SeekEvtEnd();

   Bool_t GetNextEvent(Float_t ** buffer, Bool_t & readError);
   Bool_t IsEventioFormat()   {return kTRUE;}

private:
	Bool_t NextTopLevelBlock(Int_t & length, Bool_t & readError);
	Bool_t NextEventBlock(Int_t & length, Bool_t & readError);

};


MCorsikaFormat * CorsikaFormatFactory(MLog * log, const char * fileName);


#endif

