///////////////////////////////////////////////////////////////////////////////
//
//  MRawEvtPixelIter
//
//  class to iterate over all pixels of one event.
//  The calling is similar to a root iterator:
//  
//  MRawEvtData *evtdata;            // must be filled with data from somewhere
//  MRawEvtPixelIter pixel(evtdata); // evtdata: ptr to event you want to iterate
//
//  while (pixel.Next())
//  {
//     // here you can access the actual time slices by using
//     //   pixel.GetPixelId();
//     //   pixel.GetHiGainFadcSamples()[i]; // i is the number of the slice
//     //   pixel.IsLoGain();                // check if pixel has
//     //   pixel.GetLoGainFadcSamples()[i]; // i is the number of the slice
//
//     // WARNING: Don't acces more time slices than available.
//     //   Get the numbers by calling: evtdata->GetNum[Lo,Hi]GainSamples()
//     //   This number is constant for one event
//  }
//
///////////////////////////////////////////////////////////////////////////////
#include "MRawEvtPixelIter.h"

#include "MRawEvtData.h"

#include "MArrayS.h"
#include "MArrayB.h"

ClassImp(MRawEvtPixelIter)

Byte_t MRawEvtPixelIter::GetNumPixels() const
{
    return fData->GetNumPixels();
}

MRawEvtData *MRawEvtPixelIter::Next()
{
    //
    // if we are already at the last entry there is no 'next' entry anymore
    //
    if (fNumHiGainEntry==fData->fHiGainPixId->GetSize())
        return NULL;

    //
    // if we are already at the last entry there is no 'next' entry anymore
    //
    if (fNumLoGainEntry != fData->fLoGainPixId->GetSize())
        if (*fHiGainId == *fLoGainId)
        {
            //
            // if higainpixid and logainpixid of the actual pixel are
            // identical then we have to move the pointer to the next
            // entry in the lo gains
            //
            fNumLoGainEntry++;
            fLoGainId++;
            fLoGainPos += fData->GetNumLoGainSamples();
        }

    //
    // here we have to move the pointer to the next entry in the hi gains
    //
    fNumHiGainEntry++;
    fHiGainId++;
    fHiGainPos += fData->GetNumHiGainSamples();

    //
    // return a pointer to the 'source' class if we succeed
    //
    return fData;
}

void MRawEvtPixelIter::Reset()
{
    //
    // set counter to zero
    //
    fNumLoGainEntry = 0;
    fNumHiGainEntry = 0;

    //
    // set pointer to first entry of arrays
    //
    fHiGainId   = fData->fHiGainPixId->GetArray()-1;
    fLoGainId   = fData->fLoGainPixId->GetArray()-1;
    fHiGainPos  = fData->fHiGainFadcSamples->GetArray()-fData->GetNumHiGainSamples();
    fLoGainPos  = fData->fLoGainFadcSamples->GetArray()-fData->GetNumLoGainSamples();
}

void MRawEvtPixelIter::Draw(Option_t *t)
{ 
  //
  // Draw the actual pixel (for options see: MRawEvtData::Draw)
  //
  char *txt = new char[6+strlen(t)];
  sprintf(txt, "%s%d", t, *fHiGainId);
  fData->Draw(txt);
  delete txt; 
}

ULong_t MRawEvtPixelIter::GetSumHiGainFadcSamples() const
{
    //
    // return the sum of the hi gain samples of the present pixel
    //
    Byte_t *ptr = fHiGainPos;
    const Byte_t *end = ptr + fData->GetNumHiGainSamples();

    ULong_t sum=0;

    do sum += *ptr++;
    while (ptr != end);

    return sum;
}

ULong_t MRawEvtPixelIter::GetSumLoGainFadcSamples() const
{
    //
    // return the sum of the lo gain samples of the present pixel
    //
    if (!IsLoGain())
        return 0;

    Byte_t *ptr = fLoGainPos;
    const Byte_t *end = ptr + fData->GetNumLoGainSamples();

    ULong_t sum=0;

    do sum += *ptr++;
    while (ptr != end);

    return sum;
}
