#ifndef StHbtEvent_hh
#define StHbtEvent_hh

#include "StHbtMaker/Infrastructure/StHbtTypes.hh"
#include "StHbtMaker/Infrastructure/StHbtTrackCollection.hh"
#include "StHbtMaker/Infrastructure/StHbtV0Collection.hh"
#include "StHbtMaker/Infrastructure/StHbtXiCollection.hh"
#include "StHbtMaker/Infrastructure/StHbtKinkCollection.hh"

#include "StMuDSTMaker/COMMON/StMuPrimaryVertex.h"
#include "StBTofHeader.h"
#include "StMuDSTMaker/COMMON/StMuBTofPidTraits.h"
#include "StMuDSTMaker/COMMON/StMuBTofHit.h"
#include "TLorentzVector.h"
#include <vector>

class StHbtTrackCut;
class StHbtV0Cut;
class StHbtXiCut;
class StHbtKinkCut;
#ifdef __ROOT__
class StHbtTTreeEvent;
class StMuDst;
#endif

class StHbtEvent{

public:
  StHbtEvent();
#ifdef __ROOT__
  StHbtEvent(const StHbtTTreeEvent* ); 
  StHbtEvent(const StMuDst*, int trackType );
  StHbtEvent(const StMuDst*, int trackType, bool readV0Daughters);
#endif
  StHbtEvent(const StHbtEvent&, StHbtTrackCut* =0, StHbtV0Cut* =0,  StHbtXiCut* =0, StHbtKinkCut* =0); // copy constructor with track and v0 cuts
  ~StHbtEvent();
  void RotateZ(const double);

  ///////////////
  //  Getters  //
  ///////////////
  unsigned short RefMult() const {return mUncorrectedNumberOfPrimaries;}
  unsigned int CorrectedNumberOfPrimaries() const {return mCorrectedNumberOfPrimaries;} //From StRefMultCorr
  unsigned int RefMultCorr() const {return mCorrectedNumberOfPrimaries;}                //From StRefMultCorr
  float VpdVz() const {return mVpdVz;}
  int EventNumber() const {return mEventNumber;}
  int RunNumber() const   {return mRunNumber;}
  unsigned int CtbMult() const {return mCtbMultiplicity;}
  unsigned int ZdcAdcEast() const {return mZdcAdc[0];}
  unsigned int ZdcAdcWest() const {return mZdcAdc[1];}
  int NumberOfTpcHits() const {return mTpcNhits;}
  unsigned short NumberOfTracks() const {return mNumberOfTracks;}
  unsigned short NumberOfGoodTracks() const {return mNumberOfGoodTracks;}
  unsigned int UncorrectedNumberOfPositivePrimaries() const {return mUncorrectedNumberOfPositivePrimaries;}
  unsigned int UncorrectedNumberOfNegativePrimaries() const {return mUncorrectedNumberOfNegativePrimaries;}
  unsigned int UncorrectedNumberOfPrimaries() const {return mUncorrectedNumberOfPrimaries;}
  float ReactionPlane(const int& wgt=0) const;
  float ReactionPlaneError(const int& wgt=0) const;
  float ReactionPlaneSubEventDifference(const int& wgt=0) const;
  StHbtThreeVector PrimVertPos() const {return mPrimVertPos;}
  StHbtV0Collection* V0Collection() const {return mV0Collection;}
  StHbtXiCollection* XiCollection() const {return mXiCollection;}
  StHbtKinkCollection* KinkCollection() const {return mKinkCollection;}
  StHbtTrackCollection* TrackCollection() const {return mTrackCollection;}
  double MagneticField() const {return mMagneticField;}
  unsigned int TriggerWord() const {return mTriggerWord;}
  unsigned int TriggerActionWord() const {return mTriggerActionWord;}
  unsigned int L3TriggerAlgorithm(const unsigned int& i) const {return mL3TriggerAlgorithm[i];}
  const double ZdcCoincidenceRate(void) const {return mZdcCoincidenceRate;}
  const double BbcCoincidenceRate(void) const {return mBbcCoincidenceRate;}
  int Cent9() const {return (int)mCent9;}
  int Cent16() const {return (int)mCent16;}
  bool IsSimulation() const {return mIsSim;}

