#pragma newdecls required

#include <sourcemod>
#include <sdktools>
#include <dhooks>

Handle hAcceptInput;

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Plugin myinfo =
{
	name         = "GameTextManager",
	author       = "zaCade",
	description  = "",
	version      = "1.0.0",
};

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnPluginStart()
{
	Handle hGameConf;
	if ((hGameConf = LoadGameConfigFile("sdktools.games")) == INVALID_HANDLE)
	{
		SetFailState("Couldn't load \"sdktools.games\" game config!");
		return;
	}

	// CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
	int iOffset;
	if ((iOffset = GameConfGetOffset(hGameConf, "AcceptInput")) == -1)
	{
		CloseHandle(hGameConf);
		SetFailState("GameConfGetOffset(hGameConf, \"AcceptInput\") failed!");
		return;
	}

	if ((hAcceptInput = DHookCreate(iOffset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, OnAcceptInput)) == INVALID_HANDLE)
	{
		CloseHandle(hGameConf);
		SetFailState("DHookCreate(iOffset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, OnAcceptInput) failed!");
		return;
	}

	DHookAddParam(hAcceptInput, HookParamType_CharPtr);
	DHookAddParam(hAcceptInput, HookParamType_CBaseEntity);
	DHookAddParam(hAcceptInput, HookParamType_CBaseEntity);
	DHookAddParam(hAcceptInput, HookParamType_Object, 20, DHookPass_ByVal|DHookPass_ODTOR|DHookPass_OCTOR|DHookPass_OASSIGNOP);
	DHookAddParam(hAcceptInput, HookParamType_Int);

	// Late load.
	int entity = INVALID_ENT_REFERENCE;
	while ((entity = FindEntityByClassname(entity, "game_text")) != INVALID_ENT_REFERENCE)
	{
		OnEntityCreated(entity, "game_text");
	}

	CloseHandle(hGameConf);
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnEntityCreated(int entity, const char[] classname)
{
	if (StrEqual(classname, "game_text", false) == 0)
	{
		DHookEntity(hAcceptInput, false, entity);
	}
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//
// <int>    m_textParms.channel
// <float>  m_textParms.x
// <float>  m_textParms.y
// <int>    m_textParms.r1
// <int>    m_textParms.g1
// <int>    m_textParms.b1
// <int>    m_textParms.a1
// <int>    m_textParms.r2
// <int>    m_textParms.g2
// <int>    m_textParms.b2
// <int>    m_textParms.a2
// <int>    m_textParms.effect
// <float>  m_textParms.fadeinTime
// <float>  m_textParms.fadeoutTime
// <float>  m_textParms.holdTime
// <float>  m_textParms.fxTime
// <char>   m_iszMessage
//----------------------------------------------------------------------------------------------------
public MRESReturn OnAcceptInput(int entity, Handle hReturn, Handle hParams)
{
	char sInputName[128];
	DHookGetParamString(hParams, 1, sInputName, sizeof(sInputName));

	if(!StrEqual(sInputName, "Display", false))
		return MRES_Ignored;

	char sMessage[512];
	GetEntPropString(entity, Prop_Data, "m_iszMessage", sMessage, sizeof(sMessage));

	if (!sMessage[0])
		return MRES_Ignored;

	CMessage Message = new CMessage(sMessage);

	Message.hPlugin         = INVALID_HANDLE;
	Message.iEntity         = EntIndexToEntRef(entity);
	Message.iChannel        = GetEntProp(entity, Prop_Data, "m_textParms.channel");

	Message.fPositionX      = GetEntPropFloat(entity, Prop_Data, "m_textParms.x");
	Message.fPositionY      = GetEntPropFloat(entity, Prop_Data, "m_textParms.y");

	Message.iColorOneR      = GetEntProp(entity, Prop_Data, "m_textParms.r1");
	Message.iColorOneG      = GetEntProp(entity, Prop_Data, "m_textParms.g1");
	Message.iColorOneB      = GetEntProp(entity, Prop_Data, "m_textParms.b1");
	Message.iColorOneA      = GetEntProp(entity, Prop_Data, "m_textParms.a1");

	Message.iColorTwoR      = GetEntProp(entity, Prop_Data, "m_textParms.r2");
	Message.iColorTwoG      = GetEntProp(entity, Prop_Data, "m_textParms.g2");
	Message.iColorTwoB      = GetEntProp(entity, Prop_Data, "m_textParms.b2");
	Message.iColorTwoA      = GetEntProp(entity, Prop_Data, "m_textParms.a2");

	Message.iEffect         = GetEntProp(entity, Prop_Data, "m_textParms.effect");

	Message.fFadeInTime     = GetEntPropFloat(entity, Prop_Data, "m_textParms.fadeinTime");
	Message.fFadeOutTime    = GetEntPropFloat(entity, Prop_Data, "m_textParms.fadeoutTime");
	Message.fHoldTime       = GetEntPropFloat(entity, Prop_Data, "m_textParms.holdTime");
	Message.fFXTime         = GetEntPropFloat(entity, Prop_Data, "m_textParms.fxTime");

	g_hMessageQueue.Push(Message);

	DHookSetReturn(hReturn, false);
	return MRES_Supercede;
}
