//////////////////////////////////////////////////////////////////////////////
//
// ToolsAVP_Entity_InteractRetinalScanner.cpp
//
// Created by AJK 05/01/2009
//
// Copyright (c) 2008 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

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

// This file's header.
#include "Entity/PhysicalObject/Interact/ToolReceptacle/RetinalScanner/ToolsAVP_Entity_InteractRetinalScanner.h"

// Asura
#include "Entity/Asura_StaticMessage_System.h"

// AVP
#include "Blueprint/AVP_Blueprint_HashIDs.h"
#include "Entity/PhysicalObject/Interact/ToolReceptacle/RetinalScanner/AVP_ServerEntity_InteractRetinalScanner.h"
#include "Entity/PhysicalObject/Pickup/AVP_ServerEntity_Pickup.h"

// Tools Asura
#include "Blueprint/Tools_Mode_Blueprint.h"
#include "Entity/Tools_MessageEditor.h"
#include "Load&Save/Tools_SaveAsura.h"

// Class statics
Asura_Hashed_List<ToolsAVP_Entity_InteractRetinalScanner>	ToolsAVP_Entity_InteractRetinalScanner::s_xList;

ToolsAVP_Entity_InteractRetinalScanner::ToolsAVP_Entity_InteractRetinalScanner( AVP_ServerEntity_InteractRetinalScanner* pxInteractObject )
: PARENT( pxInteractObject )
, Tools_Entity_PhysicalObject( pxInteractObject )
{
	Type = TOT_Entity_InteractRetinalScanner;
	s_xList.AddToList(this);
}

ToolsAVP_Entity_InteractRetinalScanner::~ToolsAVP_Entity_InteractRetinalScanner()
{
	s_xList.RemoveFromList(this);
}

void ToolsAVP_Entity_InteractRetinalScanner::Create()
{
	CreationHelper( "Retinal Scanner", "RetinalScanner", 
		AVP_ServerEntity_InteractRetinalScanner::CreateFromTools, Create);
}

Tools_Object* ToolsAVP_Entity_InteractRetinalScanner::Create( Asura_Entity* pxEntity )
{
	ToolsAVP_Entity_InteractRetinalScanner* pxObject = new ToolsAVP_Entity_InteractRetinalScanner( AVP_ServerEntity_InteractRetinalScanner::FindEntity( pxEntity->GetGuid() ) );
	pxObject->UpdateToolsData();
	return pxObject;
}

Tools_Object* ToolsAVP_Entity_InteractRetinalScanner::CreateObjectOfThisType() const
{
	const Asura_Guid uGuid = Asura_Entity_System::GetCreatedByToolsGuid();

	// Set up tools data and auto-create a unique name (prompt for new name if there is a clash).
	Tools_Entity_Data *pxToolsData = CreateToolsDataWithDefaultName("Retinal Scanner", "RetinalScanner", uGuid);

	if(pxToolsData == NULL)
	{
		Asura_Assert(false, "ToolsAVP_Entity_InteractRetinalScanner::Create() - no tools data");
	}
	else
	{
		AVP_ServerEntity_InteractRetinalScanner* pxServerObject = new AVP_ServerEntity_InteractRetinalScanner(uGuid);
		pxServerObject->ToolsData = pxToolsData;
		ToolsAVP_Entity_InteractRetinalScanner *pxToolsObject = new ToolsAVP_Entity_InteractRetinalScanner(pxServerObject);
		Tools_Object_System::SelectObject(pxToolsObject);

		pxToolsObject->Position		= *Asura_Camera::GetPosition();
		pxToolsObject->Orientation.Identity();

		Tools_SaveAsura::SetEntityModified();
		return pxToolsObject;
	}
	return NULL;
}

