#ifndef MpsUsbDaqConfigurationData_HH
#define MpsUsbDaqConfigurationData_HH

#include <iostream>
#include <fstream>

#include "UtlPack.hh"


class MpsUsbDaqConfigurationData {

public:
  enum {
    versionNumber=0
  };

  MpsUsbDaqConfigurationData();

  void setV11Defaults();

  unsigned spillCycleCount() const;
  void     spillCycleCount(unsigned c);

  unsigned short clockPhase(unsigned i) const;
  void           clockPhase(unsigned i, unsigned short v);

  unsigned short debugDiodeResetDuration() const;
  void           debugDiodeResetDuration(unsigned short v);

  unsigned short debugShaperResetDuration() const;
  void           debugShaperResetDuration(unsigned short v);

  unsigned short debugReset200Duration() const;
  void           debugReset200Duration(unsigned short v);

  unsigned short debugSampleResetDuration() const;
  void           debugSampleResetDuration(unsigned short v);

  unsigned short debugReset600Duration() const;
  void           debugReset600Duration(unsigned short v);

  unsigned short debugTrim() const;
  void           debugTrim(unsigned short v);

  unsigned short discriminatorThreshold(unsigned i) const;
  void           discriminatorThreshold(unsigned i, unsigned short v);

  unsigned short senseDelay() const;
  void           senseDelay(unsigned short v);

  unsigned short diodeResetDuration() const;
  void           diodeResetDuration(unsigned short v);

  unsigned short shaperResetDuration() const;
  void           shaperResetDuration(unsigned short v);

  unsigned short sampleResetDuration() const;
  void           sampleResetDuration(unsigned short v);

  //unsigned short preAmpResetDuration() const;            // Obsolete
  //void           preAmpResetDuration(unsigned short v);  // Obsolete

  unsigned short timeStampPrescale() const;
  void           timeStampPrescale(unsigned short v);

  unsigned short spillMode() const;
  void           spillMode(unsigned short v);

  bool           spillModeInhibitReadout() const;
  void           spillModeInhibitReadout(bool b);

  bool           spillModeInhibitSpill() const;
  void           spillModeInhibitSpill(bool b);

  bool           spillModeFillSrams() const;
  void           spillModeFillSrams(bool b);

  bool           spillModeHistoryEnable() const;
  void           spillModeHistoryEnable(bool b);

  bool           spillModeRowMarkerEnable() const;
  void           spillModeRowMarkerEnable(bool b);

  unsigned short masterClockResetDuration() const;
  void           masterClockResetDuration(unsigned short v);

  unsigned short sramFillClockSleep() const;
  void           sramFillClockSleep(unsigned short v);

  unsigned short readoutColumnOrder() const;
  void           readoutColumnOrder(unsigned short v);

  unsigned short staticTimeStamp() const;
  void           staticTimeStamp(unsigned short v);
  unsigned short staticTimeStampGray() const;
  void           staticTimeStampGray(unsigned short v);

  unsigned short readoutStartIndex() const;
  void           readoutStartIndex(unsigned short v);

  unsigned short stackPointerOffset() const;
  void           stackPointerOffset(unsigned short v);

  unsigned short debugHitInEnableValue() const;
  void           debugHitInEnableValue(unsigned short v);

  unsigned short postPixResetSleepDuration() const;
  void           postPixResetSleepDuration(unsigned short v);

  unsigned short testTriggerMode() const;
  void           testTriggerMode(unsigned short v);

  unsigned short testTriggerStart() const;
  void           testTriggerStart(unsigned short v);

  unsigned short testTriggerStop() const;
  void           testTriggerStop(unsigned short v);

  unsigned short spillCycleStart() const;
  void           spillCycleStart(unsigned short v);

  unsigned short triggerMask() const;
  void           triggerMask(unsigned short v);

  unsigned short triggerSource() const;
  void           triggerSource(unsigned short v);

  void zeroBools();

  bool debugDiodeResetHold() const;
  void debugDiodeResetHold(bool b);

  bool debugShaperResetHold() const;
  void debugShaperResetHold(bool b);

  bool debugReset200Hold() const;
  void debugReset200Hold(bool b);

  bool debugSampleResetHold() const;
  void debugSampleResetHold(bool b);

  bool debugReset600Hold() const;
  void debugReset600Hold(bool b);

  bool hitOverride() const;
  void hitOverride(bool b);

  bool monoPOR() const;
  void monoPOR(bool b);

