//
// Tools_Overlay_PickMaterialResponse.cpp
//
// Created by Richard Rice - 19/06/2007
// 
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"
#include "Tools_Overlay_PickMaterialResponse.h"

#if defined ASURA_USE_MATERIAL_RESPONSE_SYSTEM
#include "Core/Asura_TextureManagement.h"
#include "Core/Asura_UserInput.h"
#include "Interface/Asura_Overlay.h"

#include "Materials/Tools_MaterialResponse_System.h"
#include "Texturing/Tools_Texturing_MaterialResponse.h"
#include "Rendering/Asura_Text_Output.h"
#include "Rendering/Asura_Render.h"
#include "Rendering/Asura_Direct3D.h"


static const char* g_szNone = "*None*";//string for none option in tree


bool Tools_Overlay_PickMaterialResponse::s_bFilterTreeByEnv = false;

Tools_Overlay_PickMaterialResponse::Tools_Overlay_PickMaterialResponse(const char* szTitle)
:Tools_Modal_Overlay(szTitle)
{
	m_uInitialSelection = 0;
	m_pxTreeDialog = 0;
	m_pxImageDialog = 0;
	m_bOkaySelected = false;
	m_bSelectionChanged = false;
	m_bFilterTreeByEnvChanged = false;
}

bool Tools_Overlay_PickMaterialResponse::DoModal(Asura_Hash_ID uInitialSelection)
{
	m_uInitialSelection = uInitialSelection;
	m_bOkaySelected = false;

	ShowOverlay();

	return m_bOkaySelected;
}


void Tools_Overlay_PickMaterialResponse::InitialiseOverlay(Asura_Overlay* pxOverlay)
{
	//build material tree
	m_xMaterialNameTree.DeleteAll();
	if(s_bFilterTreeByEnv)
		Tools_Texturing_MaterialResponse::CreateMaterialNameTree_FilteredByEnv( m_xMaterialNameTree );
	else
		Tools_MaterialResponse_System::CreateMaterialNameTree( m_xMaterialNameTree );
	//and add option for none
	Asura_TreeDialog_Item* pxNone = m_xMaterialNameTree.AddItem(g_szNone,0);

	//set the initial selection
	if(m_uInitialSelection)
	{
		Asura_TreeDialog_Item* pxTreeItem = m_xMaterialNameTree.FindByData(m_uInitialSelection);
		if(pxTreeItem)
		{
			m_xMaterialNameTree.SetSelectedItem(pxTreeItem);
		}
	}
	else
	{
		m_xMaterialNameTree.SetSelectedItem(pxNone);
	}

	Asura_Vector_2 xOffset(1.0f,3.0f);
	Asura_Dialog* pxDialog;

	pxDialog = new Asura_Tickbox_Dialog("Filter By Env", xOffset, &s_bFilterTreeByEnv, &m_bFilterTreeByEnvChanged);
	pxDialog->SetHelpText( "Filters the list of materials so that it only shows the materials used by the 'environment'." );
	pxOverlay->AddDialog( pxDialog );
	xOffset.y += Asura_Function_Dialog::DefaultSpacing();


	//add main tree view
	m_bSelectionChanged = false;
	m_pxTreeDialog = new Asura_Tree_Dialog( xOffset, &m_xMaterialNameTree, 30.0f, 30.0f, &m_bSelectionChanged );
	m_pxTreeDialog->SetDoubleClickedFunction(OnOkay, (int)this);
	pxOverlay->AddDialog( m_pxTreeDialog );
	xOffset.y += 30.0f + 1.0f;

	//add small texture thumbnail for albedo texture
	m_pxImageDialog = new Asura_Image_Dialog(xOffset,ASURA_TEXTURE_NONE,128.0f,128.0f);
	m_pxImageDialog->SetHelpText("Albedo texture from the selected material");
	m_pxImageDialog->SetTranslucent(false);
	pxOverlay->AddDialog( m_pxImageDialog );
	xOffset.y = m_pxImageDialog->m_xMaxCoord.y + 2.0f;

	UpdateImageDialog();


	//and okay and cancel buttons
	pxDialog = new Asura_Function_Dialog("Okay",xOffset,OnOkay,(int)this);
	pxDialog->SetIsEnabledFunction(IsEnabled_Okay,(int)this);
	pxOverlay->AddDialog(pxDialog);

	xOffset.x += 12.0f;
	pxDialog = new Asura_Function_Dialog("Cancel",xOffset,OnCancel,(int)this);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();
	xOffset.x -= 12.0f;

}

void Tools_Overlay_PickMaterialResponse::OnOkay()
{
	m_bOkaySelected = true;
	CloseOverlay();
}

void Tools_Overlay_PickMaterialResponse::OnCancel()
{
	m_bOkaySelected = false;
	CloseOverlay();
}

