// @(#)root/gl:$Id$
// Author:  Richard Maunder  25/05/2005

/*************************************************************************
 * Copyright (C) 1995-2004, 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_TGLLogicalShape
#define ROOT_TGLLogicalShape

#ifndef ROOT_TGLBoundingBox
#include "TGLBoundingBox.h"
#endif

class TBuffer3D;
class TObject;
class TContextMenu;

class TGLPhysicalShape;
class TGLRnrCtx;
class TGLSelectRecord;
class TGLViewer;
class TGLSceneBase;
class TGLScene;


class TGLLogicalShape
{
   friend class TGLScene;

private:
   TGLLogicalShape(const TGLLogicalShape&);            // Not implemented.
   TGLLogicalShape& operator=(const TGLLogicalShape&); // Not implemented.

public:
   enum ELODAxes  { kLODAxesNone = 0,  // LOD will be set to high or pixel.
                    kLODAxesX    = 1 << 0,
                    kLODAxesY    = 1 << 1,
                    kLODAxesZ    = 1 << 2,
                    kLODAxesAll  = kLODAxesX | kLODAxesY | kLODAxesZ
                  };

protected:
   mutable UInt_t             fRef;           //! physical instance ref counting
   mutable TGLPhysicalShape  *fFirstPhysical; //! first replica

   TObject           *fExternalObj; //! Also plays the role of ID.
   TGLBoundingBox     fBoundingBox; //! Shape's bounding box.
   mutable TGLScene  *fScene;       //! scene where object is stored (can be zero!)
   mutable UInt_t     fDLBase;      //! display-list id base
   mutable Int_t      fDLSize;      //! display-list size for different LODs
   mutable UShort_t   fDLValid;     //! display-list validity bit-field
   mutable Bool_t     fDLCache;     //! use display list caching
   mutable Bool_t     fRefStrong;   //! Strong ref (delete on 0 ref); not in scene
   mutable Bool_t     fOwnExtObj;   //! External object is a fake

   void PurgeDLRange(UInt_t base, Int_t size) const;

   static  Bool_t     fgIgnoreSizeForCameraInterest;

public:
   TGLLogicalShape();
   TGLLogicalShape(TObject* obj);
   TGLLogicalShape(const TBuffer3D & buffer);
   virtual ~TGLLogicalShape();

   // Physical shape reference-counting, replica management
   UInt_t Ref() const { return fRef; }
   void   AddRef(TGLPhysicalShape* phys) const;
   void   SubRef(TGLPhysicalShape* phys) const;
   void   StrongRef(Bool_t strong) const { fRefStrong = strong; }
   void   DestroyPhysicals();
   UInt_t UnrefFirstPhysical();

   const TGLPhysicalShape* GetFirstPhysical() const { return fFirstPhysical; }

   TObject*  ID()          const { return fExternalObj; }
   TObject*  GetExternal() const { return fExternalObj; }
   TGLScene* GetScene()    const { return fScene; }

   const TGLBoundingBox& BoundingBox() const { return fBoundingBox; }
   virtual void          UpdateBoundingBox() {}
   void                  UpdateBoundingBoxesOfPhysicals();

   // Display List Caching
           Bool_t SetDLCache(Bool_t cached);
   virtual Bool_t ShouldDLCache(const TGLRnrCtx & rnrCtx) const;
   virtual UInt_t DLOffset(Short_t /*lod*/) const { return 0; }
   virtual void   DLCacheClear();
   virtual void   DLCacheDrop();
   virtual void   DLCachePurge();

   virtual ELODAxes SupportedLODAxes() const { return kLODAxesNone; }
   virtual Short_t  QuantizeShapeLOD(Short_t shapeLOD, Short_t combiLOD) const;
   virtual void     Draw(TGLRnrCtx& rnrCtx) const;
   virtual void     DirectDraw(TGLRnrCtx& rnrCtx) const = 0; // Actual draw method (non DL cached)

   virtual void     DrawHighlight(TGLRnrCtx& rnrCtx, const TGLPhysicalShape* pshp, Int_t lvl=-1) const;

   virtual Bool_t IgnoreSizeForOfInterest() const;

   // Override in sub-classes that do direct object rendering (e.g. TGLObject).
   virtual Bool_t KeepDuringSmartRefresh() const { return kFALSE; }
   // Override in sub-classes that support secondary selection (e.g. TPointSet3DGL).
   virtual Bool_t SupportsSecondarySelect() const { return kFALSE; }
   virtual Bool_t AlwaysSecondarySelect()   const { return kFALSE; }
   virtual void   ProcessSelection(TGLRnrCtx& rnrCtx, TGLSelectRecord& rec);

   void InvokeContextMenu(TContextMenu & menu, UInt_t x, UInt_t y) const;

   static Bool_t GetIgnoreSizeForCameraInterest();
   static void   SetIgnoreSizeForCameraInterest(Bool_t isfci);

   ClassDef(TGLLogicalShape,0) // a logical (non-placed, local frame) drawable object
};


