#include "hades.h"
#include "hdatasource.h"
#include "hdebug.h"
#include "hevent.h"
#include "heventheader.h"
#include "hlatchunpacker.h"
#include "hldsubevt.h"
#include "hstartdef.h"
#include <iomanip>
#include <iostream>
#include <stdlib.h>
#define TEST 0
using namespace std;
ClassImp(HLatchUnpacker)
HLatchUnpacker::HLatchUnpacker(Int_t id)
{
   
   
   subEvtId = id;
}
Int_t HLatchUnpacker::execute()
{
   
#if DEBUG_LEVEL>4
   gDebuger->enterFunc("HLatchUnpacker::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;     
   if (pSubEvt) {
      trbExtensionSize = 0;
      data = pSubEvt->getData();
      end  = pSubEvt->getEnd();
#if DEBUG_LEVEL>4
      printf("Next SubEvt. data between: %p and %p\n", data, end);
      pSubEvt->dumpIt();
#endif
      
      while (data != end) {
#if DEBUG_LEVEL>2
         printf("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
            printf("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
            printf("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
            printf("Latch data word: %08x (%p)\n", *data, data);
#endif
            fillLatch(data);
            
            ++data;
            
            
            
            data += uSubBlockSizeScalers ;
         }
         ++data;
      }
   }
#if DEBUG_LEVEL>4
   gDebuger->leaveFunc("HLatchUnpacker::execute\n");
#endif
   return 1;
}
UInt_t* HLatchUnpacker::fillLatch(UInt_t* data)
{
   
   
   UInt_t latchData = *data & 0xFFFFFFFF;
   gHades->getCurrentEvent()->getHeader()->setTBit(latchData);
   return data;
}