#ifndef CrcVlinkFeData_HH
#define CrcVlinkFeData_HH

#include <string>
#include <iostream>

#include "UtlPack.hh"


class CrcVlinkAdcSample;

class CrcVlinkFeData {

public:
  enum {
    versionNumber=0
  };

  CrcVlinkFeData();

  unsigned char fe() const;
  void          fe(unsigned char f);

  unsigned fifoStatus() const;
  void     fifoStatus(unsigned n);

  unsigned fifoWords() const;

  bool fifoEmpty() const;
  bool fifoFull() const;

  unsigned triggerCounter() const;
  void     triggerCounter(unsigned c);

  const CrcVlinkAdcSample* adcSample(unsigned n) const;
  CrcVlinkAdcSample*       adcSample(unsigned n);

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


private:
  UtlPack _fifo;
  unsigned _triggerCounter;
};


#ifdef CALICE_DAQ_ICC

#include <cstring>

#include "UtlPrintHex.hh"
#include "CrcVlinkAdcSample.hh"


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

unsigned char CrcVlinkFeData::fe() const {
  return _fifo.byte(0);
}

void CrcVlinkFeData::fe(unsigned char f) {
  _fifo.byte(0,f);
}

unsigned CrcVlinkFeData::fifoStatus() const {
  return _fifo.word()>>8;
}

void CrcVlinkFeData::fifoStatus(unsigned n) {
  UtlPack pn(n);
  _fifo.byte(1,pn.byte(0));
  _fifo.byte(2,pn.byte(1));
  _fifo.byte(3,pn.byte(2));
}

unsigned CrcVlinkFeData::fifoWords() const {
  return (_fifo.byte(2)<<8)+_fifo.byte(1);
}

bool CrcVlinkFeData::fifoEmpty() const {
  return _fifo.bit(24);
}

bool CrcVlinkFeData::fifoFull() const {
  return _fifo.bit(25);
}

unsigned CrcVlinkFeData::triggerCounter() const {
  return _triggerCounter;
}

void CrcVlinkFeData::triggerCounter(unsigned c) {
  _triggerCounter=c;
}

const CrcVlinkAdcSample* CrcVlinkFeData::adcSample(unsigned n) const {
  return (const CrcVlinkAdcSample*)((&_triggerCounter)+1)+n;
}

CrcVlinkAdcSample* CrcVlinkFeData::adcSample(unsigned n) {
  return (CrcVlinkAdcSample*)((&_triggerCounter)+1)+n;
}

std::ostream& CrcVlinkFeData::print(std::ostream &o, std::string s) const {
  o << s << "CrcVlinkFeData::print()  FE" << (unsigned)fe() << std::endl;
  o << s << " Fifo status = " << printHex(fifoStatus()) << std::endl;
  o << s << "  Number of fifo words = " << std::setw(4) << fifoWords();
  if(fifoFull()) o << ", full";
  if(fifoEmpty()) o << ", empty";
  o << std::endl;
  o << s << " Trigger counter = " << std::setw(10) << _triggerCounter << std::endl;
  return o;
}

#endif
#endif
