#include "hades.h"
#include "hcategory.h"
#include "hdebug.h"
#include "hevent.h"
#include "heventheader.h"
#include "hldsource.h"
#include "hldsubevt.h"
#include "hruntimedb.h"
#include "hspectrometer.h"
#include "hstart2detector.h"
#include "hstart2raw.h"
#include "hstart2trb3lookup.h"
#include "hstart2trb3calpar.h"
#include "hstart2trb3unpacker.h"
#include "htrbnetunpacker.h"
#include <iostream>
using namespace std;
ClassImp(HStart2Trb3Unpacker)
Bool_t HStart2Trb3Unpacker::fHasPrintedTDC = kFALSE;
HStart2Trb3Unpacker::HStart2Trb3Unpacker(vector<UInt_t>& ids) : HTrb3TdcUnpacker(ids) {
  
  pRawCat = NULL;
  timeRef = kTRUE;
  lookup  = NULL;
}
Bool_t HStart2Trb3Unpacker::init(void) {
  
   HStart2Detector* det = (HStart2Detector*)gHades->getSetup()->getDetector("Start");
   if (!det) {
      Error("init", "No Start Detector found.");
      return kFALSE;
   }
  pRawCat = det->buildCategory(catStart2Raw);
  if (!pRawCat) return kFALSE;
  loc.set(2, 0, 0);
  lookup = (HStart2Trb3Lookup*)(gHades->getRuntimeDb()->getContainer("Start2Trb3Lookup"));
  if (!lookup) {
     Error("init", "No Pointer to parameter container Start2Trb3Lookup.");
     return kFALSE;
  }
  if (NULL == trbNetUnpacker) {
    if (gHades->getDataSource()) {
      HDataSource* source = gHades->getDataSource();
      if (source->InheritsFrom("HldSource")) {
        trbNetUnpacker = ((HldSource *)gHades->getDataSource())->getTrbNetUnpacker();
      } else {
        Warning("init", "DataSource not inherited from HldSource! trbNetUnpacker == 0 ");
      }
    } else {
      Warning("init", "Could not retrieve DataSource! trbNetUnpacker == 0 ");
    }
  }
  if (!trbNetUnpacker->init()) {
    Error("init", "Failed to initialize HTrbNetUnpacker!");
    return kFALSE;
  }
  return kTRUE;
}
Bool_t HStart2Trb3Unpacker::reinit(void)
{
    
    
    
    
    if (numTDC() == 0 )  
    {
	if (fMinAddress == 0 && fMaxAddress == 0)
	{
	    
	    Int_t numTDC = lookup->getSize();
	    Int_t offset = lookup->getArrayOffset() ;
	    for (Int_t slot = 0; slot < numTDC; ++slot) {
		Int_t trbnetaddress = offset+slot;
		HStart2Trb3LookupTdc* tdc = lookup->getTdc(trbnetaddress);
		if(tdc){
		    Int_t nChan = tdc->getSize();
		    if (trbnetaddress) {
			Int_t tindex = addTDC(trbnetaddress,nChan);
			Info("reinit", "Added TDC 0x%04x with %d channels from HStart2Trb3Lookup to map index %d",
			     trbnetaddress, nChan,tindex);
		    }
		}
	    }
	    
	    setMinAddress(lookup->getArrayOffset());
	    setMaxAddress(lookup->getArrayOffset() + lookup->getSize());
	    fUseTDCFromLookup = kTRUE; 
            fHasPrintedTDC = kTRUE;
	} else {
            Info("reinit", "TDCs will be added in auto register mode between min address 0x%04x and max address 0x%04x!",fMinAddress,fMaxAddress);
	}
    }
    
    return kTRUE;
}
Int_t HStart2Trb3Unpacker::execute(void) {
  HStart2Raw *pRaw = 0;  
  if (gHades->isCalibration()) {
    
    return 1;
  }
  if (gHades->getCurrentEvent()->getHeader()->getId() == 0xe) {
    
    return 1;
  }
  
  
  if (!pSubEvt) return 1;
  Int_t nEvt = gHades->getCurrentEvent()->getHeader()->getEventSeqNumber();
  
  if (!decode()) {
     Error("decode", "subsubevent decoding failed!!! Evt Nr : %i SubEvtId: %x", nEvt, getSubEvtId());
     return -1;
  }
  
  
  
  
  if (timeRef) {
     correctRefTimeCh(REFCHAN);
  }
  for (UInt_t ntdc=0;ntdc<numActiveTDC();ntdc++) {
     TDC* tdc = getActiveTDC(ntdc);
    
    HStart2Trb3LookupTdc *board = lookup->getTdc(tdc->getTrbAddr());
    if (!board) {
       if (debugFlag > 0) Warning("execute", "Evt Nr : %i  SubEvId: %x (%i) unpacked but TDC Board 0x%x not in lookup table",
	                          nEvt, getSubEvtId(), getSubEvtId(), tdc->getTrbAddr());
       continue;
    }
    
    for (UInt_t i = 0; i < tdc->numChannels(); i++) {
	if(REFCHAN == i) continue;
       
       HStart2Trb3LookupChan *chan = board->getChannel(i);
       if (chan==0) continue;
       
       chan->getAddress(loc[0], loc[1]);
       if (loc[0] < 0) continue;
       HTrb3TdcUnpacker::ChannelRec& rec0 = tdc->getCh(i);
       
       if (rec0.rising_mult < 1) continue;
       
       pRaw = (HStart2Raw*)pRawCat->getObject(loc);
       if (!pRaw) {
          pRaw = (HStart2Raw *)pRawCat->getSlot(loc);
          if (pRaw) {
             pRaw = new(pRaw) HStart2Raw;
             pRaw->setAddress(loc[0], loc[1]);
          } else {
             Error("execute()", "Can't get slot mod=%i, cell=%i", loc[0], loc[1]);
             return -1;
          }
       } else {
          Error("execute", "Slot already exists for mod=%i, cell=%i", loc[0], loc[1]);
          return -1;
       }
       
       for (UInt_t chmult = 0; chmult < rec0.rising_mult; chmult++) {
          Double_t tm0 = rec0.rising_tm[chmult]*1e9;
          if (debugFlag > 0)
             printf("--filling data TDC:%04x ch:%2d loc0:%2d loc1:%2d xtime: %6.3f\n",
                   tdc->getTrbAddr(), i, loc[0], loc[1], tm0);
          Double_t adc = -1000;
	  for (UInt_t n1=0; n1<rec0.falling_mult; n1++) {
	      Double_t tm1 = rec0.falling_tm[n1]*1e9;
	      if (debugFlag > 0)
		  cout<<"--ADC, tm0: "<<tm0<<", tm1: "<<tm1<<", ToT: "<<tm1 - tm0<<endl;
	      if (tm1<=tm0) continue;
	      if ((adc<0.) || (adc>tm1-tm0)) adc = tm1-tm0;
	  }
          pRaw->setTimeAndWidth(tm0, adc);
      }
    } 
  } 
  return 1;
}
 hstart2trb3unpacker.cc:10  hstart2trb3unpacker.cc:11  hstart2trb3unpacker.cc:12  hstart2trb3unpacker.cc:13  hstart2trb3unpacker.cc:14  hstart2trb3unpacker.cc:15  hstart2trb3unpacker.cc:16  hstart2trb3unpacker.cc:17  hstart2trb3unpacker.cc:18  hstart2trb3unpacker.cc:19  hstart2trb3unpacker.cc:20  hstart2trb3unpacker.cc:21  hstart2trb3unpacker.cc:22  hstart2trb3unpacker.cc:23  hstart2trb3unpacker.cc:24  hstart2trb3unpacker.cc:25  hstart2trb3unpacker.cc:26  hstart2trb3unpacker.cc:27  hstart2trb3unpacker.cc:28  hstart2trb3unpacker.cc:29  hstart2trb3unpacker.cc:30  hstart2trb3unpacker.cc:31  hstart2trb3unpacker.cc:32  hstart2trb3unpacker.cc:33  hstart2trb3unpacker.cc:34  hstart2trb3unpacker.cc:35  hstart2trb3unpacker.cc:36  hstart2trb3unpacker.cc:37  hstart2trb3unpacker.cc:38  hstart2trb3unpacker.cc:39  hstart2trb3unpacker.cc:40  hstart2trb3unpacker.cc:41  hstart2trb3unpacker.cc:42  hstart2trb3unpacker.cc:43  hstart2trb3unpacker.cc:44  hstart2trb3unpacker.cc:45  hstart2trb3unpacker.cc:46  hstart2trb3unpacker.cc:47  hstart2trb3unpacker.cc:48  hstart2trb3unpacker.cc:49  hstart2trb3unpacker.cc:50  hstart2trb3unpacker.cc:51  hstart2trb3unpacker.cc:52  hstart2trb3unpacker.cc:53  hstart2trb3unpacker.cc:54  hstart2trb3unpacker.cc:55  hstart2trb3unpacker.cc:56  hstart2trb3unpacker.cc:57  hstart2trb3unpacker.cc:58  hstart2trb3unpacker.cc:59  hstart2trb3unpacker.cc:60  hstart2trb3unpacker.cc:61  hstart2trb3unpacker.cc:62  hstart2trb3unpacker.cc:63  hstart2trb3unpacker.cc:64  hstart2trb3unpacker.cc:65  hstart2trb3unpacker.cc:66  hstart2trb3unpacker.cc:67  hstart2trb3unpacker.cc:68  hstart2trb3unpacker.cc:69  hstart2trb3unpacker.cc:70  hstart2trb3unpacker.cc:71  hstart2trb3unpacker.cc:72  hstart2trb3unpacker.cc:73  hstart2trb3unpacker.cc:74  hstart2trb3unpacker.cc:75  hstart2trb3unpacker.cc:76  hstart2trb3unpacker.cc:77  hstart2trb3unpacker.cc:78  hstart2trb3unpacker.cc:79  hstart2trb3unpacker.cc:80  hstart2trb3unpacker.cc:81  hstart2trb3unpacker.cc:82  hstart2trb3unpacker.cc:83  hstart2trb3unpacker.cc:84  hstart2trb3unpacker.cc:85  hstart2trb3unpacker.cc:86  hstart2trb3unpacker.cc:87  hstart2trb3unpacker.cc:88  hstart2trb3unpacker.cc:89  hstart2trb3unpacker.cc:90  hstart2trb3unpacker.cc:91  hstart2trb3unpacker.cc:92  hstart2trb3unpacker.cc:93  hstart2trb3unpacker.cc:94  hstart2trb3unpacker.cc:95  hstart2trb3unpacker.cc:96  hstart2trb3unpacker.cc:97  hstart2trb3unpacker.cc:98  hstart2trb3unpacker.cc:99  hstart2trb3unpacker.cc:100  hstart2trb3unpacker.cc:101  hstart2trb3unpacker.cc:102  hstart2trb3unpacker.cc:103  hstart2trb3unpacker.cc:104  hstart2trb3unpacker.cc:105  hstart2trb3unpacker.cc:106  hstart2trb3unpacker.cc:107  hstart2trb3unpacker.cc:108  hstart2trb3unpacker.cc:109  hstart2trb3unpacker.cc:110  hstart2trb3unpacker.cc:111  hstart2trb3unpacker.cc:112  hstart2trb3unpacker.cc:113  hstart2trb3unpacker.cc:114  hstart2trb3unpacker.cc:115  hstart2trb3unpacker.cc:116  hstart2trb3unpacker.cc:117  hstart2trb3unpacker.cc:118  hstart2trb3unpacker.cc:119  hstart2trb3unpacker.cc:120  hstart2trb3unpacker.cc:121  hstart2trb3unpacker.cc:122  hstart2trb3unpacker.cc:123  hstart2trb3unpacker.cc:124  hstart2trb3unpacker.cc:125  hstart2trb3unpacker.cc:126  hstart2trb3unpacker.cc:127  hstart2trb3unpacker.cc:128  hstart2trb3unpacker.cc:129  hstart2trb3unpacker.cc:130  hstart2trb3unpacker.cc:131  hstart2trb3unpacker.cc:132  hstart2trb3unpacker.cc:133  hstart2trb3unpacker.cc:134  hstart2trb3unpacker.cc:135  hstart2trb3unpacker.cc:136  hstart2trb3unpacker.cc:137  hstart2trb3unpacker.cc:138  hstart2trb3unpacker.cc:139  hstart2trb3unpacker.cc:140  hstart2trb3unpacker.cc:141  hstart2trb3unpacker.cc:142  hstart2trb3unpacker.cc:143  hstart2trb3unpacker.cc:144  hstart2trb3unpacker.cc:145  hstart2trb3unpacker.cc:146  hstart2trb3unpacker.cc:147  hstart2trb3unpacker.cc:148  hstart2trb3unpacker.cc:149  hstart2trb3unpacker.cc:150  hstart2trb3unpacker.cc:151  hstart2trb3unpacker.cc:152  hstart2trb3unpacker.cc:153  hstart2trb3unpacker.cc:154  hstart2trb3unpacker.cc:155  hstart2trb3unpacker.cc:156  hstart2trb3unpacker.cc:157  hstart2trb3unpacker.cc:158  hstart2trb3unpacker.cc:159  hstart2trb3unpacker.cc:160  hstart2trb3unpacker.cc:161  hstart2trb3unpacker.cc:162  hstart2trb3unpacker.cc:163  hstart2trb3unpacker.cc:164  hstart2trb3unpacker.cc:165  hstart2trb3unpacker.cc:166  hstart2trb3unpacker.cc:167  hstart2trb3unpacker.cc:168  hstart2trb3unpacker.cc:169  hstart2trb3unpacker.cc:170  hstart2trb3unpacker.cc:171  hstart2trb3unpacker.cc:172  hstart2trb3unpacker.cc:173  hstart2trb3unpacker.cc:174  hstart2trb3unpacker.cc:175  hstart2trb3unpacker.cc:176  hstart2trb3unpacker.cc:177  hstart2trb3unpacker.cc:178  hstart2trb3unpacker.cc:179  hstart2trb3unpacker.cc:180  hstart2trb3unpacker.cc:181  hstart2trb3unpacker.cc:182  hstart2trb3unpacker.cc:183  hstart2trb3unpacker.cc:184  hstart2trb3unpacker.cc:185  hstart2trb3unpacker.cc:186  hstart2trb3unpacker.cc:187  hstart2trb3unpacker.cc:188  hstart2trb3unpacker.cc:189  hstart2trb3unpacker.cc:190  hstart2trb3unpacker.cc:191  hstart2trb3unpacker.cc:192  hstart2trb3unpacker.cc:193  hstart2trb3unpacker.cc:194  hstart2trb3unpacker.cc:195  hstart2trb3unpacker.cc:196  hstart2trb3unpacker.cc:197  hstart2trb3unpacker.cc:198  hstart2trb3unpacker.cc:199  hstart2trb3unpacker.cc:200  hstart2trb3unpacker.cc:201  hstart2trb3unpacker.cc:202  hstart2trb3unpacker.cc:203  hstart2trb3unpacker.cc:204  hstart2trb3unpacker.cc:205  hstart2trb3unpacker.cc:206  hstart2trb3unpacker.cc:207  hstart2trb3unpacker.cc:208  hstart2trb3unpacker.cc:209  hstart2trb3unpacker.cc:210  hstart2trb3unpacker.cc:211  hstart2trb3unpacker.cc:212  hstart2trb3unpacker.cc:213  hstart2trb3unpacker.cc:214  hstart2trb3unpacker.cc:215  hstart2trb3unpacker.cc:216  hstart2trb3unpacker.cc:217  hstart2trb3unpacker.cc:218  hstart2trb3unpacker.cc:219  hstart2trb3unpacker.cc:220  hstart2trb3unpacker.cc:221  hstart2trb3unpacker.cc:222  hstart2trb3unpacker.cc:223  hstart2trb3unpacker.cc:224  hstart2trb3unpacker.cc:225  hstart2trb3unpacker.cc:226  hstart2trb3unpacker.cc:227  hstart2trb3unpacker.cc:228  hstart2trb3unpacker.cc:229