////////////////////////////////////////////////////////////////////
/// \class RAT::VertexGen_ELLIE
///
/// \brief Vertex generator - for ELLIE (or other light source) beams
///
/// \author Jeanne Wilson <j.r.wilson@qmul.ac.uk> -- contact person
///
///  REVISION HISTORY
/// 	- first version : J. Wilson - a modification of Gen_ELLIE to only deal with vertex.
///                 motivated by need for separate vertex, position generators for
///                  use with coincidence generator
///     - 2014-11-26: Matt Strait - doxygen fixes
///     - 2017-02-07: Nuno Barros - Added BeginOfRun to load the database
///
/// \details This generator simulates bunches of photons from fibres. User RatDB settings for fibre position, direction, angular, timing and wavelength distributions.
////////////////////////////////////////////////////////////////////

#ifndef __RAT_VertexGen_ELLIE__
#define __RAT_VertexGen_ELLIE__

#include <RAT/GLG4VertexGen.hh>
#include <vector>
#include <globals.hh>
#include <CLHEP/Random/RandGeneral.h>
#include "RAT/GLG4Gen.hh"

class G4ParticleDefinition;

namespace RAT {

class VertexGen_ELLIE : public GLG4VertexGen {
public:
  VertexGen_ELLIE(const char *arg_dbname="vertexellie");
  virtual ~VertexGen_ELLIE();
  void Init();
  virtual void GeneratePrimaryVertex(G4Event *event,
                                    G4ThreeVector &dx,
                                    G4double dt);
  float SampleRandom(std::vector<float> myx, std::vector<float> myy, std::vector<float> mycum);

  /** interface for getting and setting the state*/
  virtual void SetState(G4String state);
  virtual G4String GetState();
  virtual void BeginOfRun();

private:
  /** Only call the initialisation once - if this flag isn't set */
  bool  fInitDB;

  /** Fibre IDs  */
  std::string fFibreID;
  /** Source  */
  std::string fSource;
  /** ELLIE direction  */
  float fDirX, fDirY, fDirZ;

  /** Wavelength mode for this ELLIE (1 for "mono", 0 for the distribution) The distribution
  name is the wavelength as a string and defines the index of the ELLIEWAVE ratdb table*/
  int fMono_wls;
  /** ELLIE wavelength distribution - string tells you what distribution to read */
  std::string fELLIEWavelength;
  /** ELLIE wavelength range - use a portion of the wavelength distribution within low and high setpoints */
  std::vector<float> fELLIEWavelengthRange;

  /** Time mode for this ELLIE (1 for "mono", 0 for the distribution) The distribution
  name is the wavelength as a string and defines the index of the ELLIETIME ratdb table*/
  int fMono_time;
  /** ELLIE time distribution - string tells you what distribution to read */
  std::string fELLIETime;

  /** Angle mode for this ELLIE (1 for "iso", 0 otherwise) The distribution
  name is the fibre id and defines the index of the ELLIEANGLE ratdb table*/
  int fIso_angle;
  /** flag set to 1 if there is to be no dispersion of the beam */
  int fZero_angle;
  /** ELLIE angular distribution - string tells you what distribution to read */
  std::string fELLIEAngle;

  /** true = number of photons per pulse is selected from poisson distribution with mean=photons_per_event, \n
      false = number of photons per pulse=photons_per_event */
  bool fPoisson;

  /** Vector for specified angles */
  std::vector<float> fang;
  /** Vector for cumulative angular intensity distribution */
  std::vector<float> fangCumMag;
  /** Vector for angular intensity */
  std::vector<float> fangInt;

  /** Vector for specified times */
  std::vector<float> ftime;
  /** Vector for cumulative time intensity distribution */
  std::vector<float> ftimeCumMag;
  /** Vector for time intensity */
  std::vector<float> ftimeInt;

  /** Vector for specified wavelengths */
  std::vector<float> fwave;
  /** Vector for cumulative wave intensity distribution */
  std::vector<float> fwaveCumMag;
  /** Vector for wave intensity */
  std::vector<float> fwaveInt;

  /** Limits in angular distribution */
  float fMinAngle, fMaxAngle;
  /** Limits on wavelength distribution */
  float fMinWl, fMaxWl;
  /** Limits on time distribution */
  float fMinTime,fMaxTime;
  /** Factor for converting angles (random generator uses radians so if distribution set in degrees = 360/twopi, otherwise =1*/
  float fConvertAngle;

  /** Number of photons per ELLIE pulse */
  int fPhotonsPerEvent;
  /** Particles must be defined as optical photons */
  G4ParticleDefinition *fPhotonDef;

};

} // namespace RAT

#endif