// @(#)root/eve:$Id$
// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TEveRGBAPalette
#define ROOT_TEveRGBAPalette

#include "TEveUtil.h"

#include "TObject.h"
#include "TQObject.h"

#include "TMath.h"

class TEveRGBAPalette : public TObject,
                        public TQObject,
                        public TEveRefCnt
{
   friend class TEveRGBAPaletteEditor;
   friend class TEveRGBAPaletteSubEditor;

   friend class TEveRGBAPaletteOverlay;

public:
   enum ELimitAction_e { kLA_Cut, kLA_Mark, kLA_Clip, kLA_Wrap };

private:
   TEveRGBAPalette(const TEveRGBAPalette&);            // Not implemented
   TEveRGBAPalette& operator=(const TEveRGBAPalette&); // Not implemented

protected:
   Double_t  fUIf;       // UI representation calculated as: d = fUIf*i + fUIc
   Double_t  fUIc;       // UI representation calculated as: d = fUIf*i + fUIc

   Int_t     fLowLimit;  // Low  limit for Min/Max values (used by editor)
   Int_t     fHighLimit; // High limit for Min/Max values (used by editor)
   Int_t     fMinVal;
   Int_t     fMaxVal;

   Bool_t    fUIDoubleRep;    // Represent UI parts with real values.
   Bool_t    fInterpolate;    // Interpolate colors for signal values.
   Bool_t    fShowDefValue;   // Flags whether signals with default value should be shown.
   Bool_t    fFixColorRange;  // If true, map palette to low/high limit otherwise to min/max value.
   Int_t     fUnderflowAction;
   Int_t     fOverflowAction;

   Color_t   fDefaultColor;   // Color for when value is not specified
   UChar_t   fDefaultRGBA[4];
   Color_t   fUnderColor;     // Underflow color
   UChar_t   fUnderRGBA[4];
   Color_t   fOverColor;      // Overflow color
   UChar_t   fOverRGBA[4];

   mutable Int_t    fNBins;      // Number of signal-color entries.
   mutable Int_t    fCAMin;      // Minimal signal in color-array.
   mutable Int_t    fCAMax;      // Maximal signal in color-array.
   mutable UChar_t* fColorArray; //[4*fNBins]

   void SetupColor(Int_t val, UChar_t* pix) const;

   Double_t IntToDouble(Int_t i)    const { return fUIf*i + fUIc; }
   Int_t    DoubleToInt(Double_t d) const { return TMath::Nint((d - fUIc) / fUIf); }

   Double_t GetCAMinAsDouble() const { return IntToDouble(fCAMin); }
   Double_t GetCAMaxAsDouble() const { return IntToDouble(fCAMax); }

   static TEveRGBAPalette* fgDefaultPalette;

public:
   TEveRGBAPalette();
   TEveRGBAPalette(Int_t min, Int_t max, Bool_t interp=kTRUE,
                   Bool_t showdef=kTRUE, Bool_t fixcolrng=kFALSE);
   virtual ~TEveRGBAPalette();

   void SetupColorArray() const;
   void ClearColorArray();

   Bool_t   WithinVisibleRange(Int_t val) const;
   const UChar_t* ColorFromValue(Int_t val) const;
   void     ColorFromValue(Int_t val, UChar_t* pix, Bool_t alpha=kTRUE) const;
   Bool_t   ColorFromValue(Int_t val, Int_t defVal, UChar_t* pix, Bool_t alpha=kTRUE) const;

   Int_t  GetMinVal() const { return fMinVal; }
   Int_t  GetMaxVal() const { return fMaxVal; }

   void   SetLimits(Int_t low, Int_t high);
   void   SetLimitsScaleMinMax(Int_t low, Int_t high);
   void   SetMinMax(Int_t min, Int_t max);
   void   SetMin(Int_t min);
   void   SetMax(Int_t max);

   Int_t  GetLowLimit()  const { return fLowLimit;  }
   Int_t  GetHighLimit() const { return fHighLimit; }

   // ================================================================

   Bool_t GetUIDoubleRep() const { return fUIDoubleRep; }
   void   SetUIDoubleRep(Bool_t b, Double_t f=1, Double_t c=0);

   Bool_t GetInterpolate() const { return fInterpolate; }
   void   SetInterpolate(Bool_t b);

   Bool_t GetShowDefValue() const { return fShowDefValue; }
   void   SetShowDefValue(Bool_t v) { fShowDefValue = v; }

   Bool_t GetFixColorRange() const { return fFixColorRange; }
   void   SetFixColorRange(Bool_t v);

   Int_t GetUnderflowAction() const  { return fUnderflowAction; }
   Int_t GetOverflowAction()  const  { return fOverflowAction;  }
   void  SetUnderflowAction(Int_t a) { fUnderflowAction = a;    }
   void  SetOverflowAction(Int_t a)  { fOverflowAction  = a;    }

   // ================================================================

   Color_t  GetDefaultColor() const { return fDefaultColor; }
   Color_t* PtrDefaultColor() { return &fDefaultColor; }
   UChar_t* GetDefaultRGBA()  { return fDefaultRGBA;  }
   const UChar_t* GetDefaultRGBA() const { return fDefaultRGBA;  }

   void   SetDefaultColor(Color_t ci);
   void   SetDefaultColorPixel(Pixel_t pix);
   void   SetDefaultColorRGBA(UChar_t r, UChar_t g, UChar_t b, UChar_t a=255);

   // ----------------------------------------------------------------

   Color_t  GetUnderColor() const { return fUnderColor; }
   Color_t* PtrUnderColor() { return &fUnderColor; }
   UChar_t* GetUnderRGBA()  { return fUnderRGBA;  }
   const UChar_t* GetUnderRGBA() const { return fUnderRGBA;  }

   void   SetUnderColor(Color_t ci);
   void   SetUnderColorPixel(Pixel_t pix);
   void   SetUnderColorRGBA(UChar_t r, UChar_t g, UChar_t b, UChar_t a=255);

   // ----------------------------------------------------------------

   Color_t  GetOverColor() const { return fOverColor; }
   Color_t* PtrOverColor() { return &fOverColor; }
   UChar_t* GetOverRGBA()  { return fOverRGBA;  }
   const UChar_t* GetOverRGBA() const { return fOverRGBA;  }

   void   SetOverColor(Color_t ci);
   void   SetOverColorPixel(Pixel_t pix);
   void   SetOverColorRGBA(UChar_t r, UChar_t g, UChar_t b, UChar_t a=255);

   // ================================================================

   void MinMaxValChanged(); // *SIGNAL*

   ClassDef(TEveRGBAPalette, 1); // A generic, speed-optimised mapping from value to RGBA color supporting different wrapping and range truncation modes.
};


