#ifndef LCDFASTMC_H
#define LCDFASTMC_H

#include "LCDEventMarker.h"
#include "LCDMCPartPrint.h"
#include "LCDIPSmear.h"
#include "LCDTrackFullSmear.h"
#include "LCDCalRecon.h"
#include "LCDRecModule.h"
#include "LCDEventSource.h"
#include "LCDEvent.h"
#include "LCDGetParameters.h"

#include "TObject.h"
#include "TObjArray.h"
#include "TFile.h"
#include "TTree.h"
#include <stdio.h>

class LCDFastMC : public TObject {

 private:

  LCDEvent* m_event;
  LCDEventSource*    m_source;     // e.g., base class that can produce events
  TObjArray          m_ModuleList; // processors which have signed up
  TObjArrayIter*     m_iter;       // iterate through m_ModuleList
  LCDRecModule*      m_module;
  LCDEventMarker*    m_eventMarker;   // our instance of EventMarker
  LCDMCPartPrint*    m_mcPartPrint;   // our instance of MCPartPrint
  LCDTrackFullSmear* m_trackFullSmear;// our instance of TrackFullSmear
  LCDIPSmear*        m_ipSmear;       // our instance of IPSmear
  LCDCalRecon*       m_calRecon;      // our instance of CalRecon
  //FILE* m_ofile;       
  TFile *m_ofile;      // output file
  TTree *m_tree;
  FILE* m_geomfile;    // detector parameter file
  LCDGetParameters* m_gp;

  void Init();

 public:
  LCDFastMC();
  LCDFastMC(LCDEventSource* eventSource,
	    LCDGetParameters* gp,
	    Char_t* smearFileName,
	    Char_t* outputFileName);

  LCDFastMC(LCDEventSource* eventSource,
	    Char_t* geometryFileName,
	    Char_t* smearFileName,
	    Char_t* outputFileName);

  ~LCDFastMC();

  void  CreateModules(LCDGetParameters* gp, Char_t* fname);
  void  SetSource(LCDEventSource* eventSource) {m_source = eventSource;}
  Int_t DoEventBatch();
  Int_t FetchEvent(LCDEvent *evt);
  void  Doit(LCDEvent *evt); // call doit for each module
  void  Spew();              // call spew for each module
  void  Cleanup();           // call cleanup for each module
  void  OutputFile();        // Output root file

  LCDCalRecon* GetCalRecon() {return m_calRecon;}
  LCDGetParameters* GetParameters() { return m_gp; }

  void SetNoClusterMerge();

  // Set sigma of the IP smearing
  void SetIPSigmaX(Double_t s_x){ m_ipSmear->SetSigmaX(s_x);}
  void SetIPSigmaY(Double_t s_y){ m_ipSmear->SetSigmaY(s_y);}
  void SetIPSigmaZ(Double_t s_z){ m_ipSmear->SetSigmaZ(s_z);}

  void SetFastMC(LCDEventSource* eventSource,
		 LCDGetParameters* gp,
		 Char_t* smearFileName,
		 Char_t* outputFileName);

  void SetFastMC(LCDEventSource* eventSource,
		 Char_t* geometryFileName,
		 Char_t* smearFileName,
		 Char_t* outputFileName);

  ClassDef(LCDFastMC,0)  // Manager class for Fast MC 
};
#endif