  bool pixelEnable12() const;
  void pixelEnable12(bool b);

  bool pixelEnable34() const;
  void pixelEnable34(bool b);

  bool senseEnable() const;
  void senseEnable(bool b);

  bool debugHitInEnable() const;
  void debugHitInEnable(bool b);

  bool fastPhiOverride() const;
  void fastPhiOverride(bool b);

  bool readEnableOverride() const;
  void readEnableOverride(bool b);

  bool initBPolarity() const;
  void initBPolarity(bool b);

  bool rstBPolarity() const;
  void rstBPolarity(bool b);

  bool fwdBPolarity() const;
  void fwdBPolarity(bool b);

  bool slowSpillPhi() const;
  void slowSpillPhi(bool b);

  bool timeStampOverride() const;
  void timeStampOverride(bool b);

  bool triggerEnable() const;
  void triggerEnable(bool b);

  bool diodeResetHold() const;
  void diodeResetHold(bool b);

  bool shaperResetHold() const;
  void shaperResetHold(bool b);

  bool sampleResetHold() const;
  void sampleResetHold(bool b);

  /////////////////////////////////////////////////////

  bool externalStart() const;
  void externalStart(bool b);

  bool externalLaserStart() const;
  void externalLaserStart(bool b);

  bool fireLaser() const;
  void fireLaser(bool b);

  bool retryStart() const;
  void retryStart(bool b);

  //unsigned triggerMask() const;
  //void     triggerMask(unsigned n);

  unsigned triggerCondition() const;
  void     triggerCondition(unsigned n);

  unsigned externalTimeout() const;
  void     externalTimeout(unsigned n);

  unsigned numberOfRetries() const;
  void     numberOfRetries(unsigned n);

  /*
  unsigned timer(unsigned n) const;
  void     timer(unsigned n, unsigned t);
  */

  bool operator==(const MpsUsbDaqConfigurationData &d) const;
  bool operator!=(const MpsUsbDaqConfigurationData &d) const;

  void writeFile(const std::string &fileName);
  void readFile(const std::string &fileName);

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


private:
  unsigned grayToBinary(unsigned g) const;
  unsigned binaryToGray(unsigned b) const;

  unsigned _spillCycleCount;
  UtlPack _bools;
  UtlPack _discriminatorThreshold;
  UtlPack _clockPhase[4];
  UtlPack _shorts[16];


  UtlPack _data;
  u_int32_t _triggerMask; // UNUSED!!!
  u_int32_t _triggerCondition;
  u_int32_t _externalTimeout;
  u_int32_t _numberOfRetries;
  //UtlPack _moreShorts[32];
  //u_int32_t _numberOfBunchCrossings;
};


#ifdef CALICE_DAQ_ICC

#include <cstring>

#include "UtlPrintHex.hh"


MpsUsbDaqConfigurationData::MpsUsbDaqConfigurationData() {
  memset(this,0,sizeof(MpsUsbDaqConfigurationData));
  //memset(this,0xff,sizeof(MpsUsbDaqConfigurationData));

  spillCycleCount(7999);
  spillCycleStart(spillCycleCount()-1000);

  //clockPhase(0,128); // F/w version 69
  clockPhase(0,192); // F/w version 84
  clockPhase(1,128);
  clockPhase(2,70);

  debugDiodeResetDuration(4);
  debugShaperResetDuration(8);
  debugSampleResetDuration(12);
  debugTrim(0);
  discriminatorThreshold(0,140);
  discriminatorThreshold(1,140);
  senseDelay(30);

  // Shortest; this is "preamp reset" for shapers (pg 28)
  // and "diode reset" for samplers (pg 29)
  diodeResetDuration(4*10);

  // Middle; this is "shaper reset" for samplers (pg 29)
  shaperResetDuration(10*10);

  // Longest; this is "sample reset" for samplers (pg 29)
  sampleResetDuration(20*10);

  timeStampPrescale(0);
  
  spillMode(0);

  readoutStartIndex(0);
  stackPointerOffset(0);
  debugHitInEnableValue(10);

  masterClockResetDuration(10);
  sramFillClockSleep(10);
  staticTimeStampGray(0x1fff);
  readoutColumnOrder(0x1e);
  readoutStartIndex(0);

  postPixResetSleepDuration(1000+160);

  testTriggerMode(0);
  testTriggerStart(0xffff);
  testTriggerStop(0xffff);

  triggerMask(0x1f);
  triggerSource(0);

  //monoPOR(true);
  hitOverride(false);
  pixelEnable12(true);
  pixelEnable34(true);

  readEnableOverride(false);
  initBPolarity(false);
  rstBPolarity(false);
  fwdBPolarity(false);
  slowSpillPhi(false);

  timeStampOverride(false);
  triggerEnable(true);

  //setV11Defaults();
}