#endif // ROOT_TGLLogicalShape
 TGLLogicalShape.h:1
 TGLLogicalShape.h:2
 TGLLogicalShape.h:3
 TGLLogicalShape.h:4
 TGLLogicalShape.h:5
 TGLLogicalShape.h:6
 TGLLogicalShape.h:7
 TGLLogicalShape.h:8
 TGLLogicalShape.h:9
 TGLLogicalShape.h:10
 TGLLogicalShape.h:11
 TGLLogicalShape.h:12
 TGLLogicalShape.h:13
 TGLLogicalShape.h:14
 TGLLogicalShape.h:15
 TGLLogicalShape.h:16
 TGLLogicalShape.h:17
 TGLLogicalShape.h:18
 TGLLogicalShape.h:19
 TGLLogicalShape.h:20
 TGLLogicalShape.h:21
 TGLLogicalShape.h:22
 TGLLogicalShape.h:23
 TGLLogicalShape.h:24
 TGLLogicalShape.h:25
 TGLLogicalShape.h:26
 TGLLogicalShape.h:27
 TGLLogicalShape.h:28
 TGLLogicalShape.h:29
 TGLLogicalShape.h:30
 TGLLogicalShape.h:31
 TGLLogicalShape.h:32
 TGLLogicalShape.h:33
 TGLLogicalShape.h:34
 TGLLogicalShape.h:35
 TGLLogicalShape.h:36
 TGLLogicalShape.h:37
 TGLLogicalShape.h:38
 TGLLogicalShape.h:39
 TGLLogicalShape.h:40
 TGLLogicalShape.h:41
 TGLLogicalShape.h:42
 TGLLogicalShape.h:43
 TGLLogicalShape.h:44
 TGLLogicalShape.h:45
 TGLLogicalShape.h:46
 TGLLogicalShape.h:47
 TGLLogicalShape.h:48
 TGLLogicalShape.h:49
 TGLLogicalShape.h:50
 TGLLogicalShape.h:51
 TGLLogicalShape.h:52
 TGLLogicalShape.h:53
 TGLLogicalShape.h:54
 TGLLogicalShape.h:55
 TGLLogicalShape.h:56
 TGLLogicalShape.h:57
 TGLLogicalShape.h:58
 TGLLogicalShape.h:59
 TGLLogicalShape.h:60
 TGLLogicalShape.h:61
 TGLLogicalShape.h:62
 TGLLogicalShape.h:63
 TGLLogicalShape.h:64
 TGLLogicalShape.h:65
 TGLLogicalShape.h:66
 TGLLogicalShape.h:67
 TGLLogicalShape.h:68
 TGLLogicalShape.h:69
 TGLLogicalShape.h:70
 TGLLogicalShape.h:71
 TGLLogicalShape.h:72
 TGLLogicalShape.h:73
 TGLLogicalShape.h:74
 TGLLogicalShape.h:75
 TGLLogicalShape.h:76
 TGLLogicalShape.h:77
 TGLLogicalShape.h:78
 TGLLogicalShape.h:79
 TGLLogicalShape.h:80
 TGLLogicalShape.h:81
 TGLLogicalShape.h:82
 TGLLogicalShape.h:83
 TGLLogicalShape.h:84
 TGLLogicalShape.h:85
 TGLLogicalShape.h:86
 TGLLogicalShape.h:87
 TGLLogicalShape.h:88
 TGLLogicalShape.h:89
 TGLLogicalShape.h:90
 TGLLogicalShape.h:91
 TGLLogicalShape.h:92
 TGLLogicalShape.h:93
 TGLLogicalShape.h:94
 TGLLogicalShape.h:95
 TGLLogicalShape.h:96
 TGLLogicalShape.h:97
 TGLLogicalShape.h:98
 TGLLogicalShape.h:99
 TGLLogicalShape.h:100
 TGLLogicalShape.h:101
 TGLLogicalShape.h:102
 TGLLogicalShape.h:103
 TGLLogicalShape.h:104
 TGLLogicalShape.h:105
 TGLLogicalShape.h:106
 TGLLogicalShape.h:107
 TGLLogicalShape.h:108
 TGLLogicalShape.h:109
 TGLLogicalShape.h:110
 TGLLogicalShape.h:111
 TGLLogicalShape.h:112
 TGLLogicalShape.h:113
 TGLLogicalShape.h:114
 TGLLogicalShape.h:115
 TGLLogicalShape.h:116
 TGLLogicalShape.h:117
 TGLLogicalShape.h:118
 TGLLogicalShape.h:119
 TGLLogicalShape.h:120
 TGLLogicalShape.h:121
 TGLLogicalShape.h:122