#ifndef BmlLalHodoscopeConfigurationData_HH
#define BmlLalHodoscopeConfigurationData_HH

#include <iostream>
#include <fstream>

#include "UtlPack.hh"


class BmlLalHodoscopeConfigurationData {

public:
  enum {
    versionNumber=0
  };

  BmlLalHodoscopeConfigurationData();

  unsigned numberOfWords() const;
  void     numberOfWords(unsigned d);

  unsigned acquisitionMode() const;
  void     acquisitionMode(unsigned m);

  unsigned char threshold(unsigned c) const;
  void          threshold(unsigned c, unsigned char t);

  unsigned char delay(unsigned c) const;
  void          delay(unsigned c, unsigned char d);

  unsigned char gain(unsigned c) const;
  void          gain(unsigned c, unsigned char g);

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


private:
  unsigned _numberOfWords;
  UtlPack _modeACQ;
  UtlPack _thrOPERA[2];
  UtlPack _delay;
  UtlPack _gain[64];
};


#ifdef CALICE_DAQ_ICC

#include <cstring>

#include "UtlPrintHex.hh"


BmlLalHodoscopeConfigurationData::BmlLalHodoscopeConfigurationData() {
  memset(this,0,sizeof(BmlLalHodoscopeConfigurationData));
  _numberOfWords=0xffffffff;
  _thrOPERA[0]=0xe0e0e0e0;
  _thrOPERA[1]=0xe0e0e0e0;
  _delay=0x04040404;
  for(unsigned i(0);i<64;i++) _gain[i]=0x0f0f0f0f; 
}

unsigned BmlLalHodoscopeConfigurationData::numberOfWords() const {
  return _numberOfWords;
}

void BmlLalHodoscopeConfigurationData::numberOfWords(unsigned n) {
  _numberOfWords=n;
}

unsigned BmlLalHodoscopeConfigurationData::acquisitionMode() const {
  return _modeACQ.word();
}

void BmlLalHodoscopeConfigurationData::acquisitionMode(unsigned m) {
  _modeACQ.word(m);
}

unsigned char BmlLalHodoscopeConfigurationData::threshold(unsigned c) const {
  assert(c<8);
  return _thrOPERA[c/4].byte(c%4);
}

void BmlLalHodoscopeConfigurationData::threshold(unsigned c, unsigned char t) {
  assert(c<8);
  _thrOPERA[c/4].byte(c%4,t);
}

unsigned char BmlLalHodoscopeConfigurationData::delay(unsigned c) const {
  assert(c<4);
  return _delay.byte(c);
}

void BmlLalHodoscopeConfigurationData::delay(unsigned c, unsigned char d) {
  assert(c<4);
  _delay.byte(c,d);
}

unsigned char BmlLalHodoscopeConfigurationData::gain(unsigned c) const {
  assert(c<256);
  return _gain[c/4].byte(c%4);
}

void BmlLalHodoscopeConfigurationData::gain(unsigned c, unsigned char g) {
  assert(c<256);
  _gain[c/4].byte(c%4,g);
}

std::ostream& BmlLalHodoscopeConfigurationData::print(std::ostream &o, std::string s) const {
  o << s << "BmlLalHodoscopeConfigurationData::print()" << std::endl;
  o << s << " Number of words = " << _numberOfWords << std::endl;

  o << s << " Acquisition mode = " << printHex(_modeACQ) << std::endl;

  for(unsigned i(0);i<2;i++) {
    o << s << " Threshold word " << i << " = " << printHex(_thrOPERA[i]) << std::endl;
    for(unsigned j(0);j<4;j++) {
      o << s << "  Threshold channel " << 4*i+j << " = " << (unsigned)threshold(4*i+j) << std::endl;
    }
  }
 
  o << s << " Delay word = " << printHex(_delay) << std::endl;
  for(unsigned j(0);j<4;j++) {
    o << s << "  Delay channel " << j << " = " << (unsigned)delay(j) << std::endl;
  }
 
  for(unsigned i(0);i<64;i++) {
    o << s << " Gain word " << i << " = " << printHex(_gain[i]) << std::endl;
    for(unsigned j(0);j<4;j++) {
      o << s << "  Gain channel " << std::setw(3) << 4*i+j << " = "
	<< (unsigned)gain(4*i+j) << std::endl;
    }
  }

  return o;
}

#endif
#endif
