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

namespace
{
   inline Float_t sqr(Float_t x) { return x*x; }
}

//==============================================================================
//==============================================================================
// TEveLine
//==============================================================================

//______________________________________________________________________________
//
// An arbitrary polyline with fixed line and marker attributes.

ClassImp(TEveLine);

Bool_t TEveLine::fgDefaultSmooth = kFALSE;

//______________________________________________________________________________
TEveLine::TEveLine(Int_t n_points, ETreeVarType_e tv_type) :
   TEvePointSet("Line", n_points, tv_type),
   fRnrLine   (kTRUE),
   fRnrPoints (kFALSE),
   fSmooth    (fgDefaultSmooth)
{
   // Constructor.

   fMainColorPtr = &fLineColor;
   fMarkerColor  =  kGreen;
}

//______________________________________________________________________________
TEveLine::TEveLine(const char* name, Int_t n_points, ETreeVarType_e tv_type) :
   TEvePointSet(name, n_points, tv_type),
   fRnrLine   (kTRUE),
   fRnrPoints (kFALSE),
   fSmooth    (fgDefaultSmooth)
{
   // Constructor.

   fMainColorPtr = &fLineColor;
   fMarkerColor = kGreen;
}

//______________________________________________________________________________
const TGPicture* TEveLine::GetListTreeIcon(Bool_t)
{
   // Returns list-tree icon for TEveLine.

   return fgListTreeIcons[8];
}

//______________________________________________________________________________
void TEveLine::SetMarkerColor(Color_t col)
{
   // Set marker color. Propagate to projected lines.

   std::list<TEveProjected*>::iterator pi = fProjectedList.begin();
   while (pi != fProjectedList.end())
   {
      TEveLine* l = dynamic_cast<TEveLine*>(*pi);
      if (l && fMarkerColor == l->GetMarkerColor())
      {
         l->SetMarkerColor(col);
         l->StampObjProps();
      }
      ++pi;
   }
   TAttMarker::SetMarkerColor(col);
}

//______________________________________________________________________________
void TEveLine::SetLineStyle(Style_t lstyle)
{
   // Set line-style of the line.
   // The style is propagated to projecteds.

   std::list<TEveProjected*>::iterator pi = fProjectedList.begin();
   while (pi != fProjectedList.end())
   {
      TEveLine* pt = dynamic_cast<TEveLine*>(*pi);
      if (pt)
      {
         pt->SetLineStyle(lstyle);
         pt->StampObjProps();
      }
      ++pi;
   }
   TAttLine::SetLineStyle(lstyle);
}

//______________________________________________________________________________
void TEveLine::SetLineWidth(Width_t lwidth)
{
   // Set line-style of the line.
   // The style is propagated to projecteds.

   std::list<TEveProjected*>::iterator pi = fProjectedList.begin();
   while (pi != fProjectedList.end())
   {
      TEveLine* pt = dynamic_cast<TEveLine*>(*pi);
      if (pt)
      {
         pt->SetLineWidth(lwidth);
         pt->StampObjProps();
      }
      ++pi;
   }
   TAttLine::SetLineWidth(lwidth);
}

//______________________________________________________________________________
void TEveLine::SetRnrLine(Bool_t r)
{
   // Set rendering of line. Propagate to projected lines.

   fRnrLine = r;
   std::list<TEveProjected*>::iterator pi = fProjectedList.begin();
   while (pi != fProjectedList.end())
   {
      TEveLine* l = dynamic_cast<TEveLine*>(*pi);
      if (l)
      {
         l->SetRnrLine(r);
         l->ElementChanged();
      }
      ++pi;
   }
}

//______________________________________________________________________________
void TEveLine::SetRnrPoints(Bool_t r)
{
   // Set rendering of points. Propagate to projected lines.

   fRnrPoints = r;
   std::list<TEveProjected*>::iterator pi = fProjectedList.begin();
   while (pi != fProjectedList.end())
   {
      TEveLine* l = dynamic_cast<TEveLine*>(*pi);
      if (l)
      {
         l->SetRnrPoints(r);
         l->ElementChanged();
      }
      ++pi;
   }
}

//______________________________________________________________________________
void TEveLine::SetSmooth(Bool_t r)
{
   // Set smooth rendering. Propagate to projected lines.

   fSmooth = r;
   std::list<TEveProjected*>::iterator pi = fProjectedList.begin();
   while (pi != fProjectedList.end())
   {
      TEveLine* l = dynamic_cast<TEveLine*>(*pi);
      if (l)
      {
         l->SetSmooth(r);
         l->ElementChanged();
      }
      ++pi;
   }
}

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

