#ifndef CrcFeFakeEventData_HH
#define CrcFeFakeEventData_HH

#include <string>
#include <iostream>

class CrcFeFakeEventData {

public:
  enum {
    versionNumber=0
  };

  CrcFeFakeEventData();

  unsigned numberOfWords() const;
  void     numberOfWords(unsigned n);

  bool enable() const;
  void enable(bool e);

  unsigned control() const;
  void     control(unsigned c);

  const unsigned* data() const;
  unsigned*       data();

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

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

  /*
  void write(std::string fileName) const;
  void write(std::ostream &o) const;

  void read(std::string fileName);
  void read(std::istream &i);
  */

private:
  unsigned _control;
};


#ifdef CALICE_DAQ_ICC

#include <cstring>
#include "UtlPrintHex.hh"

CrcFeFakeEventData::CrcFeFakeEventData() {
  memset(this,0,sizeof(CrcFeFakeEventData));
}

unsigned CrcFeFakeEventData::numberOfWords() const {
  return _control&0x00007fff;
}

void CrcFeFakeEventData::numberOfWords(unsigned n) {
  _control&=   0xffff8000;
  _control|=(n&0x00007fff);
}

bool CrcFeFakeEventData::enable() const {
  return (_control&0x00008000)!=0;
}

void CrcFeFakeEventData::enable(bool e) {
  if(e) _control|=0x00008000;
  else  _control&=0xffff7fff;
}

unsigned CrcFeFakeEventData::control() const {
  return _control;
}

void CrcFeFakeEventData::control(unsigned c) {
  _control=c;
}

const unsigned* CrcFeFakeEventData::data() const {
  return (&_control)+1;
}

unsigned* CrcFeFakeEventData::data() {
  return (&_control)+1;
}

bool CrcFeFakeEventData::operator!=(const CrcFeFakeEventData &c) {
  if(_control!=c._control) return true;
  
  const unsigned *a(data());
  const unsigned *b(c.data());
  for(unsigned i(0);i<numberOfWords();i++) {
    if(a[i]!=b[i]) return true;
  }

  return false;
}

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

std::ostream& CrcFeFakeEventData::print(std::ostream &o, std::string s) const {
  o << s << "CrcFeFakeEventData::print()  Number of words = " 
    << numberOfWords();
  if(enable()) o << ", enabled" << std::endl;
  else         o << ", disabled" << std::endl;
  
  const unsigned *p(data());
  for(unsigned i(0);i<numberOfWords();i++) {
    o << s << " Data word " << std::setw(4) << i << " = "
      << printHex(p[i]) << std::endl;
  }
  
  return o;
}

/*
  void CrcFeFakeEventData::write(std::string fileName) const {
  ofstream o(fileName.c_str());
  write(o);
  }
  
  void CrcFeFakeEventData::write(std::ostream &o) const {
  for(unsigned i(0);i<numberOfWords();i++) {
  o << i << " " << _eventData[i] << std::endl;
  }
  }
  
  void CrcFeFakeEventData::read(std::string fileName) {
  ifstream i(fileName.c_str());
  read(i);
  }
  
  void CrcFeFakeEventData::read(std::istream &i) {
  unsigned n(0);
  for(unsigned j(0);j<numberOfWords();j++) {
  i >> n >> _eventData[j];
      if(n!=j) std::cout << "CrcFeFakeEventData::read()  error "
      << n << " != " << j << std::endl;
      }
      }
*/

#endif
#endif
