// @(#)root/eve:$Id$
// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

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

#include "TEveProjectionBases.h"
#include "TEveProjectionManager.h"
#include "TEveManager.h"

#include <cassert>

//==============================================================================
//==============================================================================
// TEveProjectable
//==============================================================================

//______________________________________________________________________________
//
// Abstract base-class for non-linear projectable objects.
//
// Via ProjectedClass(const TEveProjection* p) method it returns a
// TClass instance for the projected class and keeps references to the
// projected objects.
//
// It is assumed that all classes deriving from TEveProjectable are also
// derived from TEveElement.
//
// See also TEveProjectionManager::ImportElements().

ClassImp(TEveProjectable);

//______________________________________________________________________________
TEveProjectable::TEveProjectable()
{
   // Constructor.
}

//______________________________________________________________________________
TEveProjectable::~TEveProjectable()
{
   // Destructor.
   // Force projected replicas to unreference *this, then destroy them.

   while ( ! fProjectedList.empty())
   {
      TEveProjected* p = fProjectedList.front();
      p->UnRefProjectable(this);
      TEveElement* el = p->GetProjectedAsElement();
      assert(el);
      {
         gEve->PreDeleteElement(el);
         delete el;
      }
   }
}

//______________________________________________________________________________
void TEveProjectable::AnnihilateProjecteds()
{
   // Optimized destroy of projected elements with condition
   // there is only one parent for projected element. Method is
   // called from TEveElement::Annihilate().

   for (ProjList_i i=fProjectedList.begin(); i!=fProjectedList.end(); ++i)
   {
      (*i)->UnRefProjectable(this, kFALSE);
      (*i)->GetProjectedAsElement()->Annihilate();
   }
   fProjectedList.clear();
}

//______________________________________________________________________________
void TEveProjectable::ClearProjectedList()
{
   fProjectedList.clear();
}

//______________________________________________________________________________
void TEveProjectable::AddProjectedsToSet(std::set<TEveElement*>& set)
{
   // Add the projected elements to the set, dyn-casting them to
   // TEveElement.

   for (ProjList_i i=fProjectedList.begin(); i!=fProjectedList.end(); ++i)
   {
      set.insert((*i)->GetProjectedAsElement());
   }
}

//==============================================================================

//______________________________________________________________________________
void TEveProjectable::PropagateVizParams(TEveElement* el)
{
   // Set visualization parameters of projecteds.
   // Use element el as model. If el == 0 (default), this casted to
   // TEveElement is used.

   if (el == 0)
      el = dynamic_cast<TEveElement*>(this);

   for (ProjList_i i=fProjectedList.begin(); i!=fProjectedList.end(); ++i)
   {
      (*i)->GetProjectedAsElement()->CopyVizParams(el);
   }
}

//______________________________________________________________________________
void TEveProjectable::PropagateRenderState(Bool_t rnr_self, Bool_t rnr_children)
{
   // Set render state of projecteds.

   for (ProjList_i i=fProjectedList.begin(); i!=fProjectedList.end(); ++i)
   {
      if ((*i)->GetProjectedAsElement()->SetRnrSelfChildren(rnr_self, rnr_children))
         (*i)->GetProjectedAsElement()->ElementChanged();
   }
}

//______________________________________________________________________________
void TEveProjectable::PropagateMainColor(Color_t color, Color_t old_color)
{
   // Set main color of projecteds if their color is the same as old_color.

   for (ProjList_i i=fProjectedList.begin(); i!=fProjectedList.end(); ++i)
   {
      if ((*i)->GetProjectedAsElement()->GetMainColor() == old_color)
         (*i)->GetProjectedAsElement()->SetMainColor(color);
   }
}

//______________________________________________________________________________
void TEveProjectable::PropagateMainTransparency(Char_t t, Char_t old_t)
{
   // Set main transparency of projecteds if their transparecy is the
   // same as the old one.

   for (ProjList_i i=fProjectedList.begin(); i!=fProjectedList.end(); ++i)
   {
      if ((*i)->GetProjectedAsElement()->GetMainTransparency() == old_t)
         (*i)->GetProjectedAsElement()->SetMainTransparency(t);
   }
}


//==============================================================================
//==============================================================================
// TEveProjected
//==============================================================================

//______________________________________________________________________________
//
// Abstract base class for classes that hold results of a non-linear
// projection transformation.
//
// It is assumed that all classes deriving from TEveProjected are also
// derived from TEveElement.

ClassImp(TEveProjected);

//______________________________________________________________________________
TEveProjected::TEveProjected() :
   fManager     (0),
   fProjectable (0),
   fDepth       (0)
{
   // Constructor.
}

//______________________________________________________________________________
TEveProjected::~TEveProjected()
{
   // Destructor.
   // If fProjectable is non-null, *this is removed from its list of
   // projected replicas.

   if (fProjectable) fProjectable->RemoveProjected(this);
}

//______________________________________________________________________________
TEveElement* TEveProjected::GetProjectedAsElement()
{
   // Returns this projected dynamic-casted to TEveElement.
   // This is needed as class TEveProjected is used as secondary
   // inheritance.

   return dynamic_cast<TEveElement*>(this);
}

//______________________________________________________________________________
void TEveProjected::SetProjection(TEveProjectionManager* mng, TEveProjectable* model)
{
   // Sets projection manager and reference in the projectable object. Method called
   // immediately after default constructor.
   // See also TEveProjectionManager::ImportElements().

   fManager   = mng;
   if (fProjectable) fProjectable->RemoveProjected(this);
   fProjectable = model;
   if (fProjectable) fProjectable->AddProjected(this);
}

//______________________________________________________________________________
void TEveProjected::UnRefProjectable(TEveProjectable* assumed_parent, bool notifyParent)
{
   // Remove reference to projectable.

   static const TEveException eH("TEveProjected::UnRefProjectable ");

   R__ASSERT(fProjectable == assumed_parent);

   if (notifyParent) fProjectable->RemoveProjected(this);
   fProjectable = 0;
}

//______________________________________________________________________________
void TEveProjected::SetDepth(Float_t d)
{
   // Set depth coordinate for the element.
   // Bounding-box should also be updated.
   // If projection type is 3D, this only sets fDepth member.

   if (fManager->GetProjection()->Is2D())
   {
      SetDepthLocal(d);
   }
   else
   {
      fDepth = d;
   }
}

//______________________________________________________________________________
void TEveProjected::SetDepthCommon(Float_t d, TEveElement* el, Float_t* bbox)
{
   // Utility function to update the z-values of the bounding-box.
   // As this is an abstract interface, the element and bbox pointers
   // must be passed from outside.

   Float_t delta = d - fDepth;
   fDepth = d;
   if (bbox) {
      bbox[4] += delta;
      bbox[5] += delta;
      el->StampTransBBox();
   }
}

//______________________________________________________________________________
void TEveProjected::SetDepthLocal(Float_t d)
{
   // Base-class implementation -- just sets fDepth.

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