#pragma semicolon 1

#define DEBUG

#define PLUGIN_AUTHOR "jenz"
#define PLUGIN_VERSION "1.00"

#include <sourcemod>
#include <sdktools>
#include <system2>

#pragma newdecls required

static char g_sEventURL[PLATFORM_MAX_PATH];
char c_EventContent[526][526];
bool b_eventLink[MAXPLAYERS];


public Plugin myinfo = 
{
	name = "unloze_EventScheduler",
	author = PLUGIN_AUTHOR,
	description = "Ingame Event Notifier",
	version = PLUGIN_VERSION,
	url = "www.unloze.com"
};

//----------------------------------------------------------------------------------------------------
// Purpose: pluginstart/ mapstart
//----------------------------------------------------------------------------------------------------

public void OnPluginStart()
{
	//commands
	RegConsoleCmd("say", Cmd_Say);
	RegAdminCmd("sm_event", Cmd_EventNotifier, ADMFLAG_GENERIC);
	RegAdminCmd("sm_mapstartevent", Cmd_CheckEventInfo, ADMFLAG_ROOT);
	
	//FilePath
	BuildPath(Path_SM, g_sEventURL, sizeof(g_sEventURL), "configs/EventURL.txt");
}

public void OnMapStart()
{
	EventInfo();
}

//----------------------------------------------------------------------------------------------------
// Purpose: timer notifications
//----------------------------------------------------------------------------------------------------

public Action EventCountDown(Handle timer)
{
	//PrintToChatAll("c_EventContent[1]: %s", c_EventContent[1]);
	//PrintToChatAll("c_EventContent[2]: %s", c_EventContent[2]);
	CalculateTimeToNextEvent(c_EventContent[1], c_EventContent[2]);
	return Plugin_Handled;
}

//----------------------------------------------------------------------------------------------------
// Purpose: CalculateTimeToNextEvent
//----------------------------------------------------------------------------------------------------
public void CalculateTimeToNextEvent(char[] content, char[] content1)
{
	char sPart[2][526];
	char sMonth[24];
	char sDay[24];
	char sHour[24];
	char sMinute[24];
	int i_Month;
	int i_Day;
	int i_Hour;
	int i_Minute;
	int months;
	int days;
	int hours;
	int minutes;
	FormatTime(sMonth, sizeof(sMonth), "%m");
	FormatTime(sDay, sizeof(sDay), "%d");
	FormatTime(sHour, sizeof(sHour), "%H");
	FormatTime(sMinute, sizeof(sMinute), "%M");
	TrimString(content);
	TrimString(content1);
	ExplodeString(content, "/", sPart, 2, 526);
	//update we apperently need to know month
	i_Day = StringToInt(sDay);
	days = StringToInt(sPart[0]);
	i_Month = StringToInt(sMonth);
	ExplodeString(sPart[1], "/", sPart, 2, 526);
	months = StringToInt(sPart[0]);
	i_Hour = StringToInt(sHour);
	hours = StringToInt(content1);
	//PrintToChatAll("hours: %i", hours);
	i_Minute = StringToInt(sMinute);
	if (days >= i_Day || months > i_Month)
	{
		///SHIIIET
		if (days >= i_Day)
		{
			days -= i_Day;
		}
		else if (i_Month == 1 || i_Month == 3 || i_Month == 5 || i_Month == 7 || i_Month == 8 || i_Month == 10 || i_Month == 12)
		{
			days += (31 - i_Day);
		}
		else if (i_Month == 2)
		{
			days += (28 - i_Day);
		}
		else
		{
			days += (30 - i_Day);
		}
		
		//from 12 to 24 or from 7 to 19 etc etc
		hours += 12;
		if (i_Hour > hours)
		{
			days -= 1;
			hours = 24 - (i_Hour - hours);
			//PrintToChatAll("if statement hours: %i", hours);
		}
		else
		{
			hours -= i_Hour;
			//PrintToChatAll("else statement: hours: %i", hours);
		}
		//should solve one hour delay
		if (hours != 0)
		{
			hours -= 1;
		}
		
		minutes = 60 - i_Minute;
		PrintToChatAll("\x06[UNLOZE]\x03 Next Event is: Event# %s", c_EventContent[0]);
		PrintToChatAll("\x06[UNLOZE]\x03 Taking Place in: %i Days, %i Hours, %i Minutes", days, hours, minutes);
		PrintToChatAll("\x06[UNLOZE]\x03 Rewards: %s VIP", c_EventContent[3]);
	}
	else
	{
		//PrintToChatAll("days: %i \ni_Day: %i", days, i_Day);
		//PrintToChatAll("months: %i \ni_Month: %i", months, i_Month);
		PrintToChatAll("[UNLOZE] Waiting for next Event to be Scheduled...");
	}
}

