// @(#)root/geom:$Id$
// Author: Andrei Gheata   24/10/01

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TGeoNode
#define ROOT_TGeoNode

#ifndef ROOT_Riosfwd
#include "Riosfwd.h"
#endif

#ifndef ROOT_TGeoAtt
#include "TGeoAtt.h"
#endif

#ifndef ROOT_TNamed
#include "TNamed.h"
#endif

#ifndef ROOT_TGeoVolume
#include "TGeoVolume.h"
#endif

#ifndef ROOT_TGeoPatternFinder
#include "TGeoPatternFinder.h"
#endif

// forward declarations
class TString;
class TGeoVolume;
class TGeoShape;
class TGeoMedium;
class TGeoMatrix;
class TGeoHMatrix;
class TGeoExtension;

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// TGeoNode - base class for logical nodes. They represent volumes        //
//   positioned inside a mother volume                                    //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

class TGeoNode : public TNamed,
                 public TGeoAtt
{
protected:
   TGeoVolume       *fVolume;         // volume associated with this
   TGeoVolume       *fMother;         // mother volume
   Int_t             fNumber;         // copy number
   Int_t             fNovlp;          // number of overlaps
   Int_t            *fOverlaps;       //[fNovlp] list of indices for overlapping brothers
   TGeoExtension    *fUserExtension;  //! Transient user-defined extension to volumes
   TGeoExtension    *fFWExtension;    //! Transient framework-defined extension to volumes

   TGeoNode(const TGeoNode&);
   TGeoNode& operator=(const TGeoNode&);

public:
   enum {
      kGeoNodeMatrix = BIT(14),
      kGeoNodeOffset = BIT(15),
      kGeoNodeVC     = BIT(16),
      kGeoNodeOverlap = BIT(17),
      kGeoNodeCloned = BIT(18)
   };

   // constructors
   TGeoNode();
   TGeoNode(const TGeoVolume *vol);
   // destructor
   virtual ~TGeoNode();

   void              Browse(TBrowser *b);
   virtual void      cd() const {;}
   void              CheckOverlaps(Double_t ovlp=0.1, Option_t *option=""); // *MENU*
   void              CheckShapes();
   Int_t             CountDaughters(Bool_t unique_volumes=kFALSE);
   virtual Int_t     DistancetoPrimitive(Int_t px, Int_t py);
   void              Draw(Option_t *option="");
   void              DrawOnly(Option_t *option="");
   void              DrawOverlaps();
   virtual void      ExecuteEvent(Int_t event, Int_t px, Int_t py);
   void              FillIdArray(Int_t &ifree, Int_t &nodeid, Int_t *array) const;
   Int_t             FindNode(const TGeoNode *node, Int_t level);
   virtual Int_t     GetByteCount() const {return 44;}
   TGeoNode         *GetDaughter(Int_t ind) const {return fVolume->GetNode(ind);}
   virtual TGeoMatrix *GetMatrix() const = 0;

   Int_t             GetColour() const {return fVolume->GetLineColor();}
   virtual Int_t     GetIndex() const                    {return 0;}
   virtual TGeoPatternFinder *GetFinder() const          {return 0;}
   TGeoMedium       *GetMedium() const                   {return fVolume->GetMedium();}
   TGeoVolume       *GetMotherVolume() const             {return fMother;}
   Int_t             GetNdaughters() const {return fVolume->GetNdaughters();}
   TObjArray        *GetNodes() const {return fVolume->GetNodes();}
   Int_t             GetNumber() const {return fNumber;}
   Int_t            *GetOverlaps(Int_t &novlp) const {novlp=fNovlp; return fOverlaps;}
   TGeoVolume       *GetVolume() const                   {return fVolume;}
   virtual char     *GetObjectInfo(Int_t px, Int_t py) const;
   virtual Int_t     GetOptimalVoxels() const {return 0;}
   void              InspectNode() const; // *MENU*
   Bool_t            IsCloned() const {return TObject::TestBit(kGeoNodeCloned);}
   virtual Bool_t    IsFolder() const {return (GetNdaughters()?kTRUE:kFALSE);}
   Bool_t            IsOffset() const {return TObject::TestBit(kGeoNodeOffset);}
   Bool_t            IsOnScreen() const; // *MENU*
   Bool_t            IsOverlapping() const {return TObject::TestBit(kGeoNodeOverlap);}
   Bool_t            IsVirtual() const {return TObject::TestBit(kGeoNodeVC);}
   Bool_t            IsVisible() const {return (TGeoAtt::IsVisible() && fVolume->IsVisible());}
   Bool_t            IsVisDaughters() const {return (TGeoAtt::IsVisDaughters() && fVolume->IsVisDaughters());}
   Bool_t            MayOverlap(Int_t iother) const;

   virtual TGeoNode *MakeCopyNode() const {return 0;}
   Double_t          Safety(const Double_t *point, Bool_t in=kTRUE) const;
   void              SaveAttributes(std::ostream &out);
   void              SetCurrentPoint(Double_t x, Double_t y, Double_t z) {fVolume->SetCurrentPoint(x,y,z);}// *MENU*
   void              SetVolume(TGeoVolume *volume)       {fVolume = volume;}
   void              SetNumber(Int_t number)             {fNumber=number;}
   void              SetCloned(Bool_t flag=kTRUE)        {TObject::SetBit(kGeoNodeCloned, flag);}
   void              SetOverlapping(Bool_t flag=kTRUE)   {TObject::SetBit(kGeoNodeOverlap, flag);}
   void              SetVirtual()                        {TObject::SetBit(kGeoNodeVC, kTRUE);}
   void              SetVisibility(Bool_t vis=kTRUE); // *MENU*
   void              SetInvisible()                      {SetVisibility(kFALSE);} // *MENU*
   void              SetAllInvisible()                   {VisibleDaughters(kFALSE);} // *MENU*
   void              SetMotherVolume(TGeoVolume *mother) {fMother = mother;}
   void              SetOverlaps(Int_t *ovlp, Int_t novlp);
   void              SetUserExtension(TGeoExtension *ext);
   void              SetFWExtension(TGeoExtension *ext);
   TGeoExtension    *GetUserExtension() const {return fUserExtension;}
   TGeoExtension    *GetFWExtension() const   {return fFWExtension;}
   TGeoExtension    *GrabUserExtension() const;
   TGeoExtension    *GrabFWExtension() const;

   virtual void      MasterToLocal(const Double_t *master, Double_t *local) const;
   virtual void      MasterToLocalVect(const Double_t *master, Double_t *local) const;
   virtual void      LocalToMaster(const Double_t *local, Double_t *master) const;
   virtual void      LocalToMasterVect(const Double_t *local, Double_t *master) const;

   virtual void      ls(Option_t *option = "") const;
   virtual void      Paint(Option_t *option = "");
   void              PrintCandidates() const; // *MENU*
   void              PrintOverlaps() const; // *MENU*
   void              VisibleDaughters(Bool_t vis=kTRUE); // *MENU*

   ClassDef(TGeoNode, 2)               // base class for all geometry nodes
};

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// TGeoNodeMatrix - node containing a general transformation              //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

