//
// $Id: DhcReadoutConfigurationData.hh,v 1.1 2008/06/27 10:34:05 meyern Exp $
//

#ifndef DhcReadoutConfigurationData_HH
#define DhcReadoutConfigurationData_HH

#include <string>
#include <iostream>

#include "UtlPack.hh"
#include "UtlTime.hh"


class DhcReadoutConfigurationData {

public:
  enum {
    versionNumber=0
  };

  DhcReadoutConfigurationData();

  unsigned char crateNumber() const;
  void          crateNumber(unsigned char c);

  bool slotFeEnable(unsigned s, unsigned f) const;
  void slotFeEnable(unsigned s, unsigned f, bool b);

  unsigned short slotFeEnables(unsigned s) const;
  void           slotFeEnables(unsigned s, unsigned short b);

  bool slotEnable(unsigned s) const;
  void slotEnable(unsigned s, bool b);

  unsigned bltSize() const;
  void     bltSize(unsigned n);

  UtlTimeDifference pollInterval() const;
  void     pollInterval(UtlTimeDifference t);

  bool triggerByWaiting() const;
  void triggerByWaiting(bool b);

  bool triggerInternally() const;
  void triggerInternally(bool b);

  bool triggerExternally() const;
  void triggerExternally(bool b);

  UtlPack mode() const;
  void mode(UtlPack m);

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

private:
  UtlPack _numbers;
  UtlPack _slotEnable;
  UtlPack _slotFeEnable[10];
  unsigned _bltSize;
  UtlTimeDifference _pollInterval;
  UtlPack _mode;
};


DhcReadoutConfigurationData::DhcReadoutConfigurationData() {
  memset(this,0,sizeof(DhcReadoutConfigurationData));

  for(unsigned i(2);i<=11;i++) {
    slotEnable(i,false);
    for(unsigned f(0);f<12;f++) slotFeEnable(i,f,false);
  }

  pollInterval(0);
  triggerByWaiting(true);
}

unsigned char DhcReadoutConfigurationData::crateNumber() const {
  return _numbers.byte(0);
}

void DhcReadoutConfigurationData::crateNumber(unsigned char c) {
  _numbers.byte(0,c);
}

bool DhcReadoutConfigurationData::slotFeEnable(unsigned s, unsigned f) const {
  assert(s>=2 && s<=21 && f<12);
  return _slotFeEnable[(s-2)/2].bit(16*((s-2)%2)+f);
}

void DhcReadoutConfigurationData::slotFeEnable(unsigned s, unsigned f, bool b) {
  assert(s>=2 && s<=21 && f<12);
  _slotFeEnable[(s-2)/2].bit(16*((s-2)%2)+f,b);
}

unsigned short DhcReadoutConfigurationData::slotFeEnables(unsigned s) const {
  assert(s>=2 && s<=21);
  return _slotFeEnable[(s-2)/2].halfWord((s-2)%2);
}

void DhcReadoutConfigurationData::slotFeEnables(unsigned s, unsigned short b) {
  assert(s>=2 && s<=11);
  _slotFeEnable[(s-2)/2].halfWord((s-2)%2,b);
}

bool DhcReadoutConfigurationData::slotEnable(unsigned s) const { 
  assert(s>=2 && s<=11);
  return _slotEnable.bit(s);
}

void DhcReadoutConfigurationData::slotEnable(unsigned s, bool b) { 
  assert(s>=2 && s<=11);
  if(!b) for(unsigned f(0);f<12;f++) slotFeEnable(s,f,false);
  _slotEnable.bit(s,b);
}

unsigned DhcReadoutConfigurationData::bltSize() const {
  return _bltSize;
}

void DhcReadoutConfigurationData::bltSize(unsigned n) {
  _bltSize=n;
}

UtlTimeDifference DhcReadoutConfigurationData::pollInterval() const {
  return _pollInterval;
}

void DhcReadoutConfigurationData::pollInterval(UtlTimeDifference t) {
  _pollInterval=t;
}

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

void DhcReadoutConfigurationData::mode(UtlPack m) {
  _mode.word(m.word());
}

bool DhcReadoutConfigurationData::triggerByWaiting() const {
  return _mode.bit(0);
}

void DhcReadoutConfigurationData::triggerByWaiting(bool b) {
  _mode.byte(0,0);
  _mode.bit(0,b);
}

bool DhcReadoutConfigurationData::triggerInternally() const {
  return _mode.bit(1);
}

void DhcReadoutConfigurationData::triggerInternally(bool b) {
  _mode.byte(0,0);
  _mode.bit(1,b);
}

bool DhcReadoutConfigurationData::triggerExternally() const {
  return _mode.bit(2);
}

void DhcReadoutConfigurationData::triggerExternally(bool b) {
  _mode.byte(0,0);
  _mode.bit(2,b);
}

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

  o << s << " Crate number  = " << printHex(_numbers.byte(0)) << std::endl;
  for(unsigned i(2);i<=11;i++) {
    if(slotEnable(i)) {
      o << s << "  Slot " << std::setw(2) << i << ", FE enables = "
	<< printHex(_slotFeEnable[(i-2)/2].halfWord((i-2)%2)) << std::endl;
    }
  }
  o << s << " BLT Size        = " << _bltSize << std::endl;
  o << s << " Poll interval   = " << _pollInterval << std::endl;
  if(triggerByWaiting()) o << s << "  Triggered By Waiting" << std::endl;
  if(triggerInternally()) o << s << "  Triggered Internally" << std::endl;
  if(triggerExternally()) o << s << "  Triggered Externally" << std::endl;
  o << s << std::endl;

  return o;
}

#endif // DhcReadoutConfigurationData_HH
