using namespace std;
#include "hrpctrbunpacker.h"
#include "rpcdef.h"
#include "htrblookup.h"
#include "hrpcraw.h"
#include "hdebug.h"
#include "hades.h"
#include "hevent.h"
#include "hspectrometer.h"
#include "hdetector.h"
#include "hruntimedb.h"
#include "hcategory.h"
#include "hldsubevt.h"
#include "heventheader.h"
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include "TCanvas.h"
#include "TStyle.h"
ClassImp(HRpcTrbUnpacker) 
  HRpcTrbUnpacker::HRpcTrbUnpacker (UInt_t id):HTrbBaseUnpacker(id) {
  
  pRawCat = NULL;
  fNoTimeRefCorr=false;
  fControlHistograms=false;
  histdbos = NULL;
  histdbombo = NULL;
  histmbotrb = NULL;
  histtrbchan = NULL;
  debugRpcFlag=0;
  printf("\n\nDetector Id: %d\n\n",id);
}
Bool_t HRpcTrbUnpacker::init (void) {
  
  pRawCat = gHades->getCurrentEvent()->getCategory(catRpcRaw);
  if (!pRawCat) {
    pRawCat = gHades->getSetup()->getDetector("Rpc")->buildCategory(catRpcRaw);
    if (!pRawCat)
      return kFALSE;
    gHades->getCurrentEvent()->addCategory(catRpcRaw,pRawCat,"Rpc");
  }
  loc.set(3,0,0,0);
  lookup = (HTrbLookup *)(gHades->getRuntimeDb()->getContainer("TrbLookup"));
  if (!lookup) {cerr << "init(): could not get container TrbLookup" << endl;  return kFALSE; }
  if(fControlHistograms){
    TString name="MBO*5+DBOinput_DBOnum_";
    name+=getSubEvtId();
    histdbos = new TH2F(name,name,9,-1,8,21,-1,20);
    name="MBOnum_DBOnum_";
    name+=getSubEvtId();
    histdbombo = new TH2F(name,name,9,-1,8,5,-1,4);
    name="TRBnum_MBOnum_";
    name+=getSubEvtId();
    histmbotrb = new TH2F(name,name,5,-1,4,5,-1,4);
    name="TRBnum_CHANnum_";
    name+=getSubEvtId();
    histtrbchan = new TH2F(name,name,129,-1,128,5,-1,4);
  }
  return kTRUE;
}
Bool_t HRpcTrbUnpacker::finalize(void)
{
  if(fControlHistograms){
    if(histdbos){
      histdbos->Write();
      gStyle->SetPalette(1);
      TCanvas c1("c1","c1");
      histdbos->Draw("colz");
      histdbos->SetStats(kFALSE);
      c1.Print(histdbos->GetName()+TString(".ps"));
      delete histdbos;
      histdbos=NULL;
    }
    if(histdbombo){
      histdbombo->Write();
      gStyle->SetPalette(1);
      TCanvas c1("c1","c1");
      histdbombo->Draw("colz");
      histdbombo->SetStats(kFALSE);
      
      c1.Print(histdbombo->GetName()+TString(".ps"));
      delete histdbombo;
      histdbombo=NULL;
    }
    if(histmbotrb){
      histmbotrb->Write();
      gStyle->SetPalette(1);
      TCanvas c1("c1","c1");
      histmbotrb->Draw("colz");
      histmbotrb->SetStats(kFALSE);
      c1.Print(histmbotrb->GetName()+TString(".ps"));
      delete histmbotrb;
      histmbotrb=NULL;
    }
    if(histtrbchan){
      histtrbchan->Write();
      gStyle->SetPalette(1);
      TCanvas c1("c1","c1");
      histtrbchan->Draw("colz");
      histtrbchan->SetStats(kFALSE);
      c1.Print(histtrbchan->GetName()+TString(".ps"));
      delete histtrbchan;
      histtrbchan=NULL;
    }
  }
  return kTRUE;
}
Int_t HRpcTrbUnpacker::execute(void) {
  HRpcRaw *pRaw = 0;	  
  Int_t nEvt = 0;	  
  Char_t side = 'U';      
  Float_t ns2bin = 10.;   
  Int_t FeAddress;
  nEvt = gHades->getCurrentEvent()->getHeader()->getEventSeqNumber();
  
  if (pSubEvt) {		
    decode();			
    
    
    
    
    
    
    
    
    
    if(!fNoTimeRefCorr){
      switch(trbDataVer){
      case 0:   
      case 2:   
	correctRefTimeCh31();
	break;
      case 3:   
	correctRefTimeCh31();
	
	break;
      default:  
	break;
      }
    }
    HTrbLookupBoard *board = lookup->getBoard(subEvtId);
    if (!board) {  
      
      
      
      Warning ("execute", "SubEvent: %i unpacked but channel in Lookup table does not exist", subEvtId);
    }
    
    for (Int_t i = 0; i < 128; i++) {
      if (trbLeadingMult[i]<1 && trbTrailingTotalMult[i]<1) continue;		
      
      
      HTrbLookupChan *chan = board->getChannel(i);
      if (chan && 'R' == chan->getDetector()) {	
	side      = chan->getSide();
	loc[0]    = chan->getSector();
	loc[1]    = chan->getCell()/100;
	loc[2]    = chan->getCell() - 100*loc[1];
	FeAddress = chan->getFeAddress();
	pRaw = (HRpcRaw *)pRawCat->getObject(loc);
	if (!pRaw) {
	  pRaw = (HRpcRaw *)pRawCat->getSlot(loc);
	  pRaw = new (pRaw) HRpcRaw;
	}
	if (pRaw) {
	  if((pRaw->getRightTot()>=0)&&(pRaw->getLeftTot()>=0)) {
#if DEBUG_LEVEL>4
	    Warning("execute", "Slot already exists!\n"); 
#endif
	    continue;
	  }
	  pRaw->setAddress(loc[0],loc[1],loc[2]);
	  if(side=='r') {
	    pRaw->setRightTime(trbLeadingTime[i][0]);
	    pRaw->setRightTot(trbADC[i][0]);
	    pRaw->setRightTime2(trbLeadingTime[i][1]);
	    pRaw->setRightTot2(trbADC[i][1]);
	  } else {
	    pRaw->setLeftTime(trbLeadingTime[i][0]);
	    pRaw->setLeftTot(trbADC[i][0]);
	    pRaw->setLeftTime2(trbLeadingTime[i][1]);
	    pRaw->setLeftTot2(trbADC[i][1]);
	  }
	  
	  Float_t totLast=trbADC[i][0];     
	  Int_t lastTotFlag=0;              
	  Float_t max_time=500.;            
	  Int_t  k_trail_fail =1;
	  Int_t lastTrailingIndex=-1;
	  Int_t k;
	  
	  if(trbLeadingMult[i]>1) {         
	    for(k=0;k<trbLeadingMult[i];k++) {       
	      if(trbTrailingTime[i][k]<0) {
		k_trail_fail++;
		if (k>0) lastTrailingIndex = k-1;
	      }
	    }
	    if (k_trail_fail==k) {
	      
	      totLast=-100000;
	    } 
	    if (lastTrailingIndex==-1) lastTrailingIndex = k; 
	    totLast = trbTrailingTime[i][lastTrailingIndex] - trbLeadingTime[i][0];
	    Int_t ind=0;
	    while(totLast>(max_time*ns2bin)) {    
	      
	      lastTotFlag=1;
	      ind++;
	      if(ind>lastTrailingIndex) cerr<<"algorithm for last Tot does not work!"<<endl;
	      totLast = trbTrailingTime[i][lastTrailingIndex-ind] - trbLeadingTime[i][0]; 
	    }
	  }
	  if(side=='r') {    
	    pRaw->setRightTotLast(totLast);
	  } else {
	    pRaw->setLeftTotLast(totLast);
	  }
	  Int_t trbDataType=0,extra=0;
	  if(side=='r') {
	    pRaw->setRightLogBit(trbLeadingMult[i],trbTrailingTotalMult[i],lastTotFlag,
				 (Int_t)trbDataPairFlag,trbDataVer,trbDataType,extra); 
	  } else {
	    pRaw->setLeftLogBit(trbLeadingMult[i],trbTrailingTotalMult[i],lastTotFlag,
				(Int_t)trbDataPairFlag,trbDataVer,trbDataType,extra); 
	  }
	  
	  Int_t dboInput,dboNum,mboNum,trbNum;
                            
	  trbNum    = FeAddress/1000000;
	  mboNum    = (FeAddress-trbNum*1000000)/10000;
	  dboNum    = (FeAddress-trbNum*1000000-mboNum*10000)/100;
	  dboInput  = FeAddress-trbNum*1000000-mboNum*10000-dboNum*100;
	  
	  if (side=='r') pRaw->setRightFeeAddress(subEvtId,i,dboInput,dboNum,mboNum,trbNum);
	  if (side=='l') pRaw->setLeftFeeAddress(subEvtId,i,dboInput,dboNum,mboNum,trbNum);
	
	  
	  if(fControlHistograms && histdbos && histdbombo && histmbotrb && histtrbchan) {
	    histdbos->Fill(dboNum,mboNum*5+dboInput);
	    histdbombo->Fill(dboNum,mboNum);
	    histmbotrb->Fill(mboNum,trbNum);
	    histtrbchan->Fill(i,trbNum);
	  }
	  
	} else {
	  Error ("execute()", "Can't get slot");
	  cerr << "execute(): Can't get slot Column: "<<loc[1]<< " Cell: " 
	       <<loc[2]<< " Sec: " <<loc[0]<< " SubEvent: " 
	       <<subEvtId << " EvtNb: " <<nEvt << endl;
	  return -1;
	}
      }  
    }  
  }	
  return 1;
}