#ifndef BOT_CHAT_H
#define BOT_CHAT_H

#define MAX_BOT_CHAT				300
#define MAX_CHAT_SENTENCE_LENGTH	80
#define MAX_CHAT_KEYWORDS			6
#define MAX_CHAT_KEYTOKENS			6
#define MAX_OLD_TEXTS_SAVED			5
#define MAX_RECENT_USED_TEXTS		5

class CChatClass
{
	enum EChatCatagory
	{
		WELCOME_CHAT,
		NORMAL_CHAT,
		WHINE_CHAT,
		TAUNT_CHAT,
		NONE_CHAT
	};

	enum EKeyType
	{
		KEY_TYPE_KEYWORD,
		KEY_TYPE_KEYWORD2,
		KEY_TYPE_KEYTOKEN,
		KEY_TYPE_NONE
	};

	class CChatSentence
	{
		char szSenderName[33]; // Used if bot uses this sentence to respond on something.
		char *szText;
		bool CanModify;
		byte UseValue;
		byte RandomNameCount; // The number of "%r" in this sentence
		byte TargetNameCount; // The number of "%n" in this sentence

		friend class CChatClass;

	public:
		CChatSentence(const char *szSentence, bool CM, byte UV, byte RCount, byte TCount);
		~CChatSentence(void);
	};

	class CChatNode
	{
		TLinkedList<CChatSentence*> *pChatSentences;
		char *szKeyStr;
		EKeyType KeyType;
		int TotalValue;
		int SentenceCount;

		friend class CChatClass;

	public:
		CChatNode(void) : pChatSentences(new TLinkedList<CChatSentence*>), szKeyStr(NULL),
						  KeyType(KEY_TYPE_NONE), TotalValue(0), SentenceCount(0)
		{};
		CChatNode(const char *KW, EKeyType KT);
		~CChatNode(void);

		void AddSentence(const char *szSentence);
		int GetRegularVal(void);
		int GetTotalVal(void) { return TotalValue; };
	};

	struct SOldChatText
	{
		char szSenderName[33];
		char szText[128];
		float flCreateTime;
	};

	SOldChatText OldChatTexts[MAX_OLD_TEXTS_SAVED];

	CChatNode *pWelcomeSentences;
	TLinkedList<CChatNode*> *pNormalChatNodeList;
	TLinkedList<CChatNode*> *pTauntChatNodeList;
	TLinkedList<CChatNode*> *pWhineChatNodeList;

	CChatSentence *pRecentNormalChatTexts[MAX_RECENT_USED_TEXTS];
	CChatSentence *pRecentWhineChatTexts[MAX_RECENT_USED_TEXTS];
	CChatSentence *pRecentTauntChatTexts[MAX_RECENT_USED_TEXTS];

	friend class CChatNode;

public:

	CChatClass(void);
	~CChatClass(void);

	void AddWelcomeSentence(const char *Sentence) { pWelcomeSentences->AddSentence(Sentence); };
	void AddNormalChatSentence(const char *Sentence, const char *KeyWord, EKeyType KT);
	void AddTauntChatSentence(const char *Sentence, const char *KeyWord, EKeyType KT);
	void AddWhineChatSentence(const char *Sentence, const char *KeyWord, EKeyType KT);

	void ReadChatFile(void);

	// Returns true when made a response
	bool CreateResponseList(SOldChatText *pOldChatText, 
							TMultiChoice<CChatSentence*> *pSentenceList);

	void MakeChatSentence(bot_personality_s *pPerso, const char *szSentence, char *szOutput);
	void FillInNames(CBot *pBot, const char *szSentence, char *szOutput, const char *PlayerName,
		             const char *BotName);
	void HumanizeName(bot_personality_s *pPerso, const char *szName, char *szOutput);

	void LetBotSayAWelcomeSentence(CBot *pBot);
	void LetBotCheckForReply(CBot *pBot);
	void LetBotSaySomething(CBot *pBot);
	void LetBotWhine(CBot *pBot, CBasePlayer *pKiller);
	void LetBotTaunt(CBot *pBot, CBasePlayer *pVictim);

	int CutTags(const char *szName, char *szOutput);
	void SwapChars(const char *szSentence, char *szOutput);
	void DropChars(const char *szSentence, char *szOutput);
	void CutSpaces(const char *szInput, char *szOutput);

	void StoreChatMsg(edict_t *pEntity, const char *szMsgText);
	void StoreRecentUsedSentence(CChatSentence *VarToStore[], CChatSentence *pSentence);

	CChatNode *GetChatNodeByKeyWord(TLinkedList<CChatNode *> *pChatNodeList, const char *szKeyWord);
	CChatNode *GetChatNodeByKeyToken(TLinkedList<CChatNode *> *pChatNodeList, const char KeyToken);

	// Debug function(s)
	void LogPrevMessages(void);
	void LogChatLists(void);
	void LogChatNode(CChatNode *pNode);
	void LogChatSentences(CChatSentence *pSentence);
	void PrintChatSentences(void);
	void PrintChatNode(CChatNode *pNode);
	void PrintChatSentence(CChatSentence *pSentence);
};

#endif // BOT_CHAT_H