#ifndef _CUSTOMGUI_GRADIENT_H_
#define _CUSTOMGUI_GRADIENT_H_

#include "c4d_library.h"
#include "c4d_basecontainer.h"
#include "c4d_gui.h"
#include "c4d_customdatatype.h"
#include "customgui_base.h"


#define CUSTOMGUI_GRADIENT			1000480
#define CUSTOMDATATYPE_GRADIENT 1000481


enum
{
	GRADIENT_INTERPOLATION_CUBICKNOT	= 0,
	GRADIENT_INTERPOLATION_CUBICBIAS	= 1,
	GRADIENT_INTERPOLATION_SMOOTHKNOT	= 2,
	GRADIENT_INTERPOLATION_LINEARKNOT	= 3,
	GRADIENT_INTERPOLATION_LINEAR			= 4,
	GRADIENT_INTERPOLATION_NONE				= 5
};

#define GRADIENTMODE_COLOR					0
#define GRADIENTMODE_ALPHA					1
#define GRADIENTMODE_COLORALPHA			2

#define GRADIENT_INTERPOLATION	1000	// LONG
#define GRADIENT_KNOT						1001	// BASECONTAINER
#define GRADIENT_MODE						1002	// LONG
#define GRADIENT_UNCLAMPED			1003  // BOOL

#define GRADIENTKNOT_COLOR			1000	// VECTOR
#define GRADIENTKNOT_BRIGHTNESS	1001	// REAL
#define GRADIENTKNOT_POSITION		1002	// REAL
#define GRADIENTKNOT_BIAS				1003	// REAL
#define GRADIENTKNOT_ID					1004  // LONG

struct GradientKnot
{
	GradientKnot(void) { col=1.0; brightness=1.0; pos=0.0; bias=0.5; index=0; }

	Vector	col;
	Real		brightness;
	Real		pos;
	Real		bias;
	LONG		index;
};

class Gradient : public iCustomDataType<Gradient>
{
		Gradient(void);

	public:
		Bool					InvertKnots(void);
		Bool					DoubleKnots(void);
		void					FlushKnots(void);

		Bool					InitRender(void);
		void					FreeRender(void);
		Vector				CalcGradientPixel(Real pos);

		LONG					GetKnotCount(void);
			
		LONG					InsertKnot(const GradientKnot &knot);
		Bool					RemoveKnot(LONG index);
		
		GradientKnot	GetKnot(LONG index);
		void					SetKnot(LONG index, const GradientKnot &k);

		GeData				GetData(LONG id) const;
		Bool					SetData(LONG id,const GeData &data);

		GradientKnot	*GetRenderKnot(LONG index);
		LONG					GetRenderKnotCount(void);

		Gradient*			GetAlphaGradient(void);

		static Gradient *Alloc();
		static void Free(Gradient *&grad);
};

class GradientCustomGui : public BaseCustomGui<CUSTOMGUI_GRADIENT>
{
		GradientCustomGui();

	public:
		Gradient *GetGradient();

		LONG GetActiveKnot(Bool &bias);
		void SetActiveKnot(LONG index, Bool bias);

};

// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF

#ifndef _INTERNAL_DEF_
	class iGradientCustomGui
	{
	};
	class iGradient
	{
	};
#else
	class iGradientCustomGui;
	class iGradient;
#endif

										
struct CustomGuiGradientLib : public BaseCustomGuiLib
{
	Bool							(iGradient::*InvertKnots)(void);
	Bool							(iGradient::*DoubleKnots)(void);
	void							(iGradient::*FlushKnots)(void);
										
	Bool							(iGradient::*InitRender)(void);
	void							(iGradient::*FreeRender)(void);
	Vector						(iGradient::*CalcGradientPixel)(Real pos);
										
	LONG							(iGradient::*GetKnotCount)(void);
										
	LONG							(iGradient::*InsertKnot)(const GradientKnot &knot);
	Bool							(iGradient::*RemoveKnot)(LONG index);
										
	GradientKnot			(iGradient::*GetKnot)(LONG index);
	void							(iGradient::*SetKnot)(LONG index, const GradientKnot &k);

	GeData						(iGradient::*iGetData)(LONG id) const;
	Bool							(iGradient::*iSetData)(LONG id,const GeData &data);

	GradientKnot*			(iGradient::*GetRenderKnot)(LONG index);
	LONG							(iGradient::*GetRenderKnotCount)(void);

	Gradient*					(iGradient::*GetAlphaGradient)(void);

	Gradient*					(*AllocGradient)(void);
	void							(*FreeGradient)(Gradient *grad);
										
	Gradient*					(iGradientCustomGui::*GetGradient)();
										
	LONG							(iGradientCustomGui::*GetActiveKnot)(Bool &bias);
	void							(iGradientCustomGui::*SetActiveKnot)(LONG index, Bool bias);
};

#endif
