/* ======================================================================== *\
!
! *
! * This file is part of MARS, the MAGIC Analysis and Reconstruction
! * Software. It is distributed to you in the hope that it can be a useful
! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
! * It is distributed WITHOUT ANY WARRANTY.
! *
! * Permission to use, copy, modify and distribute this software and its
! * documentation for any purpose is hereby granted without fee,
! * provided that the above copyright notice appear in all copies and
! * that both that copyright notice and this permission notice appear
! * in supporting documentation. It is provided "as is" without express
! * or implied warranty.
! *
!
!
!   Author(s): Thomas Bretz, 5/2003 <mailto:tbretz@astro.uni-wuerzburg.de>
!
!   Copyright: MAGIC Software Development, 2000-2003
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// MReadCurrents                                                         //
//                                                                         //
//  Input Containers:                                                      //
//   -/-                                                                   //
//                                                                         //
//  Output Containers:                                                     //
//   MCerPhotEvt                                                           //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
#include "MReadCurrents.h"

#include <stdlib.h>  // atoi
#include <fstream>

#include <TList.h>
#include <TSystem.h>

#include "MTime.h"
#include "MCurrents.h"

#include "MLog.h"
#include "MLogManip.h"

#include "MParList.h"

ClassImp(MReadCurrents);

using namespace std;

// --------------------------------------------------------------------------
//
// Default constructor. Creates an array which stores the file names of
// the files which should be read. If a filename is given it is added
// to the list.
//
MReadCurrents::MReadCurrents(const char *fname,
			     const char *name, 
                             const char *title)
    : fIn(NULL)
{
    fName  = name  ? name  : "MReadCurrents";
    fTitle = title ? title : "Task to loop over events in CT1 ascii file";

    //
    // remember file name for opening the file in the preprocessor
    //
    fFileNames = new TList;
    fFileNames->SetOwner();

    if (fname)
        AddFile(fname);
}

// --------------------------------------------------------------------------
//
// Delete the filename list and the input stream if one exists.
//
MReadCurrents::~MReadCurrents()
{
    delete fFileNames;
    if (fIn)
        delete fIn;
}

// --------------------------------------------------------------------------
//
// Add this file as the last entry in the chain
//
Int_t MReadCurrents::AddFile(const char *txt, Int_t)
{
    TNamed *name = new TNamed(txt, "");
    fFileNames->AddLast(name);
    return 1;
}

// --------------------------------------------------------------------------
//
// This opens the next file in the list and deletes its name from the list.
//
Bool_t MReadCurrents::OpenNextFile()
{
    //
    // open the input stream and check if it is really open (file exists?)
    //
    if (fIn)
        delete fIn;
    fIn = NULL;

    //
    // Check for the existance of a next file to read
    //
    TNamed *file = (TNamed*)fFileNames->First();
    if (!file)
        return kFALSE;

    //
    // open the file which is the first one in the chain
    //
    const char *name = file->GetName();

    const char *expname = gSystem->ExpandPathName(name);
    fIn = new ifstream(expname);
    delete [] expname;

    const Bool_t noexist = !(*fIn);

    if (noexist)
        *fLog << dbginf << "Cannot open file '" << name << "'" << endl;
    else
        *fLog << "Open file: '" << name << "'" << endl;

    //
    // Remove this file from the list of pending files
    //
    fFileNames->Remove(file);

    return !noexist;
}

// --------------------------------------------------------------------------
//
// Open the first file in the list. Check for the output containers or create
// them if they don't exist.
//
// Initialize the size of the MPedestalCam container to 127 pixels (CT1 camera)
//
Int_t MReadCurrents::PreProcess(MParList *pList)
{
    //
    // Preprocessing
    //

    //
    // Try to open at least one (the first) file
    //
    if (!OpenNextFile())
        return kFALSE;

    //
    // 
    //
    fTime = (MTime*)pList->FindCreateObj("MTime", "MTimeCurrents");
    if (!fTime)
        return kFALSE;

    //
    // 
    //
    fCurrents = (MCurrents*)pList->FindCreateObj("MCurrents");
    if (!fCurrents)
        return kFALSE;

    // FIXME: Calculate number of events!

    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Check for the event number and depending on this number decide if
// pedestals or event data has to be read.
//
// If the end of the file is reached try to open the next in the list. If
// there is now next file stop the eventloop.
//
Int_t MReadCurrents::Process()
{
    //
    // check if we are done. Try to open the next file in chain.
    // If it was possible start reading. If not break the event loop
    //
    //
    //   "DC %s %s %02d %02d %02d %03d 577*%05d \n",
    //   status1, status2, hour, minute, second, ms,
    //   577 * pixel_DC_readout_in_nAmp
    //
    TString str;
    *fIn >> str;
    while (!(*fIn))
    {
        if (!OpenNextFile())
            return kFALSE;
        *fIn >> str;
    }
    if (str!=TString("DC"))
    {
        *fLog << err << "DC not found in file..." << endl;
        return kFALSE;
    }

    *fIn >> str;
    fCurrents->SetStatus1(str);

    *fIn >> str;
    fCurrents->SetStatus2(str);

    Int_t h, m, s, ms;
    *fIn >> h >> m >> s >> ms;
    fTime->SetTime(h, m, s, ms*1000000);

    for (int i=0; i<577; i++)
        *fIn >> (*fCurrents)[i];

    return (bool)*fIn;
}
