/////////////////////////////////////////////////////////////////////
// Author: Henrik Tydesjo                                          //
// Alternative cluster finder for SPD. Usage instructions below.   //
//                                                                 //
//  For each event:                                                //
//  1. Call StartEvent()                                           //
//  2. For each pixel hit:                                         //
//     Call ProcessHit(..) or ProcessHitOnline(..)                 //
//  3. Call FinishEvent()                                          //
//  4. Access cluster information for this event by methods:       //
//     GetClusterCount(module)                                     //
//     GetClusterMeanCol(module,index)                             //
//     GetClusterMeanRow(module,index)                             //
//     GetClusterSize(module,index)                                //
//     GetClusterType(module,index)                                //
//                                                                 //
/////////////////////////////////////////////////////////////////////

#ifndef HenrikClusterFinderSPD_H
#define HenrikClusterFinderSPD_H

#include <Rtypes.h>
#include "HenrikClusterList.h"

class HenrikClusterFinderSPD {

 public:
  HenrikClusterFinderSPD();
  ~HenrikClusterFinderSPD();

  void   ActivateClusterTypeSearch(){fClusterTypeFlag=kTRUE;}
  void DeActivateClusterTypeSearch(){fClusterTypeFlag=kFALSE;}

  void  StartEvent();
  Int_t ProcessHit(UInt_t mod, UInt_t colM, UInt_t rowM);
  Int_t ProcessHitOnline(UInt_t eq, UInt_t hs, UInt_t chip, UInt_t col, UInt_t row);
  void  FinishEvent();

  UInt_t  GetClusterCount(UInt_t mod);
  Float_t GetClusterMeanCol(UInt_t mod, UInt_t index);
  Float_t GetClusterMeanRow(UInt_t mod, UInt_t index);
  UInt_t  GetClusterSize(UInt_t mod, UInt_t index);
  UInt_t  GetClusterWidthZ(UInt_t mod, UInt_t index);
  UInt_t  GetClusterWidthPhi(UInt_t mod, UInt_t index);
  UInt_t  GetClusterType(UInt_t mod, UInt_t index);

  void  PrintClusters(UInt_t mod);
  void  PrintAllClusters();

 private:

  enum {kMAXCLUSTERTYPESIDEZ=3,kMAXCLUSTERTYPESIDEY=4}; // region of interest for cluster type pattern
  enum {kSHIFTRIGHT,kSHIFTDOWN};  // used for shifting the region of interest for cluster type pattern

  UInt_t   fNhitsLeft;     // number of hits still left to process for this module
  Bool_t   fHits[160][256];// hit map for this module
  UShort_t fHitCol[40960]; // these two arrays remember which pixels are hit for this module
  UShort_t fHitRow[40960]; // these two arrays remember which pixels are hit for this module
  Short_t  fOldModule;     // remember previous module (-1 at start of event)

  Bool_t   fClusterTypeFlag;   // should we classify the clusters at all
  Bool_t   fFindClusterType;   // temporary, for classifying a cluster (pattern of pixels)
  UShort_t fClusterTypeOrigCol;// temporary, for classifying a cluster (pattern of pixels)
  UShort_t fClusterTypeOrigRow;// temporary, for classifying a cluster (pattern of pixels)

  UShort_t fClusterWidthMaxCol;
  UShort_t fClusterWidthMinCol;
  UShort_t fClusterWidthMaxRow;
  UShort_t fClusterWidthMinRow;

  Bool_t   fClusterTypeArea[kMAXCLUSTERTYPESIDEZ][kMAXCLUSTERTYPESIDEY];// same as above comments

  UInt_t   fColSum; // used to determine the center of a cluster
  UInt_t   fRowSum; // used to determine the center of a cluster

  HenrikClusterList fClusterList[240];

  void   NewEvent();
  void   NewModule();
  Int_t  DoModuleClustering(Int_t module);
  UInt_t FindClusterRecu(Int_t colM, Int_t rowM);
  void   ShiftClusterTypeArea(UInt_t direction);
  UInt_t GetClusterType(UInt_t size);
  UInt_t GetClusterWidthZ();
  UInt_t GetClusterWidthPhi();

};


#endif

