//
// Tools_ColourPicker.cpp
//
// Created by Richard Rice - 28/07/2024
// 
// Copyright (C) 2004 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"
#include "Interface/Tools_ColourPicker.h"
#include "Interface/Tools_ColourPicker_Internal.h"

#include "Core/Asura_TextureManagement.h"
#include "Core/Asura_UserInput.h"
#include "Core/Asura_Timers.h"
#include "Debugging/Asura_Assert.h"
#include "Interface/Asura_Gadget.h"
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay_System.h"
#include "Interface/Asura_Overlay.h"
#include "Interface/Asura_Cursor.h"
#include "Misc/Tools_Modal_Overlay.h"
#include "Rendering/Asura_Text_Output.h"
#include "Rendering/Asura_Render.h"

#include "Tools_System.h"
#include "Load&Save/Tools_ModeDataFile.h"
#include "Misc/Tools_Dialog.h"

extern unsigned int Asura_OverlayBrightness;
///////////////////////////////////////////////////////////////////////////////////////////////
/*--------------------**
** Tools_ColourPicker **
**--------------------*/

static const int g_iNumFixedColours = 48;
static u_int g_auFixedColours[g_iNumFixedColours] = 
{
	0xffff8080,	0xffffff80,	0xff80ff80, 0xff00ff80, 0xff80ffff, 0xff0080ff, 0xffff80c0, 0xffff80ff,
	0xffff0000, 0xffffff00, 0xff80ff00, 0xff00ff40, 0xff00ffff, 0xff0080c0, 0xff8080c0, 0xffff00ff,
	0xff804040, 0xffff8040, 0xff00ff00, 0xff008080, 0xff004080, 0xff8080ff, 0xff800040, 0xffff0080,
	0xff800000, 0xffff8000, 0xff008000, 0xff008040, 0xff0000ff, 0xff0000a0, 0xff800080, 0xff8000ff,
	0xff400000, 0xff804000, 0xff004000, 0xff004040, 0xff000080, 0xff000040, 0xff400040, 0xff400080,
	0xff000000, 0xff808000, 0xff808040, 0xff808080, 0xff408080, 0xffc0c0c0, 0xff400040, 0xffffffff
};

static const int g_iNumCustomColours = 48;
static u_int g_auCustomColours[g_iNumCustomColours] = 
{
	0xffffffff,	0xffffffff,	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
	0xffffffff,	0xffffffff,	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
	0xffffffff,	0xffffffff,	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
	0xffffffff,	0xffffffff,	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
	0xffffffff,	0xffffffff,	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
	0xffffffff,	0xffffffff,	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
};


static Asura_Vector_2 g_xOverlayPosition(30.0f,3.0f);

bool Tools_ColourPicker::s_bCustomColoursLoaded = false;


//For keeping track of the open colour picker. Essentially just needed so that the previous one
//can be closed when a new one is opened.
//It may not actually be open if the user has closed it
static Tools_ColourPicker* g_pxCurrentPicker = 0;


Tools_ColourPicker::Tools_ColourPicker(const char* pszTitle,float* pfRed,float* pfGreen,float* pfBlue, float fMax,bool* pbChangedFlag)
{
	Asura_Assert(pfRed,"");
	Asura_Assert(pfGreen,"");
	Asura_Assert(pfBlue,"");
	Asura_Assert(fMax,"");


	m_xTitle = pszTitle;
	m_pfRed = pfRed;
	m_pfGreen = pfGreen;
	m_pfBlue = pfBlue;
	m_pxSharedRed = 0;
	m_pxSharedGreen = 0;
	m_pxSharedBlue = 0;
	m_fMax = fMax;
	m_pbChangedFlag = pbChangedFlag;
	m_bModal = false;
	m_bHDR = false;

	m_pfAlpha = NULL;
	
	m_iOverlayID = (int) this;
}

Tools_ColourPicker::Tools_ColourPicker(const char* pszTitle,Asura_Dialog_SharedValue<float>* pxSharedRed,Asura_Dialog_SharedValue<float>* pxSharedGreen,Asura_Dialog_SharedValue<float>* pxSharedBlue, float fMax,bool* pbChangedFlag)
{
	Asura_Assert(pxSharedRed,"");
	Asura_Assert(pxSharedGreen,"");
	Asura_Assert(pxSharedBlue,"");
	Asura_Assert(fMax,"");


	m_xTitle = pszTitle;
	m_pfRed = 0;
	m_pfGreen = 0;
	m_pfBlue = 0;
	m_pxSharedRed = pxSharedRed;
	m_pxSharedGreen = pxSharedGreen;
	m_pxSharedBlue = pxSharedBlue;
	m_fMax = fMax;
	m_pbChangedFlag = pbChangedFlag;
	m_bModal = false;
	m_bHDR = false;

	m_pfAlpha = NULL;
	
	m_iOverlayID = (int) this;
}


void Tools_ColourPicker::InitColourValues()
{
	//convert input RGB values to 0 to 255 range
	if(m_pxSharedRed)
		m_pxSharedRed->GetValue(&m_fRed,0);
	else
		m_fRed = *m_pfRed;
	m_fRed = (m_fRed/m_fMax)*255.0f;

	if(m_pxSharedGreen)
		m_pxSharedGreen->GetValue(&m_fGreen,0);
	else
		m_fGreen = *m_pfGreen;
	m_fGreen = (m_fGreen/m_fMax)*255.0f;

	if(m_pxSharedBlue)
		m_pxSharedBlue->GetValue(&m_fBlue,0);
	else
		m_fBlue = *m_pfBlue;
	m_fBlue = (m_fBlue/m_fMax)*255.0f;

	const float fMaxElement = Asura_Maths::Max(m_fRed,Asura_Maths::Max(m_fGreen,m_fBlue));
	if(m_bHDR && fMaxElement>255.0f)
	{
		//rescale the values so they're in the [0,255] range, and remember what the factor was

		m_fHDRScale = fMaxElement/255.0f;

		m_fRed /= m_fHDRScale;
		m_fGreen /= m_fHDRScale;
		m_fBlue /= m_fHDRScale;
	}
	else
	{
		m_fHDRScale = 1.0f;
	}

	m_fRed = Asura_Maths::ClampToRange(m_fRed,0.0f,255.0f);
	m_fGreen = Asura_Maths::ClampToRange(m_fGreen,0.0f,255.0f);
	m_fBlue = Asura_Maths::ClampToRange(m_fBlue,0.0f,255.0f);

	if(!m_bHDR)
	{
		//don't think we want to do this for HDR, we're not constrained by integer values
		m_fRed = (float)Asura_Maths::FloatToInt_Near(m_fRed);
		m_fGreen = (float)Asura_Maths::FloatToInt_Near(m_fGreen);
		m_fBlue = (float)Asura_Maths::FloatToInt_Near(m_fBlue);
	}

	m_xColourPair.Initialise(m_fRed,m_fGreen,m_fBlue);

	m_fInitialRed = m_fRed;
	m_fInitialGreen = m_fGreen;
	m_fInitialBlue = m_fBlue;

	if(m_pfAlpha)
	{
		m_fAlpha = (*m_pfAlpha/m_fMax)*255.0f;
		m_fAlpha = Asura_Maths::ClampToRange(m_fAlpha,0.0f,255.0f);
		m_fAlpha = (float)Asura_Maths::FloatToInt_Near(m_fAlpha);
		m_fInitialAlpha = m_fAlpha;
	}

	m_fInitialHDRScale = m_fHDRScale;
}

Tools_ColourPicker::~Tools_ColourPicker()
{
	CloseOverlay();
}

void Tools_ColourPicker::EnableAlphaEditing(float* pfAlpha)
{
	m_pfAlpha = pfAlpha;
}