/******************************************************************************/
// Inlines for TEveRGBAPalette
/******************************************************************************/

//______________________________________________________________________________
inline Bool_t TEveRGBAPalette::WithinVisibleRange(Int_t val) const
{
   if ((val < fMinVal && fUnderflowAction == kLA_Cut) ||
       (val > fMaxVal && fOverflowAction  == kLA_Cut))
      return kFALSE;
   else
      return kTRUE;
}

//______________________________________________________________________________
inline const UChar_t* TEveRGBAPalette::ColorFromValue(Int_t val) const
{
   // Here we expect that kLA_Cut has been checked; we further check
   // for kLA_Wrap and kLA_Clip otherwise we proceed as for kLA_Mark.

   if (!fColorArray)  SetupColorArray();

   if (val < fMinVal)
   {
      if (fUnderflowAction == kLA_Wrap)
         val = (val+1-fCAMin)%fNBins + fCAMax;
      else if (fUnderflowAction == kLA_Clip)
         val = fMinVal;
      else
         return fUnderRGBA;
   }
   else if(val > fMaxVal)
   {
      if (fOverflowAction == kLA_Wrap)
         val = (val-1-fCAMax)%fNBins + fCAMin;
      else if (fOverflowAction == kLA_Clip)
         val = fMaxVal;
      else
         return fOverRGBA;
   }

   return fColorArray + 4 * (val - fCAMin);
}

//______________________________________________________________________________
inline void TEveRGBAPalette::ColorFromValue(Int_t val, UChar_t* pix, Bool_t alpha) const
{
   const UChar_t* c = ColorFromValue(val);
   pix[0] = c[0]; pix[1] = c[1]; pix[2] = c[2];
   if (alpha) pix[3] = c[3];
}

//______________________________________________________________________________
inline Bool_t TEveRGBAPalette::ColorFromValue(Int_t val, Int_t defVal, UChar_t* pix, Bool_t alpha) const
{
   if (val == defVal) {
      if (fShowDefValue) {
         pix[0] = fDefaultRGBA[0];
         pix[1] = fDefaultRGBA[1];
         pix[2] = fDefaultRGBA[2];
         if (alpha) pix[3] = fDefaultRGBA[3];
         return kTRUE;
      } else {
         return kFALSE;
      }
   }

   if (WithinVisibleRange(val)) {
      ColorFromValue(val, pix, alpha);
      return kTRUE;
   } else {
      return kFALSE;
   }
}

