/*
Old style text menu, place holder for vgui ....
*/

#include "gen_bot_header.h"
#include "teamplay_gamerules.h"

//harSens: Linux compile fix
extern CLeftOutput lcout;

extern int gmsgShowMenu;

void (*NMenu::pCurrentMenuFunction)(void) = NULL;
short NMenu::CurrentMenuChoice;
short NMenu::SBotType = 0;
short NMenu::BotTeam = 0;
short NMenu::BotSkill = 0;
char *NMenu::CurrentMenuText;
int NMenu::CurrentKeySlots;

const char *NMenu::MainMenuText =
{"ESF-Bot Menu\n\n"
 "1: Add Random Bot\n"
 "2: Add Custom Bot\n"   
 "3: Super Bot Menu\n"
 "4: Fill Server\n" 
 "5: Advanced Options\n"
 "6: Chat Settings\n"
 "7: Kick Last Bot\n"
 "8: Kick Bots\n"
 "9: Debug Options\n\n"
 "0: Exit"
};

const char *NMenu::CustomBotSkillMenuText =
{"Add Custom Bot - Select a Skill\n\n"
 "1: Best\n"
 "2: Good\n"
 "3: Medium\n"
 "4: Weak\n"
 "5: Bad\n"
 "6: Default\n"
 "7: Random\n\n"
 "0: Exit"
};

const char *NMenu::CustomBotTeamMenuText =
{"Add Custom Bot - Select a Team\n\n"
 "1: Team Good\n"
 "2: Team Evil\n"
 "3: Random Team\n\n"
 "0: Exit"
};

const char *NMenu::CustomBotClassMenuText =
{"Add Custom Bot - Select a Class\n\n"
 "1: Buu\n"
 "2: Goku\n"
 "3: Gohan\n"
 "4: Krillin\n"
 "5: Frieza\n"
 "6: Piccolo\n"
 "7: Trunks\n"
 "8: Vegeta\n"
 "9: Cell\n\n"
 "0: Exit"
};

const char *NMenu::SuperBotMenuText =
{"Super Bot Menu\n\n"
 "1: Add a Super Bot\n"
 "2: Add a Mega Bot\n"
 "3: Add a Ultimate Bot\n"
 "4: Add Random Super Bot Type\n"
 "5: Change Super Bot Laser Percent\n\n"
 "0: Exit"
};

const char *NMenu::FillServerMenuText =
{"Fill Server Menu\n\n"
 "1: Fill Server\n"
 "2: Fill Half Team Good\n"
 "3: Fill Half Team Evil\n"
 "4: Fill Team Good\n"
 "5: Fill Team Evil\n\n"
 "0. Exit"
};

const char *NMenu::AdvancedMenuText =
{"Advanced Settings\n\n"
 "1: Set Bot Skill\n"
 "2: Percent settings\n"
 "3: Bot Team Balancing\n"
 "4: Bots Use discs\n"
 "5: Restore Bot Personalities\n"
 "6: Set Bot Aggression Level\n\n"
 "0: Exit"
};

const char *NMenu::ChatMenuText =
{"Bot Chat Menu\n\n"
 "1: Chat On/Off\n"
 "2: Set Chat Percent\n"
 "3: Set Whine Percent\n"
 "4: Set Taunt Percent\n"
 "5: Set Swap Percent\n"
 "6: Set Lower Percent\n"
 "7: Set Drop Percent\n"
 "8: Set Tag Percent\n\n"
 "0: Exit"
};

const char *NMenu::KickMenuText =
{"Kick Bots Menu\n\n"
 "1: Kick All Bots\n"
 "2: Kick Good Team Bots\n"
 "3: Kick Evil Team Bots\n\n"
 "0: Exit"
};

const char *NMenu::DebugMenuText =
{"Debug Menu\n\n"
 "1: Bots Shoot\n"
 "2: Bots Search Enemies\n"
 "3: Bots Ignore Human Players\n"
 "4: Bots Move\n"
 "0: Exit"
};


const char *NMenu::AIPercentMenuText =
{"Percent settings\n\n"
 "1: Set Melee Percent\n"
 "2: Set Teleport Percent\n"
 "3: Set Fly Percent\n"
 "4: Set Swoop Percent\n\n"
 "0: Exit"
};

