// @(#)root/base:$Id$
// Author: Timur Pocheptsov   20/3/2012

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TColorGradient                                                       //
//                                                                      //
// TColorGradient extends basic TColor.                                 //
// Actually, this is not a simple color, but linear gradient + shadow   //
// for filled area. By inheriting from TColor, gradients can be placed  //
// inside gROOT's list of colors and use it in all TAttXXX descendants  //
// without modifying any existing code.                                 //
// Shadow, of course, is not a property of any color, and gradient is   //
// not, but this is the best way to add new attributes to filled area   //
// without re-writing all the graphics code.                            //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include <cassert>

#include "TColorGradient.h"
#include "TObjArray.h"
#include "TString.h"
#include "TError.h"
#include "TROOT.h"

ClassImp(TColorGradient)

//______________________________________________________________________________
TColorGradient::TColorGradient()
                   : fCoordinateMode(kObjectBoundingMode)
{
}

//______________________________________________________________________________
TColorGradient::TColorGradient(Color_t colorIndex, UInt_t nPoints, const Double_t *points,
                               const Color_t *indices, ECoordinateMode mode)
                   : fCoordinateMode(mode)
{
   //I have no way to validate parameters here, so it's up to user
   //to pass correct arguments.
   assert(nPoints != 0 && "TColorGradient, number of points is 0");
   assert(points != 0 && "TColorGradient, points parameter is null");
   assert(indices != 0 && "TColorGradient, indices parameter is null");

   ResetColor(nPoints, points, indices);
   RegisterColor(colorIndex);
}

//______________________________________________________________________________
TColorGradient::TColorGradient(Color_t colorIndex, UInt_t nPoints, const Double_t *points,
                               const Double_t *colors, ECoordinateMode mode)
                  : fCoordinateMode(mode)
{
   //I have no way to validate parameters here, so it's up to user
   //to pass correct arguments.
   assert(nPoints != 0 && "TColorGradient, number of points is 0");
   assert(points != 0 && "TColorGradient, points parameter is null");
   assert(colors != 0 && "TColorGradient, colors parameter is null");

   ResetColor(nPoints, points, colors);
   RegisterColor(colorIndex);
}

//______________________________________________________________________________
void TColorGradient::ResetColor(UInt_t nPoints, const Double_t *points, const Color_t *colorIndices)
{
   assert(nPoints != 0 && "ResetColor, number of points is 0");
   assert(points != 0 && "ResetColor, points parameter is null");
   assert(colorIndices != 0 && "ResetColor, colorIndices parameter is null");

   fColorPositions.assign(points, points + nPoints);
   fColors.resize(nPoints * 4);//4 == rgba.
   
   Float_t rgba[4];
   for (UInt_t i = 0, pos = 0; i < nPoints; ++i, pos += 4) {
      const TColor *clearColor = gROOT->GetColor(colorIndices[i]);
      if (!clearColor || dynamic_cast<const TColorGradient *>(clearColor)) {
         //TColorGradient can not be a step in TColorGradient.
         Error("ResetColor", "Bad color for index %d, set to opaque black", colorIndices[i]);
         fColors[pos] = 0.;
         fColors[pos + 1] = 0.;
         fColors[pos + 2] = 0.;
         fColors[pos + 3] = 1.;//Alpha.
      } else {
         clearColor->GetRGB(rgba[0], rgba[1], rgba[2]);
         rgba[3] = clearColor->GetAlpha();
         fColors[pos] = rgba[0];
         fColors[pos + 1] = rgba[1];
         fColors[pos + 2] = rgba[2];
         fColors[pos + 3] = rgba[3];
      }
   }
}

//______________________________________________________________________________
void TColorGradient::ResetColor(UInt_t nPoints, const Double_t *points,
                                const Double_t *colors)
{
   assert(nPoints != 0 && "ResetColor, number of points is 0");
   assert(points != 0 && "ResetColor, points parameter is null");
   assert(colors != 0 && "ResetColor, colors parameter is null");

   fColorPositions.assign(points, points + nPoints);
   fColors.assign(colors, colors + nPoints * 4);
}

//______________________________________________________________________________
void TColorGradient::SetCoordinateMode(ECoordinateMode mode)
{
   fCoordinateMode = mode;
}

//______________________________________________________________________________
TColorGradient::ECoordinateMode TColorGradient::GetCoordinateMode()const
{
   return fCoordinateMode;
}

//______________________________________________________________________________
TColorGradient::SizeType_t TColorGradient::GetNumberOfSteps()const
{
   //
   return fColorPositions.size();
}

//______________________________________________________________________________
const Double_t *TColorGradient::GetColorPositions()const
{
   //
   return &fColorPositions[0];
}

