/* ======================================================================== *\
!
! *
! * 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, 1/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
!
!   Copyright: MAGIC Software Development, 2000-2004
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//
//  MJStar
//
/////////////////////////////////////////////////////////////////////////////
#include "MJStar.h"

#include <TEnv.h>
#include <TFile.h>

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

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

#include "MStatusDisplay.h"

#include "MHCamEvent.h"

#include "MReadMarsFile.h"
#include "MGeomApply.h"
#include "MImgCleanStd.h"
#include "MHillasCalc.h"
#include "MFillH.h"
#include "MWriteRootFile.h"

ClassImp(MJStar);

using namespace std;

// --------------------------------------------------------------------------
//
// Default constructor. 
//
// Sets fRuns to 0, fExtractor to NULL, fDataCheck to kFALSE
//
MJStar::MJStar(const char *name, const char *title) 
{
    fName  = name  ? name  : "MJStar";
    fTitle = title ? title : "Standard analysis and reconstruction";
}

Bool_t MJStar::WriteResult()
{
    if (fPathOut.IsNull())
    {
        *fLog << inf << "No output path specified via SetPathOut - no output written." << endl;
        return kTRUE;
    }

    const TString oname = Form("%s/star%06d.root", (const char*)fPathOut, fSequence.GetSequence());

    *fLog << inf << "Writing to file: " << oname << endl;

    TFile file(oname, "RECREATE");

    *fLog << inf << " - MStatusDisplay..." << flush;
    if (fDisplay && fDisplay->Write()<=0)
    {
        *fLog << err << "Unable to write MStatusDisplay to " << oname << endl;
        return kFALSE;
    }
    *fLog << inf << "ok." << endl;

    return kTRUE;
}

Bool_t MJStar::ProcessFile()
{
    if (!fSequence.IsValid())
    {
        *fLog << err << "ERROR - Sequence invalid!" << endl;
        return kFALSE;
    }

    //if (!CheckEnv())
    //    return kFALSE;

    CheckEnv();

    // --------------------------------------------------------------------------------

    *fLog << inf;
    fLog->Separator(GetDescriptor());
    *fLog << "Calculate image parameters from sequence ";
    *fLog << fSequence.GetName() << endl;
    *fLog << endl;

    // --------------------------------------------------------------------------------

    MDirIter iter;
    const Int_t n0 = fSequence.SetupDatRuns(iter, fPathData);
    const Int_t n1 = fSequence.GetNumDatRuns();
    if (n0==0)
    {
        *fLog << err << "ERROR - No input files of sequence found!" << endl;
        return kFALSE;
    }
    if (n0!=n1)
    {
        *fLog << err << "ERROR - Number of files found (" << n0 << ") doesn't match number of files in sequence (" << n1 << ")" << endl;
        return kFALSE;
    }

    // Setup Parlist
    MParList plist;
    plist.AddToList(this); // take care of fDisplay!

    // Setup Tasklist
    MTaskList tlist;
    plist.AddToList(&tlist);

    MReadMarsFile read("Events");
    read.DisableAutoScheme();
    read.AddFiles(iter);
    //read.AddFiles(fnamein);

    MGeomApply             apply; // Only necessary to craete geometry
    //MBadPixelsMerge        merge(&badpix);
    MImgCleanStd           clean; 
    MHillasCalc            hcalc;

    MHCamEvent evt0("Cleaned");
    evt0.SetType(0);
    MFillH fill0(&evt0, "MCerPhotEvt",            "FillCerPhotEvt");
    MFillH fill1("MHHillas",      "MHillas",      "FillHillas");
    MFillH fill2("MHHillasExt",   "MHillasExt",   "FillHillasExt");
    MFillH fill3("MHHillasSrc",   "MHillasSrc",   "FillHillasSrc");
    MFillH fill4("MHImagePar",    "MImagePar",    "FillImagePar");
    MFillH fill5("MHNewImagePar", "MNewImagePar", "FillNewImagePar");
    MFillH fill6("MHCerPhot");

    MWriteRootFile write(2, "images/{s/_Y_/_I_}");
    write.AddContainer("MMcEvt",        "Events", kFALSE);
    write.AddContainer("MHillas",       "Events");
    write.AddContainer("MHillasExt",    "Events");
    write.AddContainer("MHillasSrc",    "Events");
    write.AddContainer("MImagePar",     "Events");
    write.AddContainer("MNewImagePar",  "Events");
    write.AddContainer("MTime",         "Events");
    write.AddContainer("MRawEvtHeader", "Events");
    write.AddContainer("MRawRunHeader", "RunHeaders");
    write.AddContainer("MBadPixelsCam", "RunHeaders");
    write.AddContainer("MGeomCam",      "RunHeaders");
    //write.AddContainer("MObservatory", "RunHeaders");

    tlist.AddToList(&read);
    tlist.AddToList(&apply);
    tlist.AddToList(&clean);
    tlist.AddToList(&fill0);
    tlist.AddToList(&hcalc);
    tlist.AddToList(&fill1);
    tlist.AddToList(&fill2);
    tlist.AddToList(&fill3);
    tlist.AddToList(&fill4);
    tlist.AddToList(&fill5);
    //tlist.AddToList(&fill6);
    tlist.AddToList(&write);

    // Create and setup the eventloop
    MEvtLoop evtloop(fName);
    evtloop.SetParList(&plist);
    evtloop.SetDisplay(fDisplay);
    evtloop.SetLogStream(fLog);
    if (!SetupEnv(evtloop))
        return kFALSE;

    // Execute first analysis
    if (!evtloop.Eventloop(fMaxEvents))
    {
        *fLog << err << GetDescriptor() << ": Failed." << endl;
        return kFALSE;
    }

    tlist.PrintStatistics();

    if (!WriteResult())
        return kFALSE;

    *fLog << all << GetDescriptor() << ": Done." << endl;
    *fLog << endl << endl;

    return kTRUE;
}
