#include <iostream>
#include "G4RunManager.hh"
#include "G4UImanager.hh"
#include "G4VisManager.hh"
#include "G4UIExecutive.hh"
#include "G4VisExecutive.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysListFactory.hh"
#include "FTFP_BERT.hh"

#include "DetectorConstruction.hh"
#include "PrimaryGenerator.hh"
#include "EventAction.hh"

int main(int argc, char** argv) {
  // Choose the Random engine
  CLHEP::HepRandom::setTheEngine(new CLHEP::RanecuEngine);
  // Set random seed with system time
  G4long seed = time(NULL);
  CLHEP::HepRandom::setTheSeed(seed);

  // Construct the default run manager, which manages start and stop simulation
  G4RunManager* runManager = new G4RunManager();
 
  G4double e = (argc > 2) ? std::atof(argv[2]) : 10.0;
  G4double xpps = (argc > 3) ? std::atoi(argv[3]) : 0;
  G4double ypos = (argc > 4) ? std::atof(argv[4]) : 0;

  xpos *= 2.2;
  ypos *= 2.2;
 
  DetectorConstruction* detectorConstruction = new DetectorConstruction(ironthickness);
  runManager->SetUserInitialization(detectorConstruction);
 
  G4PhysListFactory factory;
  runManager->SetUserInitialization(factory.GetReferencePhysList("FTFP_BERT"));
 
  PrimaryGenerator* genAction = new PrimaryGenerator(xpos, ypos, e);
  runManager->SetUserAction(genAction);
 
  EventAction* eventAction = new EventAction(xpos, ypos, e);
  runManager->SetUserAction(eventAction);
  
  detector->setSensitive();

  runManager->Initialize();
 
  G4VisManager *visManager = new G4VisExecutive();
  visManager->Initialize();
 
  G4UImanager *Uimanager = G4UImanager::GetUIpointer();
 
  G4UIExecutive* ui = nullptr;
  if (argc > 1) {
    ui = new G4UIExecutive(argc, argv);
  }
 
  if (ui) {
    UImanager->ApplyCommand("/control/execute init_vis.mac");
    ui->SessionStart();
    delete ui;
  } else {
    G4String command = "/control/execute";
    G4String fileName = argv[1];
    UImanager->ApplyCommand(command + fileName);
  }
 
  delete visManager;
  delete runManager;
 
  return 0;
}