void MpsUsbDaqConfigurationData::setV11Defaults() {
  clockPhase(0,128); // F/w version > 101
  clockPhase(1,128);
  clockPhase(2,180);
  //senseDelay(60)

  //spillModeRowMarkerEnable(true);
  //staticTimeStampGray(0x0000);
}

unsigned MpsUsbDaqConfigurationData::spillCycleCount() const {
  return _spillCycleCount;
}

void MpsUsbDaqConfigurationData::spillCycleCount(unsigned c) {
  assert(c<8192);
  _spillCycleCount=c;
}

unsigned short MpsUsbDaqConfigurationData::clockPhase(unsigned i) const {
  assert(i<3);
  return _clockPhase[i/2].halfWord(i%2);
}

void MpsUsbDaqConfigurationData::clockPhase(unsigned i, unsigned short v) {
  assert(i<3);
  assert(v<256);
  _clockPhase[i/2].halfWord(i%2,v);
}

unsigned short MpsUsbDaqConfigurationData::debugDiodeResetDuration() const {
  return _shorts[1].halfWord(0);
}

void MpsUsbDaqConfigurationData::debugDiodeResetDuration(unsigned short v) {
  _shorts[1].halfWord(0,v);
}

unsigned short MpsUsbDaqConfigurationData::debugShaperResetDuration() const {
  return _shorts[0].halfWord(0);
}

void MpsUsbDaqConfigurationData::debugShaperResetDuration(unsigned short v) {
  _shorts[0].halfWord(0,v);
}

unsigned short MpsUsbDaqConfigurationData::debugReset200Duration() const {
  return debugShaperResetDuration();
}

void MpsUsbDaqConfigurationData::debugReset200Duration(unsigned short v) {
  debugShaperResetDuration(v);
}

unsigned short MpsUsbDaqConfigurationData::debugSampleResetDuration() const {
  return _shorts[0].halfWord(1);
}

void MpsUsbDaqConfigurationData::debugSampleResetDuration(unsigned short v) {
  _shorts[0].halfWord(1,v);
}

unsigned short MpsUsbDaqConfigurationData::debugReset600Duration() const {
  return debugSampleResetDuration();
}

void MpsUsbDaqConfigurationData::debugReset600Duration(unsigned short v) {
  debugSampleResetDuration(v);
}

unsigned short MpsUsbDaqConfigurationData::debugTrim() const {
  return _shorts[1].halfWord(1);
}

void MpsUsbDaqConfigurationData::debugTrim(unsigned short v) {
  _shorts[1].halfWord(1,v);
}

unsigned short MpsUsbDaqConfigurationData::senseDelay() const {
  return _shorts[2].halfWord(0);
}

void MpsUsbDaqConfigurationData::senseDelay(unsigned short v) {
  assert(v<256);
  _shorts[2].halfWord(0,v);
}

unsigned short MpsUsbDaqConfigurationData::sampleResetDuration() const {
  return _shorts[2].halfWord(1);
}

void MpsUsbDaqConfigurationData::sampleResetDuration(unsigned short v) {
  _shorts[2].halfWord(1,v);
}

unsigned short MpsUsbDaqConfigurationData::shaperResetDuration() const {
  return _shorts[3].halfWord(0);
}

void MpsUsbDaqConfigurationData::shaperResetDuration(unsigned short v) {
  _shorts[3].halfWord(0,v);
}

unsigned short MpsUsbDaqConfigurationData::diodeResetDuration() const {
  return _shorts[3].halfWord(1);
}

void MpsUsbDaqConfigurationData::diodeResetDuration(unsigned short v) {
  _shorts[3].halfWord(1,v);
}

unsigned short MpsUsbDaqConfigurationData::timeStampPrescale() const {
  return _shorts[4].halfWord(0);
}

void MpsUsbDaqConfigurationData::timeStampPrescale(unsigned short v) {
  assert(v<256);
  _shorts[4].halfWord(0,v);
}

unsigned short MpsUsbDaqConfigurationData::spillMode() const {
  return _shorts[4].halfWord(1);
}

void MpsUsbDaqConfigurationData::spillMode(unsigned short v) {
  assert(v<256);
  _shorts[4].halfWord(1,v);
}

