/* ======================================================================== *\
!
! *
! * 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  12/2000 <mailto:tbretz@uni-sw.gwdg.de>
!
!   Copyright: MAGIC Software Development, 2000-2001
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// MReadMarsFile                                                           //
//                                                                         //
// This task works more or less like MReadTree, but in addition PreProcess //
// reads all the information from the 'RunHeader' tree.                    //
//                                                                         //
// Warning: Until now this works only for 'one run header per file'        //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

#include "MReadMarsFile.h"

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

#include "MParList.h"
#include "MTaskList.h"

ClassImp(MReadMarsFile);

// --------------------------------------------------------------------------
//
//  Default constructor. It creates a MReadTree object to read the
//  RunHeaders and disables Auto Scheme for this tree.
//
MReadMarsFile::MReadMarsFile(const char *tname, const char *fname,
                             const char *name, const char *title)
    : MReadTree(tname, fname)
{
    fName  = name  ? name  : "MReadMarsFile";
    fTitle = title ? title : "Task to loop over all events in a tree of a Mars file.";

    //
    // open the input stream
    //
    fRun = new MReadTree("RunHeaders", fname);

    //
    // This disables the auto scheme. because reading new runheader is done
    // at a low frequency we don't loose time if we always read all
    // runheaders
    //
    fRun->DisableAutoScheme();
}

// --------------------------------------------------------------------------
//
// Destructor. Deleted the MReadTree object for the RunHeaders
//
MReadMarsFile::~MReadMarsFile()
{
    delete fRun;
}

// --------------------------------------------------------------------------
//
//  see MReadTree::AddFile, too. The file is also added to the chain for
//  the run headers. If adding file gives a different result for both
//  chains -1 is returned, otherwise the number of files which were added.
//
Int_t MReadMarsFile::AddFile(const char *fname)
{
    //
    // FIXME! A check is missing whether the file already exists or not.
    //
    //
    // returns the number of file which were added
    //
    Int_t n1 = fRun->AddFile(fname);
    Int_t n2 = MReadTree::AddFile(fname);

    return n1 != n2 ? -1 : n1;
}

// --------------------------------------------------------------------------
//
//  This overload MReadTree::Notify. Before the MReadTree Notify
//  TObjects are called the RunHeaders of the next files are read.
//  
//  WARNING: This doesn't work correctly yet, if the files are not read in
//           increasing order.
//
Bool_t MReadMarsFile::Notify()
{
    //
    // Try to read the new run headers. If reading the new run header
    // was successfull call the ReInits
    //
    if (fRun->Process())
    {
        *fLog << inf << "MReadMarsFile: Switching to '" << GetFileName() << "' ";
        *fLog << "(before processing event #" << GetEventNum()-1 << ")" << endl;

        fTaskList->ReInit();
        //MReadTree::Notify();
    }
    else
        *fLog << warn << "Warning: Cannot read new runheaders after reading event #" << GetEventNum() << endl;

    return kTRUE;
}

// --------------------------------------------------------------------------
//
//  PreProcessed the MReadTree to read the run headers and its base class.
//  see MReadTree::PreProcess for more information
//
Bool_t MReadMarsFile::PreProcess(MParList *pList)
{
    fTaskList = (MTaskList*)pList->FindObject("MTaskList");

    if (!fRun->PreProcess(pList))
        return kFALSE;

    if (!fRun->Process())
        return kFALSE;

    fRun->SetEventNum(0);

    return MReadTree::PreProcess(pList);
}
