//In-ROOT sim data

// vis_inproc.cpp
#include <TApplication.h>
#include <TGeoManager.h>
#include <TEveManager.h>
#include <TEvePointSet.h>
#include <TSystem.h>
#include <TRandom3.h>
#include <thread>
#include <chrono>
#include <vector>
#include <iostream>

void runSimulationAndUpdate(TEvePointSet* pts){
  TRandom3 rnd(0);
  for(int ev=0; ev<10000; ++ev){
    pts->Reset();
    int n = 100;
    for(int i=0;i<n;++i){
      double x = rnd.Uniform(-50,50);
      double y = rnd.Uniform(-50,50);
      double z = rnd.Uniform(-50,50);
      pts->SetNextPoint(x,y,z);
    }
    gEve->Redraw3D();
    gSystem->ProcessEvents();
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
  }
}

void StartVis(const char* geomfile=nullptr){
  int argc=0; char** argv=nullptr;
  TApplication app("app",&argc,argv);
  if(geomfile) TGeoManager::Import(geomfile);
  TEveManager::Create();
  TEvePointSet *pts = new TEvePointSet("hits");
  gEve->AddElement(pts);
  // runSimulationAndUpdate(pts);  // or leave update API to caller
  app.Run();
}

int main(int argc, char** argv){
  TApplication app("app",&argc,argv);

  if(argc>1) TGeoManager::Import(argv[1]);

  TEveManager::Create();

  TEvePointSet *pts = new TEvePointSet("hits");
  pts->SetMarkerStyle(20);
  pts->SetMarkerSize(1.2);
  pts->SetMarkerColor(kRed);
  gEve->AddElement(pts);

  // Option A: run simulation in same thread but yield to event loop inside the sim
  runSimulationAndUpdate(pts);

  // Option B: run sim in a separate thread (only if sim avoids ROOT globals)
  // std::thread simThread(runSimulationAndUpdate, pts);
  // simThread.detach();

  app.Run();
  return 0;
}