bool MpsUsbDaqConfigurationData::spillModeInhibitReadout() const {
  return _shorts[4].bit(1+16);
}

void MpsUsbDaqConfigurationData::spillModeInhibitReadout(bool b) {
  _shorts[4].bit(1+16,b);
}

bool MpsUsbDaqConfigurationData::spillModeInhibitSpill() const {
  return _shorts[4].bit(3+16);
}

void MpsUsbDaqConfigurationData::spillModeInhibitSpill(bool b) {
  _shorts[4].bit(3+16,b);
}

bool MpsUsbDaqConfigurationData::spillModeFillSrams() const {
  return _shorts[4].bit(4+16);
}

void MpsUsbDaqConfigurationData::spillModeFillSrams(bool b) {
  _shorts[4].bit(4+16,b);
}

bool MpsUsbDaqConfigurationData::spillModeHistoryEnable() const {
  return _shorts[4].bit(6+16);
}

void MpsUsbDaqConfigurationData::spillModeHistoryEnable(bool b) {
  _shorts[4].bit(6+16,b);
}

bool MpsUsbDaqConfigurationData::spillModeRowMarkerEnable() const {
  return _shorts[4].bit(8+16);
}

void MpsUsbDaqConfigurationData::spillModeRowMarkerEnable(bool b) {
  _shorts[4].bit(8+16,b);
}

unsigned short MpsUsbDaqConfigurationData::masterClockResetDuration() const {
  return _shorts[5].halfWord(0);
}

void MpsUsbDaqConfigurationData::masterClockResetDuration(unsigned short v) {
  assert(v<256);
  _shorts[5].halfWord(0,v);
}

unsigned short MpsUsbDaqConfigurationData::sramFillClockSleep() const {
  return _shorts[5].halfWord(1);
}

void MpsUsbDaqConfigurationData::sramFillClockSleep(unsigned short v) {
  assert(v<256);
  _shorts[5].halfWord(1,v);
}

unsigned short MpsUsbDaqConfigurationData::readoutColumnOrder() const {
  return _shorts[6].halfWord(0);
}

void MpsUsbDaqConfigurationData::readoutColumnOrder(unsigned short v) {
  assert(v<256);
  _shorts[6].halfWord(0,v);
}

unsigned short MpsUsbDaqConfigurationData::staticTimeStamp() const {
  return grayToBinary(staticTimeStampGray());
}

void MpsUsbDaqConfigurationData::staticTimeStamp(unsigned short v) {
  assert(v<8192);
  staticTimeStampGray(binaryToGray(v));
}

unsigned short MpsUsbDaqConfigurationData::staticTimeStampGray() const {
  return _shorts[6].halfWord(1);
}

void MpsUsbDaqConfigurationData::staticTimeStampGray(unsigned short v) {
  _shorts[6].halfWord(1,v);
}

unsigned short MpsUsbDaqConfigurationData::readoutStartIndex() const {
  return _shorts[7].halfWord(0);
}

void MpsUsbDaqConfigurationData::readoutStartIndex(unsigned short v) {
  assert(v<4);
  _shorts[7].halfWord(0,v);
}

unsigned short MpsUsbDaqConfigurationData::stackPointerOffset() const {
  return _shorts[7].halfWord(1);
}

void MpsUsbDaqConfigurationData::stackPointerOffset(unsigned short v) {
  assert(v<19);
  _shorts[7].halfWord(1,v);
}

unsigned short MpsUsbDaqConfigurationData::debugHitInEnableValue() const {
  return _shorts[8].halfWord(0);
}

void MpsUsbDaqConfigurationData::debugHitInEnableValue(unsigned short v) {
  _shorts[8].halfWord(0,v);
}

unsigned short MpsUsbDaqConfigurationData::postPixResetSleepDuration() const {
  return _shorts[8].halfWord(1);
}

void MpsUsbDaqConfigurationData::postPixResetSleepDuration(unsigned short v) {
  _shorts[8].halfWord(1,v);
}

unsigned short MpsUsbDaqConfigurationData::testTriggerMode() const {
  return _shorts[9].halfWord(0);
}

void MpsUsbDaqConfigurationData::testTriggerMode(unsigned short v) {
  assert(v<16);
  _shorts[9].halfWord(0,v);
}

unsigned short MpsUsbDaqConfigurationData::testTriggerStart() const {
  return _shorts[9].halfWord(1);
}

