#ifndef MARS_MBadPixelsPix
#define MARS_MBadPixelsPix

#ifndef MARS_MParContainer
#include "MParContainer.h"
#endif

#ifndef ROOT_TArrayI
#include <TArrayI.h>
#endif

class MBadPixelsPix : public MParContainer
{
private:
    TArrayI fInfo;

public:
    MBadPixelsPix(const char* name=NULL, const char* title=NULL);

    enum UnsuitableType_t {
        kUnsuitableRun = BIT(1),
        kUnsuitableEvt = BIT(2),
        kUnreliableRun = BIT(3)
    };

    static const Int_t fgRunMask; // All types which are not event wise determined

    // All types are initialized to normal behaviour
    enum UncalibratedType_t {
      kHiGainNotCalibrated      = BIT(1),
      kLoGainNotCalibrated      = BIT(2), 
      kHiGainNotFitted          = BIT(3),
      kLoGainNotFitted          = BIT(4), 
      kRelTimeNotFitted         = BIT(5),
      kHiGainOscillating        = BIT(6),
      kLoGainOscillating        = BIT(7),
      kRelTimeOscillating       = BIT(8),
      kLoGainSaturation         = BIT(9),
      kChargeIsPedestal         = BIT(10),
      kChargeErrNotValid        = BIT(11),
      kChargeRelErrNotValid     = BIT(12),
      kChargeSigmaNotValid      = BIT(13),
      kMeanTimeInFirstBin       = BIT(14),
      kMeanTimeInLast2Bins      = BIT(15), 
      kDeviatingNumPhes         = BIT(16)
    };
    
    void Reset();
    void Clear(Option_t *o="");
    void Copy(TObject &object) const
    {
        static_cast<MBadPixelsPix&>(object).fInfo = fInfo;
    }

    // Setter
    void SetUnsuitable  ( UnsuitableType_t   typ ) { fInfo[0] |= typ; }
    void SetUncalibrated( UncalibratedType_t typ ) { fInfo[1] |= typ; }

    // Getter
    Bool_t IsUnsuitable  ( UnsuitableType_t   typ ) const { return fInfo[0]&typ; }
    Bool_t IsUncalibrated( UncalibratedType_t typ ) const { return fInfo[1]&typ; }

    Bool_t IsOK() const  { return fInfo[0]==0; }
    Bool_t IsBad() const { return fInfo[0]!=0; }

    Bool_t IsLoGainBad() const { return IsUnsuitable  (kUnsuitableRun      )
				     || IsUncalibrated(kLoGainSaturation   ) 
				     || IsUncalibrated(kLoGainNotCalibrated) 
				     || IsUncalibrated(kLoGainOscillating  ) ; }
    Bool_t IsHiGainBad() const { return IsUnsuitable  (kUnsuitableRun      )
				     || IsUncalibrated(kHiGainNotCalibrated) 
  				     || IsUncalibrated(kHiGainOscillating  ) ; }

    Bool_t IsCalibrationSignalOK() const  { return !( IsUncalibrated(kChargeIsPedestal    )
					           || IsUncalibrated(kChargeErrNotValid   )
					           || IsUncalibrated(kChargeRelErrNotValid)
					           || IsUncalibrated(kChargeSigmaNotValid )
					           || IsUncalibrated(kMeanTimeInFirstBin  )
 					           || IsUncalibrated(kMeanTimeInLast2Bins )  );  }

    Bool_t IsCalibrationResultOK() const  {  return  !IsUnsuitable(kUnsuitableRun) 
					          &&  IsCalibrationSignalOK()
                                                  && !IsHiGainBad()
					          && !IsLoGainBad() ; }

    void Merge(const MBadPixelsPix &pix);

    const TArrayI &GetInfo() const { return fInfo; }

    ClassDef(MBadPixelsPix, 1)	// Storage Container for bad pixel information of a single pixel
};

#endif

