/** @file
 * $Source: /home/cvsmanager/yoda/techmodel/physics/TrackerReader.cpp,v $
 * $Id: TrackerReader.cpp,v 3.1 2005/03/06 04:29:24 kusanagi Exp $
 * $Author: kusanagi $
 * 
 * Implementation of the TrackerPhysicsReader class.
 */

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

extern "C" {
    //Passo il path verso la il file temporaneo
    extern void trkeventpkt_(int*, char*); 
    //Struct per il passaggio di dati da e verso la chiamata fortran
    extern struct {
      int good0;
      int nev0;
      int DAQmode[12];
      int DSPnumber[12];
      int DATAlength[12];
      int eventn[12];
      int nclust[12];
      int cutc[12];
      int cutcl[12];
      int addrcluster[12][3];
      int signcluster[12][3];
      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];
    } level0_; 
#include <dirent.h>
}

using namespace pamela;
using namespace pamela::tracker;

static log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(_T("pamela.techmodel.tracker.TrackerReader"));

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

/**
 * Get a string with the version info of the algorithm.
 */
std::string TrackerReader::GetVersionInfo(void) const {
  return 
    "$Header: /home/cvsmanager/yoda/techmodel/physics/TrackerReader.cpp,v 3.1 2005/03/06 04:29:24 kusanagi Exp $";
}

/**
 * Initialize the algorithm with a special run. This will initialize the
 * event reader routines for all packet types.
 */
void TrackerReader::Init(PamelaRun *run) {
  logger->debug(_T("Initialize"));
  SetInputStream(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) {
    int       ERROR;
    
    //Scrivo un file temporaneo per passarlo alla routine
    //Speriamo di cambiare la routine per passargli un buffer.....
    //DIR *dirp;
    
    //std::string pathDir((char*)getenv("YODA_DATA"));
    
    //pathDir = pathDir + "/todatemp.dat";
    stringstream oss;
    oss.str("");
    oss << getenv("YODA_DATA") << "/" << time(NULL) << "trev.dat";
    FILE *pfile;
    pfile = fopen(oss.str().c_str(), "wb");
    fwrite(subData, 1, length, pfile);
    fclose(pfile);
    
    //Call to the FORTRAN routin that unpack tracker events
    trkeventpkt_(&ERROR, (char*)oss.str().c_str());
    
    remove(oss.str().c_str());

    if (ERROR != 0) {
        char *errmsg;
        switch (ERROR){
            case 1: errmsg = "GENERIC TRACKER ERROR";
            break;
            default: errmsg = "TRACKER ERRROR CODE UNIDENTIFIED";
        }
        oss.str("");
        oss << "Fortran77 function trkeventpkt: " <<  errmsg;
        logger->warn(oss.str().c_str());
    }
    //Store the unpacked data
    tracker->unpackError    = ERROR;
    tracker->good0          = level0_.good0;
    tracker->nev0           = level0_.nev0;
    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));
//    memcpy(tracker->addrcluster, (level0_.addrcluster), sizeof(tracker->addrcluster));
//    memcpy(tracker->signcluster, (level0_.signcluster), sizeof(tracker->signcluster));
//--------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->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));          
    
    tracker->TOTDATAlength = level0_.TOTDATAlength;
    //tracker->TrackerData   = new TArrayI(level0_.TOTDATAlength, level0_.datatracker);
    tracker->TrackerData   = TArrayI(level0_.TOTDATAlength, level0_.datatracker);

    //memcpy(tracker->datatracker, level0_.datatracker, sizeof(tracker->datatracker));          
    //}
    
}