//______________________________________________________________________________
void TEveLine::ReduceSegmentLengths(Float_t max)
{
   // Make sure that no segment is longer than max.
   // Per point references and integer ids are lost.

   const Float_t max2 = max*max;

   Float_t    *p = GetP();
   Int_t       s = Size();
   TEveVector  a, b, d;

   std::vector<TEveVector> q;

   b.Set(p);
   q.push_back(b);
   for (Int_t i = 1; i < s; ++i)
   {
      a = b; b.Set(&p[3*i]); d = b - a;
      Float_t m2 = d.Mag2();
      if (m2 > max2)
      {
         Float_t f = TMath::Sqrt(m2) / max;
         Int_t   n = TMath::FloorNint(f);
         d *= 1.0f / (n + 1);
         for (Int_t j = 0; j < n; ++j)
         {
            a += d;
            q.push_back(a);
         }
      }
      q.push_back(b);
   }

   s = q.size();
   Reset(s);
   for (std::vector<TEveVector>::iterator i = q.begin(); i != q.end(); ++i)
      SetNextPoint(i->fX, i->fY, i->fZ);
}

//______________________________________________________________________________
Float_t TEveLine::CalculateLineLength() const
{
   // Sum-up lengths of individual segments.

   Float_t sum = 0;

   Int_t    s = Size();
   Float_t *p = GetP();
   for (Int_t i = 1; i < s; ++i, p += 3)
   {
      sum += TMath::Sqrt(sqr(p[3] - p[0]) + sqr(p[4] - p[1]) + sqr(p[5] - p[2]));
   }
   return sum;
}

//______________________________________________________________________________
TEveVector TEveLine::GetLineStart() const
{
   // Return the first point of the line.
   // If there are no points (0,0,0) is returned.

   TEveVector v;
   GetPoint(0, v.fX, v.fY, v.fZ);
   return v;
}

//______________________________________________________________________________
TEveVector TEveLine::GetLineEnd() const
{
   // Return the last point of the line.
   // If there are no points (0,0,0) is returned.

   TEveVector v;
   GetPoint(fLastPoint, v.fX, v.fY, v.fZ);
   return v;
}

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

//______________________________________________________________________________
void TEveLine::CopyVizParams(const TEveElement* el)
{
   // Copy visualization parameters from element el.

   const TEveLine* m = dynamic_cast<const TEveLine*>(el);
   if (m)
   {
      TAttLine::operator=(*m);
      fRnrLine   = m->fRnrLine;
      fRnrPoints = m->fRnrPoints;
      fSmooth    = m->fSmooth;
   }

   TEvePointSet::CopyVizParams(el);
}

//______________________________________________________________________________
void TEveLine::WriteVizParams(std::ostream& out, const TString& var)
{
   // Write visualization parameters.

   TEvePointSet::WriteVizParams(out, var);

   TString t = "   " + var + "->";
   TAttLine::SaveLineAttributes(out, var);
   out << t << "SetRnrLine("   << ToString(fRnrLine)   << ");\n";
   out << t << "SetRnrPoints(" << ToString(fRnrPoints) << ");\n";
   out << t << "SetSmooth("    << ToString(fSmooth)    << ");\n";
}

//______________________________________________________________________________
TClass* TEveLine::ProjectedClass(const TEveProjection*) const
{
   // Virtual from TEveProjectable, returns TEvePointSetProjected class.

   return TEveLineProjected::Class();
}

//------------------------------------------------------------------------------

//______________________________________________________________________________
Bool_t TEveLine::GetDefaultSmooth()
{
   // Get default value for smooth-line drawing flag.
   // Static function.

   return fgDefaultSmooth;
}

//______________________________________________________________________________
void TEveLine::SetDefaultSmooth(Bool_t r)
{
   // Set default value for smooth-line drawing flag (default kFALSE).
   // Static function.

   fgDefaultSmooth = r;
}



//==============================================================================
//==============================================================================
// TEveLineProjected
//==============================================================================

//______________________________________________________________________________
//
// Projected copy of a TEveLine.

ClassImp(TEveLineProjected);

//______________________________________________________________________________
TEveLineProjected::TEveLineProjected() :
   TEveLine      (),
   TEveProjected ()
{
   // Default constructor.
}

