////////////////////////////////////////////////////////////////////////
/// \class RAT::Gen_Flasher
///
/// \brief Top Level Event Producer for flashers
///
/// \author John Walker <john.walker@liverpool.ac.uk>
/// \contact Eric Marzec <marzece@gmail.com>  -- contact person
///
/// REVISION HISTORY
///     2015-05-28 : J. Walker - New file
///     2016-03-15 : J. Walker - Change to event position and direction
///                              after PMT model fix
///     2016-08-1  : E. Marzec - Make sure flashers aren't created in
///                               tubes that aren't at high voltage
///     2017-02-07  : N. Barros - Commented low level generators (inherited from GLG4Gen)
///                             - Called BeginOfRUn to load the necessary tables.
///     2017-03-20 : R. Knapik - Added new contact person (eric marzec)
///
/// \details This generator simulates photon emissions from PMTs. User
/// RatDB settings for intensity, angular, timing and wavelength distributions.
////////////////////////////////////////////////////////////////////////

#ifndef __RAT_Gen_Flasher__
#define __RAT_Gen_Flasher__

#include <RAT/GLG4Gen.hh>
#include <RAT/GLG4TimeGen.hh>
#include <RAT/VertexGen_Flasher.hh>

#include <G4Event.hh>

#include <vector>

using namespace std;

class G4ParticleDefinition;

namespace RAT {

class Gen_FlasherMessenger;

class Gen_Flasher : public GLG4Gen {
public:

  Gen_Flasher();

  virtual ~Gen_Flasher();

  virtual void GenerateEvent(G4Event *event);

  virtual bool IsRepeatable() const { return true; };

  /// Basic state - does nothing yet but should allow choice of time generator for between pulses here
  ///
  /// @param[in] state SetState state
  virtual void SetState(G4String state);
  virtual G4String GetState() const;

  /// specify the type of time generator to use to give time BETWEEN Flasher pulses, default is Poisson
  /// @param[in] state the time generator state
  virtual void SetTimeGen(G4String state);
  /// @param[in] offset Time reset to this value
  virtual void ResetTime(G4double offset=0.0);

  /// specify/get parameters for time generator for BETWEEN Flasher pulses (eg from generator/rate/ commands)
  /// @param[in] state the time generator state
  virtual void SetTimeState(G4String state);
  virtual G4String GetTimeState() const;

  /// specify/get parameters for vertex generator - (eg from generator/vtx/ commands) These don't apply for this Flasher generator so just print a warning
  /// @param[in] state the vertex generator state
  virtual void SetVertexState(G4String state);
  virtual G4String GetVertexState() const;

  /// specify/get parameters for position generator - (eg from generator/pos/ commands) These don't apply for  this Flasher generator so just print a warning
  /// @param[in] state the Position generator state
  virtual void SetPosState(G4String state);
  virtual G4String GetPosState() const;

  /// Set Poisson fluctuations for number of photons per pulse
  /// @param[in] set boolean setting, 1 for poisson fluctuations on
  void SetPoissonFluctuations(G4bool set);

  virtual void BeginOfRun();

protected:
  /// Fills the member variables with the relevant tables from the DB
  void FillTables();

  G4String fStateStr;
  // NFB : FIXME : Remove this
  //GLG4TimeGen *fTimeGen; // the time generator
  //VertexGen_Flasher *fVtxGen; // the vertex generator
  G4bool fPoisson; // poisson fluctuations flag
  vector<G4double> fpmtx; // arrays of PMT data
  vector<G4double> fpmty;
  vector<G4double> fpmtz;
  vector<G4double> fpmtu;
  vector<G4double> fpmtv;
  vector<G4double> fpmtw;
  G4double fconc_length; // length of concentrator
  G4double fconc_offset; // offset of concentrator from equator
  G4double fpmt_depth; // depth from equator to generate event
  G4double fpmt_dynode_radius; // radius of dynode stack
};

} // namespace RAT

#endif // __RAT_Gen_Flasher__