#ifndef ROOT_TGeoCache
#define ROOT_TGeoCache
#ifndef ROOT_TGeoNode
#include "TGeoNode.h"
#endif
#ifndef ROOT_TGeoStateInfo
#include "TGeoStateInfo.h"
#endif
class TGeoManager;
class TGeoHMatrix;
class TGeoCacheState : public TObject
{
protected:
Int_t fCapacity;
Int_t fLevel;
Int_t fNmany;
Int_t fStart;
Int_t fIdBranch[30];
Double_t fPoint[3];
Bool_t fOverlapping;
TGeoNode **fNodeBranch;
TGeoHMatrix **fMatrixBranch;
TGeoHMatrix **fMatPtr;
TGeoCacheState(const TGeoCacheState&);
TGeoCacheState& operator=(const TGeoCacheState&);
public:
TGeoCacheState();
TGeoCacheState(Int_t capacity);
virtual ~TGeoCacheState();
void SetState(Int_t level, Int_t startlevel, Int_t nmany, Bool_t ovlp, Double_t *point=0);
Bool_t GetState(Int_t &level, Int_t &nmany, Double_t *point) const;
ClassDef(TGeoCacheState, 0)
};
class TGeoNodeCache : public TObject
{
private:
Int_t fGeoCacheMaxLevels;
Int_t fGeoCacheStackSize;
Int_t fGeoInfoStackSize;
Int_t fLevel;
Int_t fStackLevel;
Int_t fInfoLevel;
Int_t fCurrentID;
Int_t fIndex;
Int_t fIdBranch[100];
TString fPath;
TGeoNode *fTop;
TGeoNode *fNode;
TGeoHMatrix *fMatrix;
TObjArray *fStack;
TGeoHMatrix **fMatrixBranch;
TGeoHMatrix **fMPB;
TGeoNode **fNodeBranch;
TGeoStateInfo **fInfoBranch;
TGeoStateInfo *fPWInfo;
Int_t *fNodeIdArray;
TGeoNodeCache(const TGeoNodeCache&);
TGeoNodeCache& operator=(const TGeoNodeCache&);
public:
TGeoNodeCache();
TGeoNodeCache(TGeoNode *top, Bool_t nodeid=kFALSE, Int_t capacity=30);
virtual ~TGeoNodeCache();
void BuildIdArray();
void BuildInfoBranch();
void CdNode(Int_t nodeid);
Bool_t CdDown(Int_t index);
Bool_t CdDown(TGeoNode *node);
void CdTop() {fLevel=1; CdUp();}
void CdUp();
void FillIdBranch(const Int_t *br, Int_t startlevel=0) {memcpy(fIdBranch+startlevel,br,(fLevel+1-startlevel)*sizeof(Int_t)); fIndex=fIdBranch[fLevel];}
const Int_t *GetIdBranch() const {return fIdBranch;}
void *GetBranch() const {return fNodeBranch;}
void GetBranchNames(Int_t *names) const;
void GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers) const;
void GetBranchOnlys(Int_t *isonly) const;
void *GetMatrices() const {return fMatrixBranch;}
TGeoHMatrix *GetCurrentMatrix() const {return fMatrix;}
Int_t GetCurrentNodeId() const;
TGeoNode *GetMother(Int_t up=1) const {return ((fLevel-up)>=0)?fNodeBranch[fLevel-up]:0;}
TGeoHMatrix *GetMotherMatrix(Int_t up=1) const {return ((fLevel-up)>=0)?fMatrixBranch[fLevel-up]:0;}
TGeoNode *GetNode() const {return fNode;}
TGeoNode *GetTopNode() const {return fTop;}
TGeoStateInfo *GetInfo();
TGeoStateInfo *GetMakePWInfo(Int_t nd);
void ReleaseInfo();
Int_t GetLevel() const {return fLevel;}
const char *GetPath();
Int_t GetStackLevel() const {return fStackLevel;}
Int_t GetNodeId() const;
Bool_t HasIdArray() const {return (fNodeIdArray)?kTRUE:kFALSE;}
Bool_t IsDummy() const {return kTRUE;}
void LocalToMaster(const Double_t *local, Double_t *master) const;
void MasterToLocal(const Double_t *master, Double_t *local) const;
void LocalToMasterVect(const Double_t *local, Double_t *master) const;
void MasterToLocalVect(const Double_t *master, Double_t *local) const;
void LocalToMasterBomb(const Double_t *local, Double_t *master) const;
void MasterToLocalBomb(const Double_t *master, Double_t *local) const;
Int_t PushState(Bool_t ovlp, Int_t ntmany=0, Int_t startlevel=0, Double_t *point=0);
Bool_t PopState(Int_t &nmany, Double_t *point=0);
Bool_t PopState(Int_t &nmany, Int_t level, Double_t *point=0);
void PopDummy(Int_t ipop=9999) {fStackLevel=(ipop>fStackLevel)?(fStackLevel-1):(ipop-1);}
void Refresh() {fNode=fNodeBranch[fLevel]; fMatrix=fMatrixBranch[fLevel];}
Bool_t RestoreState(Int_t &nmany, TGeoCacheState *state, Double_t *point=0);
ClassDef(TGeoNodeCache, 0)
};
#endif