const char *NMenu::PercentMenuText =
{"Select Percent\n\n"
 "1: 100%\n"
 "2: 80% - 99%\n"
 "3: 60%-80%\n"
 "4: 40%-60%\n"
 "5: 20%-40%\n"
 "6: 1%-20%\n"
 "7: 0%\n"
 "8: Random\n\n"
 "0. exit"
};

const char *NMenu::OnOffMenuText =
{"Enable Or Disable?\n\n"
 "1: Enable\n"
 "2: Disable\n\n"
 "0: Exit"
};

const char *NMenu::BotSkillMenuText =
{"Select Skill\n\n"
 "1: Best\n"
 "2: Good\n"
 "3: Medium\n"
 "4: Weak\n"
 "5: Bad\n"
 "6: Default\n\n"
 "0: Exit"
};

const char *NMenu::AggressionLevelMenuText =
{"Set Bot Aggression Level\n\n"
 "1: Defensive\n"
 "2: Normal\n"
 "3: Aggressive\n\n"
 "0: Exit"
};

const int NMenu::MainMenuKeys = 0x3FF;
const int NMenu::CustomBotSkillMenuKeys	= 0x27F;
const int NMenu::CustomBotTeamMenuKeys	= 0x207;
const int NMenu::CustomBotClassMenuKeys	= 0x3FF;
const int NMenu::SuperBotMenuKeys = 0x21F;
const int NMenu::FillServerMenuKeys = 0x21F;
const int NMenu::AdvancedMenuKeys = 0x23F;
const int NMenu::ChatMenuKeys = 0x2FF;
const int NMenu::KickMenuKeys = 0x207;
const int NMenu::DebugMenuKeys = 0x20F;
const int NMenu::PercentMenuKeys = 0x2FF;
const int NMenu::AIPercentMenuKeys	= 0x2FF;
const int NMenu::OnOffMenuKeys = 0x203;
const int NMenu::BotSkillMenuKeys = 0x23F;
const int NMenu::AutoClientMenuKeys = 0x207;
const int NMenu::AggressionLevelMenuKeys = 0x207;

// To make things easier :)
using namespace NMenu;

// This MUST be in the same order as EMenuType !!
NMenu::MenuInfo NMenu::MenuInfos[] =
{
	{MainMenuKeys, MainMenuText, &MainMenu},

	{CustomBotSkillMenuKeys, CustomBotSkillMenuText, &CustomBotSkillMenu},
	{CustomBotTeamMenuKeys, CustomBotTeamMenuText, &CustomBotTeamMenu},
	{CustomBotClassMenuKeys, CustomBotClassMenuText, &CustomBotClassMenu},

	{SuperBotMenuKeys, SuperBotMenuText, &SuperBotMenu},
	{FillServerMenuKeys, FillServerMenuText, &FillServerMenu},
	{AdvancedMenuKeys, AdvancedMenuText, &AdvancedMenu},
	{ChatMenuKeys, ChatMenuText, &ChatMenu},
	{KickMenuKeys, KickMenuText, &KickMenu},
	{DebugMenuKeys, DebugMenuText, &DebugMenu},

	{AIPercentMenuKeys, AIPercentMenuText, &AIPercentMenu},
	{PercentMenuKeys, PercentMenuText, &MeleePercentMenu},
	{PercentMenuKeys, PercentMenuText, &TeleportPercentMenu},
	{PercentMenuKeys, PercentMenuText, &SwoopPercentMenu},
	{PercentMenuKeys, PercentMenuText, &FlyPercentMenu},
	{PercentMenuKeys, PercentMenuText, &ChatPercentMenu},
	{PercentMenuKeys, PercentMenuText, &WhinePercentMenu},
	{PercentMenuKeys, PercentMenuText, &TauntPercentMenu},
	{PercentMenuKeys, PercentMenuText, &SwapPercentMenu},
	{PercentMenuKeys, PercentMenuText, &DropPercentMenu},
	{PercentMenuKeys, PercentMenuText, &TagPercentMenu},
	{PercentMenuKeys, PercentMenuText, &LowerPercentMenu},
	{PercentMenuKeys, PercentMenuText, &SBotLaserPercentMenu},

	{BotSkillMenuKeys, BotSkillMenuText, &BotSkillMenu},
	{AggressionLevelMenuKeys, AggressionLevelMenuText, &AggressionLevelMenu},
	{OnOffMenuKeys, OnOffMenuText, &ChatToggleMenu},
	{OnOffMenuKeys, OnOffMenuText, &BotsShootToggleMenu},
	{OnOffMenuKeys, OnOffMenuText, &BotsSearchEnemiesToggleMenu},
	{OnOffMenuKeys, OnOffMenuText, &ObserverToggleMenu},
	{OnOffMenuKeys, OnOffMenuText, &BotsMoveToggleMenu},
	{OnOffMenuKeys, OnOffMenuText, &DiscUsageToggleMenu},
	{OnOffMenuKeys, OnOffMenuText, &BalanceTeamsToggleMenu}
};

