// Implementation of the EventTrkReader class.
 


#include <log4cxx/logger.h>

#include <fstream>
#include "ReaderAlgorithms.h"

#include "event/EventTrkEvent.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::techmodel;

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

/**
 * Constructor. 
 */
EventTrkReader::EventTrkReader(void): 
  TechmodelAlgorithm(PacketType::EventTrk, "TechmodelEventTrkReader") { 
  logger->debug(_T("Constructor"));
  eventTrk = new EventTrkEvent();
}

/**
 * Get a string with the version info of the algorithm.
 */
std::string EventTrkReader::GetVersionInfo(void) const {
  return 
    "$Trailer: /home/cvsmanager/yoda/techmodel/EventTrkReader.cpp,v 1.1.1.1 2004/07/06 12:20:23 kusanagi Exp $\n";
}

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

/**
 * Unpack the EventTrk event from an input file.
 */
void EventTrkReader::RunEvent(int EventNumber, long int length) throw (Exception){
   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";
    char *subData;
    subData = new char[length];
    InputFile->read(subData, sizeof(unsigned char)*length);

    stringstream oss;
    oss.str("");
    oss << getenv("YODA_DATA") << "/" << time(NULL) << "evtrk.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 = "---------------------";
        }
    } else {*/
    //Store the unpacked data
    eventTrk->unpackError    = ERROR;
    eventTrk->good0          = level0_.good0;
    eventTrk->nev0           = level0_.nev0;
    memcpy(eventTrk->DAQmode, level0_.DAQmode, sizeof(eventTrk->DAQmode));
    memcpy(eventTrk->DSPnumber, level0_.DSPnumber, sizeof(eventTrk->DSPnumber));
    memcpy(eventTrk->DATAlength, level0_.DATAlength, sizeof(eventTrk->DATAlength));
    memcpy(eventTrk->eventn, level0_.eventn, sizeof(eventTrk->eventn));
    memcpy(eventTrk->nclust, level0_.nclust, sizeof(eventTrk->nclust));
    memcpy(eventTrk->cutc, level0_.cutc, sizeof(eventTrk->cutc));
    memcpy(eventTrk->cutcl, level0_.cutcl, sizeof(eventTrk->cutcl));
//    memcpy(eventTrk->addrcluster, (level0_.addrcluster), sizeof(eventTrk->addrcluster));
//    memcpy(eventTrk->signcluster, (level0_.signcluster), sizeof(eventTrk->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++){
            eventTrk->addrcluster[j][i] = tempAddr[i][j];
            eventTrk->signcluster[j][i] = tempSign[i][j];
        }
    }
//-----------------------------------------------------------------------------------------
    
    memcpy(eventTrk->fc, level0_.fc, sizeof(eventTrk->fc));
    memcpy(eventTrk->compressiontime, level0_.compressiontime, sizeof(eventTrk->compressiontime));
    memcpy(eventTrk->fl1, level0_.fl1, sizeof(eventTrk->fl1));
    memcpy(eventTrk->fl2, level0_.fl2, sizeof(eventTrk->fl2));
    memcpy(eventTrk->fl3, level0_.fl3, sizeof(eventTrk->fl3));
    memcpy(eventTrk->fl4, level0_.fl4, sizeof(eventTrk->fl4));
    memcpy(eventTrk->fl5, level0_.fl5, sizeof(eventTrk->fl5));
    memcpy(eventTrk->fl6, level0_.fl6, sizeof(eventTrk->fl6));
    memcpy(eventTrk->pnum, level0_.pnum, sizeof(eventTrk->pnum));
    memcpy(eventTrk->cmdnum, level0_.cmdnum, sizeof(eventTrk->cmdnum));    
    memcpy(eventTrk->bid, level0_.bid, sizeof(eventTrk->bid));    
    memcpy(eventTrk->alarm, level0_.alarm, sizeof(eventTrk->alarm));    
    memcpy(eventTrk->aswr, level0_.aswr, sizeof(eventTrk->aswr));          
    eventTrk->TOTDATAlength = level0_.TOTDATAlength;

    eventTrk->TrackerData  = new TArrayI(level0_.TOTDATAlength, level0_.datatracker);
    //memcpy(eventTrk->datatracker, level0_.datatracker, sizeof(eventTrk->datatracker));          
    //}
}