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

//////////////////////////////////////////////////////////////////////////////
//
//  MReport
//
//  This is a base class for all reports comming from subsystems stored in
//  a report file.
//
//  Be carefull: The class name of all classes derived from this class
//               should start with 'MReport', see SetupReading
//
//////////////////////////////////////////////////////////////////////////////
#include "MReport.h"

#include "MLogManip.h"

#include "MTime.h"
#include "MParList.h"

ClassImp(MReport);

using namespace std;

// --------------------------------------------------------------------------
//
// Interpretes the beginning of a line which starts like:
//   status hour minute second millisec skip skip skip skip skip
// The identifier is assumed to be removed.
//
// While skip are numbers which won't enter the analysis
//
// SetupReading must be called successfully before.
//
Bool_t MReport::InterpreteHeader(TString &str)
{
    int len, state;
    int yea, mon, day, hor, min, sec, ms;

    int n = sscanf(str.Data(),
                   fHasReportTime ?
                   " %d %d %d %d %d %d %d %d %*d %*d %*d %*d %*d %*d %*d %*d %n" :
                   " %d %d %d %d %d %d %d %d %n",
                   &state, &yea, &mon, &day, &hor, &min, &sec, &ms, &len);
    if (n!=8)
    {
        *fLog << err << "ERROR - Cannot interprete Body of " << fIdentifier << " (n=" << n << ")" << endl;
        return kFALSE;
    }

    fState=state;
    if (!fTime->Set(yea, mon, day, hor, min, sec, ms))
    {
        *fLog << err << "ERROR - Event has invalid time: ";
        *fLog << Form("%d.%d.%d %02d:%02d:%02d.%03d", day, mon, yea, hor, min, sec, ms);
        *fLog << "... abort." << endl;
        return kFALSE;
    }

    str.Remove(0, len);

    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Report Body must be overwritten. It will get the line idetified to belong
// to fIdentifier without the leading status and time infomration as an
// argument.
//
Int_t MReport::InterpreteBody(TString &str)
{
    *fLog << warn << "No interpreter existing for: " << fIdentifier << endl;
    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Interprets Header and Body of a report file line. Calls SetReadyToSave()
// in case the interpretation was successfull. And fTime->SetReadyToSave()
// when a corresponding time container exists.
//
// SetupReading must be called successfully before.
//
Int_t MReport::Interprete(TString &str, const MTime &start, const MTime &stop)
{
    if (!InterpreteHeader(str))
        return kFALSE;

    // return -1: This is the special case: out of time limit
    if (start && *fTime<start)
        return -1;
    if (stop  && *fTime>stop)
        return -1;

    const Int_t rc = InterpreteBody(str);
    if (rc != kTRUE)
        return rc;

    SetReadyToSave();
    fTime->SetReadyToSave();

    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Check for the existance of a corresponding MTime in the given parameter
// list. If it is not found a new one will be created. The name of the
// MTime object is created by taking the ClassName() of the derived MReport
// class and stripping the leading MReport
//
Bool_t MReport::SetupReading(MParList &plist)
{
    fTime = NULL;

    TString id(ClassName());
    if (!id.BeginsWith("MReport"))
    {
        *fLog << warn << " WARNING - Class name '" << id << "' ";
        *fLog << " doesn't begin with 'MReport'... no MTime assigned." << endl;
        return kFALSE;
    }

    id.Remove(0, 7);
    if (id.IsNull())
    {
        *fLog << warn << " WARNING - No postfix existing... no MTime assigned." << endl;
        return kFALSE;
    }

    id.Prepend("MTime");

    fTime = (MTime*)plist.FindCreateObj("MTime", id);
    if (!fTime)
        return kFALSE;

    return kTRUE;
}
