////////////////////////////////////////////////////////////////////////
//
//  MParRead
//
//  This is the task to read in the cosmic raw data from one file. 
//  Cosmics are stored in the root file under the Tree "EvtTree". 
//  This task reads them in to the needed MRawEvtBuf in the Parameter
//  list.
//
////////////////////////////////////////////////////////////////////////

#include "MParRead.h"

#include <iostream.h>

#include "MParList.h"
#include "MObjBuffer.h"
#include "MInputStreamID.h"

ClassImp(MParRead)

MParRead::MParRead()
{
}

Bool_t MParRead::PreProcess (MParList *pList)
{
    //
    // remember the pointer to the parameter list fur further usage
    //
    pParList = pList;

    //
    //  check if MEvtHeader exists in the Parameter list already.
    //  if not create one and add them to the list
    //
    fID = (MInputStreamID*)pList->FindObject("MInputStreamID");
    if (!fID)
    {
        cout << "MReadEvt::PreProcess - WARNING: MEvtHeader not found... creating." << endl;
        fID = new MInputStreamID;
        pList->AddToList(fID);
    }
  
    return kTRUE;
}
    
Bool_t MParRead::Process()
{
    //
    //   Read in the next event
    //

    //
    // Make sure that all buffers are filled
    //
    MParContainer *pCont;

    //
    // start with the first entry in the parlist
    //
    pParList->Reset();
    // loop over all entries
    while ((pCont=pParList->Next()))
    {
        // if the entry is a buffer and not only a container
        // we can ask the container whether it is a input
        // container or not
        if (!pCont->IsBuffer())
            continue;

        MObjBuffer *pBuf = (MObjBuffer*)pCont;

        // if it is an input container we tell the container
        // that it should be filled if it is not filled already
        if (pBuf->IsInput())
            pBuf->Fill();
    }

    //
    // look which is the next tree which we have to read
    //
    MObjBuffer *evt;
    Int_t up = 0;

    // start from scratch
    pParList->Reset();
    // loop over all emtries
    while ((pCont=pParList->Next()))
    {
        // ask whether it is a buffer or not
        if (!pCont->IsBuffer())
            continue;

        MObjBuffer *pBuf = (MObjBuffer*)pCont;

        // ask whether the buffer is set as an input buffer or not
        if (!pBuf->IsInput())
            continue;

        // time of event which was processed last time
        Int_t t1=fTime.GetTime();

        // time of next event in this buffer
        Int_t t2=pBuf->GetEntry(1)->GetTime();

        // compare the time of the actual event with the next
        // event in this buffer
        if (t2<=t1)
            continue;

        // if no event is scheduled as event to read next
        // set this container as next
        if (!up)
        {
            up = t2;
            evt = pBuf;
        }

        // if this container has a smaller time, than
        // the 'actual' next event set this container
        // as next input
        if (t2<up)
        {
            up = t2;
            evt = pBuf;
        }
    }

    //
    // now we have the time of the next event we want to read
    // and a pointer to this event in 'up' and 'evt'
    //

    //
    // set 'system-time' to time of this event
    //
    fTime.SetTime(up);

    //
    // set event-type to type of this event
    //
    fID->SetEvtType(evt->GetName());

    //
    // Get next event from the determined tree
    //
    evt->GetNextEvent(0);

    return kTRUE;

/*
    return  nr != fPtrTree->GetEntries();
*/
}

