#include "hades.h"
#include "hcategory.h"
#include "hdatasource.h"
#include "hdebug.h"
#include "hdetector.h"
#include "hevent.h"
#include "heventheader.h"
#include "hldsubevt.h"
#include "hspectrometer.h"
#include "htboxchan.h"
#include "htboxunpacker.h"
using namespace std;
ClassImp(HTBoxUnpacker)
HTBoxUnpacker::HTBoxUnpacker(Int_t id)
{
   fSubEvtId = id;
   fCat      = NULL;
   fLoc.set(1, 0);
}
Bool_t HTBoxUnpacker::init(void)
{
   
   fCat = (HCategory*)gHades->getCurrentEvent()->getCategory(catTBoxChan);
   if (NULL == fCat) {
      fCat = gHades->getSetup()->getDetector("TBox")->buildCategory(catTBoxChan);
      if (NULL != fCat) {
         gHades->getCurrentEvent()->addCategory(catTBoxChan, fCat, "TBox");
      } else {
         Error("init", "Can not build output category");
         return kFALSE;
      }
   }
   return kTRUE;
}
Int_t HTBoxUnpacker::execute()
{
   
#if DEBUG_LEVEL>4
   gDebuger->enterFunc("HTBoxUnpacker::execute\n");
#endif
   
   
   
   
   UInt_t* data       = 0;
   UInt_t* end        = 0;
   UInt_t uTrbNetAdress;        
   UInt_t uSubBlockSize;        
   UInt_t uSubBlockSizeTest;    
   UInt_t uSubBlockSizeScalers; 
   UInt_t trbExtensionSize;     
   HTBoxChan* ptboxchan = NULL;
   if (pSubEvt) {
      trbExtensionSize = 0;
      data = pSubEvt->getData();
      end  = pSubEvt->getEnd();
#if DEBUG_LEVEL>4
      Info("execute", "TBOX: Next SubEvt. data between: %p and %p\n", data, end);
      pSubEvt->dumpIt();
#endif
      
      while (data != end) {
#if DEBUG_LEVEL>2
         Info("execute", "standard HUB word: %08x\n", *data);
#endif
         uSubBlockSize = (*data >> 16) & 0xFF;     
         uSubBlockSizeScalers = uSubBlockSize - 4;
         uTrbNetAdress = *data       & 0xFFFF;     
         
         if (uTrbNetAdress > 0x00FF) {
            data += uSubBlockSize;
         } else {
            
            
            ++data;
#if DEBUG_LEVEL>2
            Info("execute", "first data header: %08x (%p)\n", *data, data);
#endif
            uSubBlockSizeTest = *data & 0xFF;
            if (uSubBlockSize != uSubBlockSizeTest) {
               Error("execute", "check of SubBlockSize failed : %04x != %04x", uSubBlockSize, *(data + 1) & 0xFF);
               return -1;
            }
            
            ++data;
#if DEBUG_LEVEL>2
            Info("execute", "second data header: %08x (%p)\n", *data, data);
#endif
            trbExtensionSize = *data       & 0xFFFF;
            
            if (trbExtensionSize != 0) {
               for (UInt_t ii = 0; ii < trbExtensionSize; ii++) {
                  ++data;
                  if (trbExtensionSize < 128) {
                  } else {
                     Error("execute", "too many TRB extension words (maximum = 128)");
                     return -1;
                  }
               }
            }
            
            ++data;
#if DEBUG_LEVEL>2
            Info("execute", "Latch data word: %08x (%p)\n", *data, data);
#endif
            
            ++data;
            
            for (UInt_t i = 0; i < uSubBlockSizeScalers ; i++) {
               ++data;
               
               if (NULL != fCat) {
                  ptboxchan = (HTBoxChan*)fCat->getNewSlot(fLoc);
                  if (NULL != ptboxchan) {
                     ptboxchan = new(ptboxchan) HTBoxChan;
                     ptboxchan->setScalerData(i, *data);
                     if(i==0){ 
                         Double_t time_ns = 5.* (*data); 
                         gHades->getCurrentEvent()->getHeader()->setTimeInSpill(time_ns);
                     }
                     if(i==1){ 
                         Double_t time_ns = 5.* (*data); 
                         gHades->getCurrentEvent()->getHeader()->setTimeToLastTrigger(time_ns);
                     }
                     if(i==2){ 
                         Double_t time_ns = 5.* (*data); 
                         gHades->getCurrentEvent()->getHeader()->setTimeToLastAntiCoinc(time_ns);
                     }
                  } else {
                     Error("fillScalers", "Can not get new slot for HTBoxChan");
                     continue;
                  }
               }
#if DEBUG_LEVEL>2
               Info("execute", "Scaler data word %i:  %08x (%p)\n", i, *data, data);
#endif
            }
         }
         ++data;
      }
   }
#if DEBUG_LEVEL>4
   gDebuger->leaveFunc("HTBoxUnpacker::execute\n");
#endif
   return 1;
}