
#include "IonPhysics.hh"

#include "globals.hh"
#include "G4ios.hh"


#include "G4ParticleDefinition.hh"
#include "G4ProcessManager.hh"
//#include "G4LFission.hh"
//#include "G4LCapture.hh"
#include "G4Deuteron.hh"
#include "G4Triton.hh"
#include "G4He3.hh"
#include "G4Alpha.hh"
//#include "IonC12.hh"
#include "G4GenericIon.hh"

#include "G4ExcitationHandler.hh"
#include "G4Evaporation.hh"
#include "G4FermiBreakUp.hh"
#include "G4StatMF.hh"
#include "G4GeneratorPrecompoundInterface.hh"

#include "G4HadronInelasticProcess.hh"
#include "G4BinaryLightIonReaction.hh"
#include "G4TripathiCrossSection.hh"
#include "G4IonsShenCrossSection.hh"
#include "G4LEDeuteronInelastic.hh"
#include "G4LETritonInelastic.hh"
#include "G4LEAlphaInelastic.hh"


IonPhysics::IonPhysics(const G4String& name)
                 :  G4VPhysicsConstructor(name)
{
}
IonPhysics::~IonPhysics()
{
}

//#include "G4ParticleDefinition.hh"
//#include "G4ParticleTable.hh"

// Nuclei
#include "G4IonConstructor.hh"

void IonPhysics::ConstructParticle()
{
  //  Construct light ions
  G4IonConstructor pConstructor;
  pConstructor.ConstructParticle();  
}


//#include "G4ProcessManager.hh"