void NMenu::ExecuteMenuCommand(int MenuChoice)
{
	if ((!pCurrentMenuFunction) || (!CurrentMenuText) || (MenuChoice == -1))
	{
		SetNewMenu(MainMenuType);
	}
	else
	{
		CurrentMenuChoice = MenuChoice;
		pCurrentMenuFunction();
	}

	if (CurrentMenuText)
		ShowMenu();
}

void NMenu::ShowMenu()
{
    if (IS_DEDICATED_SERVER() == false)
    {
		CBasePlayer *pHost = BotManager.GetHost();
		if (!UTIL_IsValidPlayer(pHost, false, false))
			return;

		if (gmsgShowMenu == 0)
			gmsgShowMenu = REG_USER_MSG( "ShowMenu", -1 );

		MESSAGE_BEGIN(MSG_ONE, gmsgShowMenu, NULL, pHost->pev);
			WRITE_SHORT(CurrentKeySlots); // used key slots
		    WRITE_CHAR(-1); // lifetime(forever)
	        WRITE_BYTE(false); // needmore ?
	        WRITE_STRING(CurrentMenuText); // Menu text to display
	    MESSAGE_END();
    }
    else
    {
		// Split the menu text in 2 parts when the text length > 128
	    if (strlen(CurrentMenuText) > 128)
		{
		    char MenuText1[130] = "";
		    char MenuText2[130] = "";
		   
		    strncpy(MenuText1,CurrentMenuText,128);
		    strncpy(MenuText2,&CurrentMenuText[129],strlen(CurrentMenuText)-128);
			MenuText1[128] = 0;
			MenuText2[128] = 0;
		    UTIL_Printf(MenuText1);
		    UTIL_Printf(MenuText2);
		}
	    else
		    UTIL_Printf(CurrentMenuText);

	   UTIL_Printf("\n\nTo make a choice type esf_bot menuselect X where X stands for the choice number\n");
   }
}

void NMenu::ResetMenu()
{
	pCurrentMenuFunction = NULL;
	CurrentMenuChoice = 0;
	CurrentMenuText = NULL;
	CurrentKeySlots = 0;
	SBotType = 0;
	BotTeam = 0;
}

void NMenu::SetNewMenu(EMenuType MenuType)
{
	int Index = static_cast<int>(MenuType);

	pCurrentMenuFunction = MenuInfos[Index].pMenuFunction;
	CurrentMenuText = const_cast<char*>(MenuInfos[Index].MenuText);
	CurrentKeySlots = MenuInfos[Index].MenuKeySlots;
}

void NMenu::MainMenu()
{
	switch(CurrentMenuChoice)
	{
	case 1: // Add a random bot
		BotManager.CreateBot(-1, -1, NULL, -1, NULL, DB_UNASSIGNED);
		ResetMenu();
		break;
	case 2:
		SetNewMenu(CustomBotSkillMenuType);

		break;
	case 3:
		if (g_teamplay)
			SetNewMenu(SuperBotMenuType);
		else
		{
			cout << "This option is NOT available in free fight\n";
			ResetMenu();
		}
		break;
	case 4:
		SetNewMenu(FillServerMenuType);
		break;
	case 5:
		SetNewMenu(AdvancedMenuType);
		break;
	case 6:
		SetNewMenu(ChatMenuType);
		break;
	case 7: // Kick the last created bot
		BotManager.KickLastBot(true);
		ResetMenu();
		break;
	case 8:
		SetNewMenu(KickBotsMenuType);
		break;
	case 9:
		SetNewMenu(DebugMenuType);
		break;
	default:
		ResetMenu();
	}
}