//______________________________________________________________________________
const Double_t *TColorGradient::GetColors()const
{
   //
   return &fColors[0];
}

//______________________________________________________________________________
void TColorGradient::RegisterColor(Color_t colorIndex)
{
   fNumber = colorIndex;
   SetName(TString::Format("Color%d", colorIndex));

   if (gROOT) {
      if (gROOT->GetColor(colorIndex)) {
         Warning("RegisterColor", "Color with index %d is already defined", colorIndex);
         return;
      }
      
      if (TObjArray *colors = (TObjArray*)gROOT->GetListOfColors()) {
         colors->AddAtAndExpand(this, colorIndex);
      } else {
         Error("RegisterColor", "List of colors is a null pointer in gROOT, color was not registered");
         return;
      }
   }
}

ClassImp(TLinearGradient)

//______________________________________________________________________________
TLinearGradient::TLinearGradient()
{
}

//______________________________________________________________________________
TLinearGradient::TLinearGradient(Color_t newColor, UInt_t nPoints, const Double_t *points,
                                 const Color_t *colorIndices, ECoordinateMode mode)
                   : TColorGradient(newColor, nPoints, points, colorIndices, mode)
{
}

//______________________________________________________________________________
TLinearGradient::TLinearGradient(Color_t newColor, UInt_t nPoints, const Double_t *points,
                                 const Double_t *colors, ECoordinateMode mode)
                   : TColorGradient(newColor, nPoints, points, colors, mode)
{
}

//______________________________________________________________________________
void TLinearGradient::SetStartEnd(const Point &p1, const Point &p2)
{
   fStart = p1;
   fEnd = p2;
}

//______________________________________________________________________________
const TColorGradient::Point &TLinearGradient::GetStart()const
{
   return fStart;
}

//______________________________________________________________________________
const TColorGradient::Point &TLinearGradient::GetEnd()const
{
   return fEnd;
}

ClassImp(TRadialGradient)

//______________________________________________________________________________
TRadialGradient::TRadialGradient()
{
}

//______________________________________________________________________________
TRadialGradient::TRadialGradient(Color_t newColor, UInt_t nPoints, const Double_t *points,
                                 const Color_t *colorIndices, ECoordinateMode mode)
                   : TColorGradient(newColor, nPoints, points, colorIndices, mode)
{
}

//______________________________________________________________________________
TRadialGradient::TRadialGradient(Color_t newColor, UInt_t nPoints, const Double_t *points,
                                 const Double_t *colors, ECoordinateMode mode)
                   : TColorGradient(newColor, nPoints, points, colors, mode)
{
}

//______________________________________________________________________________
TRadialGradient::EGradientType TRadialGradient::GetGradientType()const
{
   return fType;
}

//______________________________________________________________________________
void TRadialGradient::SetStartEndR1R2(const Point &p1, Double_t r1, const Point &p2, Double_t r2)
{
   fStart = p1;
   fR1 = r1;
   fEnd = p2;
   fR2 = r2;
   
   fType = kExtended;
}

//______________________________________________________________________________
const TColorGradient::Point &TRadialGradient::GetStart()const
{
   return fStart;
}

//______________________________________________________________________________
Double_t TRadialGradient::GetR1()const
{
   return fR1;
}

//______________________________________________________________________________
const TColorGradient::Point &TRadialGradient::GetEnd()const
{
   return fEnd;
}

//______________________________________________________________________________
Double_t TRadialGradient::GetR2()const
{
   return fR2;
}

//______________________________________________________________________________
void TRadialGradient::SetRadialGradient(const Point &center, Double_t radius)
{
   fStart = center;
   fR1 = radius;

   fType = kSimple;
}

//______________________________________________________________________________
const TColorGradient::Point &TRadialGradient::GetCenter()const
{
   return fStart;
}

