//////////////////////////////////////////////////////////////////////////////
//
// Asura_GameSpy_Chat.h
//
// Copyright (c) 2004 Rebellion. All rights reserved.
//
// Description:
//
//     Asura interface class for GameSpy Chat SDK
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ___ASURA_GAMESPY_CHAT_H___
#define ___ASURA_GAMESPY_CHAT_H___ 1

#ifdef ASURA_SUPPORT_MULTIPLAYER_COMMS

#include "Core/Asura_PlatformBasics.h"

#include "GameSpy/chat/chat.h"

static const u_int uASURA_CHAT_CHANNEL_NAME_MAXLEN = 31;	// e.g. "SniperElite_English"

// Asura wrapper for GameSpy chat SDK
// provided functionality is:-
// 1) to connect to a specified chat server on a specified channel, with a specified nickname
// 2) automatically have a number prepended to the nickname if it is in use e.g. [1]Mike
// 3) automatically fix up illegal characters in nickname
// 4) provide a function to send a message to the channel
// 5) on shutdown, disconnect from the chat server
// TODO: Unicode support for messages is not in yet as it requires turning on Unicode for all of GameSpy.
class Asura_GameSpy_Chat
{
	public:
	
		// default server / channels could be "peerchat.gamespy.com" / "#GSP!gmtest"
		// you need to be using gamename / secret key "gmtest" / "HA6zkS"
		static bool Initialise(const char* szServerName, const char* szChannel,
			const int iNameSpaceID, const Asura_UnicodeChar* wszNickNameExtension,
			const Asura_UnicodeChar* wszUniqueNickName, const Asura_UnicodeChar* wszPassword);
		static void Update( void );
		static void Shutdown( void );

		static bool SendMessage( const Asura_UnicodeChar* wszMessage );

	private:

		enum ConnectionState
		{
			ChatState_None,
			ChatState_ConnectingToServer,
			ChatState_ConnectedToServer,	// transient state
			ChatState_JoiningChannel,
			ChatState_GettingUserList,
			ChatState_InChannel,
			ChatState_ConnectionFailed,
			ChatState_JoinChannelFailed,
			NumChatStates
		};

		// SDK callbacks
		// "global callbacks"
		static void Callback_Raw(CHAT pxChat, const gsi_char* szRaw, void* pParam);
		static void Callback_Disconnected(CHAT pxChat, const gsi_char* szReason, void* pParam);
		static void Callback_PrivateMessage(CHAT pxChat, const gsi_char* szUser, const gsi_char* szMessage, int iType, void* pParam);
		static void Callback_Invited(CHAT pxChat, const gsi_char* szChannel, const gsi_char* szUser, void* pParam);

		// connection callbacks
		static void Callback_Connected(CHAT pxChat, CHATBool eSuccess, int iFailureReason, void* pParam);
		static void Callback_FillInUser(CHAT pxChat, unsigned int uIP, gsi_char aucUser[128], void* pParam);
		static void Callback_NicknameError(CHAT pxChat, int iType, const gsi_char* szNick, int iNumSuggestedNicks, const gsi_char** aszSuggestedNicks, void* pParam);

		// channel callbacks
		static void Callback_EnteredChannel(CHAT pxChat, CHATBool eSuccess, CHATEnterResult eResult, const gsi_char* szChannel, void* pParam);

		static void Callback_ChannelMessage(CHAT pxChat, const gsi_char* szChannel, const gsi_char* szUser, const gsi_char* szMessage, int iType, void* pParam);
		static void Callback_Kicked(CHAT pxChat, const gsi_char* szChannel, const gsi_char* szUser, const gsi_char* szReason, void* pParam);
		static void Callback_UserJoined(CHAT pxChat, const gsi_char* szChannel, const gsi_char* szUser, int iMode, void* pParam);
		static void Callback_UserParted(CHAT pxChat, const gsi_char* szChannel, const gsi_char* szUser, int iWhy, const gsi_char* szReason, const gsi_char* szKicker, void* pParam);
		static void Callback_UserChangedNick(CHAT pxChat, const gsi_char* szChannel, const gsi_char* szOldNick, const gsi_char* szNewNick, void* pParam);
		static void Callback_UserModeChanged(CHAT pxChat, const gsi_char* szChannel, const gsi_char* szUser, int iMode, void* pParam);
		static void Callback_TopicChanged(CHAT pxChat, const gsi_char* szChannel, const gsi_char* szTopic, void* pParam);
		static void Callback_ChannelModeChanged(CHAT pxChat, const gsi_char* szChannel, CHATChannelMode* pxMode, void* pParam);
		static void Callback_UserListUpdated(CHAT pxChat, const gsi_char* szChannel, void* pParam);

		// other callbacks
		static void Callback_EnumUsers(CHAT pxChat, CHATBool eSuccess, const gsi_char* szChannel, int iNumUsers, const gsi_char** aszUsers, int* aiModes, void* pParam);

		// data
		static char s_acChannelName[uASURA_CHAT_CHANNEL_NAME_MAXLEN + 1];
		static CHAT s_pxChatObject;
		static ConnectionState s_eConnectionState;
		static u_int s_uNicknameModifier;	// number added to make nickname unique.
		static char s_szNickNameExtension[10];
};

#endif // #ifdef ASURA_SUPPORT_MULTIPLAYER_COMMS

// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

#endif // #ifndef ___ASURA_GAMESPY_CHAT_H___
