/** @file
 * $Source: /repository/PamOffLineSW/physics/TrackerReader.cpp,v $
 * $Id: TrackerReader.cpp,v 1.4 2008-03-05 11:37:36 messineo Exp $
 * $Author: messineo $
 * 
 * Implementation of the TrackerPhysicsReader class.
 */


#include <string>
#include "TrackerReader.h"
#include "event/physics/tracker/TrackerEvent.h"

extern "C" {

    extern void trkeventpkt_(int*, unsigned char[], long int*, int*);
    
    //Struct per il passaggio di dati da e verso la chiamata fortran
    extern struct {
	int DAQmode[12];
	int DSPnumber[12];
	int DATAlength[12];
	int eventn[12];
	int nclust[12];
	int cutc[12];
	int cutcl[12];
	int addrcluster[3][12];
	int signcluster[3][12];
	int fc[12];
	int compressiontime[12];
	int fl5[12];
	int fl4[12];
	int fl3[12];
	int fl2[12];
	int fl1[12];
	int fl6[12];
	int checksum[12];
	int TOTDATAlength;
	int datatracker[49152];
	int pnum[12];
	int cmdnum[12];
	int bid[12];
	int alarm[12];
	int aswr[12];
	int good0;          
	int crc[12];        
    } level0_; 
#include <dirent.h>
}

using namespace pamela;
using namespace pamela::tracker;


/**
 * Constructor. 
 */
TrackerReader::TrackerReader(void): 
  TechmodelAlgorithm(PacketType::Physics, "TechmodelTrackerReader") { 
  tracker = new TrackerEvent();
}

/**
 * Get a string with the version info of the algorithm.
 */
std::string TrackerReader::GetVersionInfo(void) const {
  return 
    "$Header: /repository/PamOffLineSW/physics/TrackerReader.cpp,v 1.4 2008-03-05 11:37:36 messineo Exp $";
}

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

/**
 * Unpack the orbital event from an input file.
 */
void TrackerReader::RunEvent(int EventNumber) {
  
}

/**
 * Unpack the Tracker data event from the physical packet.
 */
void TrackerReader::RunEvent(int EventNumber, const char subData[], long int length) {
    std::stringstream oss;
    string msg;

    int       ERROR=0;
    char *data = new char[length];
    memcpy(data, subData, length);
    int curpos=1;
    
    //Call to the FORTRAN routin that unpack tracker events
    trkeventpkt_( &ERROR,(unsigned char*)data, &length, &curpos); 

    if (ERROR != 0) {
        char *errmsg;
        switch (ERROR){
            case 1: errmsg = "GENERIC TRACKER ERROR";
            break;
            default: errmsg = "TRACKER ERRROR CODE UNIDENTIFIED";
        }
        oss.str("");
        oss << "Tracker: Fortran77 function trkeventpkt: " <<  errmsg;
        msg=oss.str();
        PamOffLineSW::mainLogUtil->logWarning(msg);	  
    }
    //Store the unpacked data
    tracker->unpackError    = ERROR;
    tracker->good0          = level0_.good0;
    memcpy(tracker->DAQmode,    level0_.DAQmode,    sizeof(tracker->DAQmode));
    memcpy(tracker->DSPnumber,  level0_.DSPnumber,  sizeof(tracker->DSPnumber));
    memcpy(tracker->DATAlength, level0_.DATAlength, sizeof(tracker->DATAlength));
    memcpy(tracker->eventn,     level0_.eventn,     sizeof(tracker->eventn));
    memcpy(tracker->nclust,     level0_.nclust,     sizeof(tracker->nclust));
    memcpy(tracker->cutc,       level0_.cutc,       sizeof(tracker->cutc));
    memcpy(tracker->cutcl,      level0_.cutcl,      sizeof(tracker->cutcl));
//--------have to invert array because of FORTRAN <-> C different management of the indexes
    int tempAddr[3][12];
    int tempSign[3][12];
    memcpy(tempAddr, (level0_.addrcluster), sizeof(tempAddr));
    memcpy(tempSign, (level0_.signcluster), sizeof(tempSign));
    for (int j = 0; j < 12; j++){
        for (int i = 0; i < 3; i++){
            tracker->addrcluster[j][i] = tempAddr[i][j];
            tracker->signcluster[j][i] = tempSign[i][j];
        }
    }
//-----------------------------------------------------------------------------------------
    
    memcpy(tracker->fc,                 level0_.fc,              sizeof(tracker->fc));
    memcpy(tracker->compressiontime,    level0_.compressiontime, sizeof(tracker->compressiontime));
    memcpy(tracker->fl1,                level0_.fl1,             sizeof(tracker->fl1));
    memcpy(tracker->fl2,                level0_.fl2,             sizeof(tracker->fl2));
    memcpy(tracker->fl3,                level0_.fl3,             sizeof(tracker->fl3));
    memcpy(tracker->fl4,                level0_.fl4,             sizeof(tracker->fl4));
    memcpy(tracker->fl5,                level0_.fl5,             sizeof(tracker->fl5));
    memcpy(tracker->fl6,                level0_.fl6,             sizeof(tracker->fl6));
    memcpy(tracker->checksum,           level0_.checksum,        sizeof(tracker->checksum));
    memcpy(tracker->pnum,               level0_.pnum,            sizeof(tracker->pnum));
    memcpy(tracker->cmdnum,             level0_.cmdnum,          sizeof(tracker->cmdnum));    
    memcpy(tracker->bid,                level0_.bid,             sizeof(tracker->bid));    
    memcpy(tracker->alarm,              level0_.alarm,           sizeof(tracker->alarm));    
    memcpy(tracker->aswr,               level0_.aswr,            sizeof(tracker->aswr));          
    memcpy(tracker->crc,                level0_.crc,             sizeof(tracker->crc));          
    
    tracker->TOTDATAlength = level0_.TOTDATAlength;
    //    if ( level0_.TOTDATAlength > 0) tracker->TrackerData   = TArrayI(level0_.TOTDATAlength, level0_.datatracker);
    tracker->TrackerData   = TArrayI(level0_.TOTDATAlength, level0_.datatracker);
    delete [] data;
}
