// *************************************************************************
//
//	GuiFilter.
//
//	Apply a coloured filter (Rectangular) to the screen allowing selection
//	of colour channels to which it is applied.
//
//	Melvyn May - 23 Feb 2002.
//
// *************************************************************************


#include "dgl/dgl.h"
#include "gui/guiControl.h"
#include "console/consoleTypes.h"


// *************************************************************************
//
// Gui Filter Class.
//
// *************************************************************************
class GuiFilter : public GuiControl
{
	typedef GuiControl Parent;				// Parent Control.

	ColorF		mFilterColor;				// Filter Colour Vector.
	bool		mMaskRed;					// Red Mask Flag.
	bool		mMaskGreen;					// Green Mask Flag.
	bool		mMaskBlue;					// Blue Mask Flag.
    		
public:
	GuiFilter();

	void onRender( Point2I, const RectI &);
	static void initPersistFields();

	void setFilterColor(ColorF FilterColor);
	void setFilterMask(bool RedMask, bool GreenMask, bool BlueMask);

	DECLARE_CONOBJECT( GuiFilter );
};

// *************************************************************************
//
//	Implement the Console Object.
//
// *************************************************************************
IMPLEMENT_CONOBJECT( GuiFilter );


// *************************************************************************
//
//	Construct a GuiFilter.
//
// *************************************************************************
GuiFilter::GuiFilter()
{
	// Reset Filter Colour.
	mFilterColor.set(0, 0, 0, 1);

	// Reset Mask.
	//
	// NOTE:-	This is set to a kind of pseudo-night-vision.
	mMaskRed	= GL_TRUE;
	mMaskGreen	= GL_FALSE;
	mMaskBlue	= GL_TRUE;
}


// *************************************************************************
//
//	Initialise Persistent Fields.
//
// *************************************************************************
void GuiFilter::initPersistFields()
{
	// Initialise parents' persistent fields.
	Parent::initPersistFields();

	// Add out own persistent fields.
	addField( "FilterColor", TypeColorF, Offset( mFilterColor, GuiFilter ) );
	addField( "MaskRed", TypeBool, Offset( mMaskRed, GuiFilter ) );
	addField( "MaskGreen", TypeBool, Offset( mMaskGreen, GuiFilter ) );
	addField( "MaskBlue", TypeBool, Offset( mMaskBlue, GuiFilter ) );
}

// *************************************************************************
//
//	Render GUI Element.
//
// *************************************************************************
void GuiFilter::onRender(Point2I offset, const RectI &updateRect)
{
	// Set Colour Mask.
	//
	// NOTE:-	This is the magic in this class.  You can effectively
	//			control which colour channels are written to.
	//			See MSDN or any OpenGL manual for a MUCH better explanation.
	glColorMask(mMaskRed, mMaskGreen, mMaskBlue, GL_TRUE);

	// Draw our filled rectangle with the Filter Colour.
	dglDrawRectFill(updateRect, mFilterColor);

	// Reset the Colour Mask.
	//
	// Q:	Should I query the ColorMask state before I changed it so that
	//		I can restore it or should I use something like Canocial State??
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}

// *************************************************************************
//
//	Set the Filter Colour (Console Callback).
//
// *************************************************************************
void GuiFilter::setFilterColor(ColorF FilterColor)
{
	// Set the Filter Colour internally.
	mFilterColor = FilterColor;
}

// *************************************************************************
//
//	Set the Filter Masks (Console Callback).
//
// *************************************************************************
void GuiFilter::setFilterMask(bool RedMask, bool GreenMask, bool BlueMask)
{
	// Set the Filter Masks internally.
	mMaskRed	= RedMask;
	mMaskGreen	= GreenMask;
	mMaskBlue	= BlueMask;
}


// *************************************************************************
//	Add 'setFilterColor' as a console command.
//
//	NOTE:-	The Alpha colour is optional and will default to 1.0
//
// *************************************************************************
ConsoleMethod(GuiFilter,setFilterColor,void,5,6,"Sets Filter Color.")
{
	F32		r,g,b,a;
	ColorF	TempColor;

	// Fetch the GuiFilter object.
	GuiFilter *Filter = static_cast<GuiFilter*>(object);

	// Convert RGB Ascii parms to float.
	r = dAtof(argv[2]);
	g = dAtof(argv[3]);
	b = dAtof(argv[4]);

	// Did we get an alpha param?
	if (argc == 6)
		// Yep, so convert it.
		a = dAtof(argv[5]);
	else
		// Nope, so default to 1.
		a = 1;

	// Setup our temporary colour vector.
	TempColor.set(r,g,b,a);

	// Set the GuiFilter Filter Colour.
	Filter->setFilterColor(TempColor);
}


// *************************************************************************
//
//	Add 'setFilterMask' as a console command.
//
// *************************************************************************
ConsoleMethod(GuiFilter,setFilterMask,void,5,5,"Sets Filter Masks.")
{
	F32		r,g,b;

	// Fetch the GuiFilter object.
	GuiFilter *Filter = static_cast<GuiFilter*>(object);

	// Convert RGB Ascii parms to float.
	r = dAtof(argv[2]);
	g = dAtof(argv[3]);
	b = dAtof(argv[4]);

	// Set the GuiFilter Masks.
	Filter->setFilterMask(r,g,b);
}

