#include "PamG4RangeCutsPhysicsList.h"
#include "PamG4RangeCutsPhysics.h"

#include <TG4Globals.h>
#include <TG4G3PhysicsManager.h>

#include <G4ParticleDefinition.hh>
#include <G4ProcessManager.hh>
#include <G4ProcessTable.hh>


PamG4RangeCutsPhysicsList* PamG4RangeCutsPhysicsList::fgInstance = 0;



PamG4RangeCutsPhysicsList::PamG4RangeCutsPhysicsList()
  : G4VModularPhysicsList(),
    TG4Verbose("RangeCutsPhysicsList")
{
/// Default constructor

   SetVerboseLevel(TG4VVerbose::VerboseLevel());

   Configure();
}

PamG4RangeCutsPhysicsList::~PamG4RangeCutsPhysicsList() 
{
/// Destructor
  fgInstance = 0; 
}


void PamG4RangeCutsPhysicsList::Configure()
{
/// Create the selected physics constructors
/// and registeres them in the modular physics list.

  Int_t verboseLevel = TG4VVerbose::VerboseLevel();

  RegisterPhysics(new PamG4RangeCutsPhysics(verboseLevel));

}    


void PamG4RangeCutsPhysicsList::ConstructProcess()
{
/// Construct all processes.

  // lock physics manager
  TG4G3PhysicsManager* g3PhysicsManager = TG4G3PhysicsManager::Instance();
  g3PhysicsManager->Lock();  

  // create processes for registered physics
  // To avoid call AddTransportation twice we do not call directly
  // G4VModularPhysicsList::ConstructProcess();
  // but call registered processes ourselves:
  G4PhysConstVector::iterator itr;
  for (itr = physicsVector->begin(); itr!= physicsVector->end(); ++itr) {
    (*itr)->ConstructProcess();
  }
}

G4int PamG4RangeCutsPhysicsList::VerboseLevel() const 
{
/// Return verbose level (via TG4VVerbose)

  return TG4VVerbose::VerboseLevel();
}

void PamG4RangeCutsPhysicsList::VerboseLevel(G4int level) 
{
/// Set the specified level to both TG4Verbose and 
/// G4VModularPhysicsList.
/// The verbose level is also propagated to registered physics contructors.

  TG4VVerbose::VerboseLevel(level);
  SetVerboseLevel(level);
  
  G4PhysConstVector::iterator it;
  for ( it = physicsVector->begin(); it != physicsVector->end(); ++it ) {
    TG4Verbose* verbose = dynamic_cast<TG4Verbose*>(*it);
    if ( verbose )
      verbose->VerboseLevel(level);
    else
      (*it)->SetVerboseLevel(level);  
  }
}

  
 
