/// \file
/// \ingroup tutorial_eve
/// Multi-view (3d, rphi, rhoz) service class using EVE Window Manager.
/// Used together with alice_esd.C macro
///
/// \macro_code
///
/// \author Matevz Tadel

#include <TEveManager.h>

#include <TEveViewer.h>
#include <TGLViewer.h>

#include <TEveScene.h>

#include <TEveProjectionManager.h>
#include <TEveProjectionAxes.h>

#include <TEveBrowser.h>
#include <TEveWindow.h>

// MultiView
//
// Structure encapsulating standard views: 3D, r-phi and rho-z.
// Includes scenes and projection managers.
//
// Should be used in compiled mode.

struct MultiView {
   TEveProjectionManager *fRPhiMgr;
   TEveProjectionManager *fRhoZMgr;

   TEveViewer *f3DView;
   TEveViewer *fRPhiView;
   TEveViewer *fRhoZView;

   TEveScene *fRPhiGeomScene;
   TEveScene *fRhoZGeomScene;
   TEveScene *fRPhiEventScene;
   TEveScene *fRhoZEventScene;

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

   MultiView()
   {
      // Constructor --- creates required scenes, projection managers
      // and GL viewers.

      // Scenes
      //========

      fRPhiGeomScene = gEve->SpawnNewScene("RPhi Geometry", "Scene holding projected geometry for the RPhi view.");
      fRhoZGeomScene = gEve->SpawnNewScene("RhoZ Geometry", "Scene holding projected geometry for the RhoZ view.");
      fRPhiEventScene = gEve->SpawnNewScene("RPhi Event Data", "Scene holding projected event-data for the RPhi view.");
      fRhoZEventScene = gEve->SpawnNewScene("RhoZ Event Data", "Scene holding projected event-data for the RhoZ view.");

      // Projection managers
      //=====================

      fRPhiMgr = new TEveProjectionManager(TEveProjection::kPT_RPhi);
      gEve->AddToListTree(fRPhiMgr, kFALSE);
      {
         TEveProjectionAxes *a = new TEveProjectionAxes(fRPhiMgr);
         a->SetMainColor(kWhite);
         a->SetTitle("R-Phi");
         a->SetTitleSize(0.05);
         a->SetTitleFont(102);
         a->SetLabelSize(0.025);
         a->SetLabelFont(102);
         fRPhiGeomScene->AddElement(a);
      }

      fRhoZMgr = new TEveProjectionManager(TEveProjection::kPT_RhoZ);
      gEve->AddToListTree(fRhoZMgr, kFALSE);
      {
         TEveProjectionAxes *a = new TEveProjectionAxes(fRhoZMgr);
         a->SetMainColor(kWhite);
         a->SetTitle("Rho-Z");
         a->SetTitleSize(0.05);
         a->SetTitleFont(102);
         a->SetLabelSize(0.025);
         a->SetLabelFont(102);
         fRhoZGeomScene->AddElement(a);
      }

      // Viewers
      //=========

      TEveWindowSlot *slot = nullptr;
      TEveWindowPack *pack = nullptr;

      slot = TEveWindow::CreateWindowInTab(gEve->GetBrowser()->GetTabRight());
      pack = slot->MakePack();
      pack->SetElementName("Multi View");
      pack->SetHorizontal();
      pack->SetShowTitleBar(kFALSE);
      pack->NewSlot()->MakeCurrent();
      f3DView = gEve->SpawnNewViewer("3D View", "");
      f3DView->AddScene(gEve->GetGlobalScene());
      f3DView->AddScene(gEve->GetEventScene());

      pack = pack->NewSlot()->MakePack();
      pack->SetShowTitleBar(kFALSE);
      pack->NewSlot()->MakeCurrent();
      fRPhiView = gEve->SpawnNewViewer("RPhi View", "");
      fRPhiView->GetGLViewer()->SetCurrentCamera(TGLViewer::kCameraOrthoXOY);
      fRPhiView->AddScene(fRPhiGeomScene);
      fRPhiView->AddScene(fRPhiEventScene);

      pack->NewSlot()->MakeCurrent();
      fRhoZView = gEve->SpawnNewViewer("RhoZ View", "");
      fRhoZView->GetGLViewer()->SetCurrentCamera(TGLViewer::kCameraOrthoXOY);
      fRhoZView->AddScene(fRhoZGeomScene);
      fRhoZView->AddScene(fRhoZEventScene);
   }

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

   void SetDepth(Float_t d)
   {
      // Set current depth on all projection managers.

      fRPhiMgr->SetCurrentDepth(d);
      fRhoZMgr->SetCurrentDepth(d);
   }

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

   void ImportGeomRPhi(TEveElement *el) { fRPhiMgr->ImportElements(el, fRPhiGeomScene); }

   void ImportGeomRhoZ(TEveElement *el) { fRhoZMgr->ImportElements(el, fRhoZGeomScene); }

   void ImportEventRPhi(TEveElement *el) { fRPhiMgr->ImportElements(el, fRPhiEventScene); }

   void ImportEventRhoZ(TEveElement *el) { fRhoZMgr->ImportElements(el, fRhoZEventScene); }

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

   void DestroyEventRPhi() { fRPhiEventScene->DestroyElements(); }

   void DestroyEventRhoZ() { fRhoZEventScene->DestroyElements(); }
};
