#ifndef CrcBeConfigurationDataV0_HH
#define CrcBeConfigurationDataV0_HH

#include <string>
#include <iostream>

#include "UtlPack.hh"


class CrcBeConfigurationDataV0 {

public:
  enum {
    versionNumber=0
  };

  CrcBeConfigurationDataV0();

  unsigned char triggerSelect() const;
  void triggerSelect(unsigned char n);

  unsigned char mode() const;
  void mode(unsigned char n);

  unsigned char readoutControl() const;
  void readoutControl(unsigned char n);

  unsigned char runControl() const;
  void runControl(unsigned char n);

  unsigned char feDataEnable() const;
  void feDataEnable(unsigned char n);

  unsigned short daqId() const;
  void daqId(unsigned short n);

  unsigned char qdrAddress() const;
  void qdrAddress(unsigned char n);

  unsigned char feTriggerEnable() const;
  void feTriggerEnable(unsigned char n);

  bool j0TriggerEnable() const;
  void j0TriggerEnable(bool b);

  bool j0BypassEnable() const;
  void j0BypassEnable(bool b);

  unsigned trgEnables() const;
  void trgEnables(unsigned n);

  unsigned test() const;
  void test(unsigned n);

  unsigned short testLength() const;
  void testLength(unsigned short n);

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


private:
  unsigned _control;
  unsigned _enables;
  UtlPack _trgEnables;
  unsigned _test;
  unsigned _testLength;
};


#ifdef CALICE_DAQ_ICC

CrcBeConfigurationDataV0::CrcBeConfigurationDataV0() {
  _control=0x04020203;
  _enables=0xff000cec;
  _trgEnables=0x1ff;
  _test=0;
  _testLength=0;
}

unsigned char CrcBeConfigurationDataV0::triggerSelect() const {
  return _control>>24;
}

void CrcBeConfigurationDataV0::triggerSelect(unsigned char n) {
  _control&=0x00ffffff;
  _control|=n<<24;
}

unsigned char CrcBeConfigurationDataV0::mode() const {
  return (_control>>16)&0xff;
}

void CrcBeConfigurationDataV0::mode(unsigned char n) {
  _control&=0xff00ffff;
  _control|=n<<16;
}

unsigned char CrcBeConfigurationDataV0::readoutControl() const {
  return (_control>>8)&0xff;
}

void CrcBeConfigurationDataV0::readoutControl(unsigned char n) {
  _control&=0xffff00ff;
  _control|=n<<8;
}

unsigned char CrcBeConfigurationDataV0::runControl() const {
  return (_control)&0xff;
}

void CrcBeConfigurationDataV0::runControl(unsigned char n) {
  _control&=0xffffff00;
  _control|=n;
}

unsigned char CrcBeConfigurationDataV0::feDataEnable() const {
  return _enables>>24;
}

void CrcBeConfigurationDataV0::feDataEnable(unsigned char n) {
  _enables&=0x00ffffff;
  _enables|=n<<24;
}

unsigned short CrcBeConfigurationDataV0::daqId() const {
  return (_enables)&0xfff;
}

void CrcBeConfigurationDataV0::daqId(unsigned short n) {
  _enables&=0xfffff000;
  _enables|=n&0xfff;
}

unsigned char CrcBeConfigurationDataV0::qdrAddress() const {
  return (_enables>>12)&0x3;
}

void CrcBeConfigurationDataV0::qdrAddress(unsigned char n) {
  _enables&=0xffff0fff;
  _enables|=(n&0xf)<<12;
}

unsigned char CrcBeConfigurationDataV0::feTriggerEnable() const {
  return _trgEnables.byte(0);
}

void CrcBeConfigurationDataV0::feTriggerEnable(unsigned char n) {
  _trgEnables.byte(0,n);
}

bool CrcBeConfigurationDataV0::j0TriggerEnable() const {
  return _trgEnables.bit(8);
}

void CrcBeConfigurationDataV0::j0TriggerEnable(bool b) {
  _trgEnables.bit(8,b);
}

bool CrcBeConfigurationDataV0::j0BypassEnable() const {
  return _trgEnables.bit(9);
}

void CrcBeConfigurationDataV0::j0BypassEnable(bool b) {
  _trgEnables.bit(9,b);
}

unsigned CrcBeConfigurationDataV0::trgEnables() const {
  return _trgEnables.word();
}

void CrcBeConfigurationDataV0::trgEnables(unsigned n) {
  _trgEnables.word(n);
}

unsigned CrcBeConfigurationDataV0::test() const {
  return _test;
}

void CrcBeConfigurationDataV0::test(unsigned n) {
  _test=n;
}

unsigned short CrcBeConfigurationDataV0::testLength() const {
  return (_testLength)&0xffff;
}

void CrcBeConfigurationDataV0::testLength(unsigned short n) {
  _testLength=n;
}

std::ostream& CrcBeConfigurationDataV0::print(std::ostream &o, std::string s) const {
  o << s << "CrcBeConfigurationDataV0::print()" << std::endl;
  o << s << " Control     = " << printHex(_control) << std::endl;
  o << s << " Enables     = " << printHex(_enables) << std::endl;
  o << s << " Trg enables = " << printHex(_trgEnables.word()) << std::endl;
  o << s << " Test        = " << printHex(_test) << std::endl;
  o << s << " Test length = " << testLength() << std::endl;
  return o;
}

#endif
#endif