void MpsUsbDaqConfigurationData::testTriggerStart(unsigned short v) {
  _shorts[9].halfWord(1,v);
}

unsigned short MpsUsbDaqConfigurationData::testTriggerStop() const {
  return _shorts[10].halfWord(0);
}

void MpsUsbDaqConfigurationData::testTriggerStop(unsigned short v) {
  _shorts[10].halfWord(0,v);
}

unsigned short MpsUsbDaqConfigurationData::spillCycleStart() const {
  return _shorts[10].halfWord(1);
}

void MpsUsbDaqConfigurationData::spillCycleStart(unsigned short v) {
  assert(v<8192);
  _shorts[10].halfWord(1,v);
}

unsigned short MpsUsbDaqConfigurationData::triggerMask() const {
  return _shorts[11].halfWord(0);
}

void MpsUsbDaqConfigurationData::triggerMask(unsigned short v) {
  //assert(v<8192);
  _shorts[11].halfWord(0,v);
}

unsigned short MpsUsbDaqConfigurationData::triggerSource() const {
  return _shorts[11].halfWord(1);
}

void MpsUsbDaqConfigurationData::triggerSource(unsigned short v) {
  //assert(v<8192);
  _shorts[11].halfWord(1,v);
}

unsigned short MpsUsbDaqConfigurationData::discriminatorThreshold(unsigned i) const {
  assert(i<2);
  return _discriminatorThreshold.halfWord(i);
}

void MpsUsbDaqConfigurationData::discriminatorThreshold(unsigned i, unsigned short v) {
  assert(i<2);
  assert(v<256);
  _discriminatorThreshold.halfWord(i,v);
}

void MpsUsbDaqConfigurationData::zeroBools() {
  _bools=0;
}

bool MpsUsbDaqConfigurationData::debugShaperResetHold() const {
  return _bools.bit( 0);
}

void MpsUsbDaqConfigurationData::debugShaperResetHold(bool b) {
  _bools.bit( 0,b);
}

bool MpsUsbDaqConfigurationData::debugReset200Hold() const {
  return debugShaperResetHold();
}

void MpsUsbDaqConfigurationData::debugReset200Hold(bool b) {
  debugShaperResetHold(b);
}

bool MpsUsbDaqConfigurationData::debugSampleResetHold() const {
  return _bools.bit( 1);
}

void MpsUsbDaqConfigurationData::debugSampleResetHold(bool b) {
  _bools.bit( 1,b);
}

bool MpsUsbDaqConfigurationData::debugReset600Hold() const {
  return debugSampleResetHold();
}

void MpsUsbDaqConfigurationData::debugReset600Hold(bool b) {
  debugSampleResetHold(b);
}

bool MpsUsbDaqConfigurationData::debugDiodeResetHold() const {
  return _bools.bit( 2);
}

void MpsUsbDaqConfigurationData::debugDiodeResetHold(bool b) {
  _bools.bit( 2,b);
}

bool MpsUsbDaqConfigurationData::hitOverride() const {
  return _bools.bit( 3);
}

void MpsUsbDaqConfigurationData::hitOverride(bool b) {
  _bools.bit( 3,b);
}

bool MpsUsbDaqConfigurationData::monoPOR() const {
  return _bools.bit( 4);
}

void MpsUsbDaqConfigurationData::monoPOR(bool b) {
  _bools.bit( 4,b);
}

bool MpsUsbDaqConfigurationData::pixelEnable12() const {
  return _bools.bit( 5);
}

void MpsUsbDaqConfigurationData::pixelEnable12(bool b) {
  _bools.bit( 5,b);
}

bool MpsUsbDaqConfigurationData::pixelEnable34() const {
  return _bools.bit( 6);
}

void MpsUsbDaqConfigurationData::pixelEnable34(bool b) {
  _bools.bit( 6,b);
}

bool MpsUsbDaqConfigurationData::senseEnable() const {
  return _bools.bit( 7);
}

void MpsUsbDaqConfigurationData::senseEnable(bool b) {
  _bools.bit( 7,b);
}

bool MpsUsbDaqConfigurationData::debugHitInEnable() const {
  return _bools.bit( 8);
}

void MpsUsbDaqConfigurationData::debugHitInEnable(bool b) {
  _bools.bit( 8,b);
}

bool MpsUsbDaqConfigurationData::fastPhiOverride() const {
  return _bools.bit( 9);
}

void MpsUsbDaqConfigurationData::fastPhiOverride(bool b) {
  _bools.bit( 9,b);
}