void Tools_ColourPicker::AddOverlayControls( Asura_Overlay* pxOverlay, Asura_Vector_2& xOffset )
{
	//add the controls
	Asura_Dialog* pxDialog;

	//hue/saturation rectangle
	pxDialog = new Tools_ColourPicker_HueSat_Dialog(xOffset,&m_xColourPair.m_xHSV.m_fH,&m_xColourPair.m_xHSV.m_fS,&m_xColourPair.m_xHSV.m_fV,&m_bChanged);
	pxDialog->m_iControlID = Asura_GetHashID("HueSat");
	pxDialog->SetHelpText("Click in the rectangle to change the Hue and Saturation.");
	pxOverlay->AddDialog(pxDialog);
	xOffset.x = pxDialog->m_xMaxCoord.x + 1.0f;

	float fHueSatMaxY = pxDialog->m_xMaxCoord.y;

	//luminance strip
	pxDialog = new Tools_ColourPicker_Lum_Dialog(xOffset,&m_xColourPair.m_xHSV.m_fH,&m_xColourPair.m_xHSV.m_fS,&m_xColourPair.m_xHSV.m_fV,&m_bChanged);
	pxDialog->SetHelpText("Click in the rectangle to change the luminance.");
	pxOverlay->AddDialog(pxDialog);
	xOffset.x = pxDialog->m_xMaxCoord.x + 1.0f;

	if(m_pfAlpha)
	{
		//alpha strip
		pxDialog = new Tools_ColourPicker_Alpha_Dialog(xOffset,&m_fRed,&m_fGreen,&m_fBlue,&m_fAlpha,&m_bChanged);
		pxDialog->SetHelpText("Click in the rectangle to change the alpha.");
		pxOverlay->AddDialog(pxDialog);
		xOffset.x = pxDialog->m_xMaxCoord.x + 1.0f;
	}

	//box with preview of colour
	Asura_Vector_2 xSize(5.0f,3.0f);
	pxDialog = new Tools_ColourPicker_Colour_Dialog(xOffset,xSize,&m_fRed,&m_fGreen,&m_fBlue,m_pfAlpha ? &m_fAlpha : 0,255.0f);
	pxDialog->SetHelpText("The colour");
	pxOverlay->AddDialog(pxDialog);
	xOffset.y = pxDialog->m_xMaxCoord.y + 1.0f;

	//eyedrop icons for picking colour from screen
	if( !m_bModal )
	{		
		Asura_Vector_2 xIconOffset;
		xIconOffset.x = pxDialog->m_xMaxCoord.x + 1.0f;
		xIconOffset.y = pxDialog->m_xOffset.y + 1.0f;

		pxDialog = new Tools_ColourPicker_Sampler_Dialog(xIconOffset,1,&m_fRed,&m_fGreen,&m_fBlue,&m_bChanged);
		pxDialog->SetHelpText("Picks colour by clicking on a point on screen.");
		pxOverlay->AddDialog(pxDialog);
		xIconOffset.x += 16.0f/ASURA_TEXT_OUTPUT_FONT_WIDTH; 

		pxDialog = new Tools_ColourPicker_Sampler_Dialog(xIconOffset,3,&m_fRed,&m_fGreen,&m_fBlue,&m_bChanged);
		pxDialog->SetHelpText("Picks colour by clicking on a point on screen.\nColour is taken as the average over a 3x3 area.");
		pxOverlay->AddDialog(pxDialog);
		xIconOffset.x += 16.0f/ASURA_TEXT_OUTPUT_FONT_WIDTH; 

		pxDialog = new Tools_ColourPicker_Sampler_Dialog(xIconOffset,5,&m_fRed,&m_fGreen,&m_fBlue,&m_bChanged);
		pxDialog->SetHelpText("Picks colour by clicking on a point on screen.\nColour is taken as the average over a 5x5 area.");
		pxOverlay->AddDialog(pxDialog);
	}

	//HDR scale. Only shown if the project uses HDR
	#if defined ASURA_USE_HDR
		if( m_bHDR )
		{
			pxDialog = new Asura_Numerical_Dialog("HDR Scale",xOffset,&(m_fHDRScale), 1.0f,100.0f,1.0f,"%.2f",&m_bChanged);
			pxOverlay->AddDialog(pxDialog);
			xOffset.y+=Asura_Dialog::LargeSpacing();
		}
	#endif

	pxDialog = new Asura_Numerical_Dialog("Red",xOffset,&(m_fRed), 0,255.0f,1.0f,"%0.0f",&m_bChanged);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Numerical_Dialog("Green",xOffset,&(m_fGreen), 0,255.0f,1.0f,"%0.0f",&m_bChanged);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Numerical_Dialog("Blue",xOffset,&(m_fBlue), 0,255.0f,1.0f,"%0.0f",&m_bChanged);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::LargeSpacing();

	pxDialog = new Asura_Numerical_Dialog("Hue",xOffset,&(m_xColourPair.m_xHSV.m_fH), 0,100.0f,1.0f,"%0.0f",&m_bChanged);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Numerical_Dialog("Saturation",xOffset,&(m_xColourPair.m_xHSV.m_fS), 0,100.0f,1.0f,"%0.0f",&m_bChanged);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::DefaultSpacing();

	pxDialog = new Asura_Numerical_Dialog("Luminance",xOffset,&(m_xColourPair.m_xHSV.m_fV), 0,100.0f,1.0f,"%0.0f",&m_bChanged);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y+=Asura_Dialog::LargeSpacing();

	if(m_pfAlpha)
	{
		pxDialog = new Asura_Numerical_Dialog("Alpha",xOffset,&(m_fAlpha), 0,255.0f,1.0f,"%0.0f",&m_bChanged);
		pxOverlay->AddDialog(pxDialog);
		xOffset.y+=Asura_Dialog::LargeSpacing();
	}

	xOffset.y = 250.0f/ASURA_TEXT_OUTPUT_FONT_HEIGHT;

	if( !m_bModal )
	{
		pxDialog = new Asura_Function_Dialog("Apply",xOffset,_Apply,(int)this);
		pxDialog->SetHelpText("Apply the changes , leaving this overlay open");
		pxOverlay->AddDialog(pxDialog);

		xOffset.x += 7.0f;

		pxDialog = new Asura_Function_Dialog("Cancel",xOffset,_Cancel,(int)this);
		pxDialog->SetHelpText("Undo any changes made.");
		pxOverlay->AddDialog(pxDialog);
		xOffset.x -= 7.0f;

		xOffset.y+=Asura_Dialog::LargeSpacing();

		pxDialog = new Asura_Function_Dialog("Okay",xOffset,_Okay,(int)this);
		pxDialog->SetHelpText("Apply the changes , and close this overlay");
		pxOverlay->AddDialog(pxDialog);
		xOffset.y+=Asura_Dialog::LargeSpacing();
	}
	else
	{
		xOffset.y+=Asura_Dialog::LargeSpacing();

		pxDialog = new Asura_Function_Dialog("Okay",xOffset,_Okay,(int)this);
		pxDialog->SetHelpText("Apply the changes , and close this overlay");
		pxOverlay->AddDialog(pxDialog);
		
		xOffset.x += 7.0f;

		pxDialog = new Asura_Function_Dialog("Cancel",xOffset,_Cancel,(int)this);
		pxDialog->SetHelpText("Undo any changes made.");
		pxOverlay->AddDialog(pxDialog);	
	}

	//go back to the bottom left and add some preset colours
	xOffset.x = 1.0f;
	xOffset.y = fHueSatMaxY + 1.0f;

	pxDialog = new Asura_Dialog("Preset Cols", xOffset);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	for(int i=0;i<g_iNumFixedColours;i++)
	{
		pxDialog = new Tools_ColourPicker_PresetColour_Dialog(xOffset,this,&g_auFixedColours[i],false);
		pxOverlay->AddDialog(pxDialog);

		
		if((i%8) == 7 && (i+1 != g_iNumFixedColours))
		{
			//move onto next row
			xOffset.y = pxDialog->m_xMaxCoord.y + 0.5f;
			xOffset.x = 1.0f;
		}
		else
		{
			xOffset.x = pxDialog->m_xMaxCoord.x + 0.5f;
		}
	}

	//and another set for custom colours
	if(!s_bCustomColoursLoaded) LoadCustomColours();
	
	xOffset.x += 3.0f;
	xOffset.y = fHueSatMaxY + 1.0f;

	pxDialog = new Asura_Dialog("Custom Cols (Shift-LMB to save)", xOffset);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();

	float fRowStartX = xOffset.x;

	for(int i=0;i<g_iNumCustomColours;i++)
	{
		pxDialog = new Tools_ColourPicker_PresetColour_Dialog(xOffset,this,&g_auCustomColours[i],true);
		pxOverlay->AddDialog(pxDialog);

		if((i%8) == 7)
		{
			//move onto next row
			xOffset.y = pxDialog->m_xMaxCoord.y + 0.5f;
			xOffset.x = fRowStartX;
		}
		else
		{
			xOffset.x = pxDialog->m_xMaxCoord.x + 0.5f;
		}
	}

	m_xOffsetForExtraDialogs.x = 1.0f;
	m_xOffsetForExtraDialogs.y = pxDialog->m_xMaxCoord.y;

	
}

void Tools_ColourPicker::OpenOverlay()
{
	if(IsOverlayOpen()) return;
	
	//If another colour picker is active , close it now
	if(g_pxCurrentPicker) g_pxCurrentPicker->CloseOverlay();

	InitColourValues();
	m_bChanged = false;

	Tools_ColourPicker_Overlay* pxOverlay = new Tools_ColourPicker_Overlay(this,m_xTitle.GetString(),&g_xOverlayPosition);
	pxOverlay->m_uID = m_iOverlayID;

	Asura_Vector_2 xOffset(1.0f,3.0f);

	//add the controls
	AddOverlayControls( pxOverlay, xOffset );

	//and add to the overlay system
	Asura_Overlay_System::SubmitNewOverlay(pxOverlay);
}

bool Tools_ColourPicker::DoModal()
{
	Asura_Assert( m_pbChangedFlag, "Modal colour pickers require a changed flag to function correctly." );

	InitColourValues();
	m_bChanged = false;
	m_bModal   = true;

	Tools_ColourPicker_Overlay* pxOverlay = new Tools_ColourPicker_Overlay(this,m_xTitle.GetString(),&g_xOverlayPosition);
	pxOverlay->m_uID = m_iOverlayID;

	Asura_Vector_2 xOffset(1.0f,3.0f);

	//add the controls
	AddOverlayControls( pxOverlay, xOffset );

	//and add to the overlay system
	Asura_Overlay_System::SubmitNewOverlay(pxOverlay);

	Tools_Modal_Overlay::DoModal( pxOverlay );
	
	return m_pbChangedFlag ? *m_pbChangedFlag : false;
}

