//////////////////////////////////////////////////////////////////////////////
//
// ToolsAVP_Mode_FSFX_Template.cpp
//
// Copyright (c) 2007 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

/******************************************************************************/
/* Included Files                                                             */
/******************************************************************************/

#include "Core/Asura.h"

#if defined(ASURA_USE_FSFX)

#include "FSFX/Tools_Mode_FSFX_Template.h"

// Asura Platform-independent
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay.h"
#include "Interface/Tools_ColourPicker.h"

// AVP Platform-independent
#include "FSFX/AVP_FSFX.h"

// Tools
#include "Misc/Tools_Modal_Overlay.h"
#include "Texturing/Tools_PickTexture.h"

/******************************************************************************/
/* Tools_Mode_FSFX_Template Static Class Functions                            */
/******************************************************************************/

void Tools_Mode_FSFX_Template::Project_AddComponentsToCreationList( ListSelection_Overlay& xOverlay )
{
	xOverlay.AddItem( AVP_FSFX_Component_UseStencil::GetTypeDescID(), AVP_FSFX_Component_UseStencil::GetTypeID() );
	xOverlay.AddItem( AVP_FSFX_Component_DisplacementMap::GetTypeDescID(), AVP_FSFX_Component_DisplacementMap::GetTypeID() );
	xOverlay.AddItem( AVP_FSFX_Component_Edges::GetTypeDescID(), AVP_FSFX_Component_Edges::GetTypeID() );
}

template <u_int uFlag> bool IsModeRender(void *pData)
{
	AVP_FSFX_Component_UseStencil* const pxStencilComponent = static_cast< AVP_FSFX_Component_UseStencil* >( pData );

	return (pxStencilComponent->GetBitsToCheck() & uFlag) != 0 &&
		(pxStencilComponent->GetBitValues() & uFlag) != 0;
}

template <u_int uFlag> void SetModeRender(bool bValue, void *pData)
{
	AVP_FSFX_Component_UseStencil* const pxStencilComponent = static_cast< AVP_FSFX_Component_UseStencil* >( pData );

	if (bValue)
	{
		pxStencilComponent->SetBitsToCheck(pxStencilComponent->GetBitsToCheck() | uFlag);
		pxStencilComponent->SetBitValues(pxStencilComponent->GetBitValues() | uFlag);
	}
}

template <u_int uFlag> bool IsModeDontRender(void *pData)
{
	AVP_FSFX_Component_UseStencil* const pxStencilComponent = static_cast< AVP_FSFX_Component_UseStencil* >( pData );

	return (pxStencilComponent->GetBitsToCheck() & uFlag) != 0 &&
		(pxStencilComponent->GetBitValues() & uFlag) == 0;
}

template <u_int uFlag> void SetModeDontRender(bool bValue, void *pData)
{
	AVP_FSFX_Component_UseStencil* const pxStencilComponent = static_cast< AVP_FSFX_Component_UseStencil* >( pData );

	if (bValue)
	{
		pxStencilComponent->SetBitsToCheck(pxStencilComponent->GetBitsToCheck() | uFlag);
		pxStencilComponent->SetBitValues(pxStencilComponent->GetBitValues() & ~uFlag);
	}
}

template <u_int uFlag> bool IsModeIgnore(void *pData)
{
	AVP_FSFX_Component_UseStencil* const pxStencilComponent = static_cast< AVP_FSFX_Component_UseStencil* >( pData );

	return (pxStencilComponent->GetBitsToCheck() & uFlag) == 0;
}

template <u_int uFlag> void SetModeIgnore(bool bValue, void *pData)
{
	AVP_FSFX_Component_UseStencil* const pxStencilComponent = static_cast< AVP_FSFX_Component_UseStencil* >( pData );

	if (bValue)
	{
		pxStencilComponent->SetBitsToCheck(pxStencilComponent->GetBitsToCheck() & ~uFlag);
	}
}

static Asura_Dialog *s_pxChooseTextureDialog;
void ChooseDisplacementMapTexture( int iUserData )
{
	AVP_FSFX_Component_DisplacementMap* pxComponent = reinterpret_cast< AVP_FSFX_Component_DisplacementMap* >( iUserData );

	const int iNewTexture = Tools_PickTexture::PickTextureFromDisk();
	if ( iNewTexture != ASURA_TEXTURE_NONE )
	{
		const Asura_String *pxTextureName = Asura_Texture_Management::GetTextureName( iNewTexture );
		pxComponent->SetTexture(*pxTextureName, iNewTexture);
	}
	else
	{
		pxComponent->SetTexture("", iNewTexture);
	}

	char szStr[ 256 ];
	sprintf( szStr, "Choose Texture : %s", pxComponent->GetTextureName(0) );
	s_pxChooseTextureDialog->UpdateLabel( szStr );

}



