#ifndef HEPHBOOKFILEMANAGER_H
#define HEPHBOOKFILEMANAGER_H

// ----------------------------------------------------------------------
//
// HepHBookFileManager.h - header file for the wrapper for the CERNlib
//   HBook histogram Fortran package
//
// HepHBookFileManager 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 HBook 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 HepHBookFileManager("filename", "rootDirName");
//    :
//    :
//   [create histograms]
//
// write() writes the managed HBook objects to a file, as does the
// destructor.
// dumpAllData() and clearAllData()  initiate calls of dumpData() or
// clearData() to all managed objects.
//
// Storage for HBook is initialized in the routine "hbfinit" in
// HepHBookFile.f. You will need to override this routine if you need
// more space.
//
//
// History
//   ??-Jul-1994  Paul Rensing     Initial draft
//   ??-Aug-1994  Bob Jacobsen     Added Histos and numbering
//   07-Feb-1997  John Marraffino  Added directory functionality
//   20-May-1997  Walter Brown     General cleanup
//   29-May-1997  Jason Luther     Added comments
//   04-Jun-1997  Jason Luther     Added usage to comments
//   27-Jun-1997  Walter Brown     Replaced HepString by standard string
//   18-Jul-1997  Philippe Canal   Added HepNtuple constructor
//   25-Jul-1997  Walter Brown     Added isOpen()
//   05-Aug-1997  Walter Brown     Added writeOne()
//   14-Aug-1997  Walter Brown     Added root directory name to the
//     constructor's arg list so as to conform more closely to the
//     base class constructor arg list; added release()
//   21-Aug-1997  Walter Brown     Renamed newX() to makeX() and oldX()
//     to retrieveX(); changed return values from pointers to references;
//     added retrieveNtuple() prototype
//   27-Aug-1997  Walter Brown     Renamed makeX() to x() per committee
//   11-Aug-1997  Walter Brown     Revised to excise vestiges of CLHEP
//    9-Oct-1997  Marraffino       Add code to re-instantiate an existing
//                                   ntuple from a file
//   31-Oct-1997  Philippe Canal   Add dummy object creator for use after
//                                 an ignored exceptions
//   21-Feb-2000  Walter Brown     Improved C++ standard compliance
//   19-Mar-2001  Mark Fischler	   Added hepFileFormat method
//
// ----------------------------------------------------------------------

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

#include <string>
#include <vector>

#include "HepTuple/HepFileManager.h"


ZM_BEGIN_NAMESPACE( zmht )	/*  namespace zmht  {  */

class HepHist;
class HepHBookHist1D;
class HepHBookHist2D;
class HepHBookHistProf;
class HepHBookNtuple;
class HepFileSwitch;

class HepHBookFileManager : public HepFileManager  {

public:

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

  HepHBookFileManager(                  // constructor
    const std::string& fName            //   desired file name
  , const std::string& rootDir = ""     //   desired name of root directory
  , const std::string& gSect = ""       //   4-character global section name
  );

  HepHBookFileManager(                  // constructor
    const std::string& fName            //   desired file name
  , HepFileManager::mode req_mode       //   desired opening mode
  , const std::string& rootDir = ""     //   desired name of root directory
  , const std::string& gSect = ""       //   4-character global section name
  );

  HepHBookFileManager(                  // constructor
    const std::string& fName            //   desired file name
  , const int record_length             //   desired HBOOK record length
                                        //      (for new file only).
  , const std::string& rootDir = ""     //   desired name of root directory
  , const std::string& gSect = ""       //   4-character global section name
  );

  HepHBookFileManager(                  // constructor
    const std::string& fName            //   desired file name
  , HepFileManager::mode req_mode       //   desired opening mode
  , const int record_length             //   desired HBOOK record length
                                        //      (for new file only).
  , const std::string& rootDir = ""     //   desired name of root directory
  , const std::string& gSect = ""       //   4-character global section name
  );

  virtual ~HepHBookFileManager();   // destructor

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

  HepTupleFileFormat hepFileFormat() const;

  // directory manipulation a la HepHBook:  -------------------------------

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

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

  virtual HepFileManager::ItemList list(          // make an itemlist
    const std::string & path = ""
  , const std::string & opts = ""
  )  const;

  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


  // HepHBook 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 HepHBook-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 HBook Items.

  static HepHBookNtuple& deadHBookNtuple() ;
  static HepHBookHist1D& deadHBookHist1D() ;
  static HepHBookHist2D& deadHBookHist2D() ;
  static HepHBookHistProf& deadHBookHistProf() ;

  // For transparently switching output files at user request.
  // Implemented only for the Root Manager.
  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
  , const std::string& gSect            //   4-character global section name
  , int record_length                   //   HBook record length(for new file)
  );

  static bool init_done;
  static int  lun_;                    // placeholder only; mainly obviated
				       // by using "C" option in hropen_()

  void retrieveExistingItems();        // make C++ objects out of items in
                                       // an existing file

  virtual void writeOne( HepObj * o );

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

  // Silence g++ complaints about various functions never being called
  void silenceCompiler();

private:
  bool isOpen;                         // used to avoid duplicate hrendc_ calls
  std::string hbook_ls(                     // internal implementation
    const std::string & path = ""
  , const std::string & opts = ""
  )  const;
};  // HepHBookFileManager

typedef HepHBookFileManager HBookFile; // preserve compatibility


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


#endif  // HEPHBOOKFILEMANAGER_H