void ToolsAVP_Entity_InteractRetinalScanner::AddActionsControls( Asura_Overlay* pxOverlay, Asura_Vector_2& xOffset )
{

	// Select head blueprint
	Asura_Dialog* pxDialog = new Asura_Function_Dialog("Head blueprint", xOffset, ChooseBlueprint, reinterpret_cast< int >( this ), &Changed);
	pxDialog->m_iControlID   = Asura_GetHashID("SelectHeadBlueprint");
	pxOverlay->AddDialog( pxDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();
	PARENT::AddActionsControls(pxOverlay, xOffset);

	Asura_Char szBuffer[32];

	AVP_ServerEntity_InteractRetinalScanner* pxRetinalScanner = static_cast<AVP_ServerEntity_InteractRetinalScanner*> (m_pxInteractObject);

	Asura_PrintfToBfr( szBuffer,"On use head(%d)", 32, true, Asura_StaticMessage_System::GetNumberOfMessagesInBlock( pxRetinalScanner->m_usPredatorUseHeadMessageBlock ) );
	
	pxDialog = new Asura_Function_Dialog( szBuffer, xOffset, EditOnPredatorUseHeadMessages );
	pxOverlay->AddDialog( pxDialog );
	xOffset.y += Asura_Dialog::DefaultSpacing();

	UpdateHeadBlueprint(pxOverlay);
}

void ToolsAVP_Entity_InteractRetinalScanner::UpdateHeadBlueprint(Asura_Overlay* pxNewOverlay)
{
	if(m_pxInteractObject)
	{
		char szText[100];

		AVP_ServerEntity_InteractRetinalScanner* pxRetinalScanner = static_cast<AVP_ServerEntity_InteractRetinalScanner*> (m_pxInteractObject);
		
		if ( pxRetinalScanner->GetVictimBlueprintHash() != ASURA_HASH_ID_UNSET)
		{
			Asura_Value xValue;
			Asura_Blueprint* pxBlueprint     = Asura_Blueprint_System::GetBlueprintByHashID( pxRetinalScanner->GetVictimBlueprintType(), pxRetinalScanner->GetVictimBlueprintHash());
			if(pxBlueprint)
			{
				Asura_PrintfToBfr(szText,"Head blueprint : %s",sizeof(szText), true, pxBlueprint->GetName());	
			}
		}
		else
		{
			strcpy(szText,"Head blueprint");
		}
		pxNewOverlay->UpdateDialogLabel(Asura_GetHashID("SelectHeadBlueprint"),szText);
	}
}

void ToolsAVP_Entity_InteractRetinalScanner::ChooseBlueprint( int iData )
{
	ToolsAVP_Entity_InteractRetinalScanner*  pxData			  = reinterpret_cast< ToolsAVP_Entity_InteractRetinalScanner* >( iData );
	AVP_ServerEntity_InteractRetinalScanner* pxRetinalScanner = static_cast<AVP_ServerEntity_InteractRetinalScanner*> (pxData->GetInteractObject());

	Asura_Hash_ID uBlueprintHashID = ( pxRetinalScanner->m_uVictimBlueprintHashID != ASURA_HASH_ID_UNSET ) ? pxRetinalScanner->m_uVictimBlueprintHashID : Asura_GetHashID( "Actor" );
	Asura_Hash_ID uBlueprintType   = uAVP_BLUEPRINT_TYPE_ACTORS;

	BlueprintSelect_Overlay xBPOverlay( "Choose A Blueprint", &uBlueprintHashID, &uBlueprintType );
	if ( !xBPOverlay.DoModal() ) { return; }

	pxRetinalScanner->m_uVictimBlueprintType   = uBlueprintType;
	pxRetinalScanner->m_uVictimBlueprintHashID = uBlueprintHashID;

	pxData->SetEntityModified();
	pxData->RefreshOverlay();
}


bool ToolsAVP_Entity_InteractRetinalScanner::GetEventDescForMessageBlock( unsigned short usMessageBlockID, Asura_String& xOutputDesc )
{
	AVP_ServerEntity_InteractRetinalScanner* pxRetinalScanner = static_cast<AVP_ServerEntity_InteractRetinalScanner*> (m_pxInteractObject);

	if ( m_pxInteractObject ) 
	{
		if ( pxRetinalScanner->m_usPredatorUseHeadMessageBlock == usMessageBlockID )
		{
			xOutputDesc = "On Predator use head";
			return true;
		}
		return PARENT::GetEventDescForMessageBlock(usMessageBlockID, xOutputDesc);
	}
	else
	{
		Asura_Assert(false, "No Interaction object!");
		return false;
	}
}

void ToolsAVP_Entity_InteractRetinalScanner::EditOnPredatorUseHeadMessages()
{
	Asura_Assert( s_pxThis, "No current tools Retinal scanner object!, will crash!" );
	AVP_ServerEntity_InteractRetinalScanner* pxRetinalScanner = static_cast<AVP_ServerEntity_InteractRetinalScanner*> (s_pxThis->GetInteractObject());
	Asura_Assert( pxRetinalScanner, "No Retinal scanner; will crash!" );

	#ifdef ASURA_TOOLS_USE_NEW_MESSAGE_EDITOR
	Tools_MessageEditor::StartMessageEditingMode(&pxRetinalScanner->m_usPredatorUseHeadMessageBlock);
	#else
	Tools_Object_System::EditMessageBlock( "On predator use head", &pxRetinalScanner->m_usPredatorUseHeadMessageBlock );
	#endif
}

bool ToolsAVP_Entity_InteractRetinalScanner::OwnsThisMessageBlock( unsigned short usMessageBlockID )
{
	AVP_ServerEntity_InteractRetinalScanner* pxRetinalScanner = static_cast<AVP_ServerEntity_InteractRetinalScanner*> (m_pxInteractObject);
	if (    pxRetinalScanner 
		&& (   pxRetinalScanner->m_usPredatorUseHeadMessageBlock == usMessageBlockID )   )
	{
		return true;
	}

	return PARENT::OwnsThisMessageBlock( usMessageBlockID );
}

void ToolsAVP_Entity_InteractRetinalScanner::Destroy()
{
	AVP_ServerEntity_InteractRetinalScanner* pxRetinalScanner = static_cast<AVP_ServerEntity_InteractRetinalScanner*> (m_pxInteractObject);

	//delete all the static messages
	Asura_StaticMessage_System::DeleteMessageBlock(pxRetinalScanner->m_usPredatorUseHeadMessageBlock);
	pxRetinalScanner->m_usPredatorUseHeadMessageBlock = ASURA_STATICMESSAGE_EMPTYBLOCK;

	PARENT::Destroy();
}

void ToolsAVP_Entity_InteractRetinalScanner::AddFilesToExportList(List<Asura_String>& xNameList) const
{
	AVP_ServerEntity_InteractRetinalScanner* pxRetinalScanner = static_cast<AVP_ServerEntity_InteractRetinalScanner*> (m_pxInteractObject);

	if(pxRetinalScanner)
	{
		const Asura_Blueprint* pxActorBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(pxRetinalScanner->GetVictimBlueprintType(), pxRetinalScanner->GetVictimBlueprintHash());
		if (!pxActorBlueprint) 
		{ 
			Asura_Assert( false, "Retinal scanner has no head blueprint specified!" );
			return;
		}
		const Asura_Blueprint* pxSkinElementBlueprint = NULL;

		Asura_Value xValue;

		if(pxActorBlueprint->GetParameterValueByHashID(0x0F8AC93F, xValue)) // 0x0F8AC93F GetHash("SkinElementHead")
		{
			pxSkinElementBlueprint = Asura_Blueprint_System::GetBlueprintByHashID( pxRetinalScanner->GetVictimBlueprintType(), xValue.GetHashIDValue());
		}

		if(pxSkinElementBlueprint)
		{
			Tools_Mode_Blueprint::AddBlueprintFilesToExportList(xNameList, pxRetinalScanner->GetVictimBlueprintType(), pxSkinElementBlueprint->GetHashID(), false);
		}
		else
		{
			Asura_Assert( false, "Could not find retinal scanner head blueprint!" );
		}
	}
	PARENT::AddFilesToExportList(xNameList);
}