//______________________________________________________________________________
Double_t TRadialGradient::GetRadius()const
{
   return fR1;
}
 TColorGradient.cxx:1
 TColorGradient.cxx:2
 TColorGradient.cxx:3
 TColorGradient.cxx:4
 TColorGradient.cxx:5
 TColorGradient.cxx:6
 TColorGradient.cxx:7
 TColorGradient.cxx:8
 TColorGradient.cxx:9
 TColorGradient.cxx:10
 TColorGradient.cxx:11
 TColorGradient.cxx:12
 TColorGradient.cxx:13
 TColorGradient.cxx:14
 TColorGradient.cxx:15
 TColorGradient.cxx:16
 TColorGradient.cxx:17
 TColorGradient.cxx:18
 TColorGradient.cxx:19
 TColorGradient.cxx:20
 TColorGradient.cxx:21
 TColorGradient.cxx:22
 TColorGradient.cxx:23
 TColorGradient.cxx:24
 TColorGradient.cxx:25
 TColorGradient.cxx:26
 TColorGradient.cxx:27
 TColorGradient.cxx:28
 TColorGradient.cxx:29
 TColorGradient.cxx:30
 TColorGradient.cxx:31
 TColorGradient.cxx:32
 TColorGradient.cxx:33
 TColorGradient.cxx:34
 TColorGradient.cxx:35
 TColorGradient.cxx:36
 TColorGradient.cxx:37
 TColorGradient.cxx:38
 TColorGradient.cxx:39
 TColorGradient.cxx:40
 TColorGradient.cxx:41
 TColorGradient.cxx:42
 TColorGradient.cxx:43
 TColorGradient.cxx:44
 TColorGradient.cxx:45
 TColorGradient.cxx:46
 TColorGradient.cxx:47
 TColorGradient.cxx:48
 TColorGradient.cxx:49
 TColorGradient.cxx:50
 TColorGradient.cxx:51
 TColorGradient.cxx:52
 TColorGradient.cxx:53
 TColorGradient.cxx:54
 TColorGradient.cxx:55
 TColorGradient.cxx:56
 TColorGradient.cxx:57
 TColorGradient.cxx:58
 TColorGradient.cxx:59
 TColorGradient.cxx:60
 TColorGradient.cxx:61
 TColorGradient.cxx:62
 TColorGradient.cxx:63
 TColorGradient.cxx:64
 TColorGradient.cxx:65
 TColorGradient.cxx:66
 TColorGradient.cxx:67
 TColorGradient.cxx:68
 TColorGradient.cxx:69
 TColorGradient.cxx:70
 TColorGradient.cxx:71
 TColorGradient.cxx:72
 TColorGradient.cxx:73
 TColorGradient.cxx:74
 TColorGradient.cxx:75
 TColorGradient.cxx:76
 TColorGradient.cxx:77
 TColorGradient.cxx:78
 TColorGradient.cxx:79
 TColorGradient.cxx:80
 TColorGradient.cxx:81
 TColorGradient.cxx:82
 TColorGradient.cxx:83
 TColorGradient.cxx:84
 TColorGradient.cxx:85
 TColorGradient.cxx:86
 TColorGradient.cxx:87
 TColorGradient.cxx:88
 TColorGradient.cxx:89
 TColorGradient.cxx:90
 TColorGradient.cxx:91
 TColorGradient.cxx:92
 TColorGradient.cxx:93
 TColorGradient.cxx:94
 TColorGradient.cxx:95
 TColorGradient.cxx:96
 TColorGradient.cxx:97
 TColorGradient.cxx:98
 TColorGradient.cxx:99
 TColorGradient.cxx:100
 TColorGradient.cxx:101
 TColorGradient.cxx:102
 TColorGradient.cxx:103
 TColorGradient.cxx:104
 TColorGradient.cxx:105
 TColorGradient.cxx:106
 TColorGradient.cxx:107
 TColorGradient.cxx:108
 TColorGradient.cxx:109
 TColorGradient.cxx:110
 TColorGradient.cxx:111
 TColorGradient.cxx:112
 TColorGradient.cxx:113
 TColorGradient.cxx:114
 TColorGradient.cxx:115
 TColorGradient.cxx:116
 TColorGradient.cxx:117
 TColorGradient.cxx:118
 TColorGradient.cxx:119
 TColorGradient.cxx:120
 TColorGradient.cxx:121
 TColorGradient.cxx:122
 TColorGradient.cxx:123
 TColorGradient.cxx:124
 TColorGradient.cxx:125
 TColorGradient.cxx:126
 TColorGradient.cxx:127
 TColorGradient.cxx:128
 TColorGradient.cxx:129
 TColorGradient.cxx:130
 TColorGradient.cxx:131
 TColorGradient.cxx:132
 TColorGradient.cxx:133
 TColorGradient.cxx:134
 TColorGradient.cxx:135
 TColorGradient.cxx:136
 TColorGradient.cxx:137
 TColorGradient.cxx:138
 TColorGradient.cxx:139
 TColorGradient.cxx:140
 TColorGradient.cxx:141
 TColorGradient.cxx:142
 TColorGradient.cxx:143
 TColorGradient.cxx:144
 TColorGradient.cxx:145
 TColorGradient.cxx:146
 TColorGradient.cxx:147
 TColorGradient.cxx:148
 TColorGradient.cxx:149
 TColorGradient.cxx:150
 TColorGradient.cxx:151
 TColorGradient.cxx:152
 TColorGradient.cxx:153
 TColorGradient.cxx:154
 TColorGradient.cxx:155
 TColorGradient.cxx:156
 TColorGradient.cxx:157
 TColorGradient.cxx:158
 TColorGradient.cxx:159
 TColorGradient.cxx:160
 TColorGradient.cxx:161
 TColorGradient.cxx:162
 TColorGradient.cxx:163
 TColorGradient.cxx:164
 TColorGradient.cxx:165
 TColorGradient.cxx:166
 TColorGradient.cxx:167
 TColorGradient.cxx:168
 TColorGradient.cxx:169
 TColorGradient.cxx:170
 TColorGradient.cxx:171
 TColorGradient.cxx:172
 TColorGradient.cxx:173
 TColorGradient.cxx:174
 TColorGradient.cxx:175
 TColorGradient.cxx:176
 TColorGradient.cxx:177
 TColorGradient.cxx:178
 TColorGradient.cxx:179
 TColorGradient.cxx:180
 TColorGradient.cxx:181
 TColorGradient.cxx:182
 TColorGradient.cxx:183
 TColorGradient.cxx:184
 TColorGradient.cxx:185
 TColorGradient.cxx:186
 TColorGradient.cxx:187
 TColorGradient.cxx:188
 TColorGradient.cxx:189
 TColorGradient.cxx:190
 TColorGradient.cxx:191
 TColorGradient.cxx:192
 TColorGradient.cxx:193
 TColorGradient.cxx:194
 TColorGradient.cxx:195
 TColorGradient.cxx:196
 TColorGradient.cxx:197
 TColorGradient.cxx:198
 TColorGradient.cxx:199
 TColorGradient.cxx:200
 TColorGradient.cxx:201
 TColorGradient.cxx:202
 TColorGradient.cxx:203
 TColorGradient.cxx:204
 TColorGradient.cxx:205
 TColorGradient.cxx:206
 TColorGradient.cxx:207
 TColorGradient.cxx:208
 TColorGradient.cxx:209
 TColorGradient.cxx:210
 TColorGradient.cxx:211
 TColorGradient.cxx:212
 TColorGradient.cxx:213
 TColorGradient.cxx:214
 TColorGradient.cxx:215
 TColorGradient.cxx:216
 TColorGradient.cxx:217
 TColorGradient.cxx:218
 TColorGradient.cxx:219
 TColorGradient.cxx:220
 TColorGradient.cxx:221
 TColorGradient.cxx:222
 TColorGradient.cxx:223
 TColorGradient.cxx:224
 TColorGradient.cxx:225
 TColorGradient.cxx:226
 TColorGradient.cxx:227
 TColorGradient.cxx:228
 TColorGradient.cxx:229
 TColorGradient.cxx:230
 TColorGradient.cxx:231
 TColorGradient.cxx:232
 TColorGradient.cxx:233
 TColorGradient.cxx:234
 TColorGradient.cxx:235
 TColorGradient.cxx:236
 TColorGradient.cxx:237
 TColorGradient.cxx:238
 TColorGradient.cxx:239
 TColorGradient.cxx:240
 TColorGradient.cxx:241
 TColorGradient.cxx:242
 TColorGradient.cxx:243
 TColorGradient.cxx:244
 TColorGradient.cxx:245
 TColorGradient.cxx:246
 TColorGradient.cxx:247
 TColorGradient.cxx:248
 TColorGradient.cxx:249
 TColorGradient.cxx:250
 TColorGradient.cxx:251
 TColorGradient.cxx:252
 TColorGradient.cxx:253
 TColorGradient.cxx:254
 TColorGradient.cxx:255
 TColorGradient.cxx:256
 TColorGradient.cxx:257
 TColorGradient.cxx:258
 TColorGradient.cxx:259
 TColorGradient.cxx:260
 TColorGradient.cxx:261
 TColorGradient.cxx:262
 TColorGradient.cxx:263
 TColorGradient.cxx:264
 TColorGradient.cxx:265
 TColorGradient.cxx:266
 TColorGradient.cxx:267
 TColorGradient.cxx:268
 TColorGradient.cxx:269
 TColorGradient.cxx:270
 TColorGradient.cxx:271
 TColorGradient.cxx:272
 TColorGradient.cxx:273
 TColorGradient.cxx:274
 TColorGradient.cxx:275
 TColorGradient.cxx:276
 TColorGradient.cxx:277
 TColorGradient.cxx:278
 TColorGradient.cxx:279
 TColorGradient.cxx:280
 TColorGradient.cxx:281
 TColorGradient.cxx:282
 TColorGradient.cxx:283
 TColorGradient.cxx:284
 TColorGradient.cxx:285
 TColorGradient.cxx:286
 TColorGradient.cxx:287
 TColorGradient.cxx:288
 TColorGradient.cxx:289
 TColorGradient.cxx:290
 TColorGradient.cxx:291