#include <sourcemod>
#include <cstrike>
#include <sdktools>
#include <basics/basics>
#pragma semicolon 1
#pragma dynamic 131072 
#include <profiler>

#define AMOUNTLIMIT 256
#define SIZELIMIT 64


// ---------- HANDLE ----------
// Profiler
new Handle:g_Prof = INVALID_HANDLE;

// Timer
new Handle:DelayTimer = INVALID_HANDLE;
// ---------- HANDLE ----------


// ---------- STRING ----------
// Readin
new String:Files[SIZELIMIT];

// 2d Maps
new String:Maps[AMOUNTLIMIT][SIZELIMIT];
new MapsCount;

// 2d Maps ohne Navs
new String:MapsWithoutNavs[AMOUNTLIMIT][SIZELIMIT];
new MapsWithoutNavsCount;

// Misc
new String:sTemp[64];
// ---------- STRING ----------


// ---------- INTEGER ----------
// Locator
new StartFrom =1;
// ---------- INTEGER ----------


// ---------- BOOL ----------

// Switch
new bool:InProgress = false;
// ---------- BOOL ---------




public Plugin:myinfo = 
{
	name = "Nav Generator",
	author = "Impact",
	description = "Lets write a description, yay!",
	version = "0.1",
	url = "http://gugyclan.eu"
}




// ---------- ONPLUGINSTART ----------
public OnPluginStart()
{
	RegServerCmd("sm_generate", Command_Generate);
	g_Prof = CreateProfiler();
}
// ---------- ONPLUGINSTART ----------




// ---------- ONMAPSTART ----------
public OnMapStart()
{
	if(InProgress)
	{
		CreateTimer(5.0, AddBots, TIMER_FLAG_NO_MAPCHANGE);
	}
}
// ---------- ONMAPSTART ----------




// ---------- COMMAND_GENERATE ----------
public Action:Command_Generate(args)
{
	// Wenn im Prozess terminiere
	if(InProgress)
	{
		return Plugin_Handled;
	}
	
	StartProfiling(g_Prof);
	
	// Reset onst gibt es ueberlauefe
	MapsCount = 0;
	MapsWithoutNavsCount = 0;
	
	
	// Wichtig fuer readdirentry
	new FileType:type;
	
	// Maps Auflisten
	new Handle:dir = OpenDirectory("maps");
	// Maps lesen und in Files speichern
	while (ReadDirEntry(dir, Files, sizeof(Files), type))
	{
		// Wenns ne Map is
		if(type == FileType_File && StrContains(Files, ".bsp") != -1 && StrContains(Files, ".ztmp") == -1 && StrContains(Files, ".nav") == -1 && StrContains(Files, "test_hardware") == -1 && StrContains(Files, "test_speakers") == -1)
		{
			// .bsp entfernen
			ReplaceString(Files, sizeof(Files), ".bsp", "");
			Maps[MapsCount] = Files;
			MapsCount++;
			//PrintToServer(" -> MAP %s", Files);
		}
	}
	CloseHandle(dir);
	
	// Mapschleife, fuer Jede Map
	for(new i; i<MapsCount;i++)
	{
		Format(sTemp, sizeof(sTemp), "maps/%s.nav", Maps[i]);
		
		if(!FileExists(sTemp))
		{
			MapsWithoutNavs[MapsWithoutNavsCount] = Maps[i];
			MapsWithoutNavsCount++;
		}
	}
	
	
	PrintToServer("%d von %d Maps haben keine Navs", MapsWithoutNavsCount, MapsCount);
	StopProfiling(g_Prof);
	
	
	PrintToServer("Benchmark: %f seconds", GetProfilerTime(g_Prof));
	
	if(MapsWithoutNavsCount != 0)
	{
		ChangeMap();
		InProgress = true;
	}
	
	return Plugin_Handled;
}
// ---------- COMMAND_GENERATE ----------




// ---------- FUNCTION_CHANGEMAP ----------
ChangeMap()
{
	// Wenn die Anzahl der Start(Locators) unter oder gleich der fehlenden Navs sind
	if(StartFrom <= MapsWithoutNavsCount)
	{
		decl String:ChangedMap[64];
		Format(ChangedMap, sizeof(ChangedMap), "%s", MapsWithoutNavs[StartFrom]);
		
		ServerCommand("bot_quota 2");
		ServerCommand("bot_join_after_player 0");
		ServerCommand("changelevel %s", MapsWithoutNavs[StartFrom-1]);
		
		// Erhoehen
		StartFrom++;
		Format(sTemp, sizeof(sTemp), "maps/%s.nav",  MapsWithoutNavs[StartFrom]);
		DelayTimer = CreateTimer(5.0, ChangeMapDelayed, _, TIMER_REPEAT);
	}
	else
	{
		SafeKillTimer(DelayTimer);
		InProgress = false;
		PrintToServer("_-_-_-_- FERTIG _-_-_-_-");
		// Reset
		StartFrom = 1;
	}
}
// ---------- FUNCTION_CHANGEMAP ----------




// ---------- TIMER_CHANGEMAPDELAYED ----------
public Action:ChangeMapDelayed(Handle:timer)
{
	StartProfiling(g_Prof);
	
	decl String:CurrentMap[64], String:tTemp[64];
	GetCurrentMap(CurrentMap, sizeof(CurrentMap));
	Format(tTemp, sizeof(tTemp), "maps/%s.nav",  CurrentMap);
	
	if(FileExists(sTemp))
	{
		SafeKillTimer(DelayTimer);
		ChangeMap();
	}
	else if(FileExists(tTemp))
	{
		SafeKillTimer(DelayTimer);
		ChangeMap();
	}
	else
	{
		// Erstmal nuescht
	}
	StopProfiling(g_Prof);
	PrintToServer("Benchmark2: %f seconds", GetProfilerTime(g_Prof));
}
// ---------- TIMER_CHANGEMAPDELAYED ----------





public Action:AddBots(Handle:timer)
{
	ServerCommand("bot_join_after_player 0");
	ServerCommand("bot_quota 2");
}