#pragma semicolon 1

#include <sourcemod>
#include <cstrike>
#include <multicolors>
#include <zombiereloaded>
#include <AFKManager>

bool g_bTestRound;
bool g_bAdminTestRound;
bool g_bMotherZM[MAXPLAYERS + 1] = { false, ...};

int g_iAFKTime;

public Plugin myinfo =
{
	name = "Zombie Manager",
	author = "Dogan",
	description = "Tools to manage testround and zombies",
	version = "1.2.0",
	url = ""
};

public void OnPluginStart()
{
	g_bTestRound = false;
	g_bAdminTestRound = false;

	RegAdminCmd("sm_testround", Command_Testround, ADMFLAG_GENERIC, "Toggle to enable/disable a test round.");

	CreateTimer(20.0, Timer_MessageTestRound, _, TIMER_REPEAT);

	HookEvent("round_start", OnRoundStart);
	HookEvent("player_spawn", OnClientSpawn);
	HookEvent("player_team", OnPlayerTeam);

	ConVar cvar;
	HookConVarChange((cvar = CreateConVar("sm_player_afk_time", "120", "AFK Time in seconds after which a player won't turn into a motherzombie")), Cvar_AFKTime);
	g_iAFKTime = cvar.IntValue;
	delete cvar;

	AutoExecConfig(true, "plugin.ZombieManager");

	AddMultiTargetFilter("@mzombie", Filter_Motherzombies, "Mother Zombies", false);
	RegConsoleCmd("sm_mzombie", Command_DisplayMotherzombies, "Current Mother Zombies");
	RegConsoleCmd("sm_mzombies", Command_DisplayMotherzombies, "Current Mother Zombies");
}

public void OnPluginEnd()
{
	RemoveMultiTargetFilter("@mzombie", Filter_Motherzombies);
}

public void Cvar_AFKTime(ConVar convar, const char[] oldValue, const char[] newValue)
{
	g_iAFKTime = convar.IntValue;
}

public void OnRoundStart(Event hEvent, const char[] sName, bool bDontBroadcast)
{
	g_bTestRound = false;
	g_bAdminTestRound = false;

	for(int i = 1; i <= MaxClients; i++)
	{
		g_bMotherZM[i] = false;
	}
}

public void ZR_OnClientHumanPost(int client, bool respawn, bool protect)
{
	g_bMotherZM[client] = false;
}

public Action ZR_OnClientInfect(int &client, int &attacker, bool &motherInfect, bool &respawnOverride, bool &respawn)
{
	if(g_bTestRound)
		return Plugin_Handled;

	return Plugin_Continue;
}

public Action ZR_OnClientMotherZombieEligible(int client)
{
	if(GetClientIdleTime(client) > g_iAFKTime || IsFakeClient(client))
		return Plugin_Handled;

	return Plugin_Continue;
}

public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
{
	g_bMotherZM[client] = motherInfect;
}

public Action ZR_OnInfectCountdown()
{
	if(g_bTestRound)
		return Plugin_Handled;

	return Plugin_Continue;
}

public void OnClientSpawn(Event hEvent, const char[] sName, bool bDontBroadcast)
{
	int client = GetClientOfUserId(hEvent.GetInt("userid"));

	g_bMotherZM[client] = false;
}

public Action OnPlayerTeam(Event event, const char[] name, bool dontBroadcast)
{
	int client = GetClientOfUserId(GetEventInt(event, "userid"));

	g_bMotherZM[client] = false;
}

public bool Filter_Motherzombies(const char[] sPattern, Handle hClients, int client)
{
	for(int i = 1; i <= MaxClients; i++)
	{
		if(IsClientInGame(i) && !IsFakeClient(i))
		{
			if(g_bMotherZM[i])
				PushArrayCell(hClients, i);
		}
	}

	return true;
}

public Action Command_DisplayMotherzombies(int client, int args)
{
	char aBuf[1024];
	char aBuf2[MAX_NAME_LENGTH];

	for(int i = 1; i <= MaxClients; i++)
	{
		if(IsClientInGame(i) && !IsFakeClient(i))
		{
			if(g_bMotherZM[i])
			{
				GetClientName(i, aBuf2, sizeof(aBuf2));
				StrCat(aBuf, sizeof(aBuf), aBuf2);
				StrCat(aBuf, sizeof(aBuf), ", ");
			}
		}
	}

	if(strlen(aBuf))
	{
		aBuf[strlen(aBuf) - 2] = 0;
		ReplyToCommand(client, "[SM] Current Mother Zombies: %s", aBuf);
	}
	else
		ReplyToCommand(client, "[SM] Current Mother Zombies: none");

	return Plugin_Handled;
}

public Action Command_Testround(int client, int args)
{
	/*if(GetClientTeam(client) == CS_TEAM_SPECTATOR)
	{
		ReplyToCommand(client, "[SM] Please join a Team first.");
		return Plugin_Handled;
	}

	if(!IsPlayerAlive(client))
	{
		ReplyToCommand(client, "[SM] Please respawn yourself first.");
		return Plugin_Handled;
	}*/

	ToggleTestRound(client);
	return Plugin_Handled;
}

public void ToggleTestRound(int client)
{
	g_bAdminTestRound = !g_bAdminTestRound;

	if(g_bTestRound)
	{
		g_bTestRound = false;

		ReplyToCommand(client, "[SM] Deactivated this Test Round.");
		CPrintToChatAll("[SM] %N deactivated this Test Round!", client);
		LogAction(client, -1, "\"%L\" deactivated this Test Round.", client);
	}
	else
	{
		g_bTestRound = true;

		ReplyToCommand(client, "[SM] Activated a Test Round.");
		CPrintToChatAll("[SM] %N activated a Test Round!", client);
		LogAction(client, -1, "\"%L\" activated a Test Round.", client);

		for(int i = 1; i <= MaxClients; i++)
		{
			if(IsClientInGame(i) && !IsFakeClient(i) && IsPlayerAlive(i) && ZR_IsClientZombie(i))
			{
				ZR_HumanClient(i, false, false);
			}
		}
	}
}

public Action CS_OnTerminateRound(float &delay, CSRoundEndReason &reason)
{
	if(g_bTestRound)
		return Plugin_Handled;

	return Plugin_Continue;
}

public Action ZR_OnClientRespawn(int &client, ZR_RespawnCondition &condition)
{
    if(g_bTestRound)
        condition = ZR_Respawn_Human;

    return Plugin_Changed;
}

public Action Timer_MessageTestRound(Handle timer)
{
	if(g_bTestRound)
	{
		CPrintToChatAll("{cyan}[UNLOZE] {red}This is a Test Round!");
		CPrintToChatAll("{cyan}[UNLOZE] {red}This is a Test Round!");
		CPrintToChatAll("{cyan}[UNLOZE] {red}This is a Test Round!");
	}

	return Plugin_Continue;
}