#include <multicolors>
#include <sourcemod>
#include <sdktools>
#include <pscd>
#pragma newdecls required

float roundStartedTime = -1.0;
int g_iTextChannel;
bool g_bDisabled;
ConVar g_cvEnabled;

public Plugin myinfo =
{
	name = "UNLOZE Console Messages",
	description = "Make console messages printed by maps more fancy",
	author = "zaCade, decompiled by Neon and slightly modified by jenz",
	version = "1.2",
	url = ""
};

public void OnPluginStart()
{
	g_cvEnabled = CreateConVar("sm_centertext", "1", "Enable the 'game_text' message", 0, true, 0.0, true, 1.0);
	HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy);
}

public void OnMapStart()
{
	bool bChannelTaken[6];
	bool bChannelFound;
	int entity = -1;
	while ((entity = FindEntityByClassname(entity, "game_text")) != -1)
	{
		int channel = GetEntProp(entity, Prop_Data, "m_textParms.channel", 4, 0);
		LogMessage("Checking channel: %d", channel);
		if (channel < 6)
		{
			if (!bChannelTaken[channel])
			{
				LogMessage("Channel in use: %d", channel);
				bChannelTaken[channel] = true;
			}
		}
	}
	int channel;
	while (channel < 6)
	{
		if (!bChannelTaken[channel])
		{
			LogMessage("Using channel: %d", channel);
			g_iTextChannel = channel;
			bChannelFound = true;
			if (!bChannelFound)
			{
				LogMessage("No channel found!");
				g_bDisabled = true;
			}
			return;
		}
		channel++;
	}
	if (!bChannelFound)
	{
		LogMessage("No channel found!");
		g_bDisabled = true;
	}
	return;
}

public float GetRoundTimeAtTimerEnd(int number)
{
	float g = GetCurrentRoundTime() - number;
	return g;
}

public float GetCurrentRoundTime()
{
	Handle hFreezeTime = FindConVar("mp_freezetime"); // Freezetime Handle
	int freezeTime = GetConVarInt(hFreezeTime); // Freezetime in seconds
	return GameRules_GetProp("m_iRoundTime") - ((GetEngineTime() - roundStartedTime) - freezeTime);
}

public void Event_RoundStart(Handle event, const char[] name, bool dontBroadcast)
{
	roundStartedTime = GetEngineTime();
}

public bool CheckString(const char[] string)
{
	char Blacklist[][] = {
		"recharge", "recast", "cooldown", "cool"
	};
	for (int i = 0; i < sizeof(Blacklist); i++)
	{
		if (StrContains(string, Blacklist[i], false) != -1)
		{
			return true;
		}
	}
	return false;
}


public Action PointServerCommandForward(const char[] sCommand)
{
	if (!strncmp("say", sCommand, 3, false))
	{
		char sMessage[512];
		char sSecondsAppend[32];
                bool found_numeric = false;
		int i;
		while (strlen(sCommand) + -4 > i)
		{
			sMessage[i] = sCommand[i + 4];
			i++;
		}
		if (StrContains(sMessage, "sec", false) != -1 && !CheckString(sMessage))
		{
			int indexTracker = -1
			int endIndexTracker = -1
			for (int j = 0; j < strlen(sMessage); ++j)
			{
				if (IsCharNumeric(sMessage[j]))
				{
					found_numeric = true;
					if (indexTracker == -1)
					{
						indexTracker = j;
					}
				}
				else if (found_numeric)
				{
					endIndexTracker = j;
					break;
				}
			}
			if (found_numeric)
			{
				if (endIndexTracker == -1)
				{
					endIndexTracker = strlen(sMessage);
				}
				char SecondsLocal[512];
				for (int ij = indexTracker; ij < endIndexTracker; ij++)
				{
					StrCat(SecondsLocal, sizeof(SecondsLocal), sMessage[ij]);
				}
				int number = StringToInt(SecondsLocal);
				//PrintToChatAll("number: %i", number);
				if (GetRoundTimeAtTimerEnd(number) > 0.0)
				{
					float client_time = GetRoundTimeAtTimerEnd(number);
					char sTime[32];
					FormatPlayerTime(client_time, sTime, sizeof(sTime));
					Format(sSecondsAppend, sizeof(sSecondsAppend), " {green}@ %s", sTime);
				}
			}
		}
		if (found_numeric)
		{
			CPrintToChatAll("{CRIMSON}[NARRATOR] {WHITESMOKE}%s%s", sMessage, sSecondsAppend);
		}
		else
		{
			CPrintToChatAll("{CRIMSON}[NARRATOR] {WHITESMOKE}%s", sMessage);
		}
		if (!g_bDisabled)
		{
			if (g_cvEnabled.BoolValue)
			{
				Handle hMessage = StartMessageAll("HudMsg", 0);
				if (hMessage)
				{
					BfWriteByte(hMessage, g_iTextChannel);
					BfWriteFloat(hMessage, -1.0);
					BfWriteFloat(hMessage, 0.15);
					BfWriteByte(hMessage, 200);
					BfWriteByte(hMessage, 200);
					BfWriteByte(hMessage, 200);
					BfWriteByte(hMessage, 255);
					BfWriteByte(hMessage, 200);
					BfWriteByte(hMessage, 200);
					BfWriteByte(hMessage, 200);
					BfWriteByte(hMessage, 255);
					BfWriteByte(hMessage, 0);
					BfWriteFloat(hMessage, 0.5);
					BfWriteFloat(hMessage, 0.0);
					BfWriteFloat(hMessage, 5.0);
					BfWriteFloat(hMessage, 0.0);
					BfWriteString(hMessage, sMessage);
					EndMessage();
				}
			}
		}
		return Plugin_Handled;
	}
	return Plugin_Continue;
}

stock void FormatPlayerTime(float fTime, char[] sResult, int iMaxlength)
{
	int iMinutes = RoundToFloor(fTime / 60);
	fTime -= iMinutes * 60;
	int iSeconds = RoundToFloor(fTime);

	if(iMinutes)
		Format(sResult, iMaxlength, "%d:%02d", iMinutes, iSeconds);
	else
		Format(sResult, iMaxlength, "%d", iSeconds);
}
