#include "gen_bot_header.h"

//harSens: Linux compile fix
extern CLeftOutput lcout;

extern int gmsgBotVGUI;

// ==================================================================
// Code of bot_personality_s - Begin
// ==================================================================

void bot_personality_s::InitPerso()
{
	melee_percent = RANDOM_LONG(0, 100);
	kiblast_percent = RANDOM_LONG(0, 100);
	lightbeam_percent = RANDOM_LONG(0, 100);
	mediumbeam_percent = RANDOM_LONG(0, 100);
	heavybeam_percent = RANDOM_LONG(0, 100);
	disc_percent = RANDOM_LONG(0, 100);
	laser_percent = RANDOM_LONG(0, 100);
	heavyprojectile_percent = RANDOM_LONG(0, 100);
	kametorp_percent = RANDOM_LONG(0, 100);
	solarflare_percent = RANDOM_LONG(0, 100);

	meleethrow_percent = RANDOM_LONG(0, 100);
	meleekick_percent = RANDOM_LONG(0, 100);
	simplemelee_percent = RANDOM_LONG(0, 100);
	meleeweakbutton_percent = RANDOM_LONG(0, 100);
	meleemediumbutton_percent = RANDOM_LONG(0, 100);
	meleestrongbutton_percent = RANDOM_LONG(0, 100);
	meleecombo_percent = RANDOM_LONG(0, 100);

	chat_percent = RANDOM_LONG(0, 100);
	taunt_percent = RANDOM_LONG(0, 100);
	whine_percent = RANDOM_LONG(0, 100);
	chat_tag_percent = RANDOM_LONG(0, 100);
	chat_lower_percent = RANDOM_LONG(0, 100);
	chat_drop_percent = RANDOM_LONG(0, 100);
	chat_swap_percent = RANDOM_LONG(0, 100);

	teleport_percent = RANDOM_LONG(0, 100);
	swoop_percent = RANDOM_LONG(0, 100);
	beamexplode_percent = RANDOM_LONG(0, 100);
	fly_percent = RANDOM_LONG(0, 100);
	stopfly_percent = RANDOM_LONG(0, 100);
	jump_percent = RANDOM_LONG(0, 100);
	block_percent = RANDOM_LONG(0, 100);

	switch (RANDOM_LONG(0, 2))
	{
	case 0:
		aggression_level = Defensive;
		break;
	case 1:
		aggression_level = Normal;
		break;
	case 2:
		aggression_level = Aggressive;
		break;
	}

	if (RANDOM_LONG(0, 1))
		transkiller = true;
	else
		transkiller = false;
}

// ==================================================================
// Code of bot_personality_s - End
// ==================================================================

// ==================================================================
// Code of CBotManager - Begin
// ==================================================================

