// @(#)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 "TEveTrackProjected.h"
#include "TEveTrackPropagator.h"
#include "TEveProjectionManager.h"
#include "TEveTrans.h"

//==============================================================================
//==============================================================================
// TEveTrackProjected
//==============================================================================

//______________________________________________________________________________
//
// Projected copy of a TEveTrack.

ClassImp(TEveTrackProjected);

//______________________________________________________________________________
TEveTrackProjected::TEveTrackProjected() :
   TEveTrack (),
   fOrigPnts (0)
{
   // Default constructor.
}

/******************************************************************************/

//______________________________________________________________________________
void TEveTrackProjected::SetProjection(TEveProjectionManager* mng, TEveProjectable* model)
{
   // This is virtual method from base-class TEveProjected.

   TEveProjected::SetProjection(mng, model);
   CopyVizParams(dynamic_cast<TEveElement*>(model));

   TEveTrack* otrack = dynamic_cast<TEveTrack*>(fProjectable);
   SetTrackParams(*otrack);
   SetLockPoints(otrack->GetLockPoints());
}

/******************************************************************************/

//______________________________________________________________________________
void TEveTrackProjected::SetDepthLocal(Float_t d)
{
   // Set depth (z-coordinate) of the projected points.

   SetDepthCommon(d, this, fBBox);

   Int_t    n = Size();
   Float_t *p = GetP() + 2;
   for (Int_t i = 0; i < n; ++i, p+=3)
   {
      *p = fDepth;
   }

   for (vPathMark_i pm = fPathMarks.begin(); pm != fPathMarks.end(); ++pm)
   {
      pm->fV.fZ = fDepth;
   }
}

//______________________________________________________________________________
void TEveTrackProjected::UpdateProjection()
{
   // Virtual method from base-class TEveProjected.

   MakeTrack(kFALSE); // TEveProjectionManager makes recursive calls
}

//______________________________________________________________________________
Int_t TEveTrackProjected::GetBreakPointIdx(Int_t start)
{
   // Findex index of the last point that lies within the same
   // segment of projected space.
   // For example, rho-z projection separates upper and lower hemisphere
   // and tracks break into two lines when crossing the y=0 plane.

   TEveProjection *projection = fManager->GetProjection();

   Int_t val = fLastPoint;

   if (projection->HasSeveralSubSpaces())
   {
      TEveVector v1, v2;
      if (Size() > 1)
      {
         Int_t i = start;
         while(i < fLastPoint)
         {
            GetPoint(i,   v1.fX, v1.fY, v1.fZ);
            GetPoint(i+1, v2.fX, v2.fY, v2.fZ);
            if(projection->AcceptSegment(v1, v2, fPropagator->GetDelta()) == kFALSE)
            {
               val = i;
               break;
            }
            i++;
         }
      }
   }
   return val;
}

/******************************************************************************/

//______________________________________________________________________________
void TEveTrackProjected::MakeTrack(Bool_t recurse)
{
   // Calculate the points of the track for drawing.
   // Call base-class, project, find break-points and insert points
   // required for full representation.

   TEveTrack      *otrack     = dynamic_cast<TEveTrack*>(fProjectable);
   TEveTrans      *trans      = otrack->PtrMainTrans(kFALSE);
   TEveProjection *projection = fManager->GetProjection();

   fBreakPoints.clear();

   fPathMarks.clear();
   SetPathMarks(*otrack);
   if (GetLockPoints() || otrack->Size() > 0)
   {
      ClonePoints(*otrack);
      fLastPMIdx = otrack->GetLastPMIdx();
   }
   else
   {
      TEveTrack::MakeTrack(recurse);
   }
   if (Size() == 0) return; // All points can be outside of MaxR / MaxZ limits.

   // Break segments additionally if required by the projection.
   ReduceSegmentLengths(projection->GetMaxTrackStep());

   // Project points, store originals (needed for break-points).
   Float_t *p = GetP();
   fOrigPnts  = new TEveVector[Size()];
   for (Int_t i = 0; i < Size(); ++i, p+=3)
   {
      if (trans) trans->MultiplyIP(p);
      fOrigPnts[i].Set(p);
      projection->ProjectPointfv(p, fDepth);
   }

   Float_t x, y, z;
   Int_t   bL = 0, bR = GetBreakPointIdx(0);
   std::vector<TEveVector> vvec;
   while (kTRUE)
   {
      for (Int_t i=bL; i<=bR; i++)
      {
         GetPoint(i, x, y, z);
         vvec.push_back(TEveVector(x, y, z));
      }
      if (bR == fLastPoint)
         break;

      TEveVector vL = fOrigPnts[bR];
      TEveVector vR = fOrigPnts[bR + 1];
      projection->BisectBreakPoint(vL, vR, kTRUE, fDepth);
      vvec.push_back(vL);
      fBreakPoints.push_back((Int_t)vvec.size());
      vvec.push_back(vR);

      bL = bR + 1;
      bR = GetBreakPointIdx(bL);
   }
   fBreakPoints.push_back((Int_t)vvec.size()); // Mark the track-end for drawing.

   // Decide if points need to be fixed.
   // This (and the fixing itself) should really be done in TEveProjection but
   // for now we do it here as RhoZ is the only one that needs it.
   Bool_t  fix_y  = kFALSE;
   Float_t sign_y = 0;
   if (projection->HasSeveralSubSpaces())
   {
      switch (fPropagator->GetProjTrackBreaking())
      {
         case TEveTrackPropagator::kPTB_UseFirstPointPos:
         {
            fix_y  = kTRUE;
            sign_y = vvec.front().fY;
            break;
         }
         case TEveTrackPropagator::kPTB_UseLastPointPos:
         {
            fix_y  = kTRUE;
            sign_y = vvec.back().fY;
            break;
         }
      }
   }

   Reset((Int_t)vvec.size());
   for (std::vector<TEveVector>::iterator i=vvec.begin(); i!=vvec.end(); ++i)
   {
      if (fix_y)
         SetNextPoint((*i).fX, TMath::Sign((*i).fY, sign_y), (*i).fZ);
      else
         SetNextPoint((*i).fX, (*i).fY, (*i).fZ);
   }
   delete [] fOrigPnts; fOrigPnts = 0;

   // Project path-marks
   for (vPathMark_i pm = fPathMarks.begin(); pm != fPathMarks.end(); ++pm)
   {
      projection->ProjectPointdv(trans, pm->fV.Arr(), pm->fV.Arr(), fDepth);
   }
}