bool MpsUsbDaqConfigurationData::readEnableOverride() const {
  return _bools.bit(10);
}

void MpsUsbDaqConfigurationData::readEnableOverride(bool b) {
  _bools.bit(10,b);
}

bool MpsUsbDaqConfigurationData::initBPolarity() const {
  return _bools.bit(11);
}

void MpsUsbDaqConfigurationData::initBPolarity(bool b) {
  _bools.bit(11,b);
}

bool MpsUsbDaqConfigurationData::rstBPolarity() const {
  return _bools.bit(12);
}

void MpsUsbDaqConfigurationData::rstBPolarity(bool b) {
  _bools.bit(12,b);
}

bool MpsUsbDaqConfigurationData::fwdBPolarity() const {
  return _bools.bit(13);
}

void MpsUsbDaqConfigurationData::fwdBPolarity(bool b) {
  _bools.bit(13,b);
}

bool MpsUsbDaqConfigurationData::slowSpillPhi() const {
  return _bools.bit(14);
}

void MpsUsbDaqConfigurationData::slowSpillPhi(bool b) {
  _bools.bit(14,b);
}

bool MpsUsbDaqConfigurationData::timeStampOverride() const {
  return _bools.bit(15);
}

void MpsUsbDaqConfigurationData::timeStampOverride(bool b) {
  _bools.bit(15,b);
}

bool MpsUsbDaqConfigurationData::triggerEnable() const {
  return _bools.bit(16);
}

void MpsUsbDaqConfigurationData::triggerEnable(bool b) {
  _bools.bit(16,b);
}

bool MpsUsbDaqConfigurationData::diodeResetHold() const {
  return _bools.bit(17);
}

void MpsUsbDaqConfigurationData::diodeResetHold(bool b) {
  _bools.bit(17,b);
}

bool MpsUsbDaqConfigurationData::shaperResetHold() const {
  return _bools.bit(18);
}

void MpsUsbDaqConfigurationData::shaperResetHold(bool b) {
  _bools.bit(18,b);
}

bool MpsUsbDaqConfigurationData::sampleResetHold() const {
  return _bools.bit(19);
}

void MpsUsbDaqConfigurationData::sampleResetHold(bool b) {
  _bools.bit(19,b);
}

bool MpsUsbDaqConfigurationData::externalStart() const {
  return _data.bit(1);
}

void MpsUsbDaqConfigurationData::externalStart(bool b) {
  _data.bit(1,b);
}

bool MpsUsbDaqConfigurationData::externalLaserStart() const {
  return _data.bit(2);
}

void MpsUsbDaqConfigurationData::externalLaserStart(bool b) {
  _data.bit(2,b);
}

bool MpsUsbDaqConfigurationData::fireLaser() const {
  return _data.bit(3);
}

void MpsUsbDaqConfigurationData::fireLaser(bool b) {
  _data.bit(3,b);
}

bool MpsUsbDaqConfigurationData::retryStart() const {
  return _data.bit(4);
}

void MpsUsbDaqConfigurationData::retryStart(bool b) {
  _data.bit(4,b);
}
/*
unsigned MpsUsbDaqConfigurationData::triggerMask() const {
  return _triggerMask;
}

void MpsUsbDaqConfigurationData::triggerMask(unsigned n) {
  _triggerMask=n;
}
*/
unsigned MpsUsbDaqConfigurationData::triggerCondition() const {
  return _triggerCondition;
}

void MpsUsbDaqConfigurationData::triggerCondition(unsigned n) {
  _triggerCondition=n;
}

unsigned MpsUsbDaqConfigurationData::externalTimeout() const {
  return _externalTimeout;
}

void MpsUsbDaqConfigurationData::externalTimeout(unsigned n) {
  _externalTimeout=n;
}

unsigned MpsUsbDaqConfigurationData::numberOfRetries() const {
  return _numberOfRetries;
}

void MpsUsbDaqConfigurationData::numberOfRetries(unsigned n) {
  _numberOfRetries=n;
}
/*
unsigned MpsUsbDaqConfigurationData::timer(unsigned n) const {
  assert(n<32);
  return _timer[n];
}

void MpsUsbDaqConfigurationData::timer(unsigned n, unsigned t) {
  assert(n<32);
  _timer[n]=t;
}
*/

unsigned MpsUsbDaqConfigurationData::grayToBinary(unsigned g) const {
  g^=(g>>16);
  g^=(g>> 8);
  g^=(g>> 4);
  g^=(g>> 2);
  g^=(g>> 1);
  return g;
}