bool Tools_Overlay_PickMaterialResponse::IsEnabled_Okay()
{
	const Asura_TreeDialog_Item* pxSelected = m_xMaterialNameTree.GetSelectedItem();
	if(!pxSelected) return false;
	if(pxSelected->GetUserData()) return true;

	//if no user data , allow if the selected item is the none item
	return !(stricmp(g_szNone,pxSelected->GetName()));
	
	
}

Asura_Hash_ID Tools_Overlay_PickMaterialResponse::GetSelection() const
{
	const Asura_TreeDialog_Item* pxSelected = m_xMaterialNameTree.GetSelectedItem();
	if(pxSelected)
	{
		return (Asura_Hash_ID)pxSelected->GetUserData();
	}
	else
	{
		return 0;		
	}
}


void Tools_Overlay_PickMaterialResponse::UpdateTreeDialog()
{
	Asura_Hash_ID uSelectedMaterial = GetSelection();

	//rebuild the tree
	if(s_bFilterTreeByEnv)
		Tools_Texturing_MaterialResponse::CreateMaterialNameTree_FilteredByEnv( m_xMaterialNameTree );
	else
		Tools_MaterialResponse_System::CreateMaterialNameTree( m_xMaterialNameTree );

	//set the previous selection again if it is still available
	Asura_TreeDialog_Item* pxItem = m_xMaterialNameTree.FindByData(uSelectedMaterial);
	if(pxItem)
	{
		m_xMaterialNameTree.SetSelectedItem(pxItem);		
		m_pxTreeDialog->MakeSelectionVisible();
	}

	UpdateImageDialog();


}


void Tools_Overlay_PickMaterialResponse::UpdateImageDialog()
{
	Asura_Assert(m_pxImageDialog,"");

	int iTexture = ASURA_TEXTURE_NONE;

	//get the albedo texture from the selected material
	const Asura_TreeDialog_Item* pxSelected = m_xMaterialNameTree.GetSelectedItem();
	if(pxSelected)
	{
		Asura_Hash_ID uMaterialID = (Asura_Hash_ID)pxSelected->GetUserData();
		const Tools_MaterialResponse* pxMaterial = Tools_MaterialResponse_System::GetMaterialByHashID(uMaterialID);
		if(pxMaterial)
		{
			iTexture = pxMaterial->GetTexture(Asura_MaterialResponse::ALBEDO_TEXTURE);
		}
	}

	m_pxImageDialog->SetTexture(iTexture);
}

void Tools_Overlay_PickMaterialResponse::Update()
{
	if(m_bFilterTreeByEnvChanged)
	{
		m_bFilterTreeByEnvChanged = false;
		UpdateTreeDialog();

	}

	if(m_bSelectionChanged)
	{
		m_bSelectionChanged = false;
		UpdateImageDialog();
	}

	if(Asura_UserInput::DebouncedKeyPressed(ASURA_KEYID_ENTER) && IsEnabled_Okay())
	{
		OnOkay();
	}
	else if(Asura_UserInput::DebouncedKeyPressed(ASURA_KEYID_ESCAPE))
	{
		OnCancel();
	}

}

// Tools_MaterialResponse_Dialog /////////////////////////////////////////////////////////////////////////
Tools_MaterialResponse_Dialog::Tools_MaterialResponse_Dialog( Asura_Vector_2& xOffset, Asura_Hash_ID* puMaterialResponse, bool* pbChangedFlag /*= 0*/)
: Asura_Dialog("[NONE]", xOffset)
{
	Asura_Gadget* pxNewGadget;

	m_xFilter = "";
	m_pbChangedFlag = pbChangedFlag;
	m_puMaterialResponse = puMaterialResponse;

	Asura_Callback_MemberFunction<void, Tools_MaterialResponse_Dialog> xCallback(this, &Tools_MaterialResponse_Dialog::Clicked);
	pxNewGadget = m_pFuncGadget = new Asura_Function_Gadget( xOffset, xCallback, NULL);
	AddGadget( pxNewGadget );

	if (puMaterialResponse)
	{
		SetMaterialResponseHash(*m_puMaterialResponse);
	} else {
		SetMaterialResponseHash(ASURA_HASH_ID_UNSET);
	}


	UpdateMax();

}

