// Written by Peter Stromberger
// based on work of Mirco Deckenhoff
// modified by Bastian Rössler

#include "G4RunManager.hh"
//#include "G4MTRunManager.hh"
#include "G4UImanager.hh"
#include "G4Version.hh"

#include "G4VisExecutive.hh"
#if  G4VERSION_NUMBER>=930
#include "G4UIExecutive.hh"
#else
#include "G4UIterminal.hh"
#include "G4UItcsh.hh"
#endif

#include "DetectorConstruction.hh"
#include "PrimaryGeneratorAction.hh"
#include "StackingAction.hh"
#include "SteppingAction.hh"

#include "EventAction.hh"
#include "RunAction.hh"

#include "Analysis.hh"
#include "Parameters.hh"

#include "PhysicsList.hh"
#include "ActionInitialization.hh"

#include "Randomize.hh"

// for file output
#include <iostream>
#include <fstream>

int main(int argc,char** argv)
{

    // Set the seed for the random engine and save to file
    G4int seed = Parameters::GetInstance()->RandomSeed();
    G4Random::setTheEngine(new CLHEP::RanecuEngine);
    G4Random::setTheSeed(seed);
   
    std::ofstream myfile;
    myfile.open("randomEngineSeed.txt");
    myfile << seed;
    myfile.close();

    G4RunManager * runManager = new G4RunManager();
  

    // mandatory Initialization classes
    G4VUserDetectorConstruction* detector = new DetectorConstruction();
    runManager->SetUserInitialization(detector);

    G4VUserPhysicsList* physics = new PhysicsList();
    runManager->SetUserInitialization(physics);

    // mandatory User Action classes
    runManager->SetUserInitialization(new ActionInitialization());

    // Initialize G4 kernel
    runManager->Initialize();
      
    //Initilize the visualization manager
    G4VisManager* visManager = new G4VisExecutive();
    visManager->Initialize();
  
     
    // Get the pointer to the User Interface manager
    //
    G4UImanager * UImanager = G4UImanager::GetUIpointer();

    if (argc!=1)
    {  // batch mode
        //command line contains name of the macro to execute
        G4String command = "/control/execute ";
        G4String fileName = argv[1];
        UImanager->ApplyCommand(command+fileName);
    }
    else
    {           // interactive mode : define UI session
        
#if  G4VERSION_NUMBER>=930
        //New since G4 9.3: UI executive setups up
        //correct UI depending on env variables
        G4UIExecutive * ui = new G4UIExecutive(argc,argv);
        //If UI has graphics execute special macro: opens OpenGL Qt driver
        if (ui->IsGUI())
            UImanager->ApplyCommand("/control/execute visQt.mac");
        else
            UImanager->ApplyCommand("/control/execute vis.mac");
#else
        //Older versions of G4: UI selected by user
  #ifdef G4UI_USE_TCSH
        G4UIsession * ui = new G4UIterminal(new G4UItcsh);
  #else
        G4UIsession * ui = new G4UIterminal();
  #endif
        UImanager->ApplyCommand("/control/execute vis.mac");
#endif
        ui->SessionStart();
        delete ui;
    }

    // Free the store: user actions, physics_list and detector_description are
    //                 owned and deleted by the run manager, so they should not
    //                 be deleted in the main() program !

    Analysis::GetInstance()->Close();


    delete runManager;

    if(Analysis::GetInstance()!=NULL)
        delete Analysis::GetInstance();

    if(Parameters::GetInstance()!=NULL)
        delete Parameters::GetInstance();

    return 0;
}
