//////////////////////////////////////////////////////////////////////////////
//
// Asura_PS2_SCE_RT.h
//
// Copyright (c) 2003 Rebellion. All rights reserved.
//
// Description:
//
//     Asura interface for SCE-RT API
//
//////////////////////////////////////////////////////////////////////////////

// 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_PS2_SCE_RT_H___
#define ___ASURA_PS2_SCE_RT_H___ 1

// I N C L U D E S ///////////////////////////////////////////////////////////

#include "scert/include/dme.h"


// F O R W A R D   D E C L A R A T I O N S ///////////////////////////////////

class Asura_Message;


// D E F I N E S   E T C . ///////////////////////////////////////////////////

static const int ASURA_PS2_MAX_IP_STRING_LENGTH = 16;	// xxx.xxx.xxx.xxx + 0
static const int ASURA_PS2_SCE_RT_WORLD_ID = 1;
static const int ASURA_PS2_SCE_RT_MAX_NUM_CLIENTS = 4;

#define Asura_PS2_SCE_RT_CheckError(eError) Asura_Assertf(eError == NetErrorNone, ("error %s", Asura_PS2_SCE_RT::GetErrorString(eError)))

#define ASURA_PS2_SCE_RT_BANDWIDTH_TEXT 1
#define ASURA_PS2_BANDWIDTH_TEXT_LENGTH 256

// C L A S S E S /////////////////////////////////////////////////////////////

class Asura_PS2_SCE_RT
{
	friend class Asura_PS2_SCE_RT_Server;
	
	enum SceRtMode
	{
		SceRtMode_Idle,
		SceRtMode_Hosting,
		SceRtMode_WaitingForServer,
		SceRtMode_Client,
	};

	enum JoinState
	{
		JoinState_None,
		JoinState_Pending,
		JoinState_OK,
		JoinState_Failed,
	};

public:

	static bool Initialise();
	static void Shutdown();
	static bool StartServerAndHostSession();
	static void StopServer();
	static bool StartClientAndFindSessions();
	static void RefreshSessions();
	static void StopClient();
	static void Update();
	static void EndOfFrame();
	static void ConnectToSession(u_int uSessionID);
	static int GetLatency();

	static void SendMessageToServer(const Asura_Message* pxMessage);
	static void SendMessageToAllClients(const Asura_Message* pxMessage);
	static void SendMessageToClientMachine(int iMachineID, const Asura_Message* pxMessage);

#ifdef ASURA_ASSERT
	static const char* GetErrorString(NetErrorCode eErrorCode);
#endif

#if ASURA_PS2_SCE_RT_BANDWIDTH_TEXT
	static const char* GetBandwidthString();
#endif

private:
	
	static bool LoadIRXModules();
	static bool LoadIRXModule(const char* szRelativeFilename, int args, const char *argp);
	static bool InitialiseNetworkConnection();
	static void ServerResponseCallback(char acServerIpString[ASURA_PS2_MAX_IP_STRING_LENGTH], int iServerPort);
	static void UpdateNetwork();
	static bool Connect();
	static bool Join();
	static void CloseConnection();
	
#if DME_CLIENT_VERSION_BUILD < 0017
	static void NetConnectCallback(int iConnectionIndex, NetConnectStatus eConnectStatus, 
									NetConnectFailureReason eFailureReason, NetErrorCode eErrorCode);
#else
	static void NetConnectCallback(NetTypeConnectCallbackData* pxCallbackData);
#endif
	static void NetJoinCallback(NetCompletionData *pxCompletionData);
	static void RemoteClientEventCallback(NetRemoteClientEventData *pxRemoteClientEventData);
	static void PingCallback(NetErrorCode eCompletionResult, char acDestIP[16], unsigned int uLatency);


	static void RegisterMessageTypes();
	static int MessageHandlerCallback(int iConnectionID, int iWorldID, int iSourceClientIndex, void* pMessageData);
	static bool SendMessage(int iDestID, const Asura_Message* pxMessage);
//	static void ProcessServerMessage(void* pMessageData);

	static bool s_bIRXModulesLoaded;
	static class Asura_PS2_SCE_RT_Server* s_pxServer;
	static char s_acServerIP[ASURA_PS2_MAX_IP_STRING_LENGTH];
	static int s_iServerPortNumber;
	static int s_iConnectionIndex;
	static int s_iClientIndexOfServer;
	static u_int s_uMessageTypeID;				// value returned by NetRegisterMessage
	static bool s_bWaitingForServerResponse;	// set to true by callback
	static JoinState s_eJoinState;
	static u_int s_uLatency;
	static bool s_bWaitingForPingResponse;
	static float s_fTimeOfLastPingResponse;

	static SceRtMode s_eMode;

#if ASURA_PS2_SCE_RT_BANDWIDTH_TEXT
	// debugging text
	static char s_acBandwidthText[ASURA_PS2_BANDWIDTH_TEXT_LENGTH];
#endif
};

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

#endif // #ifndef ___ASURA_PS2_SCE_RT_H___
