#ifndef STCHAT_H
#define STCHAT_H

// Forward
class gzChatCommandBase;
class gzFloodBase;
class gzChatFloodClass;
class gzRadioFloodClass;

struct gzAutoCompleteStruct {
	aWideString input;
	aWideString output;
};

#define TYPE_NONE		0
#define TYPE_NORM		1
#define TYPE_WILDCARD	2
#define TYPE_REGEX		3

#define MSG_NONE		0
#define MSG_ALL			1
#define MSG_TEAM		2
#define MSG_PRIVATE		4

#define OPT_NONE		0
#define OPT_LOG			1

struct gzTextFilterStruct {
	aString name;
	bool enable;
	int cmpType;
	int type;
	int options;
	aWideStringArray String;
	aWideStringArray outString;
};

class gzChatManagerClass : public EventHandler {
	friend class gzFloodBase;

	//aVector<gzAutoCompleteStruct> m_autoComplete;
	//aVector<gzTextFilterStruct *> m_textFilter;
	aList<gzAutoCompleteStruct> m_autoComplete;
	aList<gzTextFilterStruct> m_textFilter;
	time_t m_autoCompleteModTime;
	time_t m_textFilterModTime;
public:
	const char *GetName()
	{
		return "gzChatManagerClass";
	};
	gzChatManagerClass();
	void Delete();
	void Level_Loaded();
	void Player_Chat(gzEventPlayerChat &);
	void Net_WolPage(gzEventNetWolPage &);
	aWideStringArray m_muteList;
	static aVector<gzChatCommandBase *> m_chatCommandList;
};
extern gzChatManagerClass *gzChat;

class gzFloodBase : public EventHandler {
protected:
	nc_cPlayer *m_owner;
public:
	gzFloodBase();
	virtual gzChatFloodClass *As_ChatFlood()
	{
		return NULL;
	};
	virtual gzRadioFloodClass *As_RadioFlood()
	{
		return NULL;
	};

	int m_Count;
	float m_Interval;
};

class gzChatFloodClass : public gzFloodBase {
public:
	const char *GetName()
	{
		return "gzChatFloodClass";
	};
	gzChatFloodClass(nc_cPlayer *);
	void Delete() { };
	void Think();
	void Player_Chat(gzEventPlayerChat &);
	gzChatFloodClass *As_ChatFlood()
	{
		return this;
	};
};

class gzRadioFloodClass : public gzFloodBase {
public:
	const char *GetName()
	{
		return "gzRadioFloodClass";
	};
	gzRadioFloodClass(nc_cPlayer *);
	void Delete() {	};
	void Think();
	void Player_Radio(gzEventPlayerRadio &);
	gzRadioFloodClass *As_RadioFlood()
	{
		return this;
	};
};

class gzChatCommandBase {
public:
	virtual void Activate(const wchar_t *msg, int type, int sender, int receiver, aWideString &ret) = 0;
	aWideStringArray m_commandList;
	int m_type;
	aString m_keyhook_Key;
	aWideString m_keyhook_Param;
};

template <class T> class gzChatCommand_Reg {
public:
	gzChatCommand_Reg(const char *commands, int type = (MSG_ALL | MSG_TEAM), const char *keyhook_key = NULL, const wchar_t *keyhook_param = NULL)
	{
		if (!*commands)
			return;
		aToken cmdTok(commands);
		gzChatCommandBase *newCmd = new T;
		newCmd->m_type = type;
		for (int i = 1; i <= cmdTok.numtok(','); i++)
			newCmd->m_commandList.Add(cmdTok.gettok(i, ',').GetData());
		if (keyhook_key)
		{
			newCmd->m_keyhook_Key = keyhook_key;
			if (keyhook_param)
				newCmd->m_keyhook_Param = keyhook_param;
		}
		gzChatManagerClass::m_chatCommandList.Add(newCmd);
	};
};

#endif
