// $Id: PamVMCApplication.cxx,v 1.0 2007/06/01 
//
// Geant4 ExampleN06 adapted to Virtual Monte Carlo 
#include <cstdlib>
#include <string>
#include <TROOT.h>
#include <TInterpreter.h>
#include <TVirtualMC.h>
#include <Riostream.h>
#include <TGeoManager.h>
#include <TVirtualGeoTrack.h>

#include "PamVMCApplication.h"
#include "PamVMCStack.h"
#include "PamVMCDetectorConstruction.h"
#include "PamVMCPrimaryGenerator.h"

ClassImp(PamVMCApplication)

PamVMCApplication::PamVMCApplication(const char *name, const char *title) 
  : TVirtualMCApplication(name,title),
    fEventNo(0),
    fVerbose(0),
    fStack(0),
    fDetConstruction(0),
    fPrimaryGenerator(0)
{
// Standard constructor

  // Create a user stack
    fStack = new PamVMCStack(10000);
  
  // Create detector construction
  fDetConstruction = new PamVMCDetectorConstruction();
  
  // Create a primary generator
  fPrimaryGenerator = new PamVMCPrimaryGenerator(fStack);
#ifdef PAMFIELD
  // Load the PAMELA magnetic field

  std::string pamcal=getenv("PAM_CALIB"); pamcal+="/trk-param/field_param-0/";
  std::cout << "PAMELA env: " << pamcal << std::endl;
  pamfield.LoadField(pamcal.c_str());
#endif
}


PamVMCApplication::PamVMCApplication()
  : TVirtualMCApplication(),
    fEventNo(0),
    fVerbose(0),
    fStack(0),
    fDetConstruction(0),
    fPrimaryGenerator(0)
{    
// Default constructor
}

PamVMCApplication::~PamVMCApplication() 
{
// Destructor  
  
  delete fStack;
  delete fDetConstruction;
  delete fPrimaryGenerator;
  delete gMC;
  gMC = 0;
}

//
// public methods
//

void PamVMCApplication::InitMC(const char* setup)
{    
// Initialize MC.

  fVerbose.InitMC();

    gROOT->LoadMacro(setup);
    gInterpreter->ProcessLine("Config()");
    gMC->SetStack(fStack);
    gMC->Init();
    gMC->BuildPhysics(); 
}

void PamVMCApplication::RunMC(Int_t nofEvents)
{    
// MC run.

  fVerbose.RunMC(nofEvents);

  gMC->ProcessRun(nofEvents);

  ////  fVerbose.FinishRun();
}

void PamVMCApplication::ConstructGeometry()
{    
// Construct geometry using detector contruction class

  fVerbose.ConstructGeometry();
  fDetConstruction->ConstructGeometry();
      
}

void PamVMCApplication::InitGeometry()
{    
// Initialize geometry
  
  fVerbose.InitGeometry();
}


void PamVMCApplication::GeneratePrimaries()
{    
// Fill the user stack (derived from TVirtualMCStack) with primary particles.
  
  ///// fVerbose.GeneratePrimaries();

  fPrimaryGenerator->GeneratePrimaries();
}

void PamVMCApplication::BeginEvent()
{    
// User actions at beginning of event

  ///// fVerbose.BeginEvent();

  fEventNo++;
 }

void PamVMCApplication::BeginPrimary()
{    
// User actions at beginning of a primary track

////  fVerbose.BeginPrimary();
}

void PamVMCApplication::PreTrack()
{    
// User actions at beginning of each track

  ////// fVerbose.PreTrack();
  
}

void PamVMCApplication::Stepping()
{    
// User actions at each step

//////  fVerbose.Stepping();
}

void PamVMCApplication::PostTrack()
{    
// User actions after finishing of each track


  ///// fVerbose.PostTrack();
}

void PamVMCApplication::FinishPrimary()
{    
// User actions after finishing of a primary track

  ///// fVerbose.FinishPrimary();
}

void PamVMCApplication::FinishEvent()
{    
// User actions after finishing of an event


  /////fVerbose.FinishEvent();
  


  fStack->Reset();
} 

void PamVMCApplication::Field(const Double_t* x, Double_t* b) const
{
// Uniform magnetic field

#ifdef PAMFIELD
     b[0] = pamfield.GetBX((float *)x);
     b[1] = pamfield.GetBY((float *)x);
     b[2] = pamfield.GetBZ((float *)x);
#else
   for (Int_t i=0; i<3; i++) b[i] = 0.0;
#endif
}
