// $Id: ETriggerPainter.hh,v 1.1 2005/02/18 15:16:46 pesce Exp $
// R.Pesce created Feb, 17 2005

/*****************************************************************************
 * ESAF: Euso Simulation and Analysis Framework                              *
 *                                                                           *
 *  Id: TriggerPainter                                                       *
 *  Package: EventViewer                                                     *
 *  Coordinator: Alessandro.Thea                                             *
 *                                                                           *
 *****************************************************************************/

#ifndef __ETRIGGERPAINTER_HH__
#define __ETRIGGERPAINTER_HH__

#include "EFocalSurfacePainter.hh"
#include "EAnimator.hh"
#include "TSeqCollection.h"
#include "TPolyLine.h"
#include "TVector3.h"
#include "TText.h"
#include "TPaveText.h"
#include <map>
#include <vector>


//////////////////////////////////////////////////////////////////////////////
//                                                                          //
//  ETriggerPainter                                                         //
//                                                                          //
//  A painter to show the development of the signal on                      //
//  the focal surface                                                       //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

class EDetector;
class ERunParameters;
class EChipTrackTrigger;
class EPolygon;

enum ETrigId { kAllHits     = 1,
               kTrgHits     = 2,
               kAllSig      = 3,
               kTrgSig      = 4,
               kCHits       = 5
};

using std::map;
using std::vector;

/*typedef map<Int_t, Int_t> Counts_t;
typedef map<Int_t, Counts_t> GtuCounts_t;

const Counts_t operator+(const Counts_t&, const Counts_t&);
Counts_t& operator+=( Counts_t&, const Counts_t&);*/

class ETriggerPainter: public EAnimator {
public:
    ETriggerPainter( EDetector *, ERunParameters*, EChipTrackTrigger*  );
    virtual ~ETriggerPainter();

    virtual void Clear( Option_t* ="");
    virtual void Draw( Option_t* ="");
    virtual void Paint( Option_t* ="");
    virtual Int_t DistancetoPrimitive(Int_t px, Int_t py);
    virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py);
    virtual char* GetObjectInfo(Int_t px, Int_t py) const;

    virtual void Play( Option_t* =""); // *MENU*
    virtual void Animate();
    virtual void NextFrame();
    virtual inline void Rewind() { fGtu = fFirstGtu; } // *MENU*
    virtual inline Bool_t IsEnded() { return fGtu >= fLastGtu; } 
    
    void MakeGifSequence(const char* option = "", const char* path="Anim");
    
    // getters
    inline Int_t   GetGtu() const { return fGtu; }
    inline Int_t   GetFirstGtu() const { return fFirstGtu; }
    inline Int_t   GetLastGtu() const { return fLastGtu; }
    
    inline ETrigId GetMapToPaintID() const { return fMaptoPaintID; }

    inline const TVector3& GetCenter() const { return fCenter; } 
    inline const TVector3& GetSpread() const { return fSpread; }
    inline const TVector3& GetXaxis() const { return fXaxis; }
    inline const TVector3& GetYaxis() const { return fYaxis; }
    inline const TVector3& GetZaxis() const { return fZaxis; }

    inline Int_t   GetViewThreshold() const { return fViewThreshold; }
    inline Float_t GetViewNspread() const { return fViewNspread; }
    inline Float_t GetViewBorder() const { return fViewBorder; }
    
    inline Bool_t  GetPixelEmpty() const { return fPixelEmpty; }
    inline Bool_t  GetPixelOff() const { return fPixelOff; }
    inline Bool_t  GetGtuCounter() const { return fGtuCounter; }
    inline Bool_t  GetTimeIntegral() const { return fTimeIntegral; }
    inline Bool_t  GetStatusBar() const { return fStatusBar; }

    inline Int_t   GetNumColors() const { return fNumColors; }
    inline Int_t   GetMaxCounts() const { return fMaxCounts; }

    inline Color_t GetPixelColorEmpty() const { return fPixelColorEmpty; }
    inline Color_t GetPixelColorOff() const { return fPixelColorOff; }
    inline Color_t GetPmtColorEmpty() const { return fPmtColorEmpty; }
    inline Color_t GetPmtColorHit() const { return fPmtColorHit; }
    
    // setters
    inline void SetGtu( Int_t gtu ) { fGtu = gtu; } // *MENU*
    inline void SetFirstGtu( Int_t gtu ) { fFirstGtu = gtu; }
    inline void SetLastGtu( Int_t gtu ) { fLastGtu = gtu; }
    
    inline void SetMapToPaintID( ETrigId id ) { fMaptoPaintID = id; } // *MENU*

    virtual void PaintAllHits() { SetMapToPaintID( kAllHits ); } // *MENU*
    virtual void PaintTrigHits() { SetMapToPaintID( kTrgHits ); } // *MENU*
    virtual void PaintAllSignals() { SetMapToPaintID( kAllSig ); } // *MENU*
    virtual void PaintTrigSignals() { SetMapToPaintID( kTrgSig ); } // *MENU*
    virtual void PaintCellHits() { SetMapToPaintID( kCHits ); } // *MENU*


    inline void SetViewThreshold( Int_t t ) { fViewThreshold = t; }  // *MENU*
    inline void SetViewNspread( Float_t s) { fViewNspread = s; }     // *MENU*
    inline void SetViewBorder( Float_t b ) {  fViewBorder = b; }     // *MENU*
   
    inline void SetPixelEmpty( Bool_t b = kTRUE ) { fPixelEmpty = b; }     // *TOGGLE*
    inline void SetPixelOff( Bool_t b = kTRUE ) { fPixelOff = b; }         // *TOGGLE*
    inline void SetGtuCounter( Bool_t b = kTRUE ) { fGtuCounter = b; }     // *TOGGLE*
    inline void SetTimeIntegral( Bool_t b = kTRUE ) { fTimeIntegral = b; } // *TOGGLE*
    inline void SetStatusBar( Bool_t b=kTRUE ) { fStatusBar = b; }         // *TOGGLE*

    inline void SetNumColors( Int_t n ) { fNumColors = n; }          // *MENU*
    inline void SetMaxCounts( Int_t n ) { fMaxCounts = n; }          // *MENU*

    inline void SetPixelColorEmpty( Color_t c ) { fPixelColorEmpty = c; }
    inline void SetPixelColorOff( Color_t c ) { fPixelColorOff = c; }
    inline void SetPmtColorEmpty( Color_t c ) { fPmtColorEmpty = c; }
    inline void SetPmtColorHit( Color_t c ) { fPmtColorHit = c; }

