/////////////////////////////////////////////////////////////////////////////
//
// MRawRunHeader
//
// Root storage container for the RUN HEADER information
//
////////////////////////////////////////////////////////////////////////////

#include "MRawRunHeader.h"

#include <fstream.h>
#include <iomanip.h>

#include "../MBase/MArrayS.h"

ClassImp(MRawRunHeader)

MRawRunHeader::MRawRunHeader(const char *name, const char *title) : fPixAssignment(NULL)
{
    *fName  = name  ? name  : "MRawRunHeader";
    *fTitle = title ? title : "Raw Run Header Information";

    fPixAssignment = new MArrayS(0);
}

MRawRunHeader::~MRawRunHeader()
{
    delete fPixAssignment;
}

void MRawRunHeader::ReadEvt(ifstream& fin)
{
    //
    // read one RUN HEADER from the input stream
    //
    fin.read((Byte_t*)&fMagicNumber,       2);

    //
    // check whether the the file has the right file type or not
    //
    if (fMagicNumber != kMagicNumber)
    {
        cout << "Error: Wrong Magic Number: Not a Magic File!" << endl;
        return;
    }

    Byte_t dummy[16];

    fin.read((Byte_t*)&fFormatVersion,    2);
    fin.read((Byte_t*)&fSoftVersion,      2);
    fin.read((Byte_t*)&fRunType,          2);
    fin.read((Byte_t*)&fRunNumber,        4);
    fin.read((Byte_t*)&fProjectName,     22);
    fin.read((Byte_t*)&fSourceName,      12);
    fin.read((Byte_t*)dummy,              4); // was RA
    fin.read((Byte_t*)dummy,              4); // was DEC
    fin.read((Byte_t*)&fSourceEpochChar,  2);
    fin.read((Byte_t*)&fSourceEpochDate,  2);
    fin.read((Byte_t*)&fMJD,              4);
    fin.read((Byte_t*)&fDateYear,         2);
    fin.read((Byte_t*)&fDateMonth,        2);
    fin.read((Byte_t*)&fDateDay,          2);
    fin.read((Byte_t*)&fNumCrates,        2);
    fin.read((Byte_t*)&fNumPixInCrate,    2);
    fin.read((Byte_t*)&fNumSamplesLoGain, 2);
    fin.read((Byte_t*)&fNumSamplesHiGain, 2);
    fin.read((Byte_t*)&fNumEvents,        4);


    //
    // calculate size of array, create it and fill it
    //
    Int_t nPixel = fNumCrates*fNumPixInCrate;
    fPixAssignment->Set(nPixel);

    fin.read((Byte_t*)fPixAssignment->GetArray(), nPixel*2);
    fin.read((Byte_t*)&dummy, 16);
}

void MRawRunHeader::Print(Option_t *t)
{
    //
    // print run header information on screen
    //
    cout << "MagicNumber:  0x" << hex << fMagicNumber << " - " << (fMagicNumber==0xc0c0?"OK":"Wrong!") << endl;
    cout << "Version:      " << dec << "Format=" << fFormatVersion << "  ";
    cout << "Software=" << fSoftVersion << endl;
    cout << "RunNumber:    " << fRunNumber << " (Type=";
    switch (fRunType)
    {
    case 0:
        cout << "Data";
        break;
    case 1:
        cout << "Pedestal";
        break;
    case 2:
        cout << "Calibration";
        break;
    }
    cout << ")" << endl;
    cout << "ProjectName: '" << fProjectName << "'" << endl;
    cout << "Source:      '" << fSourceName << "' " << "  ";
    cout << fSourceEpochChar << dec << fSourceEpochDate << endl;
    cout << "Date:         " << setprecision(1) << setiosflags(ios::fixed) << fMJD << " (MJD)  " << fDateYear << "/" << fDateMonth << "/" << fDateDay << endl;
    cout << "Crates:       " << fNumCrates << " x " << fNumPixInCrate << " Pixel/Crate = " << fNumCrates*fNumPixInCrate << " Pixel/Evt" << endl;
    cout << "Samples:      " << fNumSamplesLoGain << "/" << fNumSamplesHiGain << " (lo/hi) = " << (fNumSamplesLoGain+fNumSamplesHiGain) * fNumCrates * fNumPixInCrate /1024 << "kB/Evt" << endl;
    cout << "Evt Counter:  " << fNumEvents << endl;

    cout << hex;
    for (int i=0; i<GetNumPixel(); i++)
        cout << setfill('0') << setw(3) << (*fPixAssignment)[i] << " ";
    cout << hex << endl;

    cout << endl;
}

UShort_t MRawRunHeader::GetPixAssignment(UShort_t i) const
{
    // FIXME: Do we need a range check here?
    return (*fPixAssignment)[i];
}

UShort_t MRawRunHeader::GetNumPixel() const
{
    return fPixAssignment->GetSize();
}