//----------------------------------------------------------------------------------------------------
// Purpose: EventInfo
//----------------------------------------------------------------------------------------------------
public void EventInfo()
{
	//manual check if map event is read correctly on mapstart
	Handle zonefile = INVALID_HANDLE;
	char line[526];
	//PrintToChatAll("g_sEventURL: %s", g_sEventURL);
	zonefile = OpenFile(g_sEventURL, "r");
	if (zonefile == INVALID_HANDLE)
	{
		//PrintToChatAll("Invalid handle");
		return;
	}
	ReadFileLine(zonefile, line, sizeof(line));
	//reading the link on every mapstart
	ReplaceString(line, sizeof(line), "\"", "", false);
	//PrintToChatAll("line: %s", line);
	System2HTTPRequest httpRequest = new System2HTTPRequest(HttpResponseCallback, line);
	httpRequest.GET();
	delete httpRequest;
	delete zonefile;
	//5 minutes just
	CreateTimer(300.0, EventCountDown, INVALID_HANDLE, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
}

//----------------------------------------------------------------------------------------------------
// Purpose: cmds & menus
//----------------------------------------------------------------------------------------------------
public Action Cmd_CheckEventInfo(int client, any args)
{
	EventInfo();
	return Plugin_Handled;
}

public Action Cmd_EventNotifier(int client, any args)
{
	EventNotifierMenu(client);
	return Plugin_Handled;
}

static void EventNotifierMenu(int client)
{
	char c_local[526];
	Format(c_local, sizeof(c_local), "Next Event: %s", c_EventContent[0]);
	Menu EventMenu = CreateMenu(Event_Menu);
	EventMenu.SetTitle("UNLOZE Event Scheduler");
	EventMenu.AddItem("nothing here", c_local, ITEMDRAW_DISABLED);
	EventMenu.AddItem("nothing here", "Link an Event");
	EventMenu.ExitButton = true;
	EventMenu.ExitBackButton = true;
	EventMenu.Display(client, 30);
}

public int Event_Menu(Menu menu, MenuAction action, int client, int choice)
{
	if (action == MenuAction_Select)
	{
		if (choice == 1) 
		{
			PrintToChat(client, "Copy the Event link Into the chat!");
			b_eventLink[client] = true;
		}
		else if (action == MenuAction_End) 
		{
			delete(menu);
		}
	}
}

//----------------------------------------------------------------------------------------------------
// Purpose: simple say hook
//----------------------------------------------------------------------------------------------------
public Action Cmd_Say(int client, int args)
{
	if (b_eventLink[client])
	{
		char arg[526];
		GetCmdArgString(arg, sizeof(arg));
		PrintToChat(client, "arg: %s", arg);
		ReplaceString(arg, sizeof(arg), "\"", "", false);
		System2HTTPRequest httpRequest = new System2HTTPRequest(HttpResponseCallback, arg);
		httpRequest.GET();
		delete httpRequest;
		b_eventLink[client] = false;
		
		Handle zonefile = INVALID_HANDLE;
		zonefile = OpenFile(g_sEventURL, "w");
		//one would think storing  c_EventContent[0] could be better ohwell
		WriteFileLine(zonefile, arg);
		delete zonefile;
		return Plugin_Handled;
	}
	return Plugin_Continue;
}

//----------------------------------------------------------------------------------------------------
// Purpose: http callbacks
//----------------------------------------------------------------------------------------------------
public void HttpResponseCallback(bool success, const char[] error, System2HTTPRequest request, System2HTTPResponse response, HTTPRequestMethod method) 
{
    if (success) 
    {
		//PrintToChatAll("Success");
		char content[526];
		char content1[1080];
		//for some horrifying reason this is inconsistent
		for (int found = 0; found < response.ContentLength;) 
		{
			found += response.GetContent(content, sizeof(content), found);
			FindRelevantData(content);
		}
		for (int found = 0; found < response.ContentLength;) 
		{
			found += response.GetContent(content1, sizeof(content1), found);
			FindRelevantDataRewards(content1);
		}
		
		ReplaceString(c_EventContent[0], sizeof(c_EventContent), "<title>", "", false);
		ReplaceString(c_EventContent[0], sizeof(c_EventContent), "| UNLOZE", "", false);
    }
}

//----------------------------------------------------------------------------------------------------
// Purpose: Finds relevant data like event title, hours & days left, event rewards
//----------------------------------------------------------------------------------------------------
public void FindRelevantDataRewards(char[] content)
{
	if (StrContains(content, "Prize :", false) > -1)
	{
		//this is fragile as fuck 
		char sPart[2][526];
		//PrintToChatAll("Prize content: %s", content);
		ExplodeString(content, "Prize :", sPart, 2, 526);
		//PrintToChatAll("sPart[1]: %s", sPart[1]);
		//PrintToChatAll("sPart[0]: %s", sPart[0]);
		c_EventContent[3] = sPart[1];
		ExplodeString(c_EventContent[3], "VIP", sPart, 2, 526);
		c_EventContent[3] = sPart[0];
		ReplaceString(c_EventContent[3], sizeof(c_EventContent), "</span></b>", "");
		PrintToChatAll("c_EventContent[3]: %s", c_EventContent[3]);
	}
}
public void FindRelevantData(char[] content)
{
	if (StrContains(content, "content=\"Event#", true) > -1)
	{
		char sPart[2][526];
		//PrintToChatAll("content: %s", content);
		//if event managers change formatting heads will roll 
		ExplodeString(content, "content=\"Event#", sPart, 2, 526);
		//PrintToChatAll("sPart[0]: %s", sPart[0]);
		//PrintToChatAll("sPart[1]: %s", sPart[1]);
		c_EventContent[0] = sPart[1];
		ExplodeString(c_EventContent[0], "\"/>", sPart, 2, 526);
		//PrintToChatAll("POST sPart[0]: %s", sPart[0]);
		c_EventContent[0] = sPart[0];
		ReplaceString(c_EventContent[0], sizeof(c_EventContent), "amp;", "", false);
				
	}
	if (StrContains(content, "Date :", true) > -1)
	{
		//PrintToChatAll("StrContains Date :%s", content);
		char sPart[2][526];
		char c_localfix[526];
		//PrintToChatAll("c_EventContent[1] Pre: %s", c_EventContent[1]);
		//THIS IS FIIIINE
		ExplodeString(content, "Date :", sPart, 2, 526);
		c_localfix = sPart[1];
		//PrintToChatAll("Date c_localfix: %s", c_localfix);
		ExplodeString(c_localfix, "</span><br/>", sPart, 2, 526);
		c_localfix = sPart[0];
		TrimString(c_localfix);
		if (StrContains(c_localfix, "'\">") > -1)
		{
			ExplodeString(c_localfix, "'\">", sPart, 2, 526);
		}
		else if (StrContains(c_localfix, "</b></span>") > -1)
		{
			ExplodeString(c_localfix, "</b></span>", sPart, 2, 526);
		}
		//PrintToChatAll("</span><br/> c_localfix: %s", c_localfix);
		//PrintToChatAll("POST Day sPart[0]: %s", sPart[0]);
		c_EventContent[1] = sPart[1];
		ReplaceString(c_EventContent[1], sizeof(c_EventContent), "</span></span>", "");
		PrintToChatAll("c_EventContent[1]: %s", c_EventContent[1]);
	}
	if (StrContains(content, "Time :", true) > -1)
	{
		char sPart[2][526];
		//if event managers change formatting heads will roll 
		SplitString(content, " pm GMT+2", c_EventContent[2], sizeof(c_EventContent));
		//THIS IS FIIIINE
		ExplodeString(c_EventContent[2], "pm GMT+1", sPart, 2, 526);
		//PrintToChatAll("hour sPart[0]: %s", sPart[0]);
		c_EventContent[2] = sPart[1];
		ReplaceString(c_EventContent[2], sizeof(c_EventContent), "/", "", false);
		TrimString(c_EventContent[2]);
		PrintToChatAll("c_EventContent[2]: %s", c_EventContent[2]);
	}
}

//----------------------------------------------------------------------------------------------------
// Purpose: OnClientPostAdminCheck && disconnect
//----------------------------------------------------------------------------------------------------
public void OnClientPostAdminCheck(int client)
{
	b_eventLink[client] = false;
}

public void OnClientDisconnect(int client)
{
	b_eventLink[client] = false;
}