// $Id: ICOMETOutput.hxx,v 1.9 2011/05/06 16:05:36 mcgrew Exp $
#ifndef TCOMETOutput_hxx_seen
#define TCOMETOutput_hxx_seen

#include <TROOT.h>
#include <TFile.h>

#include <EoaCore.hxx>

class TTree;
class TGeoManager;

namespace COMET {
    class ICOMETEvent;
    class ICOMETOutput;
    class IFieldDescription;

    /// Base class for output errors.
    OA_EXCEPTION(ECOMETOutput, EoaCore);

    /// An error occurred during WriteEvent.
    OA_EXCEPTION(ECOMETOutputWriteFailed, ECOMETOutput);
}

/// The preferred file name extension for COMET event files.
#define ROOT_OUTPUT_PREFERRED_EXTENSION ".event"

/// Attach to a file so that the events can be written.  This can also write
/// the geometry to the output file.  This will work with any file name, but
/// the preferred file extension is [name].root (using this extension will
/// help root identify this file as a COMET event file).
class COMET::ICOMETOutput : public TFile {

    // Let ICOMETOutputMerged access its members
    friend class ICOMETOutputMerged;

public:
    /// Open a new output file.
    ICOMETOutput(const char* name,
                Option_t* opt="CREATE",
                Int_t compress = 1);

    virtual ~ICOMETOutput(void);

    /// Return the name of the output file.
    virtual const char* GetOutputName(void) {return GetName();};

    /// Return true if the file is attached and ready for writting.
    virtual bool IsAttached(void);

    /// Return the number of events written to the output file.
    virtual int GetEventsWritten(void);
    
    /// Write an event to the current output file. 
    virtual void WriteEvent(ICOMETEvent& event);
    
    /// Write the geometry data base to the output file.
    virtual void WriteGeometry(TGeoManager* geom);

    /// Write the fieldmap description to the output file.
    virtual void WriteEMField(COMET::IFieldDescription* field);

    /// Return a flag indicating whether or not a geometry record has already
    /// been saved to the output file.
    virtual bool GeometryWritten(void);

    /// Return a flag indicating whether or not an EM Fieldmap record has already
    /// been saved to the output file.
    virtual bool EMFieldWritten(void);

    /// Make sure that all of the events currently in memory are flushed to
    /// the output file.
    virtual void Commit(void);
    
    /// Close the ROOT output file.  No default parameter since there
    /// must be a Close(void) function to satisfy the ICOMETOutput
    /// abstract class which defines a pure virtual Close(void).
    virtual void Close(Option_t* opt = "");
    
private:
    ICOMETOutput(const ICOMETOutput& aFile);
    
    TTree *fEventTree;          // The tree with events. 
    ICOMETEvent *fEventPointer; // A memory location for the event pointer.
    
    bool fAttached;             // True if the file is ready for writing.
    int fEventsWritten;         // Number of events written to file.
    TGeoManager* fGeometry;     // The geometry saved in the output file.
    COMET::IFieldDescription* fFieldDescription;     // The fieldmap saved in the output file.

    ClassDef(ICOMETOutput,0);
};
#endif