///////////////////////////////////////////////////////////////////
//
// Code that is executed for every track (if enabled). This code
// attaches trajectory objects to tracks if the user has requested that
// the track's history be collated. This is a CPU and memory intensive
// decision, so it is off by default.
//
// Author: P G Jones <p.g.jones@qmul.ac.uk>
// Author: S Langrock <s.langrock@qmul.ac.uk> -- contact person
//
// REVISION HISTORY:
//     2014-05-25 : P G Jones - new file.
//     2016-02-12: W Heintzelman - add eBasicPhotons ETrackingLevel with less
//                 detailed photon trajectories to speed auxiliary
//                 simulations in PEnergy.  Note added 2017-03-13:  this is
//                 no longer used by PEnergy
//
///////////////////////////////////////////////////////////////////
#ifndef __RAT_TrackingAction_hh__
#define __RAT_TrackingAction_hh__

#include <G4UserTrackingAction.hh>

#include <vector>
#include <string>

namespace RAT
{
class TrackingMessenger;
class Trajectory;

class TrackingAction : public G4UserTrackingAction
{
public:
  // The various tracking levels
  enum ETrackingLevel { eNone, eCondensed, eFull, eBasicPhotons };

  // Construct the tracking action, must construct G4UserTrackingAction and new the messenger
  TrackingAction();

  // Destruct the tracking action by destroying the messenger
  virtual ~TrackingAction();

  // Called by Geant4 before it starts tracking a track
  //
  // This class decides whether to attach trajectory information to the track.
  // If attached the trajectory stores the track steps
  //
  // track: the track to consider
  void PreUserTrackingAction( const G4Track* track );

  // Called by Geant4 after a track has been fully tracked
  //
  // track: the track to consider
  void PostUserTrackingAction( const G4Track* track );

  // Called by the tracking messenger to set the tracking level
  //
  // level: the level to set
  void SetTrackingLevel( const ETrackingLevel level );

  // Called by the tracking messenger to omit a particle
  //
  // name: name of the of particle to omit
  void OmitParticle( const std::string& name ) { fParticlesToOmit.push_back( name ); }

  // Get the current trajectory
  //
  // Must strees this is current, do not hold onto this object
  //
  // Returns a pointer to the current trajectory
  Trajectory* GetTrajectory() const;
private:
  std::vector<std::string> fParticlesToOmit; // List of particles to be omitted from tracking, by name
  ETrackingLevel fTrackingLevel; // The level of tracking detail to collate
  TrackingMessenger* fTrackingMessenger; // The messenger for tracking, decodes user commands
};

} //::RAT

#endif