/******************************************************************************/

//______________________________________________________________________________
void TEveTrackProjected::PrintLineSegments()
{
   // Print line segments info.

   printf("%s LineSegments:\n", GetName());
   Int_t start = 0;
   Int_t segment = 0;
   TEveVector sVec;
   TEveVector bPnt;
   for (std::vector<Int_t>::iterator bpi = fBreakPoints.begin();
        bpi != fBreakPoints.end(); ++bpi)
   {
      Int_t size = *bpi - start;

      GetPoint(start, sVec.fX, sVec.fY, sVec.fZ);
      GetPoint((*bpi)-1, bPnt.fX, bPnt.fY, bPnt.fZ);
      printf("seg %d size %d start %d ::(%f, %f, %f) (%f, %f, %f)\n",
             segment, size, start, sVec.fX, sVec.fY, sVec.fZ,
             bPnt.fX, bPnt.fY, bPnt.fZ);
      start   += size;
      segment ++;
   }
}

/******************************************************************************/

//______________________________________________________________________________
void TEveTrackProjected::SecSelected(TEveTrack* /*track*/)
{
    // Virtual method from from base-class TEveTrack.

   TEveTrack* t = dynamic_cast<TEveTrack*>(fProjectable);
   if (t)
      t->SecSelected(t);
}


//==============================================================================
//==============================================================================
// TEveTrackListProjected
//==============================================================================

//______________________________________________________________________________
//
// Specialization of TEveTrackList for holding TEveTrackProjected objects.

ClassImp(TEveTrackListProjected);

//______________________________________________________________________________
TEveTrackListProjected::TEveTrackListProjected() :
   TEveTrackList (),
   TEveProjected ()
{
   // Default constructor.
}

/******************************************************************************/

//______________________________________________________________________________
void TEveTrackListProjected::SetProjection(TEveProjectionManager* proj, TEveProjectable* model)
{
   // This is virtual method from base-class TEveProjected.

   TEveProjected::SetProjection(proj, model);
   CopyVizParams(dynamic_cast<TEveElement*>(model));

   TEveTrackList& tl = * dynamic_cast<TEveTrackList*>(model);
   SetPropagator(tl.GetPropagator());
}

//______________________________________________________________________________
void TEveTrackListProjected::SetDepthLocal(Float_t /*d*/)
{
   // This is not needed for functionality as SetDepth(Float_t d)
   // is overriden -- but SetDepthLocal() is abstract.
   // Just emits a warning if called.

   Warning("SetDepthLocal", "This function only exists to fulfill an abstract interface.");
}

//______________________________________________________________________________
void TEveTrackListProjected::SetDepth(Float_t d)
{
   // Set depth of all children inheriting from TEveTrackProjected.

   SetDepth(d, this);
}

//______________________________________________________________________________
void TEveTrackListProjected::SetDepth(Float_t d, TEveElement* el)
{
   // Set depth of all children of el inheriting from TEveTrackProjected.

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