#ifndef GlastEvent_CALDigi_H
#define GlastEvent_CALDigi_H 1

// Include files

#include <iostream>
#include <vector>
#include "idents/CALID.h"
#include "Gaudi/Kernel/Kernel.h"
#include "Gaudi/Kernel/ContainedObject.h"

/*!
//------------------------------------------------------------------------------
//
// ClassName: CALDigi 
// 
// Description: Digitizations for CAL 
// 
// Author: J. Eric Grove 5 Feb 2001 
//------------------------------------------------------------------------------
*/

class CALDigi : virtual public ContainedObject {

public:

/// Constructors
CALDigi();

/// Destructor
~CALDigi() { };

/// Retrieve digi identifier
const CALID getID() const;

// Enumeration of ADC range values
typedef enum {
LEX8 = 0,
LEX1,
HEX8,
HEX1
} ADCRange;

typedef enum {
Pos = 0,
Neg
} LogEnd;

typedef enum{
BESTRANGE = 0,
ALLRANGE
} Mode;

class Readout {

private:
short m_adcP, m_adcM;
char m_rangeP, m_rangeM;

public:
/// constructor
// both ADC values and both ranges packed into raw tlm word
Readout(unsigned int bothEnds)
{ m_adcP = (bothEnds >> 14) & 0xfff; 
m_rangeP = ((bothEnds >> 14) & 0x3000) / 4096;
m_adcM = bothEnds & 0xfff; 
m_rangeM = (bothEnds & 0x3000) / 4096; };

// ADC values packed with range info
Readout(short adcP, short adcM)
{ m_adcP = adcP & 0xfff; m_rangeP = adcP / 4096;
m_adcM = adcM & 0xfff; m_rangeM = adcM / 4096; };

// ADC and range values unpacked
Readout(char rangeP, short adcP, char rangeM, short adcM) :
m_rangeP(rangeP), m_adcP(adcP), m_rangeM(adcM), m_adcM(adcM) {};

/// destructor
~Readout() {};

short getADC(LogEnd end) const {return end == Pos ? m_adcP : m_adcM;};
short getRange(LogEnd end) const {return end == Pos ? m_rangeP : m_rangeM;};
};

short getADC(short readoutIndex, LogEnd end) const {
return m_readout[readoutIndex].getADC(end);
};

short getRange(short readoutIndex, LogEnd end) const {
return m_readout[readoutIndex].getRange(end);
};

// Read out the current pair of log ends
Readout& getReadout(short readoutIndex) { return m_readout[index] };


/// Serialize the object for writing
virtual StreamBuffer& serialize( StreamBuffer& s ) const;
/// Serialize the object for reading
virtual StreamBuffer& serialize( StreamBuffer& s );
/// Fill the ASCII output stream
virtual std::ostream& fillStream( std::ostream& s ) const;

private:

/// CAL ID
CALID m_CalID;

// readout
vector<Readout> m_readout;

// readout mode
static Mode m_mode; // revisit whether this should be static

/// packed pulse heights
unsigned short m_ADCValues[2][4];

};


//! Definition of all container types of CALDigi
template <class TYPE> class ObjectVector;
typedef ObjectVector<CALDigi> CALDigiVector;

#endif // GlastEvent_CALDigi_H