#ifndef MWRITEROOTFILE_H
#define MWRITEROOTFILE_H

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

class TFile;
class TTree;
class TBranch;

class MRootFileTree : public TObject
{
private:
    TTree         *fTree;
    Bool_t         fWriteFlag;
    ULong_t        fNumEntries;

public:
    MRootFileTree(TTree *tree) : fTree(tree), fWriteFlag(kFALSE), fNumEntries(0) {}
    TTree *GetTree() const { return fTree; }
    Bool_t HasWriteFlag() const { return fWriteFlag; }
    ULong_t GetNumEntries() const { return fNumEntries; }
    void operator++(int) { fNumEntries++; }
    void SetWriteFlag() { fWriteFlag = kTRUE; }
    void DelWriteFlag() { fWriteFlag = kFALSE; }
};

class MRootFileBranch : public TObject
{
private:
    MRootFileTree *fTree;
    TBranch       *fBranch;
    MParContainer *fContainer;
    TString       *fContName;
    TString       *fTreeName;
    TString       *fTreeTitle;

public:
    MRootFileBranch(const char *cname, const char *tname=NULL, const char *ttitle=NULL)
        : fTree(NULL), fBranch(NULL), fContainer(NULL)
    {
        fContName  = new TString(cname);
        fTreeName  = tname ? new TString(tname) : NULL;
        fTreeTitle = ttitle ? new TString(ttitle) : NULL;
    }

    MRootFileBranch(MParContainer *cont, const char *tname=NULL, const char *ttitle=NULL)
        : fTree(NULL), fBranch(NULL), fContName(NULL)
    {
        fContainer = cont;
        fTreeName  = tname ? new TString(tname) : NULL;
        fTreeTitle = ttitle ? new TString(ttitle) : NULL;
    }

        MRootFileTree *GetTree() const { return fTree; }
    MParContainer *GetContainer() const { return fContainer; }
    void *GetAddress() { return &fContainer; }
    TBranch *GetBranch() const          { return fBranch; }
    const char *GetContName() const     { return fContName  ? (const char*)(*fContName)  : NULL; }
    const char *GetTreeName() const     { return fTreeName  ? (const char*)(*fTreeName)  : NULL; }
    const char *GetTreeTitle() const    { return fTreeTitle ? (const char*)(*fTreeTitle) : NULL; }

    void SetContainer(MParContainer *cont) { fContainer = cont; }
    void SetTree(MRootFileTree *tree) { fTree = tree; }

};

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

    TObjArray fBranches;
    TObjArray fTrees;

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

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

    void Print(Option_t *t=NULL);

    void AddContainer(const char *cname,
                      const char *tname=NULL, const char *ttitle=NULL);
    void AddContainer(MParContainer *cont,
                      const char *tname=NULL, const char *ttitle=NULL);

    ClassDef(MWriteRootFile, 0)	// Class to write one container to an ascii file
};

#endif