void Tools_ColourPicker::CloseOverlay()
{
	Asura_Overlay_System::CloseOverlays(m_iOverlayID);

	if(this == g_pxCurrentPicker)
	{
		g_pxCurrentPicker = 0;
	}
}

bool Tools_ColourPicker::IsOverlayOpen() const
{
	return Asura_Overlay_System::DoesOverlayExist(m_iOverlayID);
}

void Tools_ColourPicker::AddDialog(class Asura_Dialog* pxDialog)
{
	Asura_Overlay* pxOverlay = Asura_Overlay_System::GetOverlay(m_iOverlayID);
	if(!pxOverlay)
	{
		Asura_Assert(0,"Colour picker not open.");//will cause memory leak
		return;
	}

	
	//Move to the correct position
	Asura_Vector_2 xOffset = pxDialog->m_xOffset;
	xOffset.x += m_xOffsetForExtraDialogs.x;
	xOffset.y += m_xOffsetForExtraDialogs.y;

	pxDialog->MoveDialog(xOffset);

	//Add the control to the overlay
	pxOverlay->AddDialog(pxDialog);
	pxOverlay->ResizeOverlay();
	
}

void Tools_ColourPicker::SetColour(float fRed, float fGreen, float fBlue)
{
	fRed *= 255.f;
	fGreen *= 255.f;
	fBlue *= 255.f;
	m_xColourPair.Update(fRed, fGreen, fBlue);
	m_fRed = fRed;
	m_fGreen = fGreen;
	m_fBlue = fBlue;
}

void Tools_ColourPicker::SetColour(u_int uARGB, bool bFlagAsChanged)
{
	if(m_pfAlpha)
	{
		m_fAlpha = (float)((uARGB >> 24) & 0xff);
	}
	m_fRed = (float)((uARGB >> 16) & 0xff);
	m_fGreen = (float)((uARGB >> 8) & 0xff);
	m_fBlue = (float)((uARGB >> 0) & 0xff);

	// If storing in int, can't use HDR values
	m_fHDRScale = 1.0f;

	m_xColourPair.Update(m_fRed, m_fGreen, m_fBlue);

	if(bFlagAsChanged) m_bChanged = true;
	
}

void Tools_ColourPicker::Update()
{
	m_xColourPair.Update(m_fRed,m_fGreen,m_fBlue);
}

void Tools_ColourPicker::Apply()
{
	if(m_pxSharedRed)
		m_pxSharedRed->SetValue((m_fRed/255.0f)*m_fMax*m_fHDRScale);
	else
		*m_pfRed = (m_fRed/255.0f)*m_fMax*m_fHDRScale;

	if(m_pxSharedGreen)
		m_pxSharedGreen->SetValue((m_fGreen/255.0f)*m_fMax*m_fHDRScale);
	else
		*m_pfGreen = (m_fGreen/255.0f)*m_fMax*m_fHDRScale;

	if(m_pxSharedBlue)
		m_pxSharedBlue->SetValue((m_fBlue/255.0f)*m_fMax*m_fHDRScale);
	else
		*m_pfBlue = (m_fBlue/255.0f)*m_fMax*m_fHDRScale;

	if(m_pfAlpha) *m_pfAlpha = (m_fAlpha/255.0f)*m_fMax*m_fHDRScale;
	
	if(m_pbChangedFlag) *m_pbChangedFlag = true;
	m_bChanged = false;
}

void Tools_ColourPicker::Okay()
{
	if(m_bChanged) Apply();
	CloseOverlay();
}

void Tools_ColourPicker::Cancel()
{
	if(m_fRed != m_fInitialRed ||
	   m_fGreen != m_fInitialGreen ||
	   m_fBlue != m_fInitialBlue ||
	   (m_pfAlpha  && m_fAlpha != m_fInitialAlpha))
	{
		m_fRed = m_fInitialRed;
		m_fGreen = m_fInitialGreen;
		m_fBlue = m_fInitialBlue;
		m_fAlpha = m_fInitialAlpha;

		Apply();
	}

	if( m_bModal )
	{
		CloseOverlay();
	}
}

void Tools_ColourPicker::SaveCustomColours()
{
	TransferModeData(TOOLSMODEDATAFILE_SAVE);
}

void Tools_ColourPicker::LoadCustomColours()
{
	TransferModeData(TOOLSMODEDATAFILE_LOAD);
	s_bCustomColoursLoaded = true;
}

void Tools_ColourPicker::TransferModeData(int iMode)
{
	//open the file
	Tools_ModeDataFile xFile("ColourPicker.dat",iMode,0);

	//transfer the data
	//(none of these should be removed , and new data should go on the end, otherwise
	//the files will get screwed up)
	for(int i=0;i<g_iNumCustomColours;i++)
	{
		xFile.Transfer(g_auCustomColours[i]);
	}
}




///////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------**
** Tools_ColourPicker_Overlay **
**----------------------------*/

Tools_ColourPicker_Overlay::Tools_ColourPicker_Overlay(Tools_ColourPicker* pxPicker,const char* pszTitle,class Asura_Vector_2* pxPosition)
:Asura_Overlay(pszTitle ? pszTitle : "Colour Picker",false,pxPosition)
{
	m_pxPicker = pxPicker;
}

void Tools_ColourPicker_Overlay::PerFrameUpdate()
{
	Asura_Overlay::PerFrameUpdate();

	m_pxPicker->Update();
}

///////////////////////////////////////////////////////////////////////////////////////////////
/*---------------------------**
** Tools_ColourPicker_Dialog **
**---------------------------*/
Tools_ColourPicker_Dialog::Tools_ColourPicker_Dialog(const char* pszTitle,Asura_Vector_2 xOffset,Asura_Vector_2 xSize,float* pfRed,float* pfGreen,float* pfBlue, float fMax,bool* pbChangedFlag)
:Asura_Dialog(0,xOffset)
{
	m_pxPicker = new Tools_ColourPicker(pszTitle,pfRed,pfGreen,pfBlue,fMax,pbChangedFlag);

	Tools_ColourPicker_Colour_Gadget* pxGadget;
	pxGadget  = new Tools_ColourPicker_Colour_Gadget(xOffset,xSize,pfRed,pfGreen,pfBlue,0,fMax);
	pxGadget->SetClickedFunction(OnClicked,(int)this);
	AddGadget(pxGadget);
		
	m_xMaxCoord.x = m_xOffset.x + pxGadget->m_fWidth;
	m_xMaxCoord.y = m_xOffset.y + pxGadget->m_fHeight;
}

Tools_ColourPicker_Dialog::Tools_ColourPicker_Dialog(const char* pszTitle,Asura_Vector_2 xOffset,Asura_Vector_2 xSize,Asura_Dialog_SharedValue<float>* pxSharedRed,Asura_Dialog_SharedValue<float>* pxSharedGreen,Asura_Dialog_SharedValue<float>* pxSharedBlue, float fMax,bool* pbChangedFlag)
:Asura_Dialog(0,xOffset)
{
	m_pxPicker = new Tools_ColourPicker(pszTitle,pxSharedRed,pxSharedGreen,pxSharedBlue,fMax,pbChangedFlag);

	Tools_ColourPicker_Colour_Gadget* pxGadget;
	pxGadget  = new Tools_ColourPicker_Colour_Gadget(xOffset,xSize,pxSharedRed,pxSharedGreen,pxSharedBlue,0,fMax);
	pxGadget->SetClickedFunction(OnClicked,(int)this);
	AddGadget(pxGadget);
		
	m_xMaxCoord.x = m_xOffset.x + pxGadget->m_fWidth;
	m_xMaxCoord.y = m_xOffset.y + pxGadget->m_fHeight;
}


Tools_ColourPicker_Dialog::~Tools_ColourPicker_Dialog()
{
	delete m_pxPicker;
}

void Tools_ColourPicker_Dialog::OnClicked(int iThis)
{
	if(Asura_Overlay_System::AreAnyOverlaysAlwaysOnTop())
	{
		//If showing a modal overlay , then open up the colour picker as a modal overlay, otherwise
		//it won't be usable.
		//RAR 18/12/2008
		((Tools_ColourPicker_Dialog*)iThis)->m_pxPicker->DoModal();
	}
	else
	{
		((Tools_ColourPicker_Dialog*)iThis)->m_pxPicker->OpenOverlay();
	}
}

void Tools_ColourPicker_Dialog::EnableAlphaEditing(float* pfAlpha)
{
	m_pxPicker->EnableAlphaEditing(pfAlpha);
}

