/// \file
/// \ingroup tutorial_eve
/// Demonstrates usage of TEveJetCone class.
///
/// \image html eve_jetcone.png
/// \macro_code
///
/// \author Jochen Thaeder

const char* esd_geom_file_name =
   "http://root.cern.ch/files/alice_ESDgeometry.root";

TEveVector GetTEveVector(Float_t eta, Float_t phi);
void       geomGentleTPC();

void jetcone()
{
   TEveManager::Create();

   using namespace TMath;

   TRandom r(0);

   // -- Set Constants
   Int_t nCones  = 10;
   Int_t nTracks = 200;

   Float_t coneRadius = 0.4;
   Float_t length = 300.;

   // -- Define palette
   auto pal = new TEveRGBAPalette(0, 500);

   // -----------------------------------------------------------------------
   // -- Line sets
   // -----------------------------------------------------------------------

   // -- Define cone center
   auto axis = new TEveStraightLineSet("Cone Axis");
   axis->SetLineColor(kGreen);
   axis->SetLineWidth(2);

   auto tracksXYZ = new TEveStraightLineSet("StraightLinesXYZ");
   tracksXYZ->SetLineColor(kRed);
   tracksXYZ->SetLineWidth(2);

   auto tracksEtaPhi = new TEveStraightLineSet("StraightLinesEtaPhi");
   tracksEtaPhi->SetLineColor(kYellow);
   tracksEtaPhi->SetLineWidth(2);

   auto tracksSeedEtaPhi = new TEveStraightLineSet("StraightLinesEtaPhiSeed");
   tracksSeedEtaPhi->SetLineColor(kBlue);
   tracksSeedEtaPhi->SetLineWidth(2);

   // -----------------------------------------------------------------------
   // -- Draw track distribution in XYZ in TPC Volume +/-250, +/-250, +/-250
   // -----------------------------------------------------------------------

   for ( Int_t track=0; track < nTracks ; track++ ) {

      Float_t trackX = r.Uniform(-250.0, 250.0);
      Float_t trackY = r.Uniform(-250.0, 250.0);
      Float_t trackZ = r.Uniform(-250.0, 250.0);
      Float_t trackR = Sqrt(trackX*trackX + trackY*trackY + trackZ*trackZ);

      TEveVector trackDir(trackX/trackR, trackY/trackR ,trackZ/trackR);
      TEveVector trackEnd = trackDir * length;
      tracksXYZ->AddLine(0., 0., 0., trackEnd.fX, trackEnd.fY, trackEnd.fZ );
   }

   // -----------------------------------------------------------------------
   // -- Draw track distribution in eta phi in TPC Volume +/-0.9, {0, 2Pi}
   // -----------------------------------------------------------------------

   for ( Int_t track=0; track < nTracks ; track++ ) {

      Float_t trackEta = r.Uniform(-0.9, 0.9);
      Float_t trackPhi = r.Uniform(0.0, TwoPi());

      TEveVector trackDir( GetTEveVector(trackEta, trackPhi) );
      TEveVector trackEnd = trackDir * length;

      if ( trackEta > coneRadius || trackEta < -coneRadius )
         tracksEtaPhi->AddLine(0., 0., 0.,
                               trackEnd.fX, trackEnd.fY, trackEnd.fZ);
      else
         tracksSeedEtaPhi->AddLine(0., 0., 0.,
                                   trackEnd.fX, trackEnd.fY, trackEnd.fZ);
   }

   // -----------------------------------------------------------------------
   // -- Draw cones
   // -----------------------------------------------------------------------

   for ( Int_t iter = 0; iter < nCones; ++iter ) {

      // -- Get Random ( eta ,phi )
      Float_t coneEta = r.Uniform(-0.9, 0.9);
      Float_t conePhi = r.Uniform(0.0, TwoPi() );

      // -- Primary vertex as origin
      TEveVector coneOrigin(0.0,0.0,0.0);

      // -- Get Cone Axis - axis line 10% longer than cone height
      TEveVector coneAxis ( GetTEveVector( coneEta, conePhi) );
      coneAxis *= length * 1.1;

      axis->AddLine( 0., 0., 0., coneAxis.fX, coneAxis.fY, coneAxis.fZ );

      // -- Draw jet cone
      auto jetCone = new TEveJetCone("JetCone");
      jetCone->SetPickable(kTRUE);
      jetCone->SetCylinder( 250., 250. );
      if ( (jetCone->AddCone( coneEta, conePhi, coneRadius   ) ) != -1)
         gEve->AddElement( jetCone );
   }

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

   // -- Add cone axis
   gEve->AddElement(axis);

   // -- Add lines
   //  gEve->AddElement(tracksXYZ);
   gEve->AddElement(tracksSeedEtaPhi);
   gEve->AddElement(tracksEtaPhi);

   // -- Load TPC geometry
   geomGentleTPC();

   gEve->Redraw3D(kTRUE);

   return;
}

//___________________________________________________________________________
TEveVector GetTEveVector(Float_t eta, Float_t phi)
{
  using namespace TMath;

  TEveVector vec( (Float_t) Cos ( (Double_t) phi)/ CosH( (Double_t) eta ),
                 (Float_t) Sin ( (Double_t) phi)/ CosH( (Double_t) eta ),
                 (Float_t) TanH( (Double_t) eta ) );
  return vec;
}

//__________________________________________________________________________
void geomGentleTPC()
{
   // Simple geometry
   TFile::SetCacheFileDir(".");
   TFile* geom = TFile::Open(esd_geom_file_name, "CACHEREAD");
   if (!geom)
      return;

   TEveGeoShapeExtract* gse = (TEveGeoShapeExtract*) geom->Get("Gentle");
   TEveGeoShape* gsre = TEveGeoShape::ImportShapeExtract(gse, 0);
   geom->Close();
   delete geom;

   gEve->AddGlobalElement(gsre);

   TEveElement* elTRD = gsre->FindChild("TRD+TOF");
   elTRD->SetRnrState(kFALSE);

   TEveElement* elPHOS = gsre->FindChild("PHOS");
   elPHOS->SetRnrState(kFALSE);

   TEveElement* elHMPID = gsre->FindChild("HMPID");
   elHMPID->SetRnrState(kFALSE);
}