class TGeoNodeMatrix : public TGeoNode
{
private:
   TGeoMatrix       *fMatrix;         // transf. matrix of fNode in fMother system

protected:
   TGeoNodeMatrix(const TGeoNodeMatrix& gnm);
   TGeoNodeMatrix& operator=(const TGeoNodeMatrix& gnm);

public:
   // constructors
   TGeoNodeMatrix();
   TGeoNodeMatrix(const TGeoVolume *vol, const TGeoMatrix *matrix);
   // destructor
   virtual ~TGeoNodeMatrix();

   virtual Int_t     GetByteCount() const;
   virtual Int_t     GetOptimalVoxels() const;
   virtual Bool_t    IsFolder() const {return kTRUE;}
   virtual TGeoMatrix *GetMatrix() const   {return fMatrix;}
   virtual TGeoNode *MakeCopyNode() const;
   void              SetMatrix(const TGeoMatrix *matrix);

   ClassDef(TGeoNodeMatrix, 1)               // a geometry node in the general case
};

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// TGeoNodeOffset - node containing only an translation offset            //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

class TGeoNodeOffset : public TGeoNode
{
private:
   Double_t          fOffset; // X offset for this node with respect to its mother
   Int_t             fIndex;  // index of this node in the division
   TGeoPatternFinder *fFinder; // finder for this node

protected:
   TGeoNodeOffset(const TGeoNodeOffset&);
   TGeoNodeOffset& operator=(const TGeoNodeOffset&);

public:
   // constructors
   TGeoNodeOffset();
   TGeoNodeOffset(const TGeoVolume *vol, Int_t index, Double_t offset);
   // destructor
   virtual ~TGeoNodeOffset();