unsigned MpsUsbDaqConfigurationData::binaryToGray(unsigned b) const {
  unsigned g((b>>1)^b);
  return g;
}

bool MpsUsbDaqConfigurationData::operator!=(const MpsUsbDaqConfigurationData &d) const {
  if(true) {
    for(unsigned i(0);i<sizeof(MpsUsbDaqConfigurationData)/4;i++) {
      if(*((&_spillCycleCount)+i)!=*((&d._spillCycleCount)+i)) {
	std::cout << "MpsUsbDaqConfigurationData::operator==()  Objects differ at word " << i << std::endl;
      }
    }
  }

  for(unsigned i(0);i<sizeof(MpsUsbDaqConfigurationData)/4;i++) {
    if(*((&_spillCycleCount)+i)!=*((&d._spillCycleCount)+i)) return true;
  }

  return false;
}

bool MpsUsbDaqConfigurationData::operator==(const MpsUsbDaqConfigurationData &d) const {
  return !(this->operator!=(d));
}

void MpsUsbDaqConfigurationData::writeFile(const std::string &fileName) {
  std::ofstream fout(fileName.c_str());
  if(fout) {

    unsigned n(sizeof(MpsUsbDaqConfigurationData)/4);
    unsigned *p(&_spillCycleCount);

    for(unsigned i(0);i<n;i++) {
      fout << std::setw(2) << i << " " << p[i] << std::endl;
    }
  }
}

