/** @file
 * $Source: /home/cvsmanager/yoda/techmodel/CalibS4Reader.cpp,v $
 * $Id: CalibS4Reader.cpp,v 3.0 2005/03/04 15:54:11 kusanagi Exp $
 * $Author: kusanagi $
 * 
 * Implementation of the LogReader class.
* ToBeDone:
* Control the CRC for the entire data Packet not just for single records
 */

#define UINT unsigned int
#define BYTE  unsigned char
#include <string>
#include <log4cxx/logger.h>
extern "C" {
#include <sys/time.h>
#include "CRC.h"
}

#include <fstream>
#include "stdio.h"
#include "ReaderAlgorithms.h"
#include "event/physics/S4/S4Event.h"
//#include "event/CalibS4Event.h"


using namespace pamela;
using namespace pamela::techmodel;

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

/**
 * Constructor. 
 */
CalibS4Reader::CalibS4Reader(void): 
  TechmodelAlgorithm(PacketType::Log, "TechmodelCalibS4Reader") { 
  logger->debug(_T("Constructor"));
  calibS4 = new CalibS4Event();
}

/**
 * Get a string with the version info of the algorithm.
 */
std::string CalibS4Reader::GetVersionInfo(void) const {
  return 
    "$Header: /home/cvsmanager/yoda/techmodel/CalibS4Reader.cpp,v 3.0 2005/03/04 15:54:11 kusanagi Exp $\n";
}

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

/**
 * Unpack the CalibS4 event from an input file.
 */
void CalibS4Reader::RunEvent(int EventNumber, long int length) throw (WrongCRCException){
    
    int offset;
    char subData[length];    //impulse*(11 + 10 + 01 + 00)*eventLength + CRC = 128*4*6 + UINT16
    UINT16    subCRC;      //CRC of the data
    UINT16    readCRC;     //CRC read from the end of the subpacket

    int numRecords = ((length - 2)/6);
        
    S4::S4Event* rec;
    calibS4->Records->Clear();
    TClonesArray &recs = *(calibS4->Records);

    InputFile->read(subData, sizeof(unsigned char)*length);
    subCRC = CM_Compute_CRC16(0, (BYTE*)subData, length - 2);
    readCRC = (((UINT16)(subData[length - 2]<<8))&0xFF00) + (((UINT16)subData[length - 1])&0x00FF);
    
    if (subCRC != readCRC) throw WrongCRCException(" Wrong CRC for CalibS4 Packet ");

    for(int i = 0; i < numRecords; i++) {
        offset = i*6; 
        rec = new(recs[i]) S4::S4Event(); //add a new S4Event
        rec->S4_REG_STATUS        = (((UINT8)subData[offset])&0xF0);
        rec->S4_DATA              = ((((UINT16)subData[offset]<<8)&0x0FFF) + (((UINT16)subData[offset+1])&0x00FF));
        rec->S4_CMD_NUM           = (((UINT8)subData[offset+2])&0xFF);
        rec->S4_RESP_LENGHT       = ((((UINT16)subData[offset+3]<<8)&0xFF00) + (((UINT16)subData[offset+4])&0x00FF));
        rec->S4_OVERALL_CHKCODE   = (((UINT8)subData[offset+5])&0xFF);
    }
}

