#ifndef MARS_MDataFormat
#define MARS_MDataFormat

#ifndef MARS_MAGIC
#include "MAGIC.h"
#endif

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

#include <iosfwd>

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

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

public:
    static const unsigned int kSyncMarker;

   MCorsikaFormat(std::istream * in)
        : fIn(in) { }
   virtual ~MCorsikaFormat();

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

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

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

   virtual Int_t  GetNextEvent(Float_t **buffer, Int_t tel=0) = 0;
   virtual Bool_t IsEventioFormat() const = 0;

   virtual Bool_t Eof() const;

   std::streampos GetCurrPos() const;

   void Read(void *ptr, Int_t i=4) const;

   static MCorsikaFormat *CorsikaFormatFactory(const char *fileName);
};


class MCorsikaFormatRaw : public MCorsikaFormat
{
private:

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

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

   Bool_t SeekEvtEnd();

   Int_t  GetNextEvent(Float_t **buffer, Int_t);
   Bool_t IsEventioFormat() const {return kFALSE;}
};


class MCorsikaFormatEventIO : public MCorsikaFormat
{
private:
    std::streampos fRunePos; // file position of the RUNE block

public:
    MCorsikaFormatEventIO(std::istream *in)
        : MCorsikaFormat(in) {fRunePos = std::streampos(0);}

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

    Bool_t SeekEvtEnd();

    Int_t  GetNextEvent(Float_t **buffer, Int_t tel);
    Bool_t IsEventioFormat() const { return kTRUE; }

private:
    Int_t  NextEventObject(Int_t &length) const;
    Int_t  NextPhotonObject(Int_t &length) const;
};

#endif

