#ifndef CrcBeTrgEventData_HH
#define CrcBeTrgEventData_HH

#include <string>
#include <iostream>


class CrcBeTrgEventData {

public:
  enum {
    versionNumber=0
  };

  enum {
    maxFifoLength=512,
    maxWordLength=maxFifoLength+8
  };

  CrcBeTrgEventData();

  unsigned inputStatus() const;
  void inputStatus(unsigned n);

  unsigned inputCatch() const;
  void inputCatch(unsigned n);

  unsigned prebusyCatch() const;
  void prebusyCatch(unsigned n);

  unsigned signalCatch() const;
  void signalCatch(unsigned n);

  unsigned control() const;
  void control(unsigned n);

  unsigned initialFifoStatus() const;
  void initialFifoStatus(unsigned n);

  unsigned finalFifoStatus() const;
  void finalFifoStatus(unsigned n);

  unsigned triggerCounter() const;
  void triggerCounter(unsigned n);

  unsigned prebusyTriggerCounter() const;
  void prebusyTriggerCounter(unsigned n);

  unsigned numberOfFifoWords() const;
  void numberOfFifoWords(unsigned n);

  const unsigned* fifoData() const;
  unsigned* fifoData();

  std::ostream& print(std::ostream &o, std::string s="") const;


private:
  unsigned _inputStatus;            // Reg  2
  unsigned _inputCatch;             // Reg  3
  unsigned _triggerCounter;         // Reg  5
  unsigned _prebusyTriggerCounter;  // Reg  8
  unsigned _control;                // Reg 11
  unsigned _prebusyCatch;           // Reg 18
  unsigned _signalCatch;           // Reg 27
  UtlPack  _initialFifoStatus;      // Reg 14
  UtlPack  _finalFifoStatus;        // Reg 14
  unsigned _numberOfFifoWords;
};


#ifdef CALICE_DAQ_ICC

#include <cstring>

CrcBeTrgEventData::CrcBeTrgEventData() {
  memset(this,0,sizeof(CrcBeTrgEventData));
}

unsigned CrcBeTrgEventData::inputStatus() const {
  return _inputStatus;
}

void CrcBeTrgEventData::inputStatus(unsigned n) {
  _inputStatus=n;
}

unsigned CrcBeTrgEventData::inputCatch() const {
  return _inputCatch;
}

void CrcBeTrgEventData::inputCatch(unsigned n) {
  _inputCatch=n;
}

unsigned CrcBeTrgEventData::prebusyCatch() const {
  return _prebusyCatch;
}

void CrcBeTrgEventData::prebusyCatch(unsigned n) {
  _prebusyCatch=n;
}

unsigned CrcBeTrgEventData::signalCatch() const {
  return _signalCatch;
}

void CrcBeTrgEventData::signalCatch(unsigned n) {
  _signalCatch=n;
}

unsigned CrcBeTrgEventData::control() const {
  return _control;
}

void CrcBeTrgEventData::control(unsigned n) {
  _control=n;
}

unsigned CrcBeTrgEventData::initialFifoStatus() const {
  return _initialFifoStatus.word();
}

void CrcBeTrgEventData::initialFifoStatus(unsigned n) {
  _initialFifoStatus=n;
}

unsigned CrcBeTrgEventData::finalFifoStatus() const {
  return _finalFifoStatus.word();
}

void CrcBeTrgEventData::finalFifoStatus(unsigned n) {
  _finalFifoStatus=n;
}

unsigned CrcBeTrgEventData::triggerCounter() const {
  return _triggerCounter;
}

void CrcBeTrgEventData::triggerCounter(unsigned n) {
  _triggerCounter=n;
}

unsigned CrcBeTrgEventData::prebusyTriggerCounter() const {
  return _prebusyTriggerCounter;
}

void CrcBeTrgEventData::prebusyTriggerCounter(unsigned n) {
  _prebusyTriggerCounter=n;
}

unsigned CrcBeTrgEventData::numberOfFifoWords() const {
  return _numberOfFifoWords;
}

void CrcBeTrgEventData::numberOfFifoWords(unsigned n) {
  assert(n<=maxFifoLength);
  _numberOfFifoWords=n;
}

const unsigned* CrcBeTrgEventData::fifoData() const {
  return &_numberOfFifoWords+1;
}

unsigned* CrcBeTrgEventData::fifoData() {
  return &_numberOfFifoWords+1;
}

std::ostream& CrcBeTrgEventData::print(std::ostream &o, std::string s) const {
  o << s << "CrcBeTrgEventData::print()" << std::endl;
  o << s << " Prebusy trigger counter  = " << std::setw(10) << _prebusyTriggerCounter << std::endl;
  o << s << " Trigger counter          = " << std::setw(10) << _triggerCounter << std::endl;
  o << s << " Input status             = " << printHex(_inputStatus) << std::endl;
  o << s << " Input catch              = " << printHex(_inputCatch) << std::endl;
  o << s << " Prebusy catch            = " << printHex(_prebusyCatch) << std::endl;
  o << s << " Signals catch            = " << printHex(_signalCatch) << std::endl;
  o << s << " Trigger control          = " << printHex(_control) << std::endl;

  o << s << " Initial fifo status      = " << printHex(_initialFifoStatus) << std::endl;
  if(_initialFifoStatus.bit(16)) o << s << "  Initial fifo empty" << std::endl;
  else                           o << s << "  Initial fifo not empty" << std::endl;
  if(_initialFifoStatus.bit(17)) o << s << "  Initial fifo full" << std::endl;
  else                           o << s << "  Initial fifo not full" << std::endl;
  o << s << "  Initial fifo depth      = " << (unsigned)_initialFifoStatus.byte(0) << std::endl;

  o << s << " Final fifo status        = " << printHex(_finalFifoStatus) << std::endl;
  if(_finalFifoStatus.bit(16))   o << s << "  Final fifo empty" << std::endl;
  else                           o << s << "  Final fifo not empty" << std::endl;
  if(_finalFifoStatus.bit(17))   o << s << "  Final fifo full" << std::endl;
  else                           o << s << "  Final fifo not full" << std::endl;
  o << s << "  Final fifo depth        = " << (unsigned)_finalFifoStatus.byte(0) << std::endl;

  o << s << " Number of fifo words     = " << _numberOfFifoWords << std::endl;
  
  const unsigned *p(fifoData());
  for(unsigned i(0);i<_numberOfFifoWords;i++) {
    o << s << "  Fifo word " << std::setw(4) << i << " = " << printHex(p[i]) << std::endl;
  }
  
  return o;
}

#endif
#endif
