#ifndef MARS_MWriteRootFile
#define MARS_MWriteRootFile

#ifndef MARS_MWriteFile
#include "MWriteFile.h"
#endif
#ifndef ROOT_TObjArray
#include <TObjArray.h>
#endif

class TFile;
class TTree;
class TBranch;

class MRootFileBranch : public TNamed
{
private:
    TTree         *fTree;       //!
    TBranch       *fBranch;     //!

    MParContainer *fContainer;
    TString        fContName;

    Bool_t         fMust;

    void Init(const char *name, Bool_t must)
    {
        SetName(name?name:"");
        fMust = must;
    }

public:
    MRootFileBranch() : fTree(NULL), fBranch(NULL), fContainer(NULL), fMust(0)
    {
        Init(NULL, kFALSE);
        fContName = "";
    }

    MRootFileBranch(const char *cname, const char *tname=NULL, Bool_t must=kFALSE)
        : fTree(NULL), fBranch(NULL), fContainer(NULL), fMust(0)
    {
        Init(tname, must);
        fContName = cname;
    }

    MRootFileBranch(MParContainer *cont, const char *tname=NULL, Bool_t must=kFALSE)
        : fTree(NULL), fBranch(NULL), fContName(""), fMust(0)
    {
        Init(tname, must);
        fContainer = cont;
    }

    TTree         *GetTree() const      { return fTree; }
    MParContainer *GetContainer() const { return fContainer; }
    void          *GetAddress()         { return &fContainer; }
    TBranch       *GetBranch() const    { return fBranch; }
    const char    *GetContName() const  { return fContName; }
    Bool_t         MustHave() const     { return fMust; }

    void SetContainer(MParContainer *cont) { fContainer = cont; }
    void SetTree(TTree *tree)              { fTree = tree; }
    void SetBranch(TBranch *branch)        { fBranch = branch; }

    ClassDef(MRootFileBranch, 1) // Storage container for MWriteRootFile to store TBranch informations
};

class MWriteRootFile : public MWriteFile
{
private:
    TFile *fOut;

    TObjArray fBranches;
    TObjArray fTrees;     //!

    //UInt_t fNumEvents; //! Number of events written in a run

    void        CheckAndWrite() const;
    Bool_t      IsFileOpen() const;
    Bool_t      GetContainer(MParList *pList);
    const char *GetFileName() const;

    void StreamPrimitive(ofstream &out) const;
    //Bool_t ReInit(MParList *pList);

    enum {
        kFillTree  = BIT(14),
        // TBranch::kAutoDelete = BIT(15)
        // TBranchElement::kDeleteObject = BIT(16)
        kIsNewTree = BIT(17)
    };

public:
    MWriteRootFile();
    MWriteRootFile(const char *fname,
                   const Option_t *opt="RECREATE",
                   const char *ftitle="Untitled",
                   const Int_t comp=9,
                   const char *name=NULL,
                   const char *title=NULL);
    ~MWriteRootFile();


    void AddContainer(const char *cname,   const char *tname=NULL, Bool_t must=kTRUE);
    void AddContainer(MParContainer *cont, const char *tname=NULL, Bool_t must=kTRUE);


    void Print(Option_t *t=NULL) const;

    ClassDef(MWriteRootFile, 1)	// Task to write data into a root file
};

#endif