private:

    // helper functions
    void LoadData();
    void FindView( ETrigId );
    void BuildPolyLines();

    EPolygon* FindPmtLine( Int_t ) const;
    EPolygon* GetPmtLine( Int_t );
    EPolygon* GetPixelLine( Int_t );
    void FindPmtsToPaint( Float_t, Float_t, Float_t, Float_t );

    // painter settings
    Int_t   fGtu;                       // current gtu

    ETrigId fMaptoPaintID;                 // identifier of the data to paint
    
    // viewport
    Int_t   fViewThreshold;             // min counts of hits used to def the VP
    Float_t fViewNspread;               // size of viewport in signal Nspread 
    Float_t fViewBorder;                // border size, from 0 to 0.5

    // gif display size
    Int_t fGifCanvasW;                 // width of the gif sequence canvas
    Int_t fGifCanvasH;                 // hieght of the gif sequence canvas

    // draw options
    Bool_t  fPixelEmpty;                // true to draw pixels with 0 hits
    Bool_t  fPixelOff;                  // true to draw pixels even not in the maps 
    Bool_t  fGtuCounter;                // true to draw the gtu counter
    Bool_t  fTimeIntegral;              // true to draw time integral of the track
    Bool_t  fStatusBar;                 // true paint the status text

    Float_t fX1;                        // X coord of the lower left corner
    Float_t fX2;                        // X coord of the lower right corner
    Float_t fY1;                        // Y coord of the lower left corner
    Float_t fY2;                        // Y coord of the lower right corner

    // colors
    Int_t   fNumColors;                 // maximum number of colors
    Int_t   fColorOffset;               // first color in the palette
    Int_t   fMaxCounts;                 //  

    Color_t fPixelColorOff;             // color code of absent pixels
    Color_t fPixelColorEmpty;           // color code of empty pixels
    Color_t fPmtColorEmpty;             // color code of empty pmts
    Color_t fPmtColorHit;               // color code of hit pmts

    TPaveText fPaveStatusBar; 

    virtual void SetStatus( Int_t uid, Int_t pmt=-1, Int_t chip=-1, Int_t cell=-1, Int_t counts=-1);
    
    // data 
    EDetector *fDetector;
    ERunParameters *fRunPars;
    EChipTrackTrigger *fTrigger;
    
    // data maps
    GtuCounts_t fChips;
    GtuCounts_t fTrgChips;
    GtuCounts_t fTrackHits;
    GtuCounts_t fTrackSignals;
    GtuCounts_t fTrgHits;
    GtuCounts_t fTrgSignals;
    GtuCounts_t fMacroCellHits;

    Int_t    fFirstGtu;                 // first gtu in data
    Int_t    fLastGtu;                  // last gtu in data
    TVector3 fCenter;                   // signal center in Detector coordinates 
    TVector3 fSpread;                   // signal spread
    TVector3 fXaxis;                    // x axis calculated from signal pixels 
    TVector3 fYaxis;                    // y axis calculated from signal pixels 
    TVector3 fZaxis;                     // normal (z ax) calculated from signal pixels 
    
    TSeqCollection *fLines;             // list of lines used by the destructor

    vector<Int_t> fPmtsToPaint;         // list of the pmt ids in the viewport

    map<Int_t, EPolygon* > fPmtLines;
    map<Int_t, EPolygon* > fPixelLines;


    // cache
    mutable GtuCounts_t fCache;
    mutable Int_t fCacheContents;

    TText fTxtCounter;

    void         CacheTimeInt() const;
    Counts_t     GetMapToPaint() const;
    const GtuCounts_t* GtuCountsToPaint() const;

    ClassDef(ETriggerPainter,1)
};

#endif  /* __ETRIGGERPAINTER_HH__ */