//
// ********************************************************************
// * License and Disclaimer                                           *
// *                                                                  *
// * The  Geant4 software  is  copyright of the Copyright Holders  of *
// * the Geant4 Collaboration.  It is provided  under  the terms  and *
// * conditions of the Geant4 Software License,  included in the file *
// * LICENSE and available at  http://cern.ch/geant4/license .  These *
// * include a list of copyright holders.                             *
// *                                                                  *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work  make  any representation or  warranty, express or implied, *
// * regarding  this  software system or assume any liability for its *
// * use.  Please see the license in the file  LICENSE  and URL above *
// * for the full disclaimer and the limitation of liability.         *
// *                                                                  *
// * This  code  implementation is the result of  the  scientific and *
// * technical work of the GEANT4 collaboration.                      *
// * By using,  copying,  modifying or  distributing the software (or *
// * any work based  on the software)  you  agree  to acknowledge its *
// * use  in  resulting  scientific  publications,  and indicate your *
// * acceptance of all terms of the Geant4 Software license.          *
// ********************************************************************
//
// Hadrontherapy advanced example for Geant4
// See more at: https://twiki.cern.ch/twiki/bin/view/Geant4/AdvancedExamplesHadrontherapy

#ifndef HadrontherapyLet_h
#define HadrontherapyLet_h 1
#endif

#include "G4ParticleDefinition.hh"
#include "globals.hh"
#include <fstream>
#include <vector>
#include <string>

#include "HadrontherapyMatrix.hh"
struct ionLet
{
    G4bool isPrimary;        // True if particle is primary
    G4int PDGencoding;      // Particle data group id for the particle
    G4String fullName;      // AZ[excitation energy]: like He3[1277.4], He4[0.0], Li7[231.4], ...
    G4String name;          // simple name without excitation energy: He3, He4, Li7, ...
    G4int Z;                // atomic number
    G4int A;            // mass number
    G4double *letDN , *letDD, *letTN , *letTD; // Track averaged LET and Dose averaged LET
    //friend G4bool operator<(const ionLet& a, const ionLet& b) {return (a.Z == b.Z) ? b.A < a.A : b.Z < a.Z ;}
    G4bool operator<(const ionLet& a) const{return (this->Z == a.Z) ? this-> A < a.A : this->Z < a.Z ;}
    // For isotopes sort by the mass number, else sort by the atomic one.
};

class G4Material;
class HadrontherapyMatrix;
class HadrontherapyPrimaryGeneratorAction;
class HadrontherapyInteractionParameters;
class HadrontherapyDetectorConstruction;

class HadrontherapyLet
{
private:
    HadrontherapyLet(HadrontherapyDetectorConstruction*);
    
public:
    ~HadrontherapyLet();
    static HadrontherapyLet* GetInstance(HadrontherapyDetectorConstruction*);
    static HadrontherapyLet* GetInstance();
    static G4bool doCalculation;
    void Initialize();
    void Clear();
    
    void Fill(G4int i, G4int j, G4int k, G4double DE, G4double DX);
    void FillEnergySpectrum (G4int trackID,
                             G4ParticleDefinition* particleDef,
                             G4double ekinMean,
                             const G4Material* mat,
                             G4double DE,
                             G4double DEEletrons,
                             G4double DX,
                             G4int i, G4int j, G4int k);
    void LetOutput();
    void StoreLetAscii();
    
    
private:
    static HadrontherapyLet *instance;
    HadrontherapyPrimaryGeneratorAction* pPGA;
    // Detector material
    G4Material* detectorMat;
    G4double density;
    G4String filename;
    
    std::ofstream ofs;
    std::ofstream stopFile;
    HadrontherapyMatrix *matrix;
    G4int nVoxels, numberOfVoxelAlongX, numberOfVoxelAlongY, numberOfVoxelAlongZ ;
    G4double primaryEnergy, energyLimit, binWidth;
    G4int nBins;
    G4double  nT, dT, nD, dD;
    G4double  nSecondaryT, nSecondaryD, dSecondaryT, dSecondaryD;
    G4double  nPrimaryT, nPrimaryD, dPrimaryT, dPrimaryD ;
    G4double *secondaryLetT,  *secondaryLetD, *totalLetT, *DtotalLetT , *DtotalLetD, *totalLetD;
    G4String nome_file;
    
    std::vector<ionLet> ionLetStore;
};