#endif
 TEveRGBAPalette.h:1
 TEveRGBAPalette.h:2
 TEveRGBAPalette.h:3
 TEveRGBAPalette.h:4
 TEveRGBAPalette.h:5
 TEveRGBAPalette.h:6
 TEveRGBAPalette.h:7
 TEveRGBAPalette.h:8
 TEveRGBAPalette.h:9
 TEveRGBAPalette.h:10
 TEveRGBAPalette.h:11
 TEveRGBAPalette.h:12
 TEveRGBAPalette.h:13
 TEveRGBAPalette.h:14
 TEveRGBAPalette.h:15
 TEveRGBAPalette.h:16
 TEveRGBAPalette.h:17
 TEveRGBAPalette.h:18
 TEveRGBAPalette.h:19
 TEveRGBAPalette.h:20
 TEveRGBAPalette.h:21
 TEveRGBAPalette.h:22
 TEveRGBAPalette.h:23
 TEveRGBAPalette.h:24
 TEveRGBAPalette.h:25
 TEveRGBAPalette.h:26
 TEveRGBAPalette.h:27
 TEveRGBAPalette.h:28
 TEveRGBAPalette.h:29
 TEveRGBAPalette.h:30
 TEveRGBAPalette.h:31
 TEveRGBAPalette.h:32
 TEveRGBAPalette.h:33
 TEveRGBAPalette.h:34
 TEveRGBAPalette.h:35
 TEveRGBAPalette.h:36
 TEveRGBAPalette.h:37
 TEveRGBAPalette.h:38
 TEveRGBAPalette.h:39
 TEveRGBAPalette.h:40
 TEveRGBAPalette.h:41
 TEveRGBAPalette.h:42
 TEveRGBAPalette.h:43
 TEveRGBAPalette.h:44
 TEveRGBAPalette.h:45
 TEveRGBAPalette.h:46
 TEveRGBAPalette.h:47
 TEveRGBAPalette.h:48
 TEveRGBAPalette.h:49
 TEveRGBAPalette.h:50
 TEveRGBAPalette.h:51
 TEveRGBAPalette.h:52
 TEveRGBAPalette.h:53
 TEveRGBAPalette.h:54
 TEveRGBAPalette.h:55
 TEveRGBAPalette.h:56
 TEveRGBAPalette.h:57
 TEveRGBAPalette.h:58
 TEveRGBAPalette.h:59
 TEveRGBAPalette.h:60
 TEveRGBAPalette.h:61
 TEveRGBAPalette.h:62
 TEveRGBAPalette.h:63
 TEveRGBAPalette.h:64
 TEveRGBAPalette.h:65
 TEveRGBAPalette.h:66
 TEveRGBAPalette.h:67
 TEveRGBAPalette.h:68
 TEveRGBAPalette.h:69
 TEveRGBAPalette.h:70
 TEveRGBAPalette.h:71
 TEveRGBAPalette.h:72
 TEveRGBAPalette.h:73
 TEveRGBAPalette.h:74
 TEveRGBAPalette.h:75
 TEveRGBAPalette.h:76
 TEveRGBAPalette.h:77
 TEveRGBAPalette.h:78
 TEveRGBAPalette.h:79
 TEveRGBAPalette.h:80
 TEveRGBAPalette.h:81
 TEveRGBAPalette.h:82
 TEveRGBAPalette.h:83
 TEveRGBAPalette.h:84
 TEveRGBAPalette.h:85
 TEveRGBAPalette.h:86
 TEveRGBAPalette.h:87
 TEveRGBAPalette.h:88
 TEveRGBAPalette.h:89
 TEveRGBAPalette.h:90
 TEveRGBAPalette.h:91
 TEveRGBAPalette.h:92
 TEveRGBAPalette.h:93
 TEveRGBAPalette.h:94
 TEveRGBAPalette.h:95
 TEveRGBAPalette.h:96
 TEveRGBAPalette.h:97
 TEveRGBAPalette.h:98
 TEveRGBAPalette.h:99
 TEveRGBAPalette.h:100
 TEveRGBAPalette.h:101
 TEveRGBAPalette.h:102
 TEveRGBAPalette.h:103
 TEveRGBAPalette.h:104
 TEveRGBAPalette.h:105
 TEveRGBAPalette.h:106
 TEveRGBAPalette.h:107
 TEveRGBAPalette.h:108
 TEveRGBAPalette.h:109
 TEveRGBAPalette.h:110
 TEveRGBAPalette.h:111
 TEveRGBAPalette.h:112
 TEveRGBAPalette.h:113
 TEveRGBAPalette.h:114
 TEveRGBAPalette.h:115
 TEveRGBAPalette.h:116
 TEveRGBAPalette.h:117
 TEveRGBAPalette.h:118
 TEveRGBAPalette.h:119
 TEveRGBAPalette.h:120
 TEveRGBAPalette.h:121
 TEveRGBAPalette.h:122
 TEveRGBAPalette.h:123
 TEveRGBAPalette.h:124
 TEveRGBAPalette.h:125
 TEveRGBAPalette.h:126
 TEveRGBAPalette.h:127
 TEveRGBAPalette.h:128
 TEveRGBAPalette.h:129
 TEveRGBAPalette.h:130
 TEveRGBAPalette.h:131
 TEveRGBAPalette.h:132
 TEveRGBAPalette.h:133
 TEveRGBAPalette.h:134
 TEveRGBAPalette.h:135
 TEveRGBAPalette.h:136
 TEveRGBAPalette.h:137
 TEveRGBAPalette.h:138
 TEveRGBAPalette.h:139
 TEveRGBAPalette.h:140
 TEveRGBAPalette.h:141
 TEveRGBAPalette.h:142
 TEveRGBAPalette.h:143
 TEveRGBAPalette.h:144
 TEveRGBAPalette.h:145
 TEveRGBAPalette.h:146
 TEveRGBAPalette.h:147
 TEveRGBAPalette.h:148
 TEveRGBAPalette.h:149
 TEveRGBAPalette.h:150
 TEveRGBAPalette.h:151
 TEveRGBAPalette.h:152
 TEveRGBAPalette.h:153
 TEveRGBAPalette.h:154
 TEveRGBAPalette.h:155
 TEveRGBAPalette.h:156
 TEveRGBAPalette.h:157
 TEveRGBAPalette.h:158
 TEveRGBAPalette.h:159
 TEveRGBAPalette.h:160
 TEveRGBAPalette.h:161
 TEveRGBAPalette.h:162
 TEveRGBAPalette.h:163
 TEveRGBAPalette.h:164
 TEveRGBAPalette.h:165
 TEveRGBAPalette.h:166
 TEveRGBAPalette.h:167
 TEveRGBAPalette.h:168
 TEveRGBAPalette.h:169
 TEveRGBAPalette.h:170
 TEveRGBAPalette.h:171
 TEveRGBAPalette.h:172
 TEveRGBAPalette.h:173
 TEveRGBAPalette.h:174
 TEveRGBAPalette.h:175
 TEveRGBAPalette.h:176
 TEveRGBAPalette.h:177
 TEveRGBAPalette.h:178
 TEveRGBAPalette.h:179
 TEveRGBAPalette.h:180
 TEveRGBAPalette.h:181
 TEveRGBAPalette.h:182
 TEveRGBAPalette.h:183
 TEveRGBAPalette.h:184
 TEveRGBAPalette.h:185
 TEveRGBAPalette.h:186
 TEveRGBAPalette.h:187
 TEveRGBAPalette.h:188
 TEveRGBAPalette.h:189
 TEveRGBAPalette.h:190
 TEveRGBAPalette.h:191
 TEveRGBAPalette.h:192
 TEveRGBAPalette.h:193
 TEveRGBAPalette.h:194
 TEveRGBAPalette.h:195
 TEveRGBAPalette.h:196
 TEveRGBAPalette.h:197
 TEveRGBAPalette.h:198
 TEveRGBAPalette.h:199
 TEveRGBAPalette.h:200
 TEveRGBAPalette.h:201
 TEveRGBAPalette.h:202
 TEveRGBAPalette.h:203
 TEveRGBAPalette.h:204
 TEveRGBAPalette.h:205
 TEveRGBAPalette.h:206
 TEveRGBAPalette.h:207
 TEveRGBAPalette.h:208
 TEveRGBAPalette.h:209
 TEveRGBAPalette.h:210
 TEveRGBAPalette.h:211
 TEveRGBAPalette.h:212
 TEveRGBAPalette.h:213
 TEveRGBAPalette.h:214
 TEveRGBAPalette.h:215
 TEveRGBAPalette.h:216
 TEveRGBAPalette.h:217
 TEveRGBAPalette.h:218
 TEveRGBAPalette.h:219
 TEveRGBAPalette.h:220
 TEveRGBAPalette.h:221
 TEveRGBAPalette.h:222
 TEveRGBAPalette.h:223
 TEveRGBAPalette.h:224
 TEveRGBAPalette.h:225
 TEveRGBAPalette.h:226
 TEveRGBAPalette.h:227
 TEveRGBAPalette.h:228
 TEveRGBAPalette.h:229
 TEveRGBAPalette.h:230
 TEveRGBAPalette.h:231
 TEveRGBAPalette.h:232
 TEveRGBAPalette.h:233
 TEveRGBAPalette.h:234
 TEveRGBAPalette.h:235
 TEveRGBAPalette.h:236
 TEveRGBAPalette.h:237