#ifndef TMCONTROLSPD_H
#define TMCONTROLSPD_H

#include <pthread.h>
#include "HenrikClusterFinderSPD.h"
#include "AdvEvCountCheck.h"
#include "AliITSOnlineCalibrationSPDhandler.h"
#include "AliITSRawStreamSPDErrorLog.h"
#include "AliRawEvent.h"

#ifndef WITH_DATE
#include "AliRawReaderDateHenrik.h"
#endif

#include <TList.h>
#include <TFile.h>
#include <TTree.h>

#include "AliITSRecPoint.h"
#include "AliGeomManager.h"
#include "AliITSgeomTGeo.h"
#include <TGeoManager.h>


typedef unsigned long int pthread_t; // needed to make rootcint happy :)

class TMControlSPD {

  public :

  virtual ~TMControlSPD();
  static TMControlSPD* Instance();

  static  void*  dumpC_thr(void *arg);
  static  void*  dump2_thr(void *arg);
  static  void*  dumpN_thr(void *arg);
  static  void*  dump1_thr(void *arg);

  virtual Bool_t  AmIdump() {return pthread_self() == th1;}

  virtual void    talk2DATElogin();
  virtual void    talk2DATElogout();

  virtual Bool_t  GetEvent();

  virtual void    Reset();
  virtual void    ResetErrorFlag();

  virtual Int_t   GetLocalEventNumber() {return fLocalEventNumber;}
  virtual Int_t   GetGlobalEventNumber() {return fGlobalEventNumber;}

  virtual Bool_t  CheckToIncrementDumpX();
  virtual void    IncrementDataSource();
  virtual void    IncrementDataSourceList();

  virtual void    TransformClusterToGlobal(UInt_t mod, Float_t meanCol, Float_t meanRow);
  virtual Float_t GetGlobalX() {return fLastGlobalX;}
  virtual Float_t GetGlobalY() {return fLastGlobalY;}
  virtual Float_t GetGlobalZ() {return fLastGlobalZ;}

  virtual void    StartDumpC();
  virtual void    StartDump2();
  virtual void    StartDumpN();
  virtual void    StartDump1();

  virtual void    StartRunning();
  virtual void    FinishRunning();
  virtual void    HoldRunning(Float_t secWait = 0);
  virtual Bool_t  TmpUnLock();
  virtual void    TmpReLock();
  virtual void    ContinueRunning(Float_t secWait = 0);
  virtual ULong_t GetRunNb() {return fRunNb;}
  virtual UInt_t  GetNrNoisy();
  virtual void    IncrementDumpNevents();
  virtual UInt_t  GetDumpNevents() {return fDumpNevents;}
  virtual void    printError(char* w, int e);

  virtual void   UpdateDisplays(Bool_t force = kFALSE);
  virtual void   UpdateStatusBar();
  virtual void   UpdateSupprError();

  //!!!  virtual Bool_t  GridSourceEnv();
  virtual Bool_t  GridConnect();
  virtual Bool_t  ReadFileList();
  virtual TString GetDataSourceFromList(UInt_t fileListIndex);

  virtual void SetMask(UInt_t eqS, UInt_t eqE, UInt_t hsS, UInt_t hsE, UInt_t chipS, UInt_t chipE, UInt_t colS, UInt_t colE, UInt_t rowS, UInt_t rowE, Bool_t bMask);
  virtual void SetMask2(UInt_t eq, UInt_t hs, UInt_t chip, UInt_t col, UInt_t row, Bool_t bMask);
  virtual void ClearMask();
  virtual void UpdateMask();
  virtual void SaveMask();
  virtual void SaveMask(const Char_t* fileLoc);
  virtual void LoadMask();
  virtual void LoadMask(const Char_t* fileLoc);
  virtual void PrintMaskedPixels();