bool Tools_Mode_FSFX_Template::Project_AddInterfaceForComponent( Asura_FSFX_Component* pxComponent,
																 Asura_Overlay* const pxOverlay,
																 Asura_Vector_2& xOffset )
{
	switch( (int)pxComponent->GetType() )
	{
		case AVP_FSFX_USE_STENCIL:
		{
			AVP_FSFX_Component_UseStencil* const pxStencilComponent = static_cast< AVP_FSFX_Component_UseStencil* >( pxComponent );

			Asura_Dialog* pxDialog;

			xOffset.x += 10;
			pxOverlay->AddDialog( new Asura_Dialog("Render", xOffset) );
			xOffset.x += 10;
			pxOverlay->AddDialog( new Asura_Dialog("Dont Render", xOffset) );
			xOffset.x += 10;
			pxOverlay->AddDialog( new Asura_Dialog("Ignore", xOffset) );
			xOffset.x -= 30;
			xOffset.y += Asura_Tickbox_Dialog::DefaultSpacing() + .5f;

			pxOverlay->AddDialog( new Asura_Dialog("Hot", xOffset) );
			xOffset.x += 10;
			pxDialog = new Asura_FunctionTickbox_Dialog( "", xOffset, pxStencilComponent, 
				IsModeRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_HOT>, 
				SetModeRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_HOT> );
			pxOverlay->AddDialog( pxDialog );
			xOffset.x += 10;
			pxDialog = new Asura_FunctionTickbox_Dialog( "", xOffset, pxStencilComponent, 
				IsModeDontRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_HOT>, 
				SetModeDontRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_HOT> );
			pxOverlay->AddDialog( pxDialog );
			xOffset.x += 10;
			pxDialog = new Asura_FunctionTickbox_Dialog( "", xOffset, pxStencilComponent, 
				IsModeIgnore<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_HOT>, 
				SetModeIgnore<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_HOT> );
			pxOverlay->AddDialog( pxDialog );
			xOffset.x -= 30;
			xOffset.y += Asura_Tickbox_Dialog::DefaultSpacing();

			pxOverlay->AddDialog( new Asura_Dialog("Alien", xOffset) );
			xOffset.x += 10;
			pxDialog = new Asura_FunctionTickbox_Dialog( "", xOffset, pxStencilComponent, 
				IsModeRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_ALIEN>, 
				SetModeRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_ALIEN> );
			pxOverlay->AddDialog( pxDialog );
			xOffset.x += 10;
			pxDialog = new Asura_FunctionTickbox_Dialog( "", xOffset, pxStencilComponent, 
				IsModeDontRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_ALIEN>, 
				SetModeDontRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_ALIEN> );
			pxOverlay->AddDialog( pxDialog );
			xOffset.x += 10;
			pxDialog = new Asura_FunctionTickbox_Dialog( "", xOffset, pxStencilComponent, 
				IsModeIgnore<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_ALIEN>, 
				SetModeIgnore<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_ALIEN> );
			pxOverlay->AddDialog( pxDialog );
			xOffset.x -= 30;
			xOffset.y += Asura_Tickbox_Dialog::DefaultSpacing();

			pxOverlay->AddDialog( new Asura_Dialog("Tech", xOffset) );
			xOffset.x += 10;
			pxDialog = new Asura_FunctionTickbox_Dialog( "", xOffset, pxStencilComponent, 
				IsModeRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_TECH>, 
				SetModeRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_TECH> );
			pxOverlay->AddDialog( pxDialog );
			xOffset.x += 10;
			pxDialog = new Asura_FunctionTickbox_Dialog( "", xOffset, pxStencilComponent, 
				IsModeDontRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_TECH>, 
				SetModeDontRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_TECH> );
			pxOverlay->AddDialog( pxDialog );
			xOffset.x += 10;
			pxDialog = new Asura_FunctionTickbox_Dialog( "", xOffset, pxStencilComponent, 
				IsModeIgnore<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_TECH>, 
				SetModeIgnore<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_TECH> );
			pxOverlay->AddDialog( pxDialog );
			xOffset.x -= 30;
			xOffset.y += Asura_Tickbox_Dialog::DefaultSpacing();

			pxOverlay->AddDialog( new Asura_Dialog("Holo", xOffset) );
			xOffset.x += 10;
			pxDialog = new Asura_FunctionTickbox_Dialog( "", xOffset, pxStencilComponent, 
				IsModeRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_HOLOGRAM>, 
				SetModeRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_HOLOGRAM> );
			pxOverlay->AddDialog( pxDialog );
			xOffset.x += 10;
			pxDialog = new Asura_FunctionTickbox_Dialog( "", xOffset, pxStencilComponent, 
				IsModeDontRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_HOLOGRAM>, 
				SetModeDontRender<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_HOLOGRAM> );
			pxOverlay->AddDialog( pxDialog );
			xOffset.x += 10;
			pxDialog = new Asura_FunctionTickbox_Dialog( "", xOffset, pxStencilComponent, 
				IsModeIgnore<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_HOLOGRAM>, 
				SetModeIgnore<AVP_MATERIAL_RESPONSE_PROJECT_FLAG_HOLOGRAM> );
			pxOverlay->AddDialog( pxDialog );
			xOffset.x -= 30;
			xOffset.y += Asura_Tickbox_Dialog::DefaultSpacing();



			return true;
		}
		case AVP_FSFX_DISPLACEMENT_MAP:
		{
			AVP_FSFX_Component_DisplacementMap* const pxDisplacementMapComponent = static_cast< AVP_FSFX_Component_DisplacementMap* >( pxComponent );

			Asura_Dialog* pxDialog;

			pxDialog = new Asura_Numerical_Dialog( "Amount (0->5000)", xOffset, &pxDisplacementMapComponent->m_fAmount, 0.0f, 5000.0f, 1.0f, "%0.0f" );
			pxOverlay->AddDialog( pxDialog );
			xOffset.y += Asura_Dialog::DefaultSpacing();

			char szStr[ 256 ];
			sprintf( szStr, "Choose Texture : %s", pxDisplacementMapComponent->m_xTextureFilename.GetString() );

			pxDialog = new Asura_Function_Dialog( szStr, xOffset, ChooseDisplacementMapTexture, reinterpret_cast< int32>( pxComponent ) );
			pxOverlay->AddDialog( pxDialog );
			::s_pxChooseTextureDialog = pxDialog;

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

		}
		return true;
		case AVP_FSFX_EDGES:
			{
				AVP_FSFX_Component_Edges* const pxEdgesComponent = static_cast< AVP_FSFX_Component_Edges* >( pxComponent );

				Asura_Dialog* pxDialog;

				static const char* pTechniqueNames[] = 
				{
					"LoG (best)",
					"Prewitt",
					"Sobel",
					"Robert",
					"L3",
					"L2",
					"L1 (worst)",
					NULL
				};
				
				pxDialog = new Asura_DropDown_List_Dialog(xOffset,pTechniqueNames,&pxEdgesComponent->m_uMethod, 7, 7, NULL, NULL,"");
				pxOverlay->AddDialog( pxDialog );
				xOffset.y += Asura_Dialog::DefaultSpacing();


				pxDialog = new Asura_Numerical_Dialog( "Amount (0->200)", xOffset, &pxEdgesComponent->m_fAmount, 0.0f, 200.0f, 1.0f, "%0.0f" );
				pxOverlay->AddDialog( pxDialog );
				xOffset.x += 20;
				pxDialog = new Tools_ColourPicker_Dialog("Tint Colour",xOffset,Asura_Vector_2(1.5f,1.0f),&pxEdgesComponent->m_xTintColour.m_fR,&pxEdgesComponent->m_xTintColour.m_fG,&pxEdgesComponent->m_xTintColour.m_fB,1.0f, NULL);
				pxDialog->SetHelpText("Sets the tint colour.");
				pxOverlay->AddDialog(pxDialog);
				xOffset.y += Asura_Dialog::DefaultSpacing();
				xOffset.x -= 20;


				pxDialog = new Asura_Numerical_Dialog( "Low threshold (0->50)", xOffset, &pxEdgesComponent->m_fLowThreshold, 0.0f, 50.0f, 1.0f, "%0.0f" );
				pxOverlay->AddDialog( pxDialog );
				xOffset.x += 20;
				pxDialog = new Asura_Numerical_Dialog( "High threshold (0->50)", xOffset, &pxEdgesComponent->m_fHighThreshold, 0.0f, 50.0f, 1.0f, "%0.0f" );
				pxOverlay->AddDialog( pxDialog );
				xOffset.x -= 20;
				xOffset.y += Asura_Dialog::DefaultSpacing();

				pxDialog = new Asura_Numerical_Dialog( "Blur Radius (0->150)", xOffset, &pxEdgesComponent->m_fBlurWidth, 0.0f, 150.0f, 1.0f, "%0.0f" );
				pxOverlay->AddDialog( pxDialog );
				xOffset.x += 20;
				pxDialog = new Asura_Numerical_Dialog( "Edge Radius (0->150)", xOffset, &pxEdgesComponent->m_fEDWidth, 0.0f, 50.0f, 1.0f, "%0.0f" );
				pxOverlay->AddDialog( pxDialog );
				xOffset.x -= 20;
				xOffset.y += Asura_Dialog::DefaultSpacing();




			}
			return true;

		default:
		{
			return false;
		}
	}
}

#endif	// defined(ASURA_USE_FSFX)


/// End of file. ///
