#ifndef HEPROOTFILEMANAGER_H
#define HEPROOTFILEMANAGER_H

// ----------------------------------------------------------------------
//
// HepRootFileManager.h - header file for the wrapper for the Nirvana
//   Rootscope package
//
// HepRootFileManager is a C++ wrapper class that controls the
// initialization and creation of histograms and ntuples and allows
// them to be written to a file in the Root format.
//
// This class is derived from the HepFileManager, and is not an abstract
// class. It should be instantiated before any histograms or ntuples - a
// pointer to the manager is passed to every histogram and ntuple upon
// creation.
//
// Usage of the class:
//
//   HepFileManager* m = new HepRootFileManager("filename", "rootDirName");
//    :
//    :
//   [create histograms]
//
// write() writes the managed Root objects to a file, as does the
// destructor.
// dumpAllData() and clearAllData()  initiate calls of dumpData() or
// clearData() to all managed objects.
//
//
// History
//   30-Nov-1998  Philippe Canal   Initial draft
//   19-Mar-2001  Mark Fischler	   hepFileFormat()
//
// ----------------------------------------------------------------------

#ifndef ZMENVIRONMENT_H
  #include "ZMutility/ZMenvironment.h"
#endif

#include <string>

#include "HepTuple/HepFileManager.h"

#ifndef FIXEDTYPES_H
  #include "ZMutility/FixedTypes.h"
#endif
  
ZM_BEGIN_NAMESPACE( zmht )	/*  namespace zmht  {  */

class HepHist;
class HepRootHist1D;
class HepRootHist2D;
class HepRootHistProf;
class HepRootNtuple;
class HepFileSwitch;

class TFile;
class TDirectory;
class TObject;

class HepRootFileManager : public HepFileManager  {

  friend class HepTFile;

public:

  // constructor/destructor:   -----------------------------------------

  HepRootFileManager(               // constructor
    const std::string& fName        //   desired file name
  , const std::string& rootDir = "" //   desired name of root directory
  , int compression = 0             //   desired compression level
  );

  HepRootFileManager(               // constructor
    const std::string& fName        //   desired file name
  , HepFileManager::mode req_mode   //   desired opening mode
  , const std::string& rootDir = "" //   desired name of root directory
  , int compression = 0             //   desired compression level
  );

  virtual ~HepRootFileManager();   // destructor

  static void initialiseRoot();

  // directory manipulation a la HepRoot:  -------------------------------

  virtual void cd( const std::string & path = "" );    // change dir

  virtual void mkdir( const std::string & path ); // create a dir

  virtual std::string ls(                       // list a dir
    const std::string & path = ""
  , const std::string & opts = ""
  )  const;

  virtual void rmdir( const std::string & path, bool recursive = false ); 
  // delete a dir

  virtual void rm( int hid = 0 );          // delete a histogram or ntuple
  virtual void rm( const std::string & what );  // delete a histogram or ntuple

  virtual TFile* file() const;  // Return a pointer the manager file structure.

  // File Format: ---------------------------------------------------------

  HepTupleFileFormat hepFileFormat() const;

  // HepRoot file manipulation:  -----------------------------------------

  virtual void writeDirectory();     // write the managed objects to the file
  virtual int write();         // write the managed objects to the file
#ifdef LATER
  virtual void dumpAllData();  // call dumpData() for all tuples in the list
  virtual void clearAllData(); // call clearData() for all tuples in the list
#endif // LATER


  // Create HepRoot-specific histograms & Ntuples:  ----------------------

  virtual HepHist1D & hist1D(
    const std::string& title,
    const int nBins, const float low, const float high,
    const int id = 0
  );
  virtual HepHist2D & hist2D(
    const std::string& title,
    const int nBinsX, const float lowX, const float highX,
    const int nBinsY, const float lowY, const float highY,
    const int id = 0
  );
  virtual HepHistProf & histProf(
    const std::string& title,
    const int nBinsX, const float lowX, const float highX,
    const float lowY, const float highY, const std::string& chopt,
    const int id = 0
  );
  virtual HepHistProf & histProf(
    const std::string& title,
    const int nBinsX, const float lowX, const float highX,
    const float lowY, const float highY,
    const int id = 0
  );
  virtual HepNtuple & ntuple(
    const std::string& title,
    const int hid = 0
  );

  // attach to existing histograms & Ntuples:
  virtual HepHist1D & retrieveHist1D(        // 1-D
    const std::string& title,
    const int hid = 0
  );
  virtual HepHist2D & retrieveHist2D(        // 2-D
    const std::string& title,
    const int hid = 0
  );
  virtual HepHistProf & retrieveHistProf(    // profile plot
    const std::string& title,
    const int hid = 0
  );
  virtual HepNtuple & retrieveNtuple(
    const std::string& title,
    const int hid = 0
  );

  // user is finished with the indicated object
  virtual void release( HepObj & me );

  // For Unmanaged Root Items.

  static HepRootNtuple& deadRootNtuple() ;
  static HepRootHist1D& deadRootHist1D() ;
  static HepRootHist2D& deadRootHist2D() ;
  static HepRootHistProf& deadRootHistProf() ;

  // For transparently switching output files at user request.
  // Implemented for the Root manager only!
  virtual bool switchFile( const std::string& newFileName,
                           const bool resetHists );

  // For transparently switching output files at user request with a user
  // supplied handler to deal with stray TObjects.
  // Implemented for the Root manager only!
  virtual bool switchFile( const std::string& newFileName,
                           const bool resetHists,
                           HepFileSwitch& userHandler );

protected:
  void init(              // constructor body (shared by both constructors)
    const std::string& fName        //   desired file name
  , HepFileManager::mode req_mode   //   desired opening mode
  , const std::string& rootDir      //   desired name of root directory
  , int compression                 //   desired compression level
  );

  static bool init_done;
  void retrieveExistingItems();        // make C++ objects out of items in
                                       // an existing file
  virtual void writeOne( HepObj * o );

  // Root specific helper routines.

  std::string inFileRootPath( const std::string& path ) const;
  const std::string& CurrentRootPath() const;

  // Dead Object creators
  virtual HepNtuple& deadNtuple() const;
  virtual HepHist1D& deadHist1D() const;
  virtual HepHist2D& deadHist2D() const;
  virtual HepHistProf& deadHistProf() const;

  bool cloneDir( TDirectory* oldFile, TDirectory* newFile,
                 std::vector<void*>& strays, bool resetHists );

  TFile * filep_;

private:

  Int4 compression_;
  Int4 writeOption_;

};  // HepRootFileManager


ZM_END_NAMESPACE( zmht )	/*  }  // namespace zmht  */


#endif  // HEPROOTFILEMANAGER_H