void NMenu::CustomBotSkillMenu()
{
	if ((CurrentMenuChoice >= 1) && (CurrentMenuChoice <= 5))
		BotSkill = CurrentMenuChoice;
	else if (CurrentMenuChoice == 6)
		BotSkill = 2;
	else if (CurrentMenuChoice == 7)
		BotSkill = RANDOM_LONG(1, 5);
	else
	{
		ResetMenu();
		return;
	}

	if (g_teamplay)
	{
		SetNewMenu(CustomBotTeamMenuType);
	}
	else
	{
		SetNewMenu(CustomBotClassMenuType);
	}
}

void NMenu::CustomBotTeamMenu()
{
	if ((CurrentMenuChoice == 1) || (CurrentMenuChoice == 2))
		BotTeam = CurrentMenuChoice;
	else if (CurrentMenuChoice == 3)
		BotTeam = RANDOM_LONG(1, 2);
	else
	{
		ResetMenu();
		return;
	}
	SetNewMenu(CustomBotClassMenuType);
}

void NMenu::CustomBotClassMenu()
{
	if (SBotType > 0)
	{
		BotManager.CreateSuperBot(CurrentMenuChoice, NULL, NULL, SBotType, DB_UNASSIGNED);
		SBotType = 0;
	}
	else
	{
		BotManager.CreateBot(BotTeam, CurrentMenuChoice, NULL, BotSkill, NULL, DB_UNASSIGNED);
		BotSkill = BotTeam = 0;
	}
 
	ResetMenu();
}

void NMenu::SuperBotMenu()
{
	switch(CurrentMenuChoice)
	{
	case 1:
	case 2:
	case 3:
	case 4:
		if (CurrentMenuChoice == 4)
			SBotType = RANDOM_LONG(1, 3);
		else
			SBotType = CurrentMenuChoice;

		SetNewMenu(CustomBotClassMenuType);
		break;
	case 5:
		SetNewMenu(SBotLaserPercentMenuType);
		break;
	default:
		ResetMenu();
		return;
	}
}

void NMenu::FillServerMenu()
{/* UNDONE
	switch (CurrentMenuChoice)
	{
	case 1: // Fill whole server
		BotManager.FillServer();
		break;
	case 2:
		BotManager.FillAHalfTeam(GOOD_TEAM);
		break;
	case 3:
		BotManager.FillAHalfTeam(EVIL_TEAM);
		break;
	case 4:
		BotManager.FillATeam(GOOD_TEAM);
		break;
	case 5:
		BotManager.FillATeam(EVIL_TEAM);
		break;
	}
*/
	ResetMenu();
}

void NMenu::AdvancedMenu()
{
	switch(CurrentMenuChoice)
	{
	case 1:
		SetNewMenu(BotSkillSelectMenuType);
		break;
	case 2:
		SetNewMenu(AIPercentMenuType);
		break;
	case 3:
		SetNewMenu(BalanceTeamsToggleMenuType);
		break;
	case 4:
		SetNewMenu(DiscUsageToggleMenuType);
		break;
	case 5: // Restore all bot personalities
		BotManager.CreateBotPersonalities();
		ResetMenu();
		break;
	case 6:
		SetNewMenu(AggressionLevelMenuType);
		break;
	default:
		ResetMenu();
		break;
	}
}

