#ifndef TrgReadoutConfigurationData_HH
#define TrgReadoutConfigurationData_HH

#include <string>
#include <iostream>

#include "UtlPack.hh"


class TrgReadoutConfigurationData {

public:
  enum {
    versionNumber=0
  };

  TrgReadoutConfigurationData();

  UtlPack mode() const;
  void mode(UtlPack m);
  void beTrgMode(unsigned char n); // ???

  bool enable() const;
  void enable(bool e);

  bool clearBeTrgTrigger() const;
  void clearBeTrgTrigger(bool e);

  bool beTrgSoftTrigger() const;
  void beTrgSoftTrigger(bool e);

  bool beTrgSoftSpill() const;
  void beTrgSoftSpill(bool e);

  bool beTrgSquirt() const;
  void beTrgSquirt(bool e);

  bool beTrgVlink() const;
  void beTrgVlink(bool e);

  bool spillInvert() const;
  void spillInvert(bool s);

  unsigned readPeriod() const;
  void     readPeriod(unsigned n);

  unsigned readcPeriod() const;
  void     readcPeriod(unsigned n);

  unsigned beTrgPollNumber() const;
  void     beTrgPollNumber(unsigned n);

  UtlTimeDifference beTrgPollTime() const;
  void              beTrgPollTime(UtlTimeDifference t);

  unsigned beTrgSpillNumber() const;
  void     beTrgSpillNumber(unsigned n);

  UtlTimeDifference beTrgSpillTime() const;
  void              beTrgSpillTime(UtlTimeDifference t);

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


private:
  UtlPack _mode;
  unsigned _readPeriod;
  unsigned _readcPeriod;
  unsigned _beTrgPollNumber;
  UtlTimeDifference _beTrgPollTime;
  unsigned _beTrgSpillNumber;
  UtlTimeDifference _beTrgSpillTime;
};


#ifdef CALICE_DAQ_ICC

#include <cstring>

TrgReadoutConfigurationData::TrgReadoutConfigurationData() {
  memset(this,0,sizeof(TrgReadoutConfigurationData));
  enable(true);
  _beTrgPollTime=UtlTimeDifference(10,0);
  _beTrgSpillTime=UtlTimeDifference(100,0);
}

UtlPack TrgReadoutConfigurationData::mode() const {
  return _mode;
}

void TrgReadoutConfigurationData::mode(UtlPack m) {
  _mode=m;
}

void TrgReadoutConfigurationData::beTrgMode(unsigned char n) {
  _mode.byte(1,n);
}

bool TrgReadoutConfigurationData::enable() const {
  return _mode.bit(0);
}

void TrgReadoutConfigurationData::enable(bool e) {
  _mode.bit(0,e);
}

bool TrgReadoutConfigurationData::clearBeTrgTrigger() const {
  return _mode.bit(1);
}

void TrgReadoutConfigurationData::clearBeTrgTrigger(bool e) {
  _mode.bit(1,e);
}

bool TrgReadoutConfigurationData::beTrgSoftTrigger() const {
  return _mode.bit(2);
}

void TrgReadoutConfigurationData::beTrgSoftTrigger(bool e) {
  _mode.bit(2,e);
}

bool TrgReadoutConfigurationData::beTrgSoftSpill() const {
  return _mode.bit(3);
}

void TrgReadoutConfigurationData::beTrgSoftSpill(bool e) {
  _mode.bit(3,e);
}

bool TrgReadoutConfigurationData::beTrgSquirt() const {
  return _mode.bit(4);
}

void TrgReadoutConfigurationData::beTrgSquirt(bool e) {
  _mode.bit(4,e);
}

bool TrgReadoutConfigurationData::beTrgVlink() const {
  return _mode.bit(5);
}

void TrgReadoutConfigurationData::beTrgVlink(bool e) {
  _mode.bit(5,e);
}

bool TrgReadoutConfigurationData::spillInvert() const {
  return _mode.bit(6);
}

void TrgReadoutConfigurationData::spillInvert(bool s) {
  _mode.bit(6,s);
}

unsigned TrgReadoutConfigurationData::readPeriod() const {
  return _readPeriod;
}

void TrgReadoutConfigurationData::readPeriod(unsigned n) {
  _readPeriod=n;
}

unsigned TrgReadoutConfigurationData::readcPeriod() const {
  return _readcPeriod;
}

void TrgReadoutConfigurationData::readcPeriod(unsigned n) {
  _readcPeriod=n;
}

unsigned TrgReadoutConfigurationData::beTrgPollNumber() const {
  return _beTrgPollNumber;
}

void TrgReadoutConfigurationData::beTrgPollNumber(unsigned n) {
  _beTrgPollNumber=n;
}

UtlTimeDifference TrgReadoutConfigurationData::beTrgPollTime() const {
  return _beTrgPollTime;
}

void TrgReadoutConfigurationData::beTrgPollTime(UtlTimeDifference t) {
  _beTrgPollTime=t;
}

unsigned TrgReadoutConfigurationData::beTrgSpillNumber() const {
  return _beTrgSpillNumber;
}

void TrgReadoutConfigurationData::beTrgSpillNumber(unsigned n) {
  _beTrgSpillNumber=n;
}

UtlTimeDifference TrgReadoutConfigurationData::beTrgSpillTime() const {
  return _beTrgSpillTime;
}

void TrgReadoutConfigurationData::beTrgSpillTime(UtlTimeDifference t) {
  _beTrgSpillTime=t;
}

std::ostream& TrgReadoutConfigurationData::print(std::ostream &o, std::string s) const {
  o << s << "TrgReadoutConfigurationData::print()" << std::endl;

  //o << s << " Crate number  = " << printHex(_numbers.byte(0)) << std::endl;
  o << s << " Mode = " << printHex(_mode) << std::endl;
  if(enable())            o << s << "  Enabled" << std::endl;
  else                    o << s << "  Disabled" << std::endl;
  if(clearBeTrgTrigger()) o << s << "  Clear trigger" << std::endl;
  else                    o << s << "  No clear trigger" << std::endl;
  if(beTrgSoftTrigger())  o << s << "  Soft trigger" << std::endl;
  else                    o << s << "  No soft trigger" << std::endl;
  if(beTrgSoftSpill()  )  o << s << "  Soft spill" << std::endl;
  else                    o << s << "  No soft spill" << std::endl;
  if(beTrgSquirt())       o << s << "  FIFO readout using squirt" << std::endl;
  else                    o << s << "  Standard FIFO readout" << std::endl;
  if(beTrgVlink())        o << s << "  FIFO readout using Vlink" << std::endl;
  else                    o << s << "  FIFO readout using serial I/O" << std::endl;
  if(spillInvert())       o << s << "  Spill signal inverted" << std::endl;
  else                    o << s << "  Spill signal not inverted" << std::endl;

  o << s << " Readout period         = " << std::setw(11) << _readPeriod << std::endl;
  o << s << " Readout counter period = " << std::setw(11) << _readcPeriod << std::endl;

  /* Unused
  o << s << " Poll number  = " << std::setw(11) << _beTrgPollNumber << std::endl;
  o << s << " Poll time    = " << std::setw(11) << _beTrgPollTime.deltaTime() << " secs" << std::endl;
  o << s << " Spill number = " << std::setw(11) << _beTrgSpillNumber << std::endl;
  o << s << " Spill time   = " << std::setw(11) << _beTrgSpillTime.deltaTime() << " sec" << std::endl;
  */
  
  return o;
}

#endif
#endif