   virtual void      cd() const           {fFinder->cd(fIndex);}
   Double_t          GetOffset() const {return fOffset;}
   virtual Int_t     GetIndex() const;
   virtual TGeoPatternFinder *GetFinder() const {return fFinder;}
   virtual TGeoMatrix *GetMatrix() const {cd(); return fFinder->GetMatrix();}
   virtual TGeoNode *MakeCopyNode() const;
   void              SetFinder(TGeoPatternFinder *finder) {fFinder = finder;}

   ClassDef(TGeoNodeOffset, 1)      // a geometry node with just an offset
};

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// TGeoIteratorPlugin - Plugin for a TGeoIterator providing the method    //
//                      ProcessNode each time Next is called.             //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

class TGeoIterator;

class TGeoIteratorPlugin : public TObject
{
protected:
   const TGeoIterator *fIterator;           // Caller iterator
private:
   // No copy
   TGeoIteratorPlugin(const TGeoIteratorPlugin &);
   TGeoIteratorPlugin &operator=(const TGeoIteratorPlugin &);
public:
   TGeoIteratorPlugin() : TObject(),fIterator(0) {}
   virtual ~TGeoIteratorPlugin() {}

   virtual void      ProcessNode() = 0;
   void              SetIterator(const TGeoIterator *iter) {fIterator = iter;}

   ClassDef(TGeoIteratorPlugin, 0)  // ABC for user plugins connecter to a geometry iterator.
};

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// TGeoIterator - iterator for the node tree                              //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

class TGeoIterator
{
private:
   TGeoVolume       *fTop;                  // Top volume of the iterated branch
   Bool_t            fMustResume;           // Private flag to resume from current node.
   Bool_t            fMustStop;             // Private flag to signal that the iterator has finished.
   Int_t             fLevel;                // Current level in the tree
   Int_t             fType;                 // Type of iteration
   Int_t            *fArray;                // Array of node indices for the current path
   TGeoHMatrix      *fMatrix;               // Current global matrix
   TString           fTopName;              // User name for top
   TGeoIteratorPlugin
                    *fPlugin;               // User iterator plugin
   Bool_t            fPluginAutoexec;       // Plugin automatically executed during next()

   void            IncreaseArray();
protected:
   TGeoIterator() : fTop(0), fMustResume(0), fMustStop(0), fLevel(0), fType(0),
                    fArray(0), fMatrix(0), fTopName(), fPlugin(0), fPluginAutoexec(kFALSE) { }

public:
   TGeoIterator(TGeoVolume *top);
   TGeoIterator(const TGeoIterator &iter);
   virtual          ~TGeoIterator();

   TGeoIterator   &operator=(const TGeoIterator &iter);
   TGeoNode       *operator()();
   TGeoNode       *Next();

   const TGeoMatrix *GetCurrentMatrix() const;
   Int_t           GetIndex(Int_t i) const {return ((i<=fLevel)?fArray[i]:-1);}
   Int_t           GetLevel() const {return fLevel;}
   TGeoNode       *GetNode(Int_t level) const;
   void            GetPath(TString &path) const;
   TGeoIteratorPlugin
                  *GetUserPlugin() const {return fPlugin;}

   TGeoVolume     *GetTopVolume() const {return fTop;}
   Int_t           GetType() const {return fType;}
   void            Reset(TGeoVolume *top=0);
   void            SetUserPlugin(TGeoIteratorPlugin *plugin);
   void            SetPluginAutoexec(Bool_t mode) {fPluginAutoexec = mode;}
   void            SetType(Int_t type) {fType = type;}
   void            SetTopName(const char* name);
   void            Skip();

   ClassDef(TGeoIterator,0)  //Iterator for geometry.
};