void NMenu::ChatMenu()
{
	switch(CurrentMenuChoice)
	{
	case 1:
		SetNewMenu(ChatToggleMenuType);
		break;
	case 2:
		SetNewMenu(ChatToggleMenuType);
		break;
	case 3:
		SetNewMenu(ChatPercentMenuType);
		break;
	case 4:
		SetNewMenu(WhinePercentMenuType);
		break;
	case 5:
		SetNewMenu(TauntPercentMenuType);
		break;
	case 6:
		SetNewMenu(SwapPercentMenuType);
		break;
	case 7:
		SetNewMenu(LowerPercentMenuType);
		break;
	case 8:
		SetNewMenu(DropPercentMenuType);
		break;
	default:
		ResetMenu();
		break;
	}
}

void NMenu::KickMenu()
{
	switch(CurrentMenuChoice)
	{
	case 1:
		BotManager.KickBots(-1);
		break;
	case 2:
		BotManager.KickBots(GOOD_TEAM);
		break;
	case 3:
		BotManager.KickBots(EVIL_TEAM);
		break;
	}

	ResetMenu();
}

void NMenu::DebugMenu()
{
	switch(CurrentMenuChoice)
	{
	case 1:
		SetNewMenu(BotsShootToggleMenuType);
		break;
	case 2:
		SetNewMenu(BotsSearchEnemiesToggleMenuType);
		break;
	case 3:
		SetNewMenu(ObserverToggleMenuType);
		break;
	case 4:
		SetNewMenu(BotsMoveToggleMenuType);
		break;
		break;
	default:
		ResetMenu();
		break;
	}
}

void NMenu::AIPercentMenu()
{
	switch(CurrentMenuChoice)
	{
	case 1:
		SetNewMenu(MeleePercentMenuType);
		break;
	case 2:
		SetNewMenu(TeleportPercentMenuType);
		break;
	case 3:
		SetNewMenu(FlyPercentMenuType);
		break;
	case 4:
		SetNewMenu(SwoopPercentMenuType);
		break;
	default:
		ResetMenu();
		break;
	}
}

void NMenu::MeleePercentMenu()
{
	if (CurrentMenuChoice <= 8)
		BotManager.ChangePersoPercentSetting(&bot_personality_s::melee_percent, GetPercentFromMenu(),
								 "melee_percent");

	ResetMenu();
}

void NMenu::TeleportPercentMenu()
{
	if (CurrentMenuChoice <= 8)
		BotManager.ChangePersoPercentSetting(&bot_personality_s::teleport_percent, GetPercentFromMenu(),
								 "teleport_percent");

	ResetMenu();
}

void NMenu::SwoopPercentMenu()
{
	if (CurrentMenuChoice <= 8)
		BotManager.ChangePersoPercentSetting(&bot_personality_s::swoop_percent, GetPercentFromMenu(),
								 "swoop_percent");

	ResetMenu();
}

void NMenu::FlyPercentMenu()
{
	if (CurrentMenuChoice <= 8)
		BotManager.ChangeBotFlyPercent(GetPercentFromMenu());

	ResetMenu();
}

void NMenu::ChatPercentMenu()
{
	if (CurrentMenuChoice <= 8)
		BotManager.ChangePersoPercentSetting(&bot_personality_s::chat_percent, GetPercentFromMenu(),
								 "chat_percent");

	ResetMenu();
}

void NMenu::TauntPercentMenu()
{
	if (CurrentMenuChoice <= 8)
		BotManager.ChangePersoPercentSetting(&bot_personality_s::taunt_percent, GetPercentFromMenu(),
								 "taunt_percent");

	ResetMenu();
}

void NMenu::WhinePercentMenu()
{
	if (CurrentMenuChoice <= 8)
		BotManager.ChangePersoPercentSetting(&bot_personality_s::whine_percent, GetPercentFromMenu(),
								 "whine_percent");

	ResetMenu();
}

void NMenu::TagPercentMenu()
{
	if (CurrentMenuChoice <= 8)
		BotManager.ChangePersoPercentSetting(&bot_personality_s::chat_tag_percent, GetPercentFromMenu(),
								 "chat_tag_percent");

	ResetMenu();
}

void NMenu::DropPercentMenu()
{
	if (CurrentMenuChoice <= 8)
		BotManager.ChangePersoPercentSetting(&bot_personality_s::chat_drop_percent, GetPercentFromMenu(),
								 "chat_drop_percent");

	ResetMenu();
}