///////////////////////////////////////////////////////////////////////////////////////////////
/*-------------------------------**
** Tools_ARGBColourPicker_Dialog **
**-------------------------------*/
Tools_ARGBColourPicker_Dialog::Tools_ARGBColourPicker_Dialog(const char* pszTitle,Asura_Vector_2 xOffset,Asura_Vector_2 xSize,u_int* puARGB,bool* pbChangedFlag,bool bAddLabel)
:Asura_Dialog(0,xOffset)
,m_xTextOffset(0.0f,0.0f)
{
	m_puARGB = puARGB;
	m_fRed = (float)((*m_puARGB >> 16) & 0xff);
	m_fGreen = (float)((*m_puARGB >> 8) & 0xff);
	m_fBlue = (float)((*m_puARGB >> 0) & 0xff);
	m_fAlpha = 255.0f;

	m_bChanged = false;
	m_pbChanged = pbChangedFlag;

	m_bEditAlpha = false;
	m_bModal = false;

	m_pxPicker = new Tools_ColourPicker(pszTitle,&m_fRed,&m_fGreen,&m_fBlue,255.0f,&m_bChanged);

	Tools_ColourPicker_Colour_Gadget* pxGadget;
	pxGadget  = new Tools_ColourPicker_Colour_Gadget(xOffset,xSize,&m_fRed,&m_fGreen,&m_fBlue,&m_fAlpha,255.0f);
	pxGadget->SetClickedFunction(OnClicked,(int)this);
	AddGadget(pxGadget);
		
	m_xMaxCoord.x = m_xOffset.x + pxGadget->m_fWidth;
	m_xMaxCoord.y = m_xOffset.y + pxGadget->m_fHeight;

	if(bAddLabel)
	{
		SetName(pszTitle);
		m_xTextOffset.x = m_xMaxCoord.x + 0.5f;
		m_xMaxCoord.x = m_xTextOffset.x + Asura_Text_Output::WidthOfString( m_xName.GetString(),ASURA_TEXT_FORMAT_SMALLFONT );

		//extend the width of the gadget to allow clicking on the label
		pxGadget->m_fWidth = m_xMaxCoord.x - m_xOffset.x;
	}
}

Tools_ARGBColourPicker_Dialog::~Tools_ARGBColourPicker_Dialog()
{
	delete m_pxPicker;
}

void Tools_ARGBColourPicker_Dialog::EnableAlphaEditing(bool bEnable)
{
	m_bEditAlpha = bEnable;
	if(m_bEditAlpha)
	{
		m_fAlpha = (float)((*m_puARGB >> 24) & 0xff);
		m_pxPicker->EnableAlphaEditing(&m_fAlpha);
	}
	else
	{
		m_fAlpha = 255.0f;
		m_pxPicker->EnableAlphaEditing(0);
	}
}

void Tools_ARGBColourPicker_Dialog::PerFrameUpdate()
{
	Asura_Dialog::PerFrameUpdate();
	if(m_bChanged)
	{
		//update the colour values in the u_int
		u_int uR = (u_int)Asura_Maths::FloatToInt_Near(m_fRed);
		u_int uG = (u_int)Asura_Maths::FloatToInt_Near(m_fGreen);
		u_int uB = (u_int)Asura_Maths::FloatToInt_Near(m_fBlue);
		u_int uA = (*m_puARGB>>24) & 0xff;
		if(m_bEditAlpha)
		{
			uA = (u_int)Asura_Maths::FloatToInt_Near(m_fAlpha);
		}
		
		*m_puARGB = (uA<<24)|(uR<<16)|(uG<<8)|uB;
		
		if(m_pbChanged) * m_pbChanged = true;
		m_bChanged = false;
	}
	else
	{
		//make sure the float colour values are up to date
		m_fRed = (float)((*m_puARGB >> 16) & 0xff);
		m_fGreen = (float)((*m_puARGB >> 8) & 0xff);
		m_fBlue = (float)((*m_puARGB >> 0) & 0xff);
		if(m_bEditAlpha)
		{
			m_fAlpha = (float)((*m_puARGB >> 24) & 0xff);
		}
	}
}

