///////////////////////////////////////////////////////////////////////
// Functions for converting ZDAB to ROOT and vice versa
//
// Author: Andy Mastbaum
//
// Revision History:
//   13 Nov 2014: Matt Strait - Fixed shadowed variable warning
//   26 Jan 2015: Andy Mastbaum - Fixed unhandled exception in event packer
//   27 Jun 2015: Javier Caravaca - Convert properly SNO EpedRecords into ECAHeaders
//   07 Jun 2016: F. Descamps - Add Valid GTID
//   19 Oct 2016 : M Stringer - Changes to how MCTracks are accessed (PR #1508).
//   15 Mar 2017 : Eric Marzec - Change how CAEN traces are indexed
//
///////////////////////////////////////////////////////////////////////

#ifndef __ZDAB_CONVERT__
#define __ZDAB_CONVERT__

#include <map>
#include <exception>

#ifdef __CINT__
// This is required due to limitations in ROOT's cint system, http://root.cern.ch/phpBB3/viewtopic.php?f=5&t=17360
typedef char __signed;
typedef char int8_t;
#endif

#include <stdint.h>

#include <RAT/DS/PMT.hh>

class PmtEventRecord;
class RunRecord;
class TriggerInfo;
class EpedRecord;

namespace RAT {
    namespace DS {
        class Entry;
        class Run;
        class TrigHeader;
        class ECAHeader;
        class Digitiser;
    }
}

namespace ratzdab {

    /* Convert ZDAB records to RAT ROOT objects */
    namespace unpack {
        RAT::DS::Entry* event(PmtEventRecord* const o);
        RAT::DS::Run* rhdr(RunRecord* const o);

        // note: TRIGInfo::runID is not set
        RAT::DS::TrigHeader* trig(TriggerInfo* const o);

        // note: EPEDInfo::runID is not set
        RAT::DS::ECAHeader* eped(EpedRecord* const o);

        // helpers
        RAT::DS::Digitiser caen(uint32_t* const p);
        RAT::DS::PMTUncal pmt(uint32_t* const p, const int lcn);
        uint32_t tubii(uint32_t* const p);
    }

    /* Convert RAT ROOT objects to ZDAB records */
    namespace pack {
        PmtEventRecord* event(RAT::DS::Entry* o, int ev_id=0);
        RunRecord* rhdr(RAT::DS::Run* const o);
        TriggerInfo* trig(RAT::DS::TrigHeader* const o,
                          const uint32_t gtid);
        EpedRecord* eped(RAT::DS::ECAHeader* const o,
                         const uint32_t gtid);
    }

    /* Mapping from PDG to SNOMAN particle code (incomplete list) */
    std::map<int, int> get_pdg_to_snoman_map();

    /* Mapping from PDG code to mass, to compute total energy
        (incomplete list) */
    std::map<int, float> get_pdg_to_mass_map();

    /* Exception thrown if unable to handle a record */
    static class unknown_record_error : public std::exception {
        public:
            virtual const char* what() const throw() {
                return "Unable to convert unknown record type.";
            }
    } record_unknown;

}  // namespace ratzdab

#endif  // __ZDAB_CONVERT__