#endif
 TGeoNode.h:1
 TGeoNode.h:2
 TGeoNode.h:3
 TGeoNode.h:4
 TGeoNode.h:5
 TGeoNode.h:6
 TGeoNode.h:7
 TGeoNode.h:8
 TGeoNode.h:9
 TGeoNode.h:10
 TGeoNode.h:11
 TGeoNode.h:12
 TGeoNode.h:13
 TGeoNode.h:14
 TGeoNode.h:15
 TGeoNode.h:16
 TGeoNode.h:17
 TGeoNode.h:18
 TGeoNode.h:19
 TGeoNode.h:20
 TGeoNode.h:21
 TGeoNode.h:22
 TGeoNode.h:23
 TGeoNode.h:24
 TGeoNode.h:25
 TGeoNode.h:26
 TGeoNode.h:27
 TGeoNode.h:28
 TGeoNode.h:29
 TGeoNode.h:30
 TGeoNode.h:31
 TGeoNode.h:32
 TGeoNode.h:33
 TGeoNode.h:34
 TGeoNode.h:35
 TGeoNode.h:36
 TGeoNode.h:37
 TGeoNode.h:38
 TGeoNode.h:39
 TGeoNode.h:40
 TGeoNode.h:41
 TGeoNode.h:42
 TGeoNode.h:43
 TGeoNode.h:44
 TGeoNode.h:45
 TGeoNode.h:46
 TGeoNode.h:47
 TGeoNode.h:48
 TGeoNode.h:49
 TGeoNode.h:50
 TGeoNode.h:51
 TGeoNode.h:52
 TGeoNode.h:53
 TGeoNode.h:54
 TGeoNode.h:55
 TGeoNode.h:56
 TGeoNode.h:57
 TGeoNode.h:58
 TGeoNode.h:59
 TGeoNode.h:60
 TGeoNode.h:61
 TGeoNode.h:62
 TGeoNode.h:63
 TGeoNode.h:64
 TGeoNode.h:65
 TGeoNode.h:66
 TGeoNode.h:67
 TGeoNode.h:68
 TGeoNode.h:69
 TGeoNode.h:70
 TGeoNode.h:71
 TGeoNode.h:72
 TGeoNode.h:73
 TGeoNode.h:74
 TGeoNode.h:75
 TGeoNode.h:76
 TGeoNode.h:77
 TGeoNode.h:78
 TGeoNode.h:79
 TGeoNode.h:80
 TGeoNode.h:81
 TGeoNode.h:82
 TGeoNode.h:83
 TGeoNode.h:84
 TGeoNode.h:85
 TGeoNode.h:86
 TGeoNode.h:87
 TGeoNode.h:88
 TGeoNode.h:89
 TGeoNode.h:90
 TGeoNode.h:91
 TGeoNode.h:92
 TGeoNode.h:93
 TGeoNode.h:94
 TGeoNode.h:95
 TGeoNode.h:96
 TGeoNode.h:97
 TGeoNode.h:98
 TGeoNode.h:99
 TGeoNode.h:100
 TGeoNode.h:101
 TGeoNode.h:102
 TGeoNode.h:103
 TGeoNode.h:104
 TGeoNode.h:105
 TGeoNode.h:106
 TGeoNode.h:107
 TGeoNode.h:108
 TGeoNode.h:109
 TGeoNode.h:110
 TGeoNode.h:111
 TGeoNode.h:112
 TGeoNode.h:113
 TGeoNode.h:114
 TGeoNode.h:115
 TGeoNode.h:116
 TGeoNode.h:117
 TGeoNode.h:118
 TGeoNode.h:119
 TGeoNode.h:120
 TGeoNode.h:121
 TGeoNode.h:122
 TGeoNode.h:123
 TGeoNode.h:124
 TGeoNode.h:125
 TGeoNode.h:126
 TGeoNode.h:127
 TGeoNode.h:128
 TGeoNode.h:129
 TGeoNode.h:130
 TGeoNode.h:131
 TGeoNode.h:132
 TGeoNode.h:133
 TGeoNode.h:134
 TGeoNode.h:135
 TGeoNode.h:136
 TGeoNode.h:137
 TGeoNode.h:138
 TGeoNode.h:139
 TGeoNode.h:140
 TGeoNode.h:141
 TGeoNode.h:142
 TGeoNode.h:143
 TGeoNode.h:144
 TGeoNode.h:145
 TGeoNode.h:146
 TGeoNode.h:147
 TGeoNode.h:148
 TGeoNode.h:149
 TGeoNode.h:150
 TGeoNode.h:151
 TGeoNode.h:152
 TGeoNode.h:153
 TGeoNode.h:154
 TGeoNode.h:155
 TGeoNode.h:156
 TGeoNode.h:157
 TGeoNode.h:158
 TGeoNode.h:159
 TGeoNode.h:160
 TGeoNode.h:161
 TGeoNode.h:162
 TGeoNode.h:163
 TGeoNode.h:164
 TGeoNode.h:165
 TGeoNode.h:166
 TGeoNode.h:167
 TGeoNode.h:168
 TGeoNode.h:169
 TGeoNode.h:170
 TGeoNode.h:171
 TGeoNode.h:172
 TGeoNode.h:173
 TGeoNode.h:174
 TGeoNode.h:175
 TGeoNode.h:176
 TGeoNode.h:177
 TGeoNode.h:178
 TGeoNode.h:179
 TGeoNode.h:180
 TGeoNode.h:181
 TGeoNode.h:182
 TGeoNode.h:183
 TGeoNode.h:184
 TGeoNode.h:185
 TGeoNode.h:186
 TGeoNode.h:187
 TGeoNode.h:188
 TGeoNode.h:189
 TGeoNode.h:190
 TGeoNode.h:191
 TGeoNode.h:192
 TGeoNode.h:193
 TGeoNode.h:194
 TGeoNode.h:195
 TGeoNode.h:196
 TGeoNode.h:197
 TGeoNode.h:198
 TGeoNode.h:199
 TGeoNode.h:200
 TGeoNode.h:201
 TGeoNode.h:202
 TGeoNode.h:203
 TGeoNode.h:204
 TGeoNode.h:205
 TGeoNode.h:206
 TGeoNode.h:207
 TGeoNode.h:208
 TGeoNode.h:209
 TGeoNode.h:210
 TGeoNode.h:211
 TGeoNode.h:212
 TGeoNode.h:213
 TGeoNode.h:214
 TGeoNode.h:215
 TGeoNode.h:216
 TGeoNode.h:217
 TGeoNode.h:218
 TGeoNode.h:219
 TGeoNode.h:220
 TGeoNode.h:221
 TGeoNode.h:222
 TGeoNode.h:223
 TGeoNode.h:224
 TGeoNode.h:225
 TGeoNode.h:226
 TGeoNode.h:227
 TGeoNode.h:228
 TGeoNode.h:229
 TGeoNode.h:230
 TGeoNode.h:231
 TGeoNode.h:232
 TGeoNode.h:233
 TGeoNode.h:234
 TGeoNode.h:235
 TGeoNode.h:236
 TGeoNode.h:237
 TGeoNode.h:238
 TGeoNode.h:239
 TGeoNode.h:240
 TGeoNode.h:241
 TGeoNode.h:242
 TGeoNode.h:243
 TGeoNode.h:244
 TGeoNode.h:245
 TGeoNode.h:246
 TGeoNode.h:247
 TGeoNode.h:248
 TGeoNode.h:249
 TGeoNode.h:250
 TGeoNode.h:251
 TGeoNode.h:252
 TGeoNode.h:253
 TGeoNode.h:254
 TGeoNode.h:255
 TGeoNode.h:256
 TGeoNode.h:257
 TGeoNode.h:258
 TGeoNode.h:259
 TGeoNode.h:260
 TGeoNode.h:261
 TGeoNode.h:262
 TGeoNode.h:263
 TGeoNode.h:264
 TGeoNode.h:265
 TGeoNode.h:266
 TGeoNode.h:267
 TGeoNode.h:268
 TGeoNode.h:269
 TGeoNode.h:270
 TGeoNode.h:271
 TGeoNode.h:272
 TGeoNode.h:273
 TGeoNode.h:274
 TGeoNode.h:275
 TGeoNode.h:276
 TGeoNode.h:277
 TGeoNode.h:278
 TGeoNode.h:279
 TGeoNode.h:280
 TGeoNode.h:281
 TGeoNode.h:282
 TGeoNode.h:283
 TGeoNode.h:284
 TGeoNode.h:285
 TGeoNode.h:286
 TGeoNode.h:287
 TGeoNode.h:288
 TGeoNode.h:289
 TGeoNode.h:290
 TGeoNode.h:291
 TGeoNode.h:292
 TGeoNode.h:293
 TGeoNode.h:294
 TGeoNode.h:295
 TGeoNode.h:296
 TGeoNode.h:297
 TGeoNode.h:298
 TGeoNode.h:299
 TGeoNode.h:300
 TGeoNode.h:301
 TGeoNode.h:302
 TGeoNode.h:303
 TGeoNode.h:304