#ifndef AhcVfeConfigurationDataFine_HH
#define AhcVfeConfigurationDataFine_HH

#include <string>
#include <iostream>

#include "AhcVfeControl.hh"
#include "AhcVfeShiftRegister.hh"

class AhcFeConfigurationDataV0;


class AhcVfeConfigurationDataFine {

public:
  enum {
    versionNumber=1
  };

  AhcVfeConfigurationDataFine();
  AhcVfeConfigurationDataFine(const AhcFeConfigurationDataV0 &a);

  UtlPack verificationData() const;
  void    verificationData(UtlPack v);

  AhcVfeShiftRegister shiftRegister(unsigned hab) const;
  void                shiftRegister(unsigned hab, AhcVfeShiftRegister s);

  bool operator!=(const AhcVfeConfigurationDataFine &c);
  bool operator==(const AhcVfeConfigurationDataFine &c);

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


private:
  UtlPack _verificationData;
  AhcVfeShiftRegister _shiftRegister[12];
};


#ifdef CALICE_DAQ_ICC

#include "AhcFeConfigurationDataV0.hh"


AhcVfeConfigurationDataFine::AhcVfeConfigurationDataFine() : _verificationData(0xaaaa5555) {
}

AhcVfeConfigurationDataFine::AhcVfeConfigurationDataFine(const AhcFeConfigurationDataV0 &a) {
  _verificationData=0xffffffff;
  for(unsigned i(0);i<12;i++) {
    shiftRegister(i,a.shiftRegister(i));
  }
}

UtlPack AhcVfeConfigurationDataFine::verificationData() const {
  return _verificationData;
}
 
void AhcVfeConfigurationDataFine::verificationData(UtlPack v) {
  _verificationData=v;
}
 
AhcVfeShiftRegister AhcVfeConfigurationDataFine::shiftRegister(unsigned hab) const {
  assert(hab<12);
  return _shiftRegister[hab];
}

void AhcVfeConfigurationDataFine::shiftRegister(unsigned hab, AhcVfeShiftRegister s) {
  assert(hab<12);
  _shiftRegister[hab]=s;
}

bool AhcVfeConfigurationDataFine::operator!=(const AhcVfeConfigurationDataFine &c) {
  unsigned *a((unsigned*)this);
  unsigned *b((unsigned*)&c);
  for(unsigned i(0);i<sizeof(AhcVfeConfigurationDataFine)/4;i++) {
    if(a[i]!=b[i]) return true;
  }
  return false;
}

bool AhcVfeConfigurationDataFine::operator==(const AhcVfeConfigurationDataFine &c) {
  return !operator!=(c);
}

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

  o << s << " Verification data = " << printHex(_verificationData) << std::endl;

  for(unsigned i(0);i<12;i++) {
    o << s << " HAB " << std::setw(2) << i << " ";
    _shiftRegister[i].print(o,s+" ");
  }
  
  return o;
}

#endif
#endif