void NMenu::SwapPercentMenu()
{
	if (CurrentMenuChoice <= 8)
		BotManager.ChangePersoPercentSetting(&bot_personality_s::chat_swap_percent, GetPercentFromMenu(),
								 "chat_swap_percent");

	ResetMenu();
}

void NMenu::LowerPercentMenu()
{
	if (CurrentMenuChoice <= 8)
		BotManager.ChangePersoPercentSetting(&bot_personality_s::chat_lower_percent, GetPercentFromMenu(),
								 "chat_lower_percent");

	ResetMenu();
}

void NMenu::SBotLaserPercentMenu()
{
	if (CurrentMenuChoice <= 8)
		BotManager.ChangeSBotLaserPercent(GetPercentFromMenu());

	ResetMenu();
}

void NMenu::BotSkillMenu()
{
	int NewSkill;

	if ((CurrentMenuChoice >= 1) && (CurrentMenuChoice <= 5))
		NewSkill = CurrentMenuChoice;
	else if (CurrentMenuChoice == 6)
		NewSkill = 2;
	else
	{
		ResetMenu();
		return;
	}
	
	BotManager.ChangeBotSkill(NewSkill);
	ResetMenu();
}

void NMenu::AggressionLevelMenu()
{
	EAggressionLevel ALevel;

	switch(CurrentMenuChoice)
	{
	case 1:
		ALevel = Defensive;
		break;
	case 2:
		ALevel = Normal;
		break;
	case 3:
		ALevel = Aggressive;
		break;
	default:
		ResetMenu();
		return;
	}

	BotManager.ChangeAggressionLevel(ALevel);
	ResetMenu();
}

void NMenu::ChatToggleMenu()
{
	if ((CurrentMenuChoice == 1) || (CurrentMenuChoice == 2))
		CVAR_SET_FLOAT("sv_botschat", float((CurrentMenuChoice == 1)));

	ResetMenu();
}

void NMenu::BotsShootToggleMenu()
{
	if ((CurrentMenuChoice == 1) || (CurrentMenuChoice == 2))
		CVAR_SET_FLOAT("sv_botsshoot", float((CurrentMenuChoice == 1)));

	ResetMenu();
}

void NMenu::BotsSearchEnemiesToggleMenu()
{
	if ((CurrentMenuChoice == 1) || (CurrentMenuChoice == 2))
		CVAR_SET_FLOAT("sv_botssearchenemies", float((CurrentMenuChoice == 1)));

	ResetMenu();
}

void NMenu::ObserverToggleMenu()
{
	if ((CurrentMenuChoice == 1) || (CurrentMenuChoice == 2))
		CVAR_SET_FLOAT("sv_observerbots", float((CurrentMenuChoice == 1)));

	ResetMenu();
}

void NMenu::BotsMoveToggleMenu()
{
	if ((CurrentMenuChoice == 1) || (CurrentMenuChoice == 2))
		CVAR_SET_FLOAT("sv_botsmove", float((CurrentMenuChoice == 1)));

	ResetMenu();
}

void NMenu::DiscUsageToggleMenu()
{
	if ((CurrentMenuChoice == 1) || (CurrentMenuChoice == 2))
		CVAR_SET_FLOAT("sv_botsusediscs", float((CurrentMenuChoice == 1)));

	ResetMenu();
}

void NMenu::BalanceTeamsToggleMenu()
{
	if ((CurrentMenuChoice == 1) || (CurrentMenuChoice == 2))
		CVAR_SET_FLOAT("sv_botsbalanceteams", float((CurrentMenuChoice == 1)));

	ResetMenu();
}

short NMenu::GetPercentFromMenu()
{
	switch (CurrentMenuChoice)
	{
	case 1:
		return 100;
	case 2:
		return RANDOM_LONG(80, 99);
	case 3:
		return RANDOM_LONG(60, 80);
	case 4:
		return RANDOM_LONG(40, 60);
	case 5:
		return RANDOM_LONG(20, 40);
	case 6:
		return RANDOM_LONG(1, 20);
	case 7:
		return 0;
	case 8:
		return RANDOM_LONG(0, 100);
	}
	return 0;
}
