/** @file
 * $Source: /repository/PamOffLineSW/techmodel/CalibTrk1Reader.cpp,v $
 * $Id: CalibTrk1Reader.cpp,v 1.8 2008-03-21 16:18:46 messineo Exp $
 * $Author: messineo $
 * 
 * Implementation of the LogReader class.
* ToBeDone:
* Control the CRC for the entire data Packet not just for single records
 */

#include "ReaderAlgorithms.h"

extern "C" {
    #include "CRC.h"
    extern void trkcalibpkt_(int*, unsigned char[], long int*, int*); //(*)

    //Struct per il passaggio di dati da e verso la chiamata fortran
    extern struct {
    int   good0;
    int   DAQmode[6];
    int   DSPnumber[6];
    int   calibnumber[6];
    int   ncalib_event[6];
    int   ped_l1[6];
    int   ped_l2[6];
    int   ped_l3[6];
    int   sig_l1[6];
    int   sig_l2[6];
    int   sig_l3[6];
    int   nbad_l1[6];
    int   nbad_l2[6];
    int   nbad_l3[6];
    int   cal_flag[6];
    float DSPped_par[3072][6];
    float DSPsig_par[3072][6];
    int   DSPbad_par[3072][6];
    int   crc_cal[3][6];
    int   crc_hcal[6];
    } trkcalib_;
#include <dirent.h>
}

using namespace pamela::techmodel;

/**
 * Constructor. 
 */
CalibTrk1Reader::CalibTrk1Reader(void): 
  TechmodelAlgorithm(PacketType::CalibTrk1, "TechmodelCalibTrk1Reader") { 
  calibTrk1 = new CalibTrk1Event();
}

/**
 * Get a string with the version info of the algorithm.
 */
std::string CalibTrk1Reader::GetVersionInfo(void) const {
  return 
    "$Header: /repository/PamOffLineSW/techmodel/CalibTrk1Reader.cpp,v 1.8 2008-03-21 16:18:46 messineo Exp $\n";
}

/**
 * Initialize the algorithm with a special run. This will initialize the
 * event reader routines for all packet types.
 */
void CalibTrk1Reader::Init(PamelaRun *run) {
	run->WriteSubPacket(this, &calibTrk1, calibTrk1->Class());
}

/**
 * Unpack the CalibTrk event
 */
void CalibTrk1Reader::PKT_RunEvent(char* data, long int dataLength) throw (CalibException){  
	std::stringstream oss; 
	string msg;
    int ERROR;
    int curpos=1;
    
    //Call to the FORTRAN routin that unpack tracker events
    trkcalibpkt_( &ERROR,(unsigned char*)data, &dataLength, &curpos); 

    calibTrk1->unpackError = ERROR;
    if (ERROR != 0) {
        oss.str("");
        oss <<  "CalibTrk1: Fortran77 function trkcalibpkt error code = " << ERROR;
 		msg=oss.str();
		PamOffLineSW::mainLogUtil->logWarning(msg);	
    }

    //Store the unpacked data
    calibTrk1->good0 = trkcalib_.good0;
    memcpy(calibTrk1->DAQmode,      trkcalib_.DAQmode,      sizeof(calibTrk1->DAQmode));
    memcpy(calibTrk1->DSPnumber,    trkcalib_.DSPnumber,    sizeof(calibTrk1->DSPnumber));
    memcpy(calibTrk1->calibnumber,  trkcalib_.calibnumber,  sizeof(calibTrk1->calibnumber));
    memcpy(calibTrk1->ncalib_event, trkcalib_.ncalib_event, sizeof(calibTrk1->ncalib_event));
    memcpy(calibTrk1->ped_l1,       trkcalib_.ped_l1,       sizeof(calibTrk1->ped_l1));
    memcpy(calibTrk1->ped_l2,       trkcalib_.ped_l2,       sizeof(calibTrk1->ped_l2));
    memcpy(calibTrk1->ped_l3,       trkcalib_.ped_l3,       sizeof(calibTrk1->ped_l3));
    memcpy(calibTrk1->sig_l1,       trkcalib_.sig_l1,       sizeof(calibTrk1->sig_l1));
    memcpy(calibTrk1->sig_l2,       trkcalib_.sig_l2,       sizeof(calibTrk1->sig_l2));
    memcpy(calibTrk1->sig_l3,       trkcalib_.sig_l3,       sizeof(calibTrk1->sig_l3));
    memcpy(calibTrk1->nbad_l1,      trkcalib_.nbad_l1,      sizeof(calibTrk1->nbad_l1));
    memcpy(calibTrk1->nbad_l2,      trkcalib_.nbad_l2,      sizeof(calibTrk1->nbad_l2));
    memcpy(calibTrk1->nbad_l3,      trkcalib_.nbad_l3,      sizeof(calibTrk1->nbad_l3));
    memcpy(calibTrk1->cal_flag,     trkcalib_.cal_flag,     sizeof(calibTrk1->cal_flag));      

    int     tempBad_par[3072][6];
    float   tempPed_par[3072][6];
    float   tempSig_par[3072][6];
    int     tempCrc_cal[3][6];
    memcpy(tempBad_par,trkcalib_.DSPbad_par, sizeof(tempBad_par));      
    memcpy(tempPed_par,trkcalib_.DSPped_par, sizeof(tempPed_par));      
    memcpy(tempSig_par,trkcalib_.DSPsig_par, sizeof(tempSig_par));      
    memcpy(tempCrc_cal,trkcalib_.crc_cal,    sizeof(tempCrc_cal));      

    for (int i = 0; i < 6; i++){
        for (int j = 0; j < 3072; j++){
            calibTrk1->DSPbad_par[i][j] = tempBad_par[j][i];
            calibTrk1->DSPped_par[i][j] = tempPed_par[j][i];
            calibTrk1->DSPsig_par[i][j] = tempSig_par[j][i];
        }
        for (int k = 0; k < 3; k++){
            calibTrk1->crc_cal[i][k] = tempCrc_cal[k][i];
        }
    }
		
    PamOffLineSW::mainLogUtil->logError("CANNOT CHECK IF CalibTrk1 IS GOOD OR NOT ...");	

    //TODO: put the correct check here ....
    if(1>2){
    	oss.str("");
    	//oss <<  "CalibTrk1 Problem: ??[0] = " <<cperror[0]<<" cperror[1] = " <<cperror[1]<<" cperror[2] = " <<cperror[2]<<" cperror[3] = " <<cperror[3];
    	msg=oss.str();
   		PamOffLineSW::mainLogUtil->logError(msg);
   	  	throw CalibException("Wrong Global CRC for CalibTrk1 Packet ");
    }
//-----------------------------------------------------------------------------------------
}



