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


#include "StackingAction.hh"

#include "G4ParticleDefinition.hh"
#include "G4ParticleTypes.hh"
#include "G4Track.hh"
#include "G4ios.hh"

#include "G4VProcess.hh"

#include "Analysis.hh"


#include "G4EventManager.hh"
#include "G4RunManager.hh"

StackingAction::StackingAction(): gammaCounter(0){}


StackingAction::~StackingAction(){}


G4ClassificationOfNewTrack StackingAction::ClassifyNewTrack(const G4Track * aTrack)
{
    /* ++ StackingAction for optical photons ++ */
    if(aTrack->GetDefinition() == G4OpticalPhoton::OpticalPhotonDefinition())
    {
        Analysis::GetInstance()->IncreaseReflectionRefractionAndScatteringVectors(aTrack->GetTrackID());
        Analysis::GetInstance()->IncreaseLengthVectors(aTrack->GetTrackID());

        if(aTrack->GetParentID()>0) // particle is secondary
        {
            gammaCounter++;
            G4int creatorProcessId = 0;

            if(aTrack->GetCreatorProcess()->GetProcessName() == "Scintillation")
                creatorProcessId = 1;

            if(aTrack->GetCreatorProcess()->GetProcessName() == "Cerenkov")
                creatorProcessId = 2;

            if(aTrack->GetCreatorProcess()->GetProcessName() == "OpWLS")
                creatorProcessId = 3;

            if (aTrack->GetCreatorProcess())
                AddProcess(aTrack->GetCreatorProcess());// classify here
        }
    }
    /* ++ End of StackingAction of optical photons ++ */

    return fUrgent;
}


void StackingAction::NewStage()
{
    G4cout << "Number of optical photons produced in this event : " << gammaCounter << G4endl << G4endl;

    for(ProcMap::iterator it=procs.begin() ; it!=procs.end() ; ++it)
        G4cout << " Process " << it->first->GetProcessName() << " generated " << it->second << " photons" << G4endl;

    G4cout<<G4endl;
}


void StackingAction::PrepareNewEvent()
{ 
    gammaCounter = 0;
    Reset();
}


void StackingAction::AddProcess(const G4VProcess * p)
{ 
    ProcMap::iterator it = procs.find(p);

    if (it!=procs.end())
        it->second++;
    else
        procs[p]=1;
}

void StackingAction::Reset()
{ 
    for (ProcMap::iterator it = procs.begin() ; it!=procs.end() ; ++it)
        it->second=0;
}
