#include <TSystem.h>

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

#include "MRawFileRead.h"
#include "MRawFileWrite.h"

#include "MLog.h"
#include "MTime.h"
#include "MRawEvtData.h"
#include "MRawRunHeader.h"
#include "MRawEvtHeader.h"
#include "MRawCrateArray.h"
#include "MInputStreamID.h"

//////////////////////////////////////////////////////////////////////////////
//                                                                          //
// This is an easy implementation of the Merging process                    //
// (as compilable prog)                                                     //
//                                                                          //
// at the moment it reads a binary file ("rawtest.bin") which was written   //
// in the DAQ raw format.                                                   //
//                                                                          //
// The data are stored in root container objects (classes derived from      //
// TObject like MRawRunHeader)                                              //
//                                                                          //
// This containers are written to a root file ("rawtest.root")              //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

int main(const int argc, const char **argv)
{
    gLog << "==================================================" << endl ;
    gLog << "                   MERPP v0.1" << endl;
    gLog << "      MARS Merging and Preprocessing Program" << endl ;
    gLog << "            Compiled on <" << __DATE__ << ">" << endl ;
    gLog << "==================================================" << endl ;
    gLog << endl;

    //
    // check for the right usage of the program
    //
    if (argc!=3)
    {
        gLog << "Sorry the usage is:" << endl;
        gLog << "   merpp inputfile outputfile" << endl << endl;
        return -1;
    }

    //
    //     initialize ROOT  (this is obligatory here)
    //
    TROOT simple("Merpp","Mars - Merging and Preprocessing Program");

    //
    // check whether the given files are OK.
    //
    if (gSystem->AccessPathName(argv[1], kFileExists))
    {
        gLog << "Sorry, the file '" << argv[1] << "' doesn't exist." << endl;
        return -1;
    }

    if (!gSystem->AccessPathName(argv[2], kFileExists))
        gLog << "Warning: The file '" << argv[2] << "' exists." << endl;
    else
        if (!gSystem->AccessPathName(argv[2], kWritePermission))
        {
            gLog << "Sorry, you don't have write permission for '" << argv[2] << "'." << endl;
            return -1;
        }

    //
    // create a (empty) list of parameters which can be used by the tasks
    // and an (empty) list of tasks which should be executed
    //
    MParList *plist  = new MParList;

    MTaskList *tasks = new MTaskList;
    plist->AddToList(tasks);

    MRawRunHeader *runheader = new MRawRunHeader;
    plist->AddToList(runheader);

    MRawEvtHeader *evtheader = new MRawEvtHeader;
    plist->AddToList(evtheader);

    MRawEvtData *evtdata = new MRawEvtData;
    plist->AddToList(evtdata);

    MRawCrateArray *cratearray = new MRawCrateArray;
    plist->AddToList(cratearray);

    MTime *evttime = new MTime("MRawEvtTime");
    plist->AddToList(evttime);

    //
    // create the tasks which should be executed and add them to the list
    // in the case you don't need parameter containers, all of them can
    // be created by MRawFileRead::PreProcess
    //
    MRawFileRead  *reader = new MRawFileRead(argv[1]);
    MRawFileWrite *writer = new MRawFileWrite(argv[2], "RECREATE");
    tasks->AddToList(reader);
    tasks->AddToList(writer);

    //
    // create the looping object and thell it about the parameters to use
    // and the tasks to execute
    //

    MEvtLoop magic;

    magic.SetParList(plist);

    //
    // Start the eventloop which reads the raw file (MRawFileRead) and
    // write all the information into a root file (MRawFileWrite)
    //
    // between reading and writing we can do, transformations, checks, etc.
    // (I'm think of a task like MRawDataCheck)
    //
    magic.Eventloop();

    return 0;
}


