/* ======================================================================== *\
!
! *
! * 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): Markus Gaug   11/2003 <mailto:markus@ifae.es>
!
!   Copyright: MAGIC Software Development, 2000-2004
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//                                                               
// MCalibrationCam                                               
//                                                               
// Base class for camera Calibration results:
//                                                               
/////////////////////////////////////////////////////////////////////////////
#include "MCalibrationCam.h"

#include <TH2.h>
#include <TCanvas.h>
#include <TClonesArray.h>

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

#include "MGeomCam.h"
#include "MGeomPix.h"

#include "MBadPixelsCam.h"
#include "MBadPixelsPix.h"

#include "MCalibrationPix.h"

ClassImp(MCalibrationCam);

using namespace std;

// --------------------------------------------------------------------------
//
// Default constructor. 
//
// Creates a TClonesArray of MCalibrationPix containers, initialized to 1 entry
// Later, a call to MCalibrationCam::InitSize(Int_t size) has to be performed
//
// Creates an MCalibrationBlindPix container 
//
MCalibrationCam::MCalibrationCam(const char *name, const char *title)
    : fPixels(NULL), fAverageAreas(NULL), fAverageSectors(NULL)
{
    fName  = name  ? name  : "MCalibrationCam";
    fTitle = title ? title : "Base class Storage container for Camera Calibration";

    fAverageBadAreas    = new TClonesArray("MBadPixelsPix",1);
    fAverageBadSectors  = new TClonesArray("MBadPixelsPix",1);

}

// --------------------------------------------------------------------------
//
// Delete the TClonesArray of MCalibrationPix containers
// Delete the MCalibrationPINDiode and the MCalibrationBlindPix
//
// Delete the histograms if they exist
//
MCalibrationCam::~MCalibrationCam()
{

  //
  // delete fPixels should delete all Objects stored inside
  // 
  if (fPixels)
    delete fPixels;

  if (fAverageAreas)
    delete fAverageAreas;

  if (fAverageSectors)
    delete fAverageSectors;

  delete fAverageBadAreas;
  delete fAverageBadSectors;
  
}

// -------------------------------------------------------------------
//
//
void MCalibrationCam::InitSize(const UInt_t i)
{
  fPixels->ExpandCreate(i);
}

void MCalibrationCam::InitAverageAreas(const UInt_t i)
{
  fAverageAreas->ExpandCreate(i);
  fAverageBadAreas->ExpandCreate(i);
}

void MCalibrationCam::InitAverageSectors(const UInt_t i)
{
  fAverageSectors->ExpandCreate(i);
  fAverageBadSectors->ExpandCreate(i);
}

// --------------------------------------------------------------------------
//
// This function returns the current size of the TClonesArray 
// independently if the MCalibrationPix is filled with values or not.
//
// It is the size of the array fPixels.
//
Int_t MCalibrationCam::GetSize() const
{
  return fPixels->GetEntriesFast();
}

Int_t MCalibrationCam::GetAverageAreas() const
{
  return fAverageAreas->GetEntriesFast();
}

Int_t MCalibrationCam::GetAverageSectors() const
{
  return fAverageSectors->GetEntriesFast();
}


// --------------------------------------------------------------------------
//
// Get i-th pixel (pixel number)
//
MCalibrationPix &MCalibrationCam::operator[](UInt_t i)
{
  return *static_cast<MCalibrationPix*>(fPixels->UncheckedAt(i));
}

// --------------------------------------------------------------------------
//
// Get i-th pixel (pixel number)
//
const MCalibrationPix &MCalibrationCam::operator[](UInt_t i) const
{
  return *static_cast<MCalibrationPix*>(fPixels->UncheckedAt(i));
}

// --------------------------------------------------------------------------
//
// Get i-th average pixel (area number)
//
MCalibrationPix &MCalibrationCam::GetAverageArea(UInt_t i)
{
  return *static_cast<MCalibrationPix*>(fAverageAreas->UncheckedAt(i));
}

// --------------------------------------------------------------------------
//
// Get i-th average pixel (area number)
//
const MCalibrationPix &MCalibrationCam::GetAverageArea(UInt_t i) const 
{
  return *static_cast<MCalibrationPix*>(fAverageAreas->UncheckedAt(i));
}

// --------------------------------------------------------------------------
//
// Get i-th average pixel (sector number)
//
MCalibrationPix &MCalibrationCam::GetAverageSector(UInt_t i)
{
  return *static_cast<MCalibrationPix*>(fAverageSectors->UncheckedAt(i));
}

// --------------------------------------------------------------------------
//
// Get i-th average pixel (sector number)
//
const MCalibrationPix &MCalibrationCam::GetAverageSector(UInt_t i) const 
{
  return *static_cast<MCalibrationPix*>(fAverageSectors->UncheckedAt(i));
}

// --------------------------------------------------------------------------
//
// Get i-th average pixel (area number)
//
MBadPixelsPix &MCalibrationCam::GetAverageBadArea(UInt_t i)
{
  return *static_cast<MBadPixelsPix*>(fAverageBadAreas->UncheckedAt(i));
}

// --------------------------------------------------------------------------
//
// Get i-th average pixel (area number)
//
const MBadPixelsPix &MCalibrationCam::GetAverageBadArea(UInt_t i) const 
{
  return *static_cast<MBadPixelsPix*>(fAverageBadAreas->UncheckedAt(i));
}

// --------------------------------------------------------------------------
//
// Get i-th average pixel (sector number)
//
MBadPixelsPix &MCalibrationCam::GetAverageBadSector(UInt_t i)
{
  return *static_cast<MBadPixelsPix*>(fAverageBadSectors->UncheckedAt(i));
}

// --------------------------------------------------------------------------
//
// Get i-th average pixel (sector number)
//
const MBadPixelsPix &MCalibrationCam::GetAverageBadSector(UInt_t i) const 
{
  return *static_cast<MBadPixelsPix*>(fAverageBadSectors->UncheckedAt(i));
}


// --------------------------------------
//
void MCalibrationCam::Clear(Option_t *o)
{

  fPixels->ForEach(TObject, Clear)();

  //
  // another ForEach does not compile, thus have to do the loop ourselves:
  //
  for (Int_t i=0;i<GetAverageAreas();i++)
    {
      fAverageAreas[i].Clear();
      fAverageBadAreas[i].Clear();
    }

  //
  // another ForEach does not compile, thus have to do the loop ourselves:
  //
  for (Int_t i=0;i<GetAverageSectors();i++)
    {
      fAverageSectors[i].Clear();
      fAverageBadSectors[i].Clear();
    }
  
  return;
}

// --------------------------------------------------------------------------
//
// Dummy needed for compilation with MCamEvent
//
Bool_t MCalibrationCam::GetPixelContent(Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type) const
{
  return kTRUE;
}



// --------------------------------------------------------------------------
//
// What MHCamera needs in order to draw an individual pixel in the camera
//
void MCalibrationCam::DrawPixelContent(Int_t idx) const
{
  (*this)[idx].DrawClone();
}