void Tools_MaterialResponse_Dialog::UpdateMax()
{
	float	fMaxWidth	= Asura_Text_Output::WidthOfString(m_xMaterialResponseName.GetString(), ASURA_TEXT_FORMAT_SMALLFONT) + 5.0f;

// 	for(u_int i=0; i < Tools_MaterialResponse_System::GetNumMaterials(); i++)
// 	{
// 		const char*			szFullTemplateName	= Tools_MaterialResponse_System::GetMaterialNameByIndex(i);
// 		const float			fStringWidth		= Asura_Text_Output::WidthOfString(szFullTemplateName, ASURA_TEXT_FORMAT_SMALLFONT);
// 
// 		fMaxWidth = Asura_Maths::Max(fMaxWidth, (fStringWidth + 5.0f));
// 	}

	m_xMaxCoord.x = m_xOffset.x + fMaxWidth;
	m_xMaxCoord.y = m_xOffset.y + 1.0f;

	//extend the width of the gadget , so that clicking on the text will activate it
	m_pFuncGadget->m_fWidth = m_xMaxCoord.x - m_pFuncGadget->m_xOffset.x;
	if (m_pxOverlay)
	{
		m_pxOverlay->FlagForResize();
	}
}


void Tools_MaterialResponse_Dialog::SetMaterialResponseHash(Asura_Hash_ID uHash)
{
	if (uHash != ASURA_HASH_ID_UNSET)
	{
		const char *pxName = Tools_MaterialResponse_System::GetMaterialNameByHashID(uHash);

		m_xMaterialResponseName = pxName ? pxName : "[NONE]";
	} else {
		m_xMaterialResponseName =  "[NONE]";
	}
	m_uHash = uHash;
	if (m_puMaterialResponse)
	{
		*m_puMaterialResponse = m_uHash;
	}

	UpdateLabel(m_xMaterialResponseName.GetString());
	UpdateMax();
}

void Tools_MaterialResponse_Dialog::SetFilter(const char* pFilter)
{
	m_xFilter = pFilter;
}


void Tools_MaterialResponse_Dialog::UpdateLabel(const char* text)
{
	m_xName = text;
}

void Tools_MaterialResponse_Dialog::Update( const Asura_Vector_2& xOrigin )
{
	Asura_Dialog::Update(xOrigin);

	if (m_puMaterialResponse)
	{
		if (*m_puMaterialResponse != m_uHash)
		{
			SetMaterialResponseHash(*m_puMaterialResponse);
		}
	}
}

void Tools_MaterialResponse_Dialog::Render( const Asura_Vector_2& xOrigin )
{
	if( !IsHidden() )
	{
		//  		if( GadgetList )
		//  		{
		//  			GadgetList->RenderList( xOrigin );
		//  		}

		Asura_Render::Overlay.Colour = 0xffffffff;
		Asura_Render::Overlay.TextureIndex = -1;
		Asura_Render::Overlay.TranslucencyMode = ASURA_TRANSLUCENCY_OFF;

		Asura_Vector_2 xTopLeft = xOrigin + m_xOffset;
		xTopLeft.x = xTopLeft.x * ASURA_TEXT_OUTPUT_FONT_WIDTH - 1;
		xTopLeft.y = xTopLeft.y * ASURA_TEXT_OUTPUT_FONT_HEIGHT - 1;
		Asura_Vector_2 xDimensions;
		xDimensions.x = (m_pFuncGadget->m_fWidth) * ASURA_TEXT_OUTPUT_FONT_WIDTH + 2;
		xDimensions.y = ((m_pFuncGadget->m_fHeight) * ASURA_TEXT_OUTPUT_FONT_HEIGHT) + 2;


		Asura_Render::Overlay.SetRectXY( xTopLeft.x, xTopLeft.y, xDimensions.x, xDimensions.y );
		Asura_Render::Overlay.SetRectUV( 0.0f, 0.0f, 1.0f, 1.0f );

		Asura_Render::Overlay.m_bNonRotated = true;
		Asura_Render::Overlay.Render(TRUE);
		Asura_Render::Overlay.Colour = 0xff000000;
		Asura_Render::Overlay.SetRectXY( xTopLeft.x+1, xTopLeft.y+1, xDimensions.x-2, xDimensions.y-2);
		Asura_Render::Overlay.Render(TRUE);
		Asura_Direct3D::FlushQuadBatches();

		if( !m_xName.IsBlank() )
		{
			Asura_Vector_2 pos = xOrigin + m_xOffset + GetTextOffset();
			Asura_Text_Output::Print(pos.x + 2 ,pos.y,GetColour(),ASURA_TEXT_FORMAT_SMALLFONT,"%s",m_xName.GetString());
		}
	}
}


void Tools_MaterialResponse_Dialog::Clicked()
{
	
	
	const char *pTitle = "Choose Material Response";

	Tools_Overlay_PickMaterialResponse xOverlay(pTitle);

	if (xOverlay.DoModal(m_puMaterialResponse ? *m_puMaterialResponse : ASURA_HASH_ID_UNSET)) 
	{

		SetMaterialResponseHash(xOverlay.GetSelection());
		if (m_pbChangedFlag)
		{
			*m_pbChangedFlag = true;
		}
	}
}


#endif ////ASURA_USE_MATERIAL_RESPONSE_SYSTEM


























