using namespace std;
#include "hrpcdetector.h"
#include "hrpccalibrater.h"
#include "rpcdef.h"
#include "hrpcraw.h"
#include "hrpccal.h"
#include "hrpccalpar.h"
#include "hrpcchargeoffsetpar.h"
#include "hdebug.h"
#include "hades.h"
#include "hiterator.h"
#include "hruntimedb.h"
#include "hspectrometer.h"
#include "hdetector.h"
#include "hevent.h"
#include "hcategory.h"
#include <iostream>
#include <iomanip>
#include <cstdlib>
HRpcCalibrater::HRpcCalibrater(void)
{
  pRawCat=NULL;
  pCalCat=NULL;
  iter=NULL;
  pCalPar=NULL;
  pChOffPar=NULL;
}
HRpcCalibrater::HRpcCalibrater(const Text_t *name,const Text_t *title) :
  HReconstructor(name,title)
{
  pRawCat=NULL;
  pCalCat=NULL;
  iter=NULL;
  pCalPar=NULL;
  pChOffPar=NULL;
}
HRpcCalibrater::~HRpcCalibrater(void)
{
  if (iter) delete iter;
  iter=NULL;
}
Bool_t HRpcCalibrater::init(void)
{
  HRpcDetector *rpc;
  rpc=(HRpcDetector *)gHades->getSetup()->getDetector("Rpc");
  if(!rpc){
    Error("init","No Rpc Detector found");
    return kFALSE;
  }
  
  pRawCat=gHades->getCurrentEvent()->getCategory(catRpcRaw);
  if (!pRawCat) {
    Error("init","No RpcRaw Category");
    return kFALSE;
  }
  pCalCat=gHades->getCurrentEvent()->getCategory(catRpcCal);
  if (!pCalCat) {
    pCalCat=gHades->getSetup()->getDetector("Rpc")->buildCategory(catRpcCal);
    if (!pCalCat) return kFALSE;
    else gHades->getCurrentEvent()->addCategory(catRpcCal,pCalCat,"Rpc");
  }
  
  pCalPar=(HRpcCalPar*)(gHades->getRuntimeDb()->getContainer("RpcCalPar"));
  if (!pCalPar){
    Error("init","No RpcCalPar Parameters");
    return kFALSE;
  }
  pChOffPar = (HRpcChargeOffsetPar*)(gHades->getRuntimeDb()->getContainer("RpcChargeOffsetPar"));
  if (!pChOffPar){
    Error("init","No RpcChargeOffsetPar Parameters");
    return kFALSE;
  }
  iter=(HIterator *)pRawCat->MakeIterator();
  loc.set(3,0,0,0);
  fActive=kTRUE;
  return kTRUE;
}
Int_t HRpcCalibrater::execute(void)
{
    HRpcCal *pCal=0;
    HRpcRaw *pRaw=0;
    
    iter->Reset();
    while ( (pRaw=(HRpcRaw *)iter->Next()) != NULL) {
	loc[0] = pRaw->getSector();
	loc[1] = pRaw->getColumn();
	loc[2] = pRaw->getCell();
	if(loc[2]>31) continue; 
	
	
	
	if(pRaw->getLeftTime()>0 && pRaw->getRightTime()>0 &&
	   pRaw->getRightTot()>0 && pRaw->getLeftTot()>0) {
	    
	    pCal=(HRpcCal*)pCalCat->getSlot(loc);
	    if (pCal) {
		pCal=new (pCal) HRpcCal;
		if ( !pCal ) return EXIT_FAILURE;
		
		pCal->setAddress(pRaw->getAddress());
		pCal->setLogBit(pRaw->getRightLogBit()); 
		
		Float_t rightTimeOffset,leftTimeOffset,rightTotOffset,leftTotOffset,rightChargeTimeOff,leftChargeTimeOff,tdc2time,tot2charge,tzero=0.0;
		HRpcCalParCol* pCalParCol=pCalPar->getCol(loc[0],loc[1]);
		if(pCalParCol) {
		    HRpcCalParCell* pCalParCell=pCalParCol->getCell(loc[2]);
		    if(pCalParCell) {
			pCalParCell->getAddress(rightTimeOffset,leftTimeOffset,rightTotOffset,leftTotOffset,tdc2time,
						tot2charge,tzero);
			leftChargeTimeOff  = pChOffPar->getPar(loc[0], pRaw->getLeftTRBNum(), pRaw->getLeftMBONum(), pRaw->getLeftDBONum() );
			rightChargeTimeOff = pChOffPar->getPar(loc[0], pRaw->getRightTRBNum(), pRaw->getRightMBONum(), pRaw->getRightDBONum() );
			
			Float_t rightTime,leftTime;
			Float_t rightTot,leftTot,rightTot2,leftTot2;
			
			rightTime = (pRaw->getLeftTime()*tdc2time - pRaw->getRightTime()*tdc2time)/2 + rightTimeOffset;
			leftTime  = (pRaw->getLeftTime()*tdc2time + pRaw->getRightTime()*tdc2time)/2 + leftTimeOffset;
			rightTot  = (pRaw->getRightTot()*tdc2time-rightTotOffset-rightChargeTimeOff);
			leftTot   = (pRaw->getLeftTot()*tdc2time-leftTotOffset-leftChargeTimeOff);
			rightTot2 = (pRaw->getRightTotLast()*tdc2time-rightTotOffset-rightChargeTimeOff);
			leftTot2  = (pRaw->getLeftTotLast()*tdc2time-leftTotOffset-leftChargeTimeOff);
			
			pCal->setRightTime(rightTime);
			pCal->setLeftTime(leftTime);
			pCal->setRightCharge(rightTot);
			pCal->setRightCharge2(rightTot2);
			pCal->setLeftCharge(leftTot);
			pCal->setLeftCharge2(leftTot2);
			
		    } else { Warning("execute","Can't get CalParCell = %i!",loc[2]); }
		} else { Warning("execute","Can't get CalParCol = %i %i!",loc[0],loc[1]); }
	    } else {
		Error ("execute()", "Can't get slot in calibrater: sec %i, col %i, cell %i",loc[0],loc[1],loc[2]);
		return -1;
	    }
	}
    }
    return EXIT_SUCCESS;
}
ClassImp(HRpcCalibrater)