void Tools_ARGBColourPicker_Dialog::OnClicked(int iThis)
{
	Tools_ARGBColourPicker_Dialog* pxThis = ((Tools_ARGBColourPicker_Dialog*)iThis);
	if(pxThis->m_bModal)
	{
		pxThis->m_pxPicker->DoModal();
	}
	else
	{
		pxThis->m_pxPicker->OpenOverlay();
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------**
** Tools_ColourPicker_HueSat_Dialog **
**----------------------------------*/

Tools_ColourPicker_HueSat_Dialog::Tools_ColourPicker_HueSat_Dialog(Asura_Vector_2 xOffset,float* pfHue,float* pfSat,const float* pfLum,bool* pbChanged)
:Asura_Dialog(0,xOffset)
{
	Asura_Gadget* pxGadget = new Tools_ColourPicker_HueSat_Gadget(xOffset,pfHue,pfSat,pfLum,pbChanged);
	AddGadget(pxGadget);
		
	m_xMaxCoord.x = m_xOffset.x + pxGadget->m_fWidth;
	m_xMaxCoord.y = m_xOffset.y + pxGadget->m_fHeight;
}

///////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------**
** Tools_ColourPicker_HueSat_Gadget **
**----------------------------------*/

Tools_ColourPicker_HueSat_Gadget::Tools_ColourPicker_HueSat_Gadget(Asura_Vector_2 xOffset,float* pfHue,float* pfSat,const float* pfLum,bool* pbChanged)
{
	m_xOffset = xOffset;
	m_pfHue = pfHue;
	m_pfSat = pfSat;
	m_pfLum = pfLum;
	m_pbChanged = pbChanged;

	//Texture is 256x256 and add 2 for a one pixel border
	m_fWidth = 258.0f / ASURA_TEXT_OUTPUT_FONT_WIDTH;
	m_fHeight = 258.0f / ASURA_TEXT_OUTPUT_FONT_HEIGHT;
}

void Tools_ColourPicker_HueSat_Gadget::Render( const Asura_Vector_2& xOrigin )
{

	//get top left in screen coords
	float fX = (float)Asura_Maths::FloatToInt_Near((xOrigin.x + m_xOffset.x) * ASURA_TEXT_OUTPUT_FONT_WIDTH);
	float fY = (float)Asura_Maths::FloatToInt_Near((xOrigin.y + m_xOffset.y) * ASURA_TEXT_OUTPUT_FONT_HEIGHT);

	//draw outline for square
	u_int uColour = Asura_OverlayBrightness|0xffffff;
	Asura_Render::Render2DLine(fX,fY,fX+258.0f,fY,uColour);
	Asura_Render::Render2DLine(fX+258.0f,fY,fX+258.0f,fY+258.0f,uColour);
	Asura_Render::Render2DLine(fX+258.0f,fY+258.0f,fX,fY+258.0f,uColour);
	Asura_Render::Render2DLine(fX,fY+258.0f,fX,fY,uColour);

	//draw the texture
	static int s_iTextureIndex = ASURA_TEXTURE_NONE;
	if(s_iTextureIndex == ASURA_TEXTURE_NONE)
	{
		s_iTextureIndex = Asura_Texture_Management::AddTexture("\\Tools\\ColourPicker.dds");
		Asura_Texture_Management::LoadTextures();
	}

	u_int uBright = Asura_Maths::FloatToInt_Near((*m_pfLum/100.0f)*255.0f);
	
	Asura_Render::Overlay.Colour = Asura_OverlayBrightness|(uBright<<16)|(uBright<<8)|uBright;
	Asura_Render::Overlay.TextureIndex = s_iTextureIndex;
	Asura_Render::Overlay.TranslucencyMode = ASURA_TRANSLUCENCY_NORMAL;

	
	Asura_Render::Overlay.SetRectUV(0.0f,0.0f,1.0f,1.0f);
	Asura_Render::Overlay.SetRectXY(fX+1.0f,fY+1.0f,257.0f,257.0f);

	Asura_Render::Overlay.Render();
	Asura_Render::FlushDisplay();

	//Draw a cross to represent the current hue/saturation
	float fCurX = fX + 1.0f + Asura_Maths::FloatToInt_Near((*m_pfHue/100.0f)*255.0f);
	float fCurY = fY + 1.0f + Asura_Maths::FloatToInt_Near(((100.0f-*m_pfSat)/100.0f)*255.0f);

	
	float fBright = Asura_Maths::Sine( Asura_Timers::GetLocalUnscaledTime() * 2.0f );
	uBright = Asura_Maths::FloatToInt(255.0f*fBright*fBright);
	uColour = Asura_OverlayBrightness|(uBright<<16)|(uBright<<8)|uBright;
	Asura_Render::Render2DLine(fCurX-3.0f,fCurY-3.0f,fCurX+4.0f,fCurY+4.0f,uColour);
	Asura_Render::Render2DLine(fCurX+3.0f,fCurY-3.0f,fCurX-4.0f,fCurY+4.0f,uColour);

    Asura_Gadget::Render( xOrigin );
}

void Tools_ColourPicker_HueSat_Gadget::Update( const Asura_Vector_2& xOrigin )
{
	if( m_bIsMouseOver && m_bIsClickable && Asura_UserInput::DebouncedKeyPressed(ASURA_KEYID_MOUSEBUTTON1) )
	{
 		Asura_Overlay_System::TakeFocus(this,OverlayFocusType_Mouse);
        m_bClickedThisFrame = true;
	}
		
 	if (Asura_UserInput::KeyPressed(ASURA_KEYID_MOUSEBUTTON1))
 	{
 		if(m_iFocusFlags)
 		{
			//move the Hue/Sat to the position clicked on
			float fX,fY;
			Asura_Cursor::GetScreenCoords(fX,fY);
			
			//get coord relative to top left of box
			fX-=(xOrigin.x + m_xOffset.x);
			fY-=(xOrigin.y + m_xOffset.y);
			
			fX *= ASURA_TEXT_OUTPUT_FONT_WIDTH;
			fY *= ASURA_TEXT_OUTPUT_FONT_HEIGHT;
			
			fX-=1.0f;//subtract an extra 1 to get past the border
			fY-=1.0f;
			

			*m_pfHue = (fX/255.0f)*100.0f;
			*m_pfSat = 100.0f-((fY/255.0f)*100.0f);

			*m_pfHue = Asura_Maths::ClampToRange(*m_pfHue,0.0f,100.0f);
			*m_pfSat = Asura_Maths::ClampToRange(*m_pfSat,0.0f,100.0f);
			
			if(m_pbChanged) *m_pbChanged = true;
		}
	}
	else if(m_iFocusFlags)
	{
		Asura_Overlay_System::ReleaseFocus(OverlayFocusType_Mouse);
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////
/*-------------------------------**
** Tools_ColourPicker_Lum_Dialog **
**-------------------------------*/

Tools_ColourPicker_Lum_Dialog::Tools_ColourPicker_Lum_Dialog(Asura_Vector_2 xOffset,const float* pfHue,const float* pfSat,float* pfLum,bool* pbChanged)
:Asura_Dialog(0,xOffset)
{
	Asura_Gadget* pxGadget = new Tools_ColourPicker_Lum_Gadget(xOffset,pfHue,pfSat,pfLum,pbChanged);
	AddGadget(pxGadget);
		
	m_xMaxCoord.x = m_xOffset.x + pxGadget->m_fWidth;
	m_xMaxCoord.y = m_xOffset.y + pxGadget->m_fHeight;
}

///////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------**
** Tools_ColourPicker_Lum_Gadget **
**----------------------------------*/

#define TOOLS_LUMSTRIP_WIDTH 50.0f
#define TOOLS_LUMSTRIP_HEIGHT 256.0f


Tools_ColourPicker_Lum_Gadget::Tools_ColourPicker_Lum_Gadget(Asura_Vector_2 xOffset,const float* pfHue,const float* pfSat,float* pfLum,bool* pbChanged)
{
	m_xOffset = xOffset;
	m_pfHue = pfHue;
	m_pfSat = pfSat;
	m_pfLum = pfLum;
	m_pbChanged = pbChanged;

	m_fWidth = (TOOLS_LUMSTRIP_WIDTH+2.0f)  / ASURA_TEXT_OUTPUT_FONT_WIDTH;
	m_fHeight = (TOOLS_LUMSTRIP_HEIGHT+2.0f) / ASURA_TEXT_OUTPUT_FONT_HEIGHT;
}

void Tools_ColourPicker_Lum_Gadget::Render( const Asura_Vector_2& xOrigin )
{

	//get top left in screen coords
	float fX = (float)Asura_Maths::FloatToInt_Near((xOrigin.x + m_xOffset.x) * ASURA_TEXT_OUTPUT_FONT_WIDTH);
	float fY = (float)Asura_Maths::FloatToInt_Near((xOrigin.y + m_xOffset.y) * ASURA_TEXT_OUTPUT_FONT_HEIGHT);

	//draw outline for rectangle
	u_int uColour = Asura_OverlayBrightness|0xffffff;
	Asura_Render::Render2DLine(fX,fY,fX+TOOLS_LUMSTRIP_WIDTH + 2.0f,fY,uColour);
	Asura_Render::Render2DLine(fX + TOOLS_LUMSTRIP_WIDTH + 2.0f,fY,fX + TOOLS_LUMSTRIP_WIDTH + 2.0f,fY + TOOLS_LUMSTRIP_HEIGHT + 2.0f,uColour);
	Asura_Render::Render2DLine(fX + TOOLS_LUMSTRIP_WIDTH + 2.0f,fY + TOOLS_LUMSTRIP_HEIGHT + 2.0f,fX,fY + TOOLS_LUMSTRIP_HEIGHT + 2.0f,uColour);
	Asura_Render::Render2DLine(fX,fY + TOOLS_LUMSTRIP_HEIGHT + 2.0f,fX,fY,uColour);

	//draw a goauraud coloured polygon for the brightness strip
	
	//determine the maximum brightness
	Tools_Colour_HSV xHSV;
	Tools_Colour_RGB xRGB;

	xHSV.m_fH = *m_pfHue; 
	xHSV.m_fS = *m_pfSat;
	xHSV.m_fV = 100.0f;

	xHSV.ToRGB(xRGB);


	uColour = xRGB.GetAsUint()|Asura_OverlayBrightness;

	Asura_Render::Overlay.TextureIndex = ASURA_TEXTURE_NONE;
	Asura_Render::Overlay.TranslucencyMode = ASURA_TRANSLUCENCY_NORMAL;

	Asura_Render::Overlay.SetRectXY(fX+1.0f,fY+1.0f,TOOLS_LUMSTRIP_WIDTH+1.0f,TOOLS_LUMSTRIP_HEIGHT+1.0f);
	Asura_Render::Overlay.SetGouraudColour(uColour,uColour,Asura_OverlayBrightness,Asura_OverlayBrightness);

	Asura_Render::Overlay.Render();
	Asura_Render::FlushDisplay();

	//Draw a line to represent the current luminance
	float fCurY = fY + 1.0f + Asura_Maths::FloatToInt_Near(((100.0f-*m_pfLum)/100.0f)*(TOOLS_LUMSTRIP_HEIGHT-1.0f));

	
	float fBright = Asura_Maths::Sine( Asura_Timers::GetLocalUnscaledTime() * 2.0f );
	u_int uBright = Asura_Maths::FloatToInt(255.0f*fBright*fBright);
	uColour = Asura_OverlayBrightness|(uBright<<16)|(uBright<<8)|uBright;
	Asura_Render::Render2DLine(fX+4.0f,fCurY,fX+TOOLS_LUMSTRIP_WIDTH-1.0f,fCurY,uColour);

	Asura_Render::Render2DLine(fX+1.0f,fCurY+3.0f,fX+5.0f,fCurY-1.0f,uColour);
	Asura_Render::Render2DLine(fX+1.0f,fCurY-3.0f,fX+5.0f,fCurY+1.0f,uColour);
	Asura_Render::Render2DLine(fX+TOOLS_LUMSTRIP_WIDTH+1.0f,fCurY+3.0f,fX+TOOLS_LUMSTRIP_WIDTH-3.0f,fCurY-1.0f,uColour);
	Asura_Render::Render2DLine(fX+TOOLS_LUMSTRIP_WIDTH+1.0f,fCurY-3.0f,fX+TOOLS_LUMSTRIP_WIDTH-3.0f,fCurY+1.0f,uColour);

    Asura_Gadget::Render( xOrigin );
}

void Tools_ColourPicker_Lum_Gadget::Update( const Asura_Vector_2& xOrigin )
{
	if( m_bIsMouseOver && m_bIsClickable && Asura_UserInput::DebouncedKeyPressed(ASURA_KEYID_MOUSEBUTTON1) )
	{
 		Asura_Overlay_System::TakeFocus(this,OverlayFocusType_Mouse);
        m_bClickedThisFrame = true;
	}
		
 	if (Asura_UserInput::KeyPressed(ASURA_KEYID_MOUSEBUTTON1))
 	{
 		if(m_iFocusFlags)
 		{
			//move the Lum to the position clicked on
			float fX,fY;
			Asura_Cursor::GetScreenCoords(fX,fY);
			
			//get coord relative to top of the strip
			fY-=(xOrigin.y + m_xOffset.y);
			fY *= ASURA_TEXT_OUTPUT_FONT_HEIGHT;
			fY-=1.0f;//subtract an extra 1 to get past the border
			

			*m_pfLum = 100.0f-((fY/255.0f)*100.0f);
			*m_pfLum = Asura_Maths::ClampToRange(*m_pfLum,0.0f,100.0f);
			
			if(m_pbChanged) *m_pbChanged = true;
		}
	}
	else if(m_iFocusFlags)
	{
		Asura_Overlay_System::ReleaseFocus(OverlayFocusType_Mouse);
	}
}
///////////////////////////////////////////////////////////////////////////////////////////////
/*---------------------------------**
** Tools_ColourPicker_Alpha_Dialog **
**---------------------------------*/

Tools_ColourPicker_Alpha_Dialog::Tools_ColourPicker_Alpha_Dialog(Asura_Vector_2 xOffset,const float* pfRed,const float* pfGreen,const float* pfBlue,float* pfAlpha,bool* pbChanged)
:Asura_Dialog(0,xOffset)
{
	Asura_Gadget* pxGadget = new Tools_ColourPicker_Alpha_Gadget(xOffset,pfRed,pfGreen,pfBlue,pfAlpha,pbChanged);
	AddGadget(pxGadget);
		
	m_xMaxCoord.x = m_xOffset.x + pxGadget->m_fWidth;
	m_xMaxCoord.y = m_xOffset.y + pxGadget->m_fHeight;
}

///////////////////////////////////////////////////////////////////////////////////////////////
/*---------------------------------**
** Tools_ColourPicker_Alpha_Gadget **
**--------------------------------*/

#define TOOLS_ALPHASTRIP_WIDTH 48.0f
#define TOOLS_ALPHASTRIP_HEIGHT 256.0f


Tools_ColourPicker_Alpha_Gadget::Tools_ColourPicker_Alpha_Gadget(Asura_Vector_2 xOffset,const float* pfRed,const float* pfGreen,const float* pfBlue,float* pfAlpha,bool* pbChanged)
{
	m_xOffset = xOffset;
	m_pfRed = pfRed;
	m_pfGreen = pfGreen;
	m_pfBlue = pfBlue;
	m_pfAlpha = pfAlpha;
	m_pbChanged = pbChanged;

	m_fWidth = (TOOLS_ALPHASTRIP_WIDTH+2.0f)  / ASURA_TEXT_OUTPUT_FONT_WIDTH;
	m_fHeight = (TOOLS_ALPHASTRIP_HEIGHT+2.0f) / ASURA_TEXT_OUTPUT_FONT_HEIGHT;
}

void Tools_ColourPicker_Alpha_Gadget::Render( const Asura_Vector_2& xOrigin )
{

	//get top left in screen coords
	float fX = (float)Asura_Maths::FloatToInt_Near((xOrigin.x + m_xOffset.x) * ASURA_TEXT_OUTPUT_FONT_WIDTH);
	float fY = (float)Asura_Maths::FloatToInt_Near((xOrigin.y + m_xOffset.y) * ASURA_TEXT_OUTPUT_FONT_HEIGHT);

	//draw outline for rectangle
	u_int uColour = Asura_OverlayBrightness|0xffffff;
	Asura_Render::Render2DLine(fX,fY,fX+TOOLS_ALPHASTRIP_WIDTH+2.0f,fY,uColour);
	Asura_Render::Render2DLine(fX+TOOLS_ALPHASTRIP_WIDTH+2.0f,fY,fX+TOOLS_ALPHASTRIP_WIDTH+2.0f,fY+TOOLS_ALPHASTRIP_HEIGHT+2.0f,uColour);
	Asura_Render::Render2DLine(fX+TOOLS_ALPHASTRIP_WIDTH+2.0f,fY+TOOLS_ALPHASTRIP_HEIGHT+2.0f,fX,fY+TOOLS_ALPHASTRIP_HEIGHT+2.0f,uColour);
	Asura_Render::Render2DLine(fX,fY+TOOLS_ALPHASTRIP_HEIGHT+2.0f,fX,fY,uColour);

	//draw checked background
	const float fCheckSize = 8.0f;
	for(u_int uX=0;uX<(TOOLS_ALPHASTRIP_WIDTH/fCheckSize);uX++)
	{
		for(u_int uY=0;uY<(TOOLS_ALPHASTRIP_HEIGHT/fCheckSize);uY++)
		{
			Asura_Render::Overlay.TranslucencyMode = ASURA_TRANSLUCENCY_NORMAL;
			Asura_Render::Overlay.Colour = ((uX + uY) % 2) ? 0x00ffffff : 0x00CCCCCC;
			Asura_Render::Overlay.Colour |= Asura_OverlayBrightness;
			Asura_Render::Overlay.SetRectXY(fX+ 1.0f + uX * fCheckSize, fY + 1.0f + uY * fCheckSize, fCheckSize+1.0f, fCheckSize+1.0f);
			Asura_Render::Overlay.Render();
		}
	}
	Asura_Render::FlushDisplay();


	//draw alphaed colour over the top

	uColour = (((u_int)*m_pfRed)<<16) | (((u_int)*m_pfGreen)<<8) | (((u_int)*m_pfBlue));
	

	Asura_Render::Overlay.TextureIndex = ASURA_TEXTURE_NONE;
	Asura_Render::Overlay.TranslucencyMode = ASURA_TRANSLUCENCY_NORMAL;

	Asura_Render::Overlay.SetRectXY(fX+1.0f,fY+1.0f,TOOLS_ALPHASTRIP_WIDTH+1.0f,TOOLS_ALPHASTRIP_HEIGHT+1.0f);
	Asura_Render::Overlay.SetGouraudColour(uColour|0xff000000,uColour|0xff000000,uColour,uColour);

	Asura_Render::Overlay.Render();
	Asura_Render::FlushDisplay();

	//Draw a line to represent the current alpha
	float fCurY = fY + 1.0f + Asura_Maths::FloatToInt_Near(((255.0f-*m_pfAlpha)/255.0f)*(TOOLS_ALPHASTRIP_HEIGHT-1.0f));

	
	float fBright = Asura_Maths::Sine( Asura_Timers::GetLocalUnscaledTime() * 2.0f );
	u_int uBright = Asura_Maths::FloatToInt(255.0f*fBright*fBright);
	uColour = Asura_OverlayBrightness|(uBright<<16)|(uBright<<8)|uBright;
	Asura_Render::Render2DLine(fX+4.0f,fCurY,fX+TOOLS_ALPHASTRIP_WIDTH-1.0f,fCurY,uColour);

	Asura_Render::Render2DLine(fX+1.0f,fCurY+3.0f,fX+5.0f,fCurY-1.0f,uColour);
	Asura_Render::Render2DLine(fX+1.0f,fCurY-3.0f,fX+5.0f,fCurY+1.0f,uColour);
	Asura_Render::Render2DLine(fX+TOOLS_ALPHASTRIP_WIDTH+1.0f,fCurY+3.0f,fX+TOOLS_ALPHASTRIP_WIDTH-3.0f,fCurY-1.0f,uColour);
	Asura_Render::Render2DLine(fX+TOOLS_ALPHASTRIP_WIDTH+1.0f,fCurY-3.0f,fX+TOOLS_ALPHASTRIP_WIDTH-3.0f,fCurY+1.0f,uColour);

    Asura_Gadget::Render( xOrigin );
}

void Tools_ColourPicker_Alpha_Gadget::Update( const Asura_Vector_2& xOrigin )
{
	if( m_bIsMouseOver && m_bIsClickable && Asura_UserInput::DebouncedKeyPressed(ASURA_KEYID_MOUSEBUTTON1) )
	{
 		Asura_Overlay_System::TakeFocus(this,OverlayFocusType_Mouse);
        m_bClickedThisFrame = true;
	}
		
 	if (Asura_UserInput::KeyPressed(ASURA_KEYID_MOUSEBUTTON1))
 	{
 		if(m_iFocusFlags)
 		{
			//move the Alpha to the position clicked on
			float fX,fY;
			Asura_Cursor::GetScreenCoords(fX,fY);
			
			//get coord relative to top of the strip
			fY-=(xOrigin.y + m_xOffset.y);
			fY *= ASURA_TEXT_OUTPUT_FONT_HEIGHT;
			fY-=1.0f;//subtract an extra 1 to get past the border
			

			*m_pfAlpha = 255.0f-((fY/255.0f)*255.0f);
			*m_pfAlpha = Asura_Maths::ClampToRange(*m_pfAlpha,0.0f,255.0f);
			
			if(m_pbChanged) *m_pbChanged = true;
		}
	}
	else if(m_iFocusFlags)
	{
		Asura_Overlay_System::ReleaseFocus(OverlayFocusType_Mouse);
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------**
** Tools_ColourPicker_Colour_Dialog **
**----------------------------------*/

Tools_ColourPicker_Colour_Dialog::Tools_ColourPicker_Colour_Dialog(Asura_Vector_2 xOffset,Asura_Vector_2 xSize,const float* pfRed,const float* pfGreen,const float* pfBlue,float fMax)
:Asura_Dialog(0,xOffset)
{
	Asura_Gadget* pxGadget = new Tools_ColourPicker_Colour_Gadget(xOffset,xSize,pfRed,pfGreen,pfBlue,0,fMax);
	AddGadget(pxGadget);
		
	m_xMaxCoord.x = m_xOffset.x + pxGadget->m_fWidth;
	m_xMaxCoord.y = m_xOffset.y + pxGadget->m_fHeight;
}

Tools_ColourPicker_Colour_Dialog::Tools_ColourPicker_Colour_Dialog(Asura_Vector_2 xOffset,Asura_Vector_2 xSize,const float* pfRed,const float* pfGreen,const float* pfBlue,const float* pfAlpha,float fMax)
:Asura_Dialog(0,xOffset)
{
	Asura_Gadget* pxGadget = new Tools_ColourPicker_Colour_Gadget(xOffset,xSize,pfRed,pfGreen,pfBlue,pfAlpha,fMax);
	AddGadget(pxGadget);
		
	m_xMaxCoord.x = m_xOffset.x + pxGadget->m_fWidth;
	m_xMaxCoord.y = m_xOffset.y + pxGadget->m_fHeight;
}



///////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------**
** Tools_ColourPicker_Colour_Gadget **
**----------------------------------*/

Tools_ColourPicker_Colour_Gadget::Tools_ColourPicker_Colour_Gadget(Asura_Vector_2 xOffset,Asura_Vector_2 xSize,const float* pfRed,const float* pfGreen,const float* pfBlue,const float* pfAlpha,float fMax)
:m_xSize(xSize)
{
	m_xOffset = xOffset;
	m_fWidth = xSize.x;
	m_fHeight = xSize.y;

	m_pfRed = pfRed;
	m_pfGreen = pfGreen;
	m_pfBlue = pfBlue;
	m_pfAlpha = pfAlpha;
	m_bSharedValues = false;
	m_fMax = fMax;

	m_pfnIntFunction = 0;
	m_iUserData = 0;
}

Tools_ColourPicker_Colour_Gadget::Tools_ColourPicker_Colour_Gadget(Asura_Vector_2 xOffset,Asura_Vector_2 xSize,const Asura_Dialog_SharedValue<float>* pxSharedRed,const Asura_Dialog_SharedValue<float>* pxSharedGreen,const Asura_Dialog_SharedValue<float>* pxSharedBlue,const Asura_Dialog_SharedValue<float>* pxSharedAlpha,float fMax)
:m_xSize(xSize)
{
	m_xOffset = xOffset;
	m_fWidth = xSize.x;
	m_fHeight = xSize.y;

	m_pxSharedRed = pxSharedRed;
	m_pxSharedGreen = pxSharedGreen;
	m_pxSharedBlue = pxSharedBlue;
	m_pxSharedAlpha = pxSharedAlpha;
	m_bSharedValues = true;
	m_fMax = fMax;

	m_pfnIntFunction = 0;
	m_iUserData = 0;
}


void Tools_ColourPicker_Colour_Gadget::Render( const Asura_Vector_2& xOrigin )
{

	//get top left in screen coords
	float fX = (float)Asura_Maths::FloatToInt_Near((xOrigin.x + m_xOffset.x) * ASURA_TEXT_OUTPUT_FONT_WIDTH);
	float fY = (float)Asura_Maths::FloatToInt_Near((xOrigin.y + m_xOffset.y) * ASURA_TEXT_OUTPUT_FONT_HEIGHT);

	//get width/height in pixels
	float fWidth = m_xSize.x * ASURA_TEXT_OUTPUT_FONT_WIDTH;
	float fHeight = m_xSize.y * ASURA_TEXT_OUTPUT_FONT_HEIGHT;

	u_int uColour;

	if(m_pfAlpha)
	{
		//draw background
		u_int uXChecks = Asura_Maths::Max((u_int)((fWidth-2.0f)/8.0f),2U);
		u_int uYChecks = Asura_Maths::Max((u_int)((fHeight-2.0f)/8.0f),2U);

		float fCheckWidth = (fWidth-2.0f)/(float)uXChecks;
		float fCheckHeight = (fHeight-2.0f)/(float)uYChecks;
		for(u_int uX=0;uX<uXChecks;uX++)
		{
			for(u_int uY=0;uY<uYChecks;uY++)
			{
				Asura_Render::Overlay.TextureIndex = ASURA_TEXTURE_NONE;
				Asura_Render::Overlay.TranslucencyMode = ASURA_TRANSLUCENCY_NORMAL;
				Asura_Render::Overlay.Colour = ((uX + uY) % 2) ? 0x00ffffff : 0x00CCCCCC;
				Asura_Render::Overlay.Colour |= Asura_OverlayBrightness;
				Asura_Render::Overlay.SetRectXY(fX+ 1.0f + uX * fCheckWidth, fY + 1.0f + uY * fCheckHeight, fCheckWidth+1.0f, fCheckHeight+1.0f);
				Asura_Render::Overlay.Render();
			}
		}
		Asura_Render::FlushDisplay();

	}

	
	//draw outline for colour box
	SetUseSharedGadgetColour(m_bSharedValues);
	uColour = Asura_OverlayBrightness | GetColour(m_bClickedThisFrame);
		
	Asura_Render::Render2DLine(fX,fY,fX+fWidth,fY,uColour);
	Asura_Render::Render2DLine(fX+fWidth,fY,fX+fWidth,fY+fHeight,uColour);
	Asura_Render::Render2DLine(fX+fWidth,fY+fHeight,fX,fY+fHeight,uColour);
	Asura_Render::Render2DLine(fX,fY+fHeight,fX,fY,uColour);


	//draw a coloured polygon
	u_int uR,uG,uB,uA;

	uA = Asura_OverlayBrightness>>24;

	float fRed,fGreen,fBlue;

	if(m_bSharedValues)
	{
		m_pxSharedRed->GetValue(&fRed,0);
		m_pxSharedGreen->GetValue(&fGreen,0);
		m_pxSharedBlue->GetValue(&fBlue,0);

		if(m_pfAlpha)
		{
			float fAlpha;
			m_pxSharedAlpha->GetValue(&fAlpha,0);
			uA = Asura_Maths::FloatToInt_Near((fAlpha/m_fMax)*255.0f);
		}
	}
	else
	{
		fRed = *m_pfRed;
		fGreen = *m_pfGreen;
		fBlue = *m_pfBlue;

		if(m_pfAlpha)
		{
			uA = Asura_Maths::FloatToInt_Near((*m_pfAlpha/m_fMax)*255.0f);
		}
	}

	fRed = (fRed/m_fMax)*255.0f;
	fGreen = (fGreen/m_fMax)*255.0f;
	fBlue = (fBlue/m_fMax)*255.0f;

	const float fMax = Asura_Maths::Max(fRed,Asura_Maths::Max(fGreen,fBlue));
	if(fMax > 255.0f)
	{
		fRed /= fMax/255.0f;
		fGreen /= fMax/255.0f;
		fBlue /= fMax/255.0f;
	}

	uR = Asura_Maths::FloatToInt_Near(fRed);
	uG = Asura_Maths::FloatToInt_Near(fGreen);
	uB = Asura_Maths::FloatToInt_Near(fBlue);

	uR = Asura_Maths::ClampToRange(uR,0U,255U);
	uG = Asura_Maths::ClampToRange(uG,0U,255U);
	uB = Asura_Maths::ClampToRange(uB,0U,255U);
	uA = Asura_Maths::ClampToRange(uA,0U,255U);
	
	uColour = (uA<<24)|(uR<<16)|(uG<<8)|uB;
	

	Asura_Render::Overlay.TextureIndex = ASURA_TEXTURE_NONE;
	Asura_Render::Overlay.TranslucencyMode = ASURA_TRANSLUCENCY_NORMAL;
	Asura_Render::Overlay.Colour = uColour;
	Asura_Render::Overlay.SetRectXY(fX+1.0f,fY+1.0f,fWidth-1.0f,fHeight-1.0f);

	Asura_Render::Overlay.Render();
	Asura_Render::FlushDisplay();

	if(!IsEnabled())
	{
		//If not enabled , draw a cross over the box.
		uColour = Asura_OverlayBrightness|0x000000;
		Asura_Render::Render2DLine(fX,fY,fX+fWidth,fY+fHeight,uColour);
		Asura_Render::Render2DLine(fX+fWidth,fY,fX,fY+fHeight,uColour);
	}

    Asura_Gadget::Render( xOrigin );
}

void Tools_ColourPicker_Colour_Gadget::Update( const Asura_Vector_2& xOrigin )
{
	if(IsEnabled())
	{
		if( m_bIsMouseOver && m_bIsClickable && Asura_UserInput::DebouncedKeyPressed(ASURA_KEYID_MOUSEBUTTON1) )
		{
			if (m_pfnIntFunction) Asura_Overlay_System::SetCallbackFunctionToCall(m_pfnIntFunction,m_iUserData);
			m_bClickedThisFrame = true;
		}
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////
/*-----------------------------------**
** Tools_ColourPicker_Sampler_Dialog **
**-----------------------------------*/

Tools_ColourPicker_Sampler_Dialog::Tools_ColourPicker_Sampler_Dialog(Asura_Vector_2 xOffset,int iSampleSize,float* pfRed,float* pfGreen,float* pfBlue,bool* pbChanged)
:Asura_Dialog(0,xOffset)
{
	int iIconIndex = TOOLS_ICON_EYEDROP1;
	if(iSampleSize == 5)
	{
		iIconIndex = TOOLS_ICON_EYEDROP5;
	}
	else if(iSampleSize == 3)
	{
		iIconIndex = TOOLS_ICON_EYEDROP3;
	}
	

	Asura_Gadget* pxGadget;
	pxGadget = new Tools_ColourPicker_Sampler_Gadget( xOffset,iSampleSize,iIconIndex, pfRed, pfGreen, pfBlue, pbChanged);
	AddGadget( pxGadget );

	m_xMaxCoord.x = m_xOffset.x + pxGadget->m_fWidth;
	m_xMaxCoord.y = m_xOffset.y + pxGadget->m_fHeight;
}


///////////////////////////////////////////////////////////////////////////////////////////////
/*-----------------------------------**
** Tools_ColourPicker_Sampler_Gadget **
**-----------------------------------*/

Tools_ColourPicker_Sampler_Gadget::Tools_ColourPicker_Sampler_Gadget(Asura_Vector_2 xOffset,int iSampleSize,int iIconIndex,float* pfRed,float* pfGreen,float* pfBlue,bool* pbChanged)
:Asura_Icon_Gadget(xOffset,Tools_Dialog::GetIconTexture(),iIconIndex)
{
	m_iSampleSize = iSampleSize;
	m_pfRed = pfRed;
	m_pfGreen = pfGreen;
	m_pfBlue = pfBlue;
	m_pbChanged = pbChanged;
	m_bPicking = false;
	
}

void Tools_ColourPicker_Sampler_Gadget::Update( const Asura_Vector_2& xOrigin )
{
	Asura_Icon_Gadget::Update(xOrigin);

	if(m_bPicking)
	{
		if(Asura_UserInput::DebouncedKeyPressed(ASURA_KEYID_ESCAPE))
		{
			CancelPicking();
		}
		else
		{
			Tools_System::GetColourSampleUnderCursor(m_pfRed,m_pfGreen,m_pfBlue);
			if(m_pbChanged) *m_pbChanged = true;
		}
	}
	
	if(m_bClickedThisFrame)
	{
		if(m_bPicking)
		{
			//take the colour
			AcceptColour();
		}
		else
		{
			//start colour picking by taking focus
			StartPicking();
		}
	}	

	if(m_bPicking)
	{
		Tools_System::RequestColourSampleUnderCursor(m_iSampleSize);
		Asura_Cursor::SetType(ASURA_CURSOR_EYEDROP);
	}
}

void Tools_ColourPicker_Sampler_Gadget::StartPicking()
{
	m_fRedCopy = *m_pfRed;
	m_fGreenCopy = *m_pfGreen;
	m_fBlueCopy = *m_pfBlue;

	m_bPicking = true;
	Asura_Overlay_System::TakeFocus(this,OverlayFocusType_Mouse|OverlayFocusType_Keyboard);
}

void Tools_ColourPicker_Sampler_Gadget::AcceptColour()
{

	if(m_pbChanged) *m_pbChanged = true;
	m_bPicking = false;
	Asura_Overlay_System::ReleaseFocus(OverlayFocusType_Mouse|OverlayFocusType_Keyboard);
}

void Tools_ColourPicker_Sampler_Gadget::CancelPicking()
{
	*m_pfRed = m_fRedCopy;
	*m_pfGreen = m_fGreenCopy;
	*m_pfBlue = m_fBlueCopy;
	if(m_pbChanged) *m_pbChanged = true;
	
	m_bPicking = false;
	Asura_Overlay_System::ReleaseFocus(OverlayFocusType_Mouse|OverlayFocusType_Keyboard);
}



void Tools_ColourPicker_Sampler_Gadget::FocusLost(int iFocusType)
{
	Asura_Icon_Gadget::FocusLost(iFocusType);
	if(m_bPicking) CancelPicking();
}


///////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------------**
** Tools_ColourPicked_PresetColour_Dialog **
**----------------------------------------*/

Tools_ColourPicker_PresetColour_Dialog::Tools_ColourPicker_PresetColour_Dialog(Asura_Vector_2 xOffset,Tools_ColourPicker* pxColourPicker,u_int* puColour,bool bCanBeChanged)
:Asura_Dialog(0,xOffset)
{
	Asura_Vector_2 xSize(1.5f,1.0f);
	
	Asura_Gadget* pxGadget = new Tools_ColourPicker_PresetColour_Gadget(xOffset,xSize,pxColourPicker,puColour,bCanBeChanged);
	AddGadget(pxGadget);
		
	m_xMaxCoord.x = m_xOffset.x + pxGadget->m_fWidth;
	m_xMaxCoord.y = m_xOffset.y + pxGadget->m_fHeight;
}



///////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------------**
** Tools_ColourPicked_PresetColour_Gadget **
**----------------------------------------*/

Tools_ColourPicker_PresetColour_Gadget::Tools_ColourPicker_PresetColour_Gadget(Asura_Vector_2 xOffset,Asura_Vector_2 xSize,Tools_ColourPicker* pxColourPicker,u_int* puColour,bool bCanBeChanged)
{
	m_xOffset = xOffset;
	m_fWidth = xSize.x;
	m_fHeight = xSize.y;

	m_pxColourPicker = pxColourPicker;
	m_puColour = puColour;
	m_bCanBeChanged = bCanBeChanged;

}


void Tools_ColourPicker_PresetColour_Gadget::Render( const Asura_Vector_2& xOrigin )
{

	//get top left in screen coords
	float fX = (float)Asura_Maths::FloatToInt_Near((xOrigin.x + m_xOffset.x) * ASURA_TEXT_OUTPUT_FONT_WIDTH);
	float fY = (float)Asura_Maths::FloatToInt_Near((xOrigin.y + m_xOffset.y) * ASURA_TEXT_OUTPUT_FONT_HEIGHT);

	//get width/height in pixels
	float fWidth = m_fWidth*ASURA_TEXT_OUTPUT_FONT_WIDTH;
	float fHeight = m_fHeight*ASURA_TEXT_OUTPUT_FONT_HEIGHT;

	u_int uColour;
	
	u_int uMainColour = *m_puColour;
	if(!m_pxColourPicker->IsAlphaEditingEnabled())
	{
		//Ignore the alpha component if the colour picker isn't allowing alpha to be edited
		uMainColour |= 0xff000000;
	}


	if((uMainColour)>>24 != 0xff )
	{
		//draw background
		u_int uXChecks = Asura_Maths::Max((u_int)((fWidth-2.0f)/8.0f),2U);
		u_int uYChecks = Asura_Maths::Max((u_int)((fHeight-2.0f)/8.0f),2U);

		float fCheckWidth = (fWidth-2.0f)/(float)uXChecks;
		float fCheckHeight = (fHeight-2.0f)/(float)uYChecks;
		for(u_int uX=0;uX<uXChecks;uX++)
		{
			for(u_int uY=0;uY<uYChecks;uY++)
			{
				Asura_Render::Overlay.TextureIndex = ASURA_TEXTURE_NONE;
				Asura_Render::Overlay.TranslucencyMode = ASURA_TRANSLUCENCY_NORMAL;
				Asura_Render::Overlay.Colour = ((uX + uY) % 2) ? 0x00ffffff : 0x00CCCCCC;
				Asura_Render::Overlay.Colour |= Asura_OverlayBrightness;
				Asura_Render::Overlay.SetRectXY(fX+ 1.0f + uX * fCheckWidth, fY + 1.0f + uY * fCheckHeight, fCheckWidth+1.0f, fCheckHeight+1.0f);
				Asura_Render::Overlay.Render();
			}
		}
		Asura_Render::FlushDisplay();

	}

	
	//draw outline for colour box
	if(IsEnabled())
	{
		uColour = Asura_OverlayBrightness|0xffffff;
	}
	else
	{
		uColour = Asura_OverlayBrightness|0x3f3f3f;
	}
	Asura_Render::Render2DLine(fX,fY,fX+fWidth,fY,uColour);
	Asura_Render::Render2DLine(fX+fWidth,fY,fX+fWidth,fY+fHeight,uColour);
	Asura_Render::Render2DLine(fX+fWidth,fY+fHeight,fX,fY+fHeight,uColour);
	Asura_Render::Render2DLine(fX,fY+fHeight,fX,fY,uColour);


	//draw a coloured polygon

	Asura_Render::Overlay.TextureIndex = ASURA_TEXTURE_NONE;
	Asura_Render::Overlay.TranslucencyMode = ASURA_TRANSLUCENCY_NORMAL;
	Asura_Render::Overlay.Colour = uMainColour;
	Asura_Render::Overlay.SetRectXY(fX+1.0f,fY+1.0f,fWidth-1.0f,fHeight-1.0f);

	Asura_Render::Overlay.Render();
	Asura_Render::FlushDisplay();

	if(!IsEnabled())
	{
		//If not enabled , draw a cross over the box.
		uColour = Asura_OverlayBrightness|0x000000;
		Asura_Render::Render2DLine(fX,fY,fX+fWidth,fY+fHeight,uColour);
		Asura_Render::Render2DLine(fX+fWidth,fY,fX,fY+fHeight,uColour);
	}

    Asura_Gadget::Render( xOrigin );
}

void Tools_ColourPicker_PresetColour_Gadget::Update( const Asura_Vector_2& xOrigin )
{
	if(IsEnabled())
	{
		if( m_bIsMouseOver && m_bIsClickable && Asura_UserInput::DebouncedKeyPressed(ASURA_KEYID_MOUSEBUTTON1) )
		{
			if(Asura_UserInput::KeyPressed(ASURA_KEYID_SHIFT))
			{
				if(m_bCanBeChanged)
				{
					//save the current colour picker colour to this preset
					float fR = m_pxColourPicker->GetRed();
					float fG = m_pxColourPicker->GetGreen();
					float fB = m_pxColourPicker->GetBlue();
					float fA = m_pxColourPicker->GetAlpha();

					u_int uR = Asura_Maths::FloatToInt_Near(fR);
					uR = Asura_Maths::ClampToRange(uR,0u,255u);
					
					u_int uG = Asura_Maths::FloatToInt_Near(fG);
					uG = Asura_Maths::ClampToRange(uG,0u,255u);

					u_int uB = Asura_Maths::FloatToInt_Near(fB);
					uB = Asura_Maths::ClampToRange(uB,0u,255u);

					u_int uA = Asura_Maths::FloatToInt_Near(fA);
					uA = Asura_Maths::ClampToRange(uA,0u,255u);

					*m_puColour = (uA<<24)|(uR<<16)|(uG<<8)|uB;

					Tools_ColourPicker::SaveCustomColours();

				}
			}
			else
			{
				//copy this colour to the colour picker
				m_pxColourPicker->SetColour(*m_puColour, true);
			}
		}
	}
}