  virtual Bool_t IsRunning() {return fRunning;}
  virtual Bool_t IsRunningHold() {return fRunningHold>0;}
  virtual Bool_t IsStopRunning() {return fStopRunning;}
  virtual Bool_t IsEventToBePlotted() {return fEventToBePlotted;}
  virtual Bool_t IsEqActive(UInt_t eqId);

  virtual void SetHolding(Bool_t val=kTRUE) {fHolding=val;}
  virtual void SetRunning(Bool_t b) {fRunning=b;}
  virtual void SetStopRunning(Bool_t b) {fStopRunning=b;}
  virtual void StopRunningSafely();
  virtual void SetEventToBePlotted(Bool_t val=kTRUE) {fEventToBePlotted=val;}

  virtual void SetTimeSafeUpdate() {timeStampSafeUpdate = time(NULL);}
  virtual void SlowDownRunning(Float_t slowdownlength);

 private:

  TMControlSPD();
  static Bool_t instanceFlag;
  static TMControlSPD *single;

  Float_t fYpitchSPD;
  Float_t fZ1pitchSPD;
  Float_t fZ2pitchSPD;
  Float_t fYSPD[260];
  Float_t fZSPD[170];
  Float_t fHwSPD;
  Float_t fHlSPD;
  Int_t   fNySPD;
  Int_t   fNzSPD;

  ULong_t fRunNb;
  Int_t   fLastNbInRun;           // Used to check if new segments contain events
  Int_t	  fGlobalEventNumber;	  // Number of events MOOD processes on total since login
  Int_t	  fLocalEventNumber;	  // Number of events MOOD processes on present source
	  
  Bool_t  fRunning;		  // Running mode or not
  Int_t   fRunningHold;           // Pause mode for run
  Bool_t  fHolding;               // We are in the Paused mode
  Bool_t  fStopRunning;           // message to Stop run
  Bool_t  fRetrievingEvent;       // true while getevent is called
  Bool_t  fStopOnError;           // stop scanning if inconsist.
	  
  Bool_t  fDisplayErrorEvents;    // do we want to display the eq. with errors
  UInt_t  fDumpNevents;           // nr of events recorded for dumpN

  Bool_t  fAdvEvCountCheck;
  Bool_t  fMiniEvIdCheck;
  Bool_t  fClustering;
  Bool_t  fEventToBePlotted;

  time_t  fLastUpdateTime;
  time_t  fLastStatusUpdate;
  Int_t   fMovieEventNr;
  Bool_t  fThisIsAMovieEvent;

  Float_t fLastGlobalX;
  Float_t fLastGlobalY;
  Float_t fLastGlobalZ;

  UInt_t  fFileListIndex;
  UInt_t  fNrFileListFiles;
  TList   fOfflineFileList;

  Bool_t  fTableDeclared;

  pthread_t     th1;
  pthread_t     th2;
  unsigned char *fBuffer;

  // for reading Root files:
  AliRawEvent* fRootEvent;
  TFile *fRootFile;
  TTree *fRootTree;
  UInt_t fRootEventCounter;

  time_t  timeStampSafeUpdate;
  time_t  fSlowDownRunningTime;
  Float_t fSlowDownRunningLength;

  UInt_t  fErrorFlagNiveau;

  AliITSRawStreamSPDErrorLog* fAdvLogger;
  HenrikClusterFinderSPD *fClusterFinderSPD;
  AliITSOnlineCalibrationSPDhandler* cHand;
  AdvEvCountCheck* fEvCountCheckObj;
#ifndef WITH_DATE
  AliRawReaderDateHenrik *fRawReaderDateHenrik;
#endif

  Int_t    rootSetDataSource(const Char_t *source);
#ifndef WITH_DATE
  Int_t    dateSetDataSource(const Char_t *source); // use of aliroot also for 'date' files
#endif
  Int_t    rootGetEvent(void *buffer);

#ifdef WITH_DATE
  void     DeclareTable();
#endif

  Bool_t   EventNumberAccepted(UInt_t ev);

};

#endif