//______________________________________________________________________________
void TEveLineProjected::SetProjection(TEveProjectionManager* mng,
                                      TEveProjectable* model)
{
   // Set projection manager and projection model.
   // Virtual from TEveProjected.

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

//______________________________________________________________________________
void TEveLineProjected::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;
}

//______________________________________________________________________________
void TEveLineProjected::UpdateProjection()
{
   // Re-apply the projection.
   // Virtual from TEveProjected.

   TEveProjection& proj = * fManager->GetProjection();
   TEveLine      & als  = * dynamic_cast<TEveLine*>(fProjectable);
   TEveTrans      *tr   =   als.PtrMainTrans(kFALSE);

   Int_t n = als.Size();
   Reset(n);
   fLastPoint = n - 1;
   Float_t *o = als.GetP(), *p = GetP();
   for (Int_t i = 0; i < n; ++i, o+=3, p+=3)
   {
      proj.ProjectPointfv(tr, o, p, fDepth);
   }
}
 TEveLine.cxx:1
 TEveLine.cxx:2
 TEveLine.cxx:3
 TEveLine.cxx:4
 TEveLine.cxx:5
 TEveLine.cxx:6
 TEveLine.cxx:7
 TEveLine.cxx:8
 TEveLine.cxx:9
 TEveLine.cxx:10
 TEveLine.cxx:11
 TEveLine.cxx:12
 TEveLine.cxx:13
 TEveLine.cxx:14
 TEveLine.cxx:15
 TEveLine.cxx:16
 TEveLine.cxx:17
 TEveLine.cxx:18
 TEveLine.cxx:19
 TEveLine.cxx:20
 TEveLine.cxx:21
 TEveLine.cxx:22
 TEveLine.cxx:23
 TEveLine.cxx:24
 TEveLine.cxx:25
 TEveLine.cxx:26
 TEveLine.cxx:27
 TEveLine.cxx:28
 TEveLine.cxx:29
 TEveLine.cxx:30
 TEveLine.cxx:31
 TEveLine.cxx:32
 TEveLine.cxx:33
 TEveLine.cxx:34
 TEveLine.cxx:35
 TEveLine.cxx:36
 TEveLine.cxx:37
 TEveLine.cxx:38
 TEveLine.cxx:39
 TEveLine.cxx:40
 TEveLine.cxx:41
 TEveLine.cxx:42
 TEveLine.cxx:43
 TEveLine.cxx:44
 TEveLine.cxx:45
 TEveLine.cxx:46
 TEveLine.cxx:47
 TEveLine.cxx:48
 TEveLine.cxx:49
 TEveLine.cxx:50
 TEveLine.cxx:51
 TEveLine.cxx:52
 TEveLine.cxx:53
 TEveLine.cxx:54
 TEveLine.cxx:55
 TEveLine.cxx:56
 TEveLine.cxx:57
 TEveLine.cxx:58
 TEveLine.cxx:59
 TEveLine.cxx:60
 TEveLine.cxx:61
 TEveLine.cxx:62
 TEveLine.cxx:63
 TEveLine.cxx:64
 TEveLine.cxx:65
 TEveLine.cxx:66
 TEveLine.cxx:67
 TEveLine.cxx:68
 TEveLine.cxx:69
 TEveLine.cxx:70
 TEveLine.cxx:71
 TEveLine.cxx:72
 TEveLine.cxx:73
 TEveLine.cxx:74
 TEveLine.cxx:75
 TEveLine.cxx:76
 TEveLine.cxx:77
 TEveLine.cxx:78
 TEveLine.cxx:79
 TEveLine.cxx:80
 TEveLine.cxx:81
 TEveLine.cxx:82
 TEveLine.cxx:83
 TEveLine.cxx:84
 TEveLine.cxx:85
 TEveLine.cxx:86
 TEveLine.cxx:87
 TEveLine.cxx:88
 TEveLine.cxx:89
 TEveLine.cxx:90
 TEveLine.cxx:91
 TEveLine.cxx:92
 TEveLine.cxx:93
 TEveLine.cxx:94
 TEveLine.cxx:95
 TEveLine.cxx:96
 TEveLine.cxx:97
 TEveLine.cxx:98
 TEveLine.cxx:99
 TEveLine.cxx:100
 TEveLine.cxx:101
 TEveLine.cxx:102
 TEveLine.cxx:103
 TEveLine.cxx:104
 TEveLine.cxx:105
 TEveLine.cxx:106
 TEveLine.cxx:107
 TEveLine.cxx:108
 TEveLine.cxx:109
 TEveLine.cxx:110
 TEveLine.cxx:111
 TEveLine.cxx:112
 TEveLine.cxx:113
 TEveLine.cxx:114
 TEveLine.cxx:115
 TEveLine.cxx:116
 TEveLine.cxx:117
 TEveLine.cxx:118
 TEveLine.cxx:119
 TEveLine.cxx:120
 TEveLine.cxx:121
 TEveLine.cxx:122
 TEveLine.cxx:123
 TEveLine.cxx:124
 TEveLine.cxx:125
 TEveLine.cxx:126
 TEveLine.cxx:127
 TEveLine.cxx:128
 TEveLine.cxx:129
 TEveLine.cxx:130
 TEveLine.cxx:131
 TEveLine.cxx:132
 TEveLine.cxx:133
 TEveLine.cxx:134
 TEveLine.cxx:135
 TEveLine.cxx:136
 TEveLine.cxx:137
 TEveLine.cxx:138
 TEveLine.cxx:139
 TEveLine.cxx:140
 TEveLine.cxx:141
 TEveLine.cxx:142
 TEveLine.cxx:143
 TEveLine.cxx:144
 TEveLine.cxx:145
 TEveLine.cxx:146
 TEveLine.cxx:147
 TEveLine.cxx:148
 TEveLine.cxx:149
 TEveLine.cxx:150
 TEveLine.cxx:151
 TEveLine.cxx:152
 TEveLine.cxx:153
 TEveLine.cxx:154
 TEveLine.cxx:155
 TEveLine.cxx:156
 TEveLine.cxx:157
 TEveLine.cxx:158
 TEveLine.cxx:159
 TEveLine.cxx:160
 TEveLine.cxx:161
 TEveLine.cxx:162
 TEveLine.cxx:163
 TEveLine.cxx:164
 TEveLine.cxx:165
 TEveLine.cxx:166
 TEveLine.cxx:167
 TEveLine.cxx:168
 TEveLine.cxx:169
 TEveLine.cxx:170
 TEveLine.cxx:171
 TEveLine.cxx:172
 TEveLine.cxx:173
 TEveLine.cxx:174
 TEveLine.cxx:175
 TEveLine.cxx:176
 TEveLine.cxx:177
 TEveLine.cxx:178
 TEveLine.cxx:179
 TEveLine.cxx:180
 TEveLine.cxx:181
 TEveLine.cxx:182
 TEveLine.cxx:183
 TEveLine.cxx:184
 TEveLine.cxx:185
 TEveLine.cxx:186
 TEveLine.cxx:187
 TEveLine.cxx:188
 TEveLine.cxx:189
 TEveLine.cxx:190
 TEveLine.cxx:191
 TEveLine.cxx:192
 TEveLine.cxx:193
 TEveLine.cxx:194
 TEveLine.cxx:195
 TEveLine.cxx:196
 TEveLine.cxx:197
 TEveLine.cxx:198
 TEveLine.cxx:199
 TEveLine.cxx:200
 TEveLine.cxx:201
 TEveLine.cxx:202
 TEveLine.cxx:203
 TEveLine.cxx:204
 TEveLine.cxx:205
 TEveLine.cxx:206
 TEveLine.cxx:207
 TEveLine.cxx:208
 TEveLine.cxx:209
 TEveLine.cxx:210
 TEveLine.cxx:211
 TEveLine.cxx:212
 TEveLine.cxx:213
 TEveLine.cxx:214
 TEveLine.cxx:215
 TEveLine.cxx:216
 TEveLine.cxx:217
 TEveLine.cxx:218
 TEveLine.cxx:219
 TEveLine.cxx:220
 TEveLine.cxx:221
 TEveLine.cxx:222
 TEveLine.cxx:223
 TEveLine.cxx:224
 TEveLine.cxx:225
 TEveLine.cxx:226
 TEveLine.cxx:227
 TEveLine.cxx:228
 TEveLine.cxx:229
 TEveLine.cxx:230
 TEveLine.cxx:231
 TEveLine.cxx:232
 TEveLine.cxx:233
 TEveLine.cxx:234
 TEveLine.cxx:235
 TEveLine.cxx:236
 TEveLine.cxx:237
 TEveLine.cxx:238
 TEveLine.cxx:239
 TEveLine.cxx:240
 TEveLine.cxx:241
 TEveLine.cxx:242
 TEveLine.cxx:243
 TEveLine.cxx:244
 TEveLine.cxx:245
 TEveLine.cxx:246
 TEveLine.cxx:247
 TEveLine.cxx:248
 TEveLine.cxx:249
 TEveLine.cxx:250
 TEveLine.cxx:251
 TEveLine.cxx:252
 TEveLine.cxx:253
 TEveLine.cxx:254
 TEveLine.cxx:255
 TEveLine.cxx:256
 TEveLine.cxx:257
 TEveLine.cxx:258
 TEveLine.cxx:259
 TEveLine.cxx:260
 TEveLine.cxx:261
 TEveLine.cxx:262
 TEveLine.cxx:263
 TEveLine.cxx:264
 TEveLine.cxx:265
 TEveLine.cxx:266
 TEveLine.cxx:267
 TEveLine.cxx:268
 TEveLine.cxx:269
 TEveLine.cxx:270
 TEveLine.cxx:271
 TEveLine.cxx:272
 TEveLine.cxx:273
 TEveLine.cxx:274
 TEveLine.cxx:275
 TEveLine.cxx:276
 TEveLine.cxx:277
 TEveLine.cxx:278
 TEveLine.cxx:279
 TEveLine.cxx:280
 TEveLine.cxx:281
 TEveLine.cxx:282
 TEveLine.cxx:283
 TEveLine.cxx:284
 TEveLine.cxx:285
 TEveLine.cxx:286
 TEveLine.cxx:287
 TEveLine.cxx:288
 TEveLine.cxx:289
 TEveLine.cxx:290
 TEveLine.cxx:291
 TEveLine.cxx:292
 TEveLine.cxx:293
 TEveLine.cxx:294
 TEveLine.cxx:295
 TEveLine.cxx:296
 TEveLine.cxx:297
 TEveLine.cxx:298
 TEveLine.cxx:299
 TEveLine.cxx:300
 TEveLine.cxx:301
 TEveLine.cxx:302
 TEveLine.cxx:303
 TEveLine.cxx:304
 TEveLine.cxx:305
 TEveLine.cxx:306
 TEveLine.cxx:307
 TEveLine.cxx:308
 TEveLine.cxx:309
 TEveLine.cxx:310
 TEveLine.cxx:311
 TEveLine.cxx:312
 TEveLine.cxx:313
 TEveLine.cxx:314
 TEveLine.cxx:315
 TEveLine.cxx:316
 TEveLine.cxx:317
 TEveLine.cxx:318
 TEveLine.cxx:319
 TEveLine.cxx:320
 TEveLine.cxx:321
 TEveLine.cxx:322
 TEveLine.cxx:323
 TEveLine.cxx:324
 TEveLine.cxx:325
 TEveLine.cxx:326
 TEveLine.cxx:327
 TEveLine.cxx:328
 TEveLine.cxx:329
 TEveLine.cxx:330
 TEveLine.cxx:331
 TEveLine.cxx:332
 TEveLine.cxx:333
 TEveLine.cxx:334
 TEveLine.cxx:335
 TEveLine.cxx:336
 TEveLine.cxx:337
 TEveLine.cxx:338
 TEveLine.cxx:339
 TEveLine.cxx:340
 TEveLine.cxx:341
 TEveLine.cxx:342
 TEveLine.cxx:343
 TEveLine.cxx:344
 TEveLine.cxx:345
 TEveLine.cxx:346
 TEveLine.cxx:347
 TEveLine.cxx:348
 TEveLine.cxx:349
 TEveLine.cxx:350
 TEveLine.cxx:351
 TEveLine.cxx:352
 TEveLine.cxx:353
 TEveLine.cxx:354
 TEveLine.cxx:355
 TEveLine.cxx:356
 TEveLine.cxx:357
 TEveLine.cxx:358
 TEveLine.cxx:359
 TEveLine.cxx:360
 TEveLine.cxx:361
 TEveLine.cxx:362
 TEveLine.cxx:363
 TEveLine.cxx:364
 TEveLine.cxx:365
 TEveLine.cxx:366
 TEveLine.cxx:367
 TEveLine.cxx:368
 TEveLine.cxx:369
 TEveLine.cxx:370
 TEveLine.cxx:371
 TEveLine.cxx:372
 TEveLine.cxx:373
 TEveLine.cxx:374
 TEveLine.cxx:375
 TEveLine.cxx:376
 TEveLine.cxx:377
 TEveLine.cxx:378
 TEveLine.cxx:379
 TEveLine.cxx:380
 TEveLine.cxx:381
 TEveLine.cxx:382
 TEveLine.cxx:383
 TEveLine.cxx:384
 TEveLine.cxx:385
 TEveLine.cxx:386
 TEveLine.cxx:387