#ifndef CrcVlinkTrgData_HH
#define CrcVlinkTrgData_HH

#include <vector>
#include <string>
#include <iostream>

#include "CrcBeTrgHistoryHit.hh"


class CrcVlinkTrgData {

public:
  enum {
    versionNumber=0
  };

  CrcVlinkTrgData();

  unsigned header() const;
  unsigned trailer(unsigned n=256) const;

  unsigned triggerCounter() const;

  std::vector<CrcBeTrgHistoryHit> lineHistory(unsigned l, unsigned n=256) const;

  const unsigned* data() const;

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


private:
  unsigned _header;
  unsigned _triggerCounter;
};


#ifdef CALICE_DAQ_ICC

#include <cstring>

#include "UtlPrintHex.hh"


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

unsigned CrcVlinkTrgData::header() const {
  return _header;
}

unsigned CrcVlinkTrgData::trailer(unsigned n) const {
  return *(&_header+n-1);
}

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

std::vector<CrcBeTrgHistoryHit> CrcVlinkTrgData::lineHistory(unsigned l, unsigned n) const {
  std::vector<CrcBeTrgHistoryHit> v;
  if(n<=3) return v;

  const UtlPack *d((const UtlPack*)data());

  bool hit(false);
  CrcBeTrgHistoryHit h;

  // Loop over the history words, not the trailer
  for(unsigned i(0);i<n-3;i++) {
    if(!hit && d[i].bit(l)) {
      hit=true;
      h.startTime(i);
    }

    if(hit && !d[i].bit(l)) {
      hit=false;
      h.endTime(i-1);
      v.push_back(h);
    }
  }

  // Catch any line active at the end
  if(hit) {
    h.endTime(n-3);
    v.push_back(h);
  }

  return v;
}

const unsigned* CrcVlinkTrgData::data() const {
  return &_triggerCounter+1;
}

std::ostream& CrcVlinkTrgData::print(std::ostream &o, std::string s) const {
  o << s << "CrcVlinkTrgData::print()" << std::endl;
  o << s << " Header          = " << printHex(_header) << std::endl;
  o << s << " Trigger counter = " << std::setw(10) << _triggerCounter << std::endl;
  return o;
}

#endif
#endif