  ///////////////
  //  Setters  //
  ///////////////
  void SetEventNumber(const int& e) {mEventNumber = e;}
  void SetRunNumber(const int& n)   {mRunNumber = n;}
  void SetCtbMult(const unsigned int& m) {mCtbMultiplicity = m;}
  void SetZdcAdcEast(const unsigned int& a) {mZdcAdc[0] = a;}
  void SetZdcAdcWest(const unsigned int& a) {mZdcAdc[1] = a;}
  void SetNumberOfTpcHits(const int& m) {mTpcNhits = m;}
  void SetNumberOfTracks(const unsigned short& n)  {mNumberOfTracks = n;}
  void SetNumberOfGoodTracks(const unsigned short& n) {mNumberOfGoodTracks = n;}
  void SetUncorrectedNumberOfPositivePrimaries(const unsigned int& n) {mUncorrectedNumberOfPositivePrimaries = (unsigned short)n;}
  void SetUncorrectedNumberOfNegativePrimaries(const unsigned int& n) {mUncorrectedNumberOfNegativePrimaries = (unsigned short)n;}
  void SetUncorrectedNumberOfPrimaries(const unsigned int& n) {mUncorrectedNumberOfPrimaries = (unsigned short)n;}
  void SetReactionPlane(const float& rp,const int& wgt = 0);
  void SetReactionPlaneError(const float& rp, const int& wgt=0);
  void SetReactionPlaneSubEventDifference(const float& rp, const int& wgt=0);
  void SetPrimVertPos(const StHbtThreeVector& p) {mPrimVertPos = p;}
  void SetMagneticField(const double& f)  {mMagneticField = (float)f;}
  void SetMagneticField(const float& f)  {mMagneticField = f;}
  void SetTriggerWord(const unsigned int& w) {mTriggerWord = w;}
  void SetTriggerActionWord(const unsigned int& w) {mTriggerActionWord = w;}
  void SetL3TriggerAlgorithm(const unsigned int& i, const unsigned int& t) {mL3TriggerAlgorithm[i] = t;}
  void SetZdcCoincidenceRate(const double x) {mZdcCoincidenceRate = x;}
  void SetBbcCoincidenceRate(const double x) {mBbcCoincidenceRate = x;}
  void SetCent9(int cent) { mCent9 = (unsigned char)cent; }
  void SetCent16(int cent) { mCent16 = (unsigned char)cent; }
  void SetCent9(unsigned short cent) { mCent9 = (unsigned char)cent; }
  void SetCent16(unsigned short cent) { mCent16 = (unsigned char)cent; }
  void SetSimulation(bool sim) {mIsSim = sim;}
  void SetRefMultCorr(float val) {mCorrectedNumberOfPrimaries = (unsigned int)val;}
  void SetCorrectedNumberOfPrimaries(float val) {mCorrectedNumberOfPrimaries = (unsigned short)val;}
  void SetVpdVz(const float& vz) {mVpdVz = vz;}

  // For I/O of this object -- functions defined in StHbtIO.cc
  friend ostream& operator<<(ostream& out, StHbtEvent& ev);
  friend istream& operator>>(istream& in,  StHbtEvent& ev);

private:
  int        mEventNumber;       //gnigmat: Should be integer and not short
  int        mRunNumber;         //gnigmat: Should be integer and not short!
  unsigned int mCtbMultiplicity; // Central Trigger Barrel
  unsigned int mZdcAdc[2];       // Zero-degree calorimeter 
                                         //values east/west
  int mTpcNhits;                         // number of TPC hits
  unsigned short mNumberOfTracks;        // total number of TPC tracks
  unsigned short mNumberOfGoodTracks;    // number of "good" tracks
  unsigned short mUncorrectedNumberOfPositivePrimaries;
  unsigned short mUncorrectedNumberOfNegativePrimaries;
  unsigned short mUncorrectedNumberOfPrimaries;      //RefMult
  unsigned short mCorrectedNumberOfPrimaries;        //after StRefMultCorr
  float mReactionPlane[2];                //reaction plane/error
  float mReactionPlanePtWgt[2];           //reaction plane/error with pT weight
  float mMagneticField;                  // magnetic field in Z direction
  unsigned int mTriggerWord;
  unsigned int mTriggerActionWord;
  unsigned int mL3TriggerAlgorithm[4];
  double mZdcCoincidenceRate;             // for StRefMultCorr's centrality determination
  double mBbcCoincidenceRate;             // for StRefMultCorr's centrality determination
  unsigned char mCent9;
  unsigned char mCent16;
  bool mIsSim;

  float mVpdVz;
  StMuPrimaryVertex*  mPrimVert;
  StMuTrack*          mMuTrack;

  StHbtThreeVector mPrimVertPos;
  StHbtTrackCollection* mTrackCollection;
  StHbtV0Collection* mV0Collection;
  StHbtXiCollection* mXiCollection;
  StHbtKinkCollection* mKinkCollection;

  friend class StHbtIOBinary;
  friend class StHbtTTreeEvent;
  friend class StHbtTTreeTrack;
  friend class StHbtTTreeV0;
  friend class StHbtTTreeXi;
  friend class StHbtTTreeKink;
};

#endif 
