#ifndef __HPARTICLEPAIRMAKER_H__
#define __HPARTICLEPAIRMAKER_H__
#include "hparticledef.h"
#include "hparticlepair.h"
#include "hparticlecand.h"
#include "hparticletool.h"
#include "hphysicsconstants.h"
#include "heventheader.h"
#include "TObject.h"
#include "TLorentzVector.h"
#include <vector>
#include <map>
#include <iostream>
#include <iomanip>
using namespace std;
class HParticlePairMaker : public TObject
{
private:
    vector<HParticleCand*> freference;                    
    vector<HParticleCand*> fothers;                       
    vector<HParticleCand*> ffullrecoOthers;               
    vector<HParticleCand*> fnofullrecoOthers;             
    vector<HParticlePair>  fpairs;                        
    map<Int_t, vector<HParticleCand*> > mTofHittoCand;       
    map<Int_t, vector<HParticleCand*> > mTofClsttoCand;      
    map<Int_t, vector<HParticleCand*> > mRpcClsttoCand;      
    map<Int_t, vector<HParticleCand*> > mShowertoCand;       
    map<Int_t, vector<HParticleCand*> > mEmctoCand;          
    map<Int_t, vector<HParticleCand*> > mInnerMdctoCand;     
    map<Int_t, vector<HParticleCand*> > mOuterMdctoCand;     
    map<Int_t, vector<HParticleCand*> > mRichtoCand;         
    map<HVirtualCand*,vector<HParticlePair*> > mCandtoPair; 
    Bool_t (*fselectPID1)(HParticleCand*);                 
    Bool_t (*fselectPID2)(HParticleCand*);                 
    Bool_t (*fuserFilter)(HParticleCand*);                 
    Int_t fPID1;                                           
    Int_t fPID2;                                           
    Int_t fMotherPID;                                      
    Bool_t fuse_kIsLepton;                                 
    Bool_t fdoSkippedFullCandPairs;                        
    static Bool_t frequireRich;                            
    Int_t         fVertexCase;                            
    HGeomVector   fVertex;                                
    vector<UInt_t>  fCaseCt;                              
    vector<UInt_t>  fCaseVec;                             
    Int_t           richCandCt;                           
    void clearVectors();
    void bookHits(HParticleCand* cand1);
    void selectPID(HParticleCand* cand1,Int_t& pid1,Bool_t warn=kTRUE);
public:
    HParticlePairMaker();
    ~HParticlePairMaker();
    
    
    void setPIDs(Int_t pid1,Int_t pid2,Int_t motherpid) {
	fPID1      = pid1;
	fPID2      = pid2;
	fMotherPID = motherpid;
    }
    void setPIDsSelection(Bool_t (*selPID1)(HParticleCand*), Bool_t (*selPID2)(HParticleCand*)) {
	fselectPID1=selPID1;
        fselectPID2=selPID2;
    }
    void setUserFilter(Bool_t (*userfilter)(HParticleCand*)) {
	fuserFilter=userfilter;
    }
    void          setDoSkippedFullCandPairs(Bool_t doit) { fdoSkippedFullCandPairs = doit; }
    void          setUseLeptons (Bool_t use) { fuse_kIsLepton = use;}
    static void   setRequireRich(Bool_t use) { frequireRich = use;}
    static Bool_t getRequireRich()           { return frequireRich ;}
    void          setVertexCase(Particle::eVertex vertexCase) { fVertexCase =  vertexCase; };
    void          setVertex(HGeomVector& v)  { fVertex = v; fVertexCase = kVertexUser;}
    void          setVertex(HVertex& v)      { fVertex = v.getPos(); fVertexCase = kVertexUser;}
    static Bool_t selectPos(HParticleCand*);
    static Bool_t selectNeg(HParticleCand*);
    
    
    void nextEvent();
    vector<HParticleCand*>& getReferenceVector() { return freference; }
    vector<HParticleCand*>& getOthersVector   () { return fothers;    }
    vector<HParticlePair>&  getPairsVector    () { return fpairs;     }
    
    
    void  filterPairsVector(vector<HParticlePair*>& filterpairs,UInt_t flag=0);
    void  filterPairsVector(vector<HParticlePair*>& filterpairs,vector<UInt_t>& flags);
    Int_t filterCandidates (HVirtualCand* cand,vector<HVirtualCand*>& candidates,UInt_t flag=0,Float_t oAngle=-1);
    Int_t filterCandidates (HVirtualCand* cand,vector<HParticlePair*>& filterpairs,UInt_t flag=0,Float_t oAngle=-1);
    
    
    Int_t getSameRich    (HParticleCand* cand,vector<HParticleCand*>& candidates,UInt_t flag=0,Bool_t isReference = kTRUE);
    Int_t getSameInnerMdc(HParticleCand* cand,vector<HParticleCand*>& candidates,UInt_t flag=0,Bool_t isReference = kTRUE);
    Int_t getSameOuterMdc(HParticleCand* cand,vector<HParticleCand*>& candidates,UInt_t flag=0,Bool_t isReference = kTRUE);
    Int_t getSameMeta    (HParticleCand* cand,vector<HParticleCand*>& candidates,UInt_t flag=0,Bool_t isReference = kTRUE);
    void plotPairCaseStat();
    ClassDef(HParticlePairMaker,0)
};
#endif // __HPARTICLEPAIRMAKER_H__