/* ======================================================================== *\
!
! *
! * 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): Wolfgang Wittek, 03/2003 <mailto:wittek@mppmu.mpg.de>
!   Author(s): Thomas Bretz, 04/2003 <mailto:tbretz@astro.uni-wuerzburg.de>
!
!   Copyright: MAGIC Software Development, 2000-2004
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//
// MHImagePar
//
////////////////////////////////////////////////////////////////////////////
#include "MHImagePar.h"

#include <math.h>

#include <TH1.h>
#include <TPad.h>
#include <TCanvas.h>

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

#include "MGeomCam.h"
#include "MBinning.h"
#include "MParList.h"

#include "MHillas.h"
#include "MImagePar.h"

ClassImp(MHImagePar);

using namespace std;

// --------------------------------------------------------------------------
//
// Setup histograms 
//
MHImagePar::MHImagePar(const char *name, const char *title)
{
    fName  = name  ? name  : "MHImagePar";
    fTitle = title ? title : "Histograms of image parameters";

    fHistSatHi.SetName("SatHi");
    fHistSatHi.SetTitle("Number of pixels with saturating hi-gains");
    fHistSatHi.SetXTitle("Pixels");
    fHistSatHi.SetYTitle("Counts");
    fHistSatHi.SetDirectory(NULL);
    fHistSatHi.UseCurrentStyle();
    fHistSatHi.SetFillStyle(4000);

    fHistSatLo.SetName("SatLo");
    fHistSatLo.SetTitle("Number of pixels with saturating lo-gains");
    fHistSatLo.SetXTitle("Pixels");
    fHistSatLo.SetYTitle("Counts");
    fHistSatLo.SetLineColor(kBlue);
    fHistSatLo.SetDirectory(NULL);
    fHistSatLo.UseCurrentStyle();
    fHistSatLo.SetFillStyle(4000);

    fHistIslands.SetName("Islands");
    fHistIslands.SetTitle("Number of Islands");
    fHistIslands.SetXTitle("N");
    fHistIslands.SetYTitle("Counts");
    fHistIslands.SetDirectory(NULL);
    fHistIslands.UseCurrentStyle();
    fHistIslands.SetLineColor(kBlue);
    fHistIslands.SetFillStyle(4000);

    MBinning bins;

    bins.SetEdges(60, -0.5, 59.5);
    bins.Apply(fHistSatHi);
    bins.Apply(fHistSatHi);

    bins.SetEdges(15, 0.5, 15.5);
    bins.Apply(fHistIslands);
}

// --------------------------------------------------------------------------
//
// Setup the Binning for the histograms automatically if the correct
// instances of MBinning
//
Bool_t MHImagePar::SetupFill(const MParList *plist)
{
    ApplyBinning(*plist, "Pixels",  &fHistSatHi);
    ApplyBinning(*plist, "Pixels",  &fHistSatHi);

    ApplyBinning(*plist, "Islands", &fHistIslands);

    return kTRUE;
}


// --------------------------------------------------------------------------
//
// Fill the histograms with data from a MNewImagePar container.
//
Bool_t MHImagePar::Fill(const MParContainer *par, const Stat_t w)
{
    if (!par)
    {
        *fLog << err << "MImagePar::Fill: Pointer (!=NULL) expected." << endl;
        return kFALSE;
    }

    const MImagePar &h = *(MImagePar*)par;

    fHistSatHi.Fill(h.GetNumSatPixelsHG(), w);
    fHistSatLo.Fill(h.GetNumSatPixelsLG(), w);

    fHistIslands.Fill(h.GetNumIslands(),   w);

    return kTRUE;
}

void MHImagePar::Paint(Option_t *o)
{
    /*
     if (TString(o)==(TString)"log1" && fHistSatHi.GetMaximum()>0)
     gPad->SetLogy();
     if (TString(o)==(TString)"log2" && fHistIslands.GetMaximum()>0)
     gPad->SetLogy();
     */
     if (fHistSatHi.GetMaximum()>0 && gPad->GetPad(1))
         gPad->GetPad(1)->SetLogy();
     if (fHistIslands.GetMaximum()>0 && gPad->GetPad(2))
         gPad->GetPad(2)->SetLogy();
}

// --------------------------------------------------------------------------
//
// Creates a new canvas and draws the two histograms into it.
// Be careful: The histograms belongs to this object and won't get deleted
// together with the canvas.
//
void MHImagePar::Draw(Option_t *o)
{
    TVirtualPad *pad = gPad ? gPad : MakeDefCanvas(this);
    pad->SetBorderMode(0);

    AppendPad("");

    TString opt(o);
    opt.ToLower();

    // FIXME: If same-option given make two independant y-axis!
    const Bool_t same = opt.Contains("same");

    if (!same)
        pad->Divide(1,2);
    else
        fHistIslands.SetLineColor(kGreen);

    if (!same)
    {
        pad->cd(1);
        gPad->SetBorderMode(0);
        MH::DrawSame(fHistSatHi, fHistSatLo, "Saturating Pixels");
        fHistSatHi.SetMinimum(); // switch off to allow log-scale
        fHistSatLo.SetMinimum(); // switch off to allow log-scale
        fHistSatLo.SetMaximum(0.1);   // dummy value to allow log-scale
        //AppendPad("log1");
    }

    pad->cd(2);
    gPad->SetBorderMode(0);
    fHistIslands.Draw(same?"same":"");
    //AppendPad("log2");
}

TH1 *MHImagePar::GetHistByName(const TString name)
{
    if (name.Contains("SatHi", TString::kIgnoreCase))
        return &fHistSatHi;
    if (name.Contains("SatLo", TString::kIgnoreCase))
        return &fHistSatLo;
    if (name.Contains("Islands", TString::kIgnoreCase))
        return &fHistIslands;

    return NULL;
}