void MpsUsbDaqConfigurationData::readFile(const std::string &fileName) {
  std::ifstream fin(fileName.c_str());
  if(fin) {

    unsigned n(sizeof(MpsUsbDaqConfigurationData)/4);
    unsigned *p(&_spillCycleCount);

    unsigned c;
    unsigned v;
    for(unsigned i(0);i<n;i++) {
      fin >> c >> v;
      if(c==i) p[i]=v;
    }
  }
}

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

  o << s << " Spill cycle counts          = " << _spillCycleCount << std::endl;
  o << s << " Spill cycle start           = " << spillCycleStart() << std::endl;
  o << s << " Clock phases                = " << clockPhase(0) << ", "
    << clockPhase(1) << ", " << clockPhase(2) << std::endl;

  o << s << " Debug diode reset duration  = " << debugDiodeResetDuration() << std::endl;
  o << s << " Debug shaper reset duration = " << debugShaperResetDuration() << std::endl;
  o << s << " Debug sample reset duration = " << debugSampleResetDuration() << std::endl;
  o << s << " Debug trim                  = " << debugTrim() << std::endl;
  o << s << " Debug hit-in enable value   = " << debugHitInEnableValue() << std::endl;

  o << s << " Sense delay                 = " << senseDelay() << std::endl;
  o << s << " Diode reset duration        = " << diodeResetDuration() << std::endl;
  o << s << " Shaper reset duration       = " << shaperResetDuration() << std::endl;
  o << s << " Sample reset duration       = " << sampleResetDuration() << std::endl;
  o << s << " Timestamp prescale          = " << timeStampPrescale() << std::endl;

  o << s << " Spill mode                  = " << printHex(spillMode()) << std::endl;
  if(spillModeInhibitReadout()) o << s << "  Inhibit readout set true"  << std::endl;
  else                          o << s << "  Inhibit readout set false" << std::endl;
  if(spillModeInhibitSpill())   o << s << "  Inhibit spill set true"  << std::endl;
  else                          o << s << "  Inhibit spill set false" << std::endl;
  if(spillModeFillSrams())      o << s << "  Fill SRAMs set true"  << std::endl;
  else                          o << s << "  Fill SRAMs set false" << std::endl;
  if(spillModeHistoryEnable())  o << s << "  History enable set true"  << std::endl;
  else                          o << s << "  History enable set false" << std::endl;
  if(spillModeRowMarkerEnable())  o << s << "  Row marker enable set true"  << std::endl;
  else                            o << s << "  Row marker enable set false" << std::endl;

  o << s << " Discriminator thresholds    = " << discriminatorThreshold(0) << ", " 
    << discriminatorThreshold(1) << std::endl;

  o << s << " Master clock reset duration = " << masterClockResetDuration() << std::endl;
  o << s << " Sram fill clock sleep       = " << sramFillClockSleep() << std::endl;
  o << s << " Readout column order        = " << printHex(readoutColumnOrder()) << std::endl;
  o << s << " Static timestamp       gray = " << staticTimeStampGray()
    << ", binary = " << staticTimeStamp() << std::endl;
  o << s << " Readout start order         = " << readoutStartIndex() << std::endl;
  o << s << " Stack pointer offset        = " << stackPointerOffset() << std::endl;
  o << s << " Post pixel reset sleep      = " << postPixResetSleepDuration() << " x 25ns" << std::endl;

  o << s << " Test trigger mode           = " << printHex(testTriggerMode()) << std::endl;
  o << s << " Test trigger start          = " << testTriggerStart() << " x 25ns" << std::endl;
  o << s << " Test trigger end            = " << testTriggerStop() << " x 25ns" << std::endl;
  o << s << " Trigger mask                = " << printHex(triggerMask()) << std::endl;
  o << s << " Trigger source              = " << printHex(triggerSource()) << std::endl;

  o << s << " Bool word = " << printHex(_bools) << std::endl;
  if(debugDiodeResetHold()) o << s << "  Debug diode reset hold set true"  << std::endl;
  else                      o << s << "  Debug diode reset hold set false" << std::endl;
  if(debugShaperResetHold()) o << s << "  Debug shaper reset hold set true"  << std::endl;
  else                       o << s << "  Debug shaper reset hold set false" << std::endl;
  if(debugSampleResetHold()) o << s << "  Debug sample reset hold set true"  << std::endl;
  else                       o << s << "  Debug sample reset hold set false" << std::endl;
  if(hitOverride()) o << s << "  Hit override set true"  << std::endl;
  else              o << s << "  Hit override set false" << std::endl;
  if(monoPOR()) o << s << "  Monostable power-on reset set true"  << std::endl;
  else          o << s << "  Monostable power-on reset set false" << std::endl;
  if(pixelEnable12()) o << s << "  Pixel enable 12 set true"  << std::endl;
  else                o << s << "  Pixel enable 12 set false" << std::endl;
  if(pixelEnable34()) o << s << "  Pixel enable 34 set true"  << std::endl;
  else                o << s << "  Pixel enable 34 set false" << std::endl;
  if(senseEnable()) o << s << "  Sense enable set true"  << std::endl;
  else              o << s << "  Sense enable set false" << std::endl;
  if(debugHitInEnable()) o << s << "  Debug hit in enable set true"  << std::endl;
  else                   o << s << "  Debug hit in enable set false" << std::endl;
  if(fastPhiOverride()) o << s << "  Fast phi override set true"  << std::endl;
  else                  o << s << "  Fast phi override set false" << std::endl;
  if(readEnableOverride()) o << s << "  Read enable override set true"  << std::endl;
  else                     o << s << "  Read enable override set false" << std::endl;
  if(initBPolarity()) o << s << "  Init B polarity set true"  << std::endl;
  else                o << s << "  Init B polarity set false" << std::endl;
  if(rstBPolarity())  o << s << "  Rst B polarity set true"  << std::endl;
  else                o << s << "  Rst B polarity set false" << std::endl;
  if(fwdBPolarity())  o << s << "  Fwd B polarity set true"  << std::endl;
  else                o << s << "  Fwd B polarity set false" << std::endl;
  if(slowSpillPhi())  o << s << "  Slow spill phi set true"  << std::endl;
  else                o << s << "  Slow spill phi set false" << std::endl;
  if(timeStampOverride()) o << s << "  Timestamp override set true"  << std::endl;
  else                    o << s << "  Timestamp override set false" << std::endl;
  if(triggerEnable()) o << s << "  Trigger enable set true"  << std::endl;
  else                o << s << "  Trigger enable set false" << std::endl;
  if(diodeResetHold()) o << s << "  Diode reset hold set true"  << std::endl;
  else                 o << s << "  Diode reset hold set false" << std::endl;
  if(shaperResetHold()) o << s << "  Shaper reset hold set true"  << std::endl;
  else                  o << s << "  Shaper reset hold set false" << std::endl;
  if(sampleResetHold()) o << s << "  Sample reset hold set true"  << std::endl;
  else                  o << s << "  Sample reset hold set false" << std::endl;

  /*
  for(unsigned i(0);i<sizeof(MpsUsbDaqConfigurationData)/4;i++) {
    std::cout << " Word " << std::setw(2) << i << " = "
	      << printHex(*((&_spillCycleCount)+i)) << std::endl;
  }
  */

  return o;
}

#endif
#endif
