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

/////////////////////////////////////////////////////////////////////////////
//
// MHSectorVsTime
//
// Display the mean and its variance vs time of the whole camera or a
// single sector
//
/////////////////////////////////////////////////////////////////////////////
#include "MHSectorVsTime.h"

#include <TCanvas.h>
#include <TGraphErrors.h>

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

#include "MParList.h"
#include "MCamEvent.h"

#include "MGeomCam.h"

#include "MRawEvtHeader.h"
#include "MTime.h"

ClassImp(MHSectorVsTime);

using namespace std;

// --------------------------------------------------------------------------
//
// Initialize the name and title of the task. If fErrType>=0 the variance is
// taken into account.
//
MHSectorVsTime::MHSectorVsTime(const char *name, const char *title)
    : fGraph(0), fEvt(NULL), fType(0), fTypeErr(-1)
{
    //
    //   set the name and title of this object
    //
    fName  = name  ? name  : "MHSectorVsTime";
    fTitle = title ? title : "Sector mean vs time";
}

// --------------------------------------------------------------------------
//
// Delete the fGraph
//
MHSectorVsTime::~MHSectorVsTime()
{
    if (fGraph)
        delete fGraph;
}

// --------------------------------------------------------------------------
//
// Get the event (MPixVsTime) the histogram might be filled with. If
// it is not given, it is assumed, that it is filled with the argument
// of the Fill function.
// Looks for the camera geometry MGeomCam and resets the sum histogram.
// Create and/or initialize fGraph
//
Bool_t MHSectorVsTime::SetupFill(const MParList *plist)
{
    fEvt = dynamic_cast<MCamEvent*>(plist->FindObject(fNameEvt, "MCamEvent"));
    if (!fEvt)
    {
        if (!fNameEvt.IsNull())
        {
            *fLog << err << GetDescriptor() << ": No " << fNameEvt <<" [MCamEvent] available..." << endl;
            return kFALSE;
        }
        *fLog << warn << GetDescriptor() << ": No MCamEvent available..." << endl;
    }

    fCam = (MGeomCam*)plist->FindObject("MGeomCam");
    if (!fCam)
    {
        *fLog << err << "MGeomCam not found... aborting." << endl;
        return kFALSE;
    }

    fHCamera.SetGeometry(*fCam);

    if (!fNameTime.IsNull())
    {
        fTime = (MTime*)plist->FindObject(fNameTime, "MTime");
        if (!fTime)
        {
            *fLog << err << fNameTime << " [MTime] not found... abort." << endl;
            return kFALSE;
        }
    }
    else
    {
        fHeader = (MRawEvtHeader*)plist->FindObject("MRawEvtHeader");
        if (!fHeader)
            *fLog << warn << "MRawEvtHeader not found... using counter." << endl;
    }

    if (fGraph)
        delete fGraph;

    fGraph = fTypeErr<0 ? new TGraph : new TGraphErrors;
    fGraph->SetName(fEvt ? dynamic_cast<TObject*>(fEvt)->GetName() : "MCamEvent");
    fGraph->SetTitle("Camera");

    fMin =  FLT_MAX;
    fMax = -FLT_MAX;

    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Fill the histograms with data from a MCamEvent
//
Bool_t MHSectorVsTime::Fill(const MParContainer *par, const Stat_t w)
{
    const MCamEvent *evt = par ? dynamic_cast<const MCamEvent*>(par) : fEvt;
    if (!evt)
    {
        *fLog << err << dbginf << "No MCamEvent found..." << endl;
        return kFALSE;
    }

    Double_t t = 0;
    if (!fNameTime.IsNull())
        t = fTime->GetAxisTime();
    else
        t = fHeader ? fHeader->GetDAQEvtNumber() : fGraph->GetN();


    fHCamera.SetCamContent(*evt, fType);

    const Double_t val0 = fHCamera.GetMeanSectors(fSectors, fAreaIndex);

    if (TMath::IsNaN(val0)/* || TMath::IsNaN(rms0)*/)
        return kCONTINUE;

    fGraph->SetPoint(fGraph->GetN(), t, val0);

    if (fTypeErr>=0)
    {
        const Double_t rms0 = fHCamera.GetRmsSectors(fSectors, fAreaIndex);
        if (TMath::IsNaN(rms0))
            return kCONTINUE;
        ((TGraphErrors*)fGraph)->SetPointError(fGraph->GetN()-1, 0, rms0);
    }

    fMin = TMath::Min(fMin, val0);
    fMax = TMath::Max(fMax, val0);

    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Set Minimum and Maximum;
//
Bool_t MHSectorVsTime::Finalize()
{
    const Double_t add = (fMax-fMin)*0.15;

    fGraph->SetMinimum(fMin-add);
    fGraph->SetMaximum(fMax+add);

    *fLog << dbg << "Min=" << fMin << " " << fMin-add << endl;
    *fLog << dbg << "Max=" << fMax << " " << fMax+add << endl;

    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Return fHistogram from TGraph
//
TH1 *MHSectorVsTime::GetHistByName(const TString name)
{
    return fGraph->GetHistogram();
}

void MHSectorVsTime::Draw(Option_t *opt)
{
    /*
    if (fGraph->GetN()==0)
        return;
        */

    if (fGraph->GetN()==0)
        return;

    TVirtualPad *pad = gPad ? gPad : MakeDefCanvas(this);
    pad->SetBorderMode(0);

    AppendPad("");

    TString str(opt);
    /*
    fGraph->GetHistogram()->SetXTitle("Time");
    fGraph->GetHistogram()->GetXaxis()->SetTimeFormat("%H:%M:%S %F1995-01-01 00:00:00");
    fGraph->GetHistogram()->GetXaxis()->SetTimeDisplay(1);
    fGraph->GetHistogram()->GetXaxis()->SetLabelSize(0.033);

    fGraph->GetHistogram()->SetYTitle("");
     */
    if (!str.Contains("A"))
        str += "A";
    if (!str.Contains("L"))
        str += "L";

    if (str.Contains("same", TString::kIgnoreCase))
    {
        str.ReplaceAll("same", "");
        str.ReplaceAll("A", "");
    }

    TH1 *h = fGraph->GetHistogram();

    h->SetXTitle("Time");
    h->SetYTitle("");

    if (!fNameTime.IsNull())
    {
        TAxis *axe = h->GetXaxis();
        axe->SetTimeFormat("%H:%M:%S %F1995-01-01 00:00:00 GMT");
        axe->SetTimeDisplay(1);
        axe->SetLabelSize(0.025);
    }

    *fLog << dbg << "Draw: " << str << endl;
    fGraph->Draw(str);
/*
    str.ReplaceAll("same", "");
    str.ReplaceAll("A", "");

    Int_t i=-1;
    Int_t col=kRed;
    while ((g=(TGraphErrors*)Next()))
    {
        i++;
        *fLog << dbg << "Check" << i << ": " << str << endl;

        while ((fMinSector>=0 && i<fMinSector) || (fMaxSector>=0 && i>fMaxSector))
            i++;

        h = g->GetHistogram();
        g->SetLineColor(col++);

        *fLog << dbg << "Draw" << i << ": " << g->GetTitle() << endl;
        g->Draw(str);

    }

    pad->Modified();
    pad->Update();*/
}