void IonPhysics::ConstructProcess()
{

  G4ParticleDefinition* particle = 0;
  G4ProcessManager* pmanager = 0;
  G4BinaryLightIonReaction* theBC = new G4BinaryLightIonReaction();
  theBC->SetMinEnergy(80*MeV);
  theBC->SetMaxEnergy(20*GeV);

  G4TripathiCrossSection * TripathiCrossSection= new G4TripathiCrossSection;
  G4IonsShenCrossSection * aShen = new G4IonsShenCrossSection;

  
  // Elastic Process
  theElasticModel = new G4LElastic();
  theElasticProcess.RegisterMe(theElasticModel);

  // Generic Ion
  //  pmanager = G4GenericIon::GenericIon()->GetProcessManager();
  // add process



  // GenericIon
  particle = G4GenericIon::GenericIon();
  pmanager = particle->GetProcessManager();
  G4HadronInelasticProcess* theIPGenericIon =
      new G4HadronInelasticProcess("IonInelastic",particle);
  theIPGenericIon->AddDataSet(TripathiCrossSection);
  theIPGenericIon->AddDataSet(aShen);
  G4BinaryLightIonReaction * theGenIonBC= new G4BinaryLightIonReaction;
  theGenIonBC->SetMinEnergy(0*MeV);
  theGenIonBC->SetMaxEnergy(10*GeV);
  theIPGenericIon->RegisterMe(theGenIonBC);
  pmanager->AddDiscreteProcess(theIPGenericIon);
  //-------------------------------------------------
  pmanager->AddDiscreteProcess(&theElasticProcess);
  pmanager->AddProcess(&fIonIonisation, ordInActive, 2, 2);
  pmanager->AddProcess(&fIonMultipleScattering);
  pmanager->SetProcessOrdering(&fIonMultipleScattering, idxAlongStep,  1);
  pmanager->SetProcessOrdering(&fIonMultipleScattering, idxPostStep,  1);
  //------------------------------------------------------------------------

  // C12
  //  particle = IonC12::Ion();
  //  pmanager = particle->GetProcessManager();
  //  G4HadronInelasticProcess* theIPIonC12 =
  //      new G4HadronInelasticProcess("IonC12Inelastic",particle);
  //  theIPIonC12->AddDataSet(TripathiCrossSection);
  //  theIPIonC12->AddDataSet(aShen);
  //  theIPIonC12->RegisterMe(theGenIonBC);
  //  pmanager->AddDiscreteProcess(theIPIonC12);
  //------------------------------------------------------------------------
  // Deuteron 
  particle = G4Deuteron::Deuteron();
  pmanager = particle->GetProcessManager();
  G4LEDeuteronInelastic* theDIModel = new G4LEDeuteronInelastic;
  theDIModel->SetMaxEnergy(100*MeV);
  theIPdeuteron.AddDataSet(TripathiCrossSection);
  theIPdeuteron.AddDataSet(aShen);
  theIPdeuteron.RegisterMe(theDIModel);
  theIPdeuteron.RegisterMe(theBC);
  pmanager->AddDiscreteProcess(&theIPdeuteron);
  //------------------------------------------------------
  //  pmanager = G4Deuteron::Deuteron()->GetProcessManager();
  // add process
  pmanager->AddDiscreteProcess(&theElasticProcess);

  //  fDeuteronModel = new G4LEDeuteronInelastic();
  //  fDeuteronProcess.RegisterMe(fDeuteronModel);
  //  pmanager->AddDiscreteProcess(&fDeuteronProcess);

  pmanager->AddProcess(&fDeuteronIonisation, ordInActive, 2, 2);

  pmanager->AddProcess(&fDeuteronMultipleScattering);
  pmanager->SetProcessOrdering(&fDeuteronMultipleScattering, idxAlongStep,  1);
  pmanager->SetProcessOrdering(&fDeuteronMultipleScattering, idxPostStep,  1);
  //------------------------------------------------------------------------------
  // Triton 
  //-----------------------------------------------------------------------------
  particle = G4Triton::Triton();
  pmanager = particle->GetProcessManager();
  G4LETritonInelastic* theTIModel = new G4LETritonInelastic;
  theTIModel->SetMaxEnergy(100*MeV);
  theIPtriton.AddDataSet(TripathiCrossSection);
  theIPtriton.AddDataSet(aShen);
  theIPtriton.RegisterMe(theTIModel);
  theIPtriton.RegisterMe(theBC);
  pmanager->AddDiscreteProcess(&theIPtriton);
  pmanager = G4Triton::Triton()->GetProcessManager();
  // add process
  //----------------------------------------------
  pmanager->AddDiscreteProcess(&theElasticProcess);

  //  fTritonModel = new G4LETritonInelastic();
  // fTritonProcess.RegisterMe(fTritonModel);
  //pmanager->AddDiscreteProcess(&fTritonProcess);

  pmanager->AddProcess(&fTritonIonisation, ordInActive, 2, 2);

  pmanager->AddProcess(&fTritonMultipleScattering);
  pmanager->SetProcessOrdering(&fTritonMultipleScattering, idxAlongStep,  1);
  pmanager->SetProcessOrdering(&fTritonMultipleScattering, idxPostStep,  1);
 
  // Alpha 

 particle = G4Alpha::Alpha();
  pmanager = particle->GetProcessManager();
  G4LEAlphaInelastic* theAIModel = new G4LEAlphaInelastic;
  theAIModel->SetMaxEnergy(100*MeV);
  theIPalpha.AddDataSet(TripathiCrossSection);
  theIPalpha.AddDataSet(aShen);
  theIPalpha.RegisterMe(theAIModel);
  theIPalpha.RegisterMe(theBC);
  pmanager->AddDiscreteProcess(&theIPalpha);
  //-------------------------------------------------------------------------
  //  pmanager = G4Alpha::Alpha()->GetProcessManager();
  // add process
  pmanager->AddDiscreteProcess(&theElasticProcess);

  //  fAlphaModel = new G4LEAlphaInelastic();
  //  fAlphaProcess.RegisterMe(fAlphaModel);
  //  pmanager->AddDiscreteProcess(&fAlphaProcess);

  pmanager->AddProcess(&fAlphaIonisation, ordInActive, 2, 2);

  pmanager->AddProcess(&fAlphaMultipleScattering);
  pmanager->SetProcessOrdering(&fAlphaMultipleScattering, idxAlongStep,  1);
  pmanager->SetProcessOrdering(&fAlphaMultipleScattering, idxPostStep,  1);
  //------------------------------------------------------------------------
  // He3
  particle = G4He3::He3();
  pmanager = particle->GetProcessManager();
  G4HadronInelasticProcess* theIPHe3 =
      new G4HadronInelasticProcess("He3Inelastic",particle);
  theIPHe3->AddDataSet(TripathiCrossSection);
  theIPHe3->AddDataSet(aShen);
  theIPHe3->RegisterMe(theGenIonBC);
  pmanager->AddDiscreteProcess(theIPHe3);
  //------------------------------------------------------------------------
  //  pmanager = G4He3::He3()->GetProcessManager();
  // add process
  pmanager->AddDiscreteProcess(&theElasticProcess);

  pmanager->AddProcess(&fHe3Ionisation, ordInActive, 2, 2);

  pmanager->AddProcess(&fHe3MultipleScattering);
  pmanager->SetProcessOrdering(&fHe3MultipleScattering, idxAlongStep,  1);
  pmanager->SetProcessOrdering(&fHe3MultipleScattering, idxPostStep,  1);
   
}