// Make random personalities for bots or read them out of the file
// 'botpersonality.cfg'
void CBotManager::CreateBotPersonalities()
{
	char PersoFileName[256] = "";
	FILE *PersoFile = NULL;
	bot_personality_s *pCurrentPersonality = NULL;

	while(m_BotPersonalities.Empty() == false)
		delete m_BotPersonalities.Pop();

	BuildBotFileName(PersoFileName, "bot_personality.cfg", NULL);

	PersoFile = fopen(PersoFileName, "r");
	(*g_engfuncs.pfnServerPrint) ("Reading bot_personalities file... ");

	if (PersoFile == NULL) // file doesn't exist
	{
		(*g_engfuncs.pfnServerPrint) ("file not found, random settings will be used\n");
		MakeRandomPersonalities();
		return;
	}

	int ch, i;
	char szCommandLine[256];
	int iCmdIndex;
	char *szCommand;
	char *szArg;
	int value = 0;
	
	while (PersoFile)
	{    
		iCmdIndex = 0;
		szCommandLine[iCmdIndex] = 0;

		ch = fgetc(PersoFile);

		// skip any leading blanks
		while (ch == ' ')
			ch = fgetc(PersoFile);

		// Read a new line from the file
		while ((ch != EOF) && (ch != '\r') && (ch != '\n'))
   		{
			if (ch == '\t')  // convert tabs to spaces
		      ch = ' ';

			szCommandLine[iCmdIndex] = ch;

			ch = fgetc(PersoFile);

			// skip multiple spaces in input file
			while ((szCommandLine[iCmdIndex] == ' ') && (ch == ' '))      
         		ch = fgetc(PersoFile);

		      iCmdIndex++;
   		}

		if (ch == '\r')  // is it a carriage return?
		{
		      ch = fgetc(PersoFile);  // skip the linefeed
   		}

		// if reached end of file, then close it
		if (ch == EOF)
   		{
			fclose(PersoFile);
			PersoFile = NULL; // So we break the loop next round
		}

		szCommandLine[iCmdIndex] = 0;  // terminate the command line

		// Read the first word(the command)
		szCommand = strtok(szCommandLine, " ");
		if (!szCommand)
			continue;

		if ((szCommand[0] == '#') || (szCommand[0] == 0))
		    continue;  // skip if comment or blank line

		// Read the arg
		szArg = strtok(NULL, "\"\n\r");

		if ((szArg == NULL) || (*szArg == 0))
			continue;

		i = strlen(szArg) - 1;
		while (((i+1) >= 0) && ((szArg[i] == ' ') || (szArg[i] == '\"') ||
			   (szArg[i] == '\n') || (szArg[i] == '\r')))
		{
			szArg[i] = 0;
			i--;
		}
		
		if ((i+1) < 0)
			continue;

		if (strcmp(szCommand, "perso_name") == 0)
		{
			char szName[32];
			// Make sure the name isn't longer then 32 chars
			strncpy(szName, szArg, 31);
			szName[31] = 0;
			pCurrentPersonality = new bot_personality_s(szName);
			m_BotPersonalities.AddNode(pCurrentPersonality);
			continue;
		}
		if (strcmp(szCommand, "default_personality") == 0)
		{
			strcpy(m_szDefaultPersonality, szArg);
			continue;
		}

		if (!pCurrentPersonality)
			continue;

		value = atoi(szArg);

		if (strcmp(szCommand, "melee_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->melee_percent = value;
		}
		else if (strcmp(szCommand, "kiblast_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->kiblast_percent = value;
		}
		else if (strcmp(szCommand, "lightbeam_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->lightbeam_percent = value;
		}
		else if (strcmp(szCommand, "mediumbeam_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))			
				pCurrentPersonality->mediumbeam_percent = value;
		}
		else if (strcmp(szCommand, "heavybeam_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->heavybeam_percent = value;
		}
		else if (strcmp(szCommand, "disc_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))				
				pCurrentPersonality->disc_percent = value;
		}
		else if (strcmp(szCommand, "laser_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->laser_percent = value;
		}
		else if (strcmp(szCommand, "heavyball_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->heavyprojectile_percent = value;
		}
		else if (strcmp(szCommand, "kametorp_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->kametorp_percent = value;
		}
		else if (strcmp(szCommand, "solarflare_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->solarflare_percent = value;
		}

		else if (strcmp(szCommand, "meleethrow_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->meleethrow_percent = value;
		}
		else if (strcmp(szCommand, "meleekick_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->meleekick_percent = value;
		}
		else if (strcmp(szCommand, "simplemelee_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->simplemelee_percent = value;
		}
		else if (strcmp(szCommand, "meleeweakbutton_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->meleeweakbutton_percent = value;
		}
		else if (strcmp(szCommand, "meleemediumbutton_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->meleemediumbutton_percent = value;
		}
		else if (strcmp(szCommand, "meleestrongbutton_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->meleestrongbutton_percent = value;
		}
		else if (strcmp(szCommand, "meleecombo_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->meleecombo_percent = value;
		}

		else if (strcmp(szCommand, "chat_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->chat_percent = value;
		}
		else if (strcmp(szCommand, "taunt_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->taunt_percent = value;
		}
		else if (strcmp(szCommand, "whine_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->whine_percent = value;
		}
		else if (strcmp(szCommand, "chat_tag_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->chat_tag_percent = value;
		}
		else if (strcmp(szCommand, "chat_drop_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->chat_drop_percent = value;
		}
		else if (strcmp(szCommand, "chat_swap_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->chat_swap_percent = value;
		}
		else if (strcmp(szCommand, "chat_lower_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->chat_lower_percent = value;
		}

		else if (strcmp(szCommand, "teleport_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))		
				pCurrentPersonality->teleport_percent = value;
		}
		else if (strcmp(szCommand, "swoop_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->swoop_percent = value;
		}
		else if (strcmp(szCommand, "beamexplode_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->beamexplode_percent = value;
		}
		else if (strcmp(szCommand, "fly_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->fly_percent = value;
		}
		else if (strcmp(szCommand, "stopfly_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->stopfly_percent = value;
		}
		else if (strcmp(szCommand, "jump_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->jump_percent = value;
		}
		else if (strcmp(szCommand, "block_percent") == 0)
		{
			if ((value <= 100) && (value >= 0))
				pCurrentPersonality->block_percent = value;
		}

	    else if (FStrEq(szCommand, "aggression_level"))
		{
			if (FStrEq(szArg,"defensive"))
				pCurrentPersonality->aggression_level = Defensive;
			else if (FStrEq(szArg,"normal"))
				pCurrentPersonality->aggression_level = Normal;
			else if (FStrEq(szArg,"aggressive"))
				pCurrentPersonality->aggression_level = Aggressive;
		}
		else if (strcmp(szCommand, "transkiller") == 0)
		{
			if ((value == 0) || (value == 1))
				pCurrentPersonality->transkiller = (value == 1) ? true : false;
		}
	}

	// If no personality found in the file
	if (m_BotPersonalities.Empty())
		MakeRandomPersonalities();

	m_bSendPersoInfoToClient = (!IS_DEDICATED_SERVER());

	(*g_engfuncs.pfnServerPrint) ("done\n");
}

// make random personalities
void CBotManager::MakeRandomPersonalities()
{
	char szPersoName[32];
	for (int count=0;count<9;count++)
	{
		sprintf(szPersoName, "random_perso_%d", count);
		m_BotPersonalities.AddNode(new bot_personality_s(szPersoName));
	}
}

bot_personality_s *CBotManager::GetRandPerso()
{
	TMultiChoice<bot_personality_s*> PersoChoiceList;
	/*modified by harSens
	TLinkedList<bot_personality_s*>::node_s *pNode = m_BotPersonalities.GetFirst();
	*/
	node_s<bot_personality_s*> *pNode = m_BotPersonalities.GetFirst();

	if (!pNode)
		return NULL;

	for(;pNode;pNode=pNode->next)
		PersoChoiceList.Insert(pNode->Entry);

	bot_personality_s *pPerso;
	if (PersoChoiceList.GetSelection(pPerso))
		return pPerso;

	return NULL;
}

bot_personality_s *CBotManager::FindPersoByName(const char *szName)
{
	/*modified by harSens
	TLinkedList<bot_personality_s*>::node_s *pNode = m_BotPersonalities.GetFirst();
	*/
	node_s<bot_personality_s*>*pNode = m_BotPersonalities.GetFirst();

	if (!pNode)
		return NULL;

	for(;pNode;pNode=pNode->next)
	{
		if (strcmp(pNode->Entry->perso_name, szName) == 0)
			return pNode->Entry;
	}

	return NULL;
}

void CBotManager::SendPersoInfoToClient()
{
	/*modified by harSens
	TLinkedList<bot_personality_s*>::node_s *pNode = m_BotPersonalities.GetFirst();
	*/
	node_s<bot_personality_s*>*pNode = m_BotPersonalities.GetFirst();

	if (!pNode)
		return;

	for(;pNode;pNode=pNode->next)
	{
		MESSAGE_BEGIN( MSG_ONE, gmsgBotVGUI, NULL, &pHost->v);
			WRITE_BYTE( byte(BOTVGUI_ADDPERSO) ); // Send personality name
			WRITE_STRING(pNode->Entry->perso_name);
		MESSAGE_END();
	}

	// Default personality selected?
	if (m_szDefaultPersonality[0])
	{
		MESSAGE_BEGIN( MSG_ONE, gmsgBotVGUI, NULL, &pHost->v);
			WRITE_BYTE( byte(BOTVGUI_DEFAULTPERSO) ); // Send default personality name
			WRITE_STRING(m_szDefaultPersonality);
		MESSAGE_END();
	}
}


// ==================================================================
// Code of CBotManager - End
// ==================================================================