// DWBS ------------------------------------------------------------------ DWBS
//
// PLATFORM		: ALL
// PRODUCT		: BIT_DEMON
// VISIBILITY	: PUBLIC
//
// DWBS ------------------------------------------------------------------ DWBS

#ifndef SIMULATION_H
#define SIMULATION_H

#include <bdExample/bdExampleCommonLobby/bdExampleCommonLobby.h>

#define MAX_NUM_SESSIONS (10u)

class Simulation : public bdDemo
{
	public:

		BD_DECLARE_NEW_AND_DELETE_OPERATORS

		Simulation();

		~Simulation();

		virtual bdBool init(bdInt argc,
							bdNChar8* argv[]);

		virtual bdBool step(const bdFloat32 time);
		
		virtual void quit();

	protected:

		enum Task
		{
			START_NETWORK,			
			CHECK_DNS,
			CREATE_PLAYER1,
			CREATE_PLAYER2,
			AUTHENTICATE_PLAYER1,
			AUTHENTICATE_PLAYER2,
			LOBBY_CONNECT,

			// friend specific tasks
			CREATE_PROFILE,
			GET_MESSAGES,
			ACCEPT_PROPOSAL,
			REJECT_PROPOSAL,
			GET_FRIENDS,
			PROPOSE_FRIENDSHIP,
			LIST_PROPOSALS,
			WITHDRAW_PROPOSAL,

			INVITE_FRIEND,
			ACCEPT_INVITATION,
			REJECT_INVITATION,
			SEND_CUSTOM,
			CREATE_GROUP,
			LIST_GROUPS,
			ADD_FRIEND_TO_GROUP,
			LIST_GROUP_FRIENDS,
			DELETE_GROUP,
			REMOVE_FRIEND,
			BLOCK_USER,
			LIST_BLOCKED,
			UNBLOCK_USER,

			LOBBY_DISCONNECT,
			STOP_NETWORK
		};

		void startTask();
		void pumpTask();
		void displayTaskResult();

		// Network startup
		void startNetworkDescription(bdString& description);
		void startNetwork();
		void pumpStartNetwork();

		// DNS lookup
		void checkDNSDescription(bdString& description);
		void startCheckDNS();
		void pumpCheckDNS();

		// Authentication service 	
		bdAuthService* getAuthService();
		const bdAuthInfo *getAuthInfo();

		void checkAuthServiceError();
		void pumpAuthServiceTask();

		// Create player1
		void createPlayer1Description(bdString& description);
		void startCreatePlayer1();
		void pumpCreatePlayer1();

		// Create player2
		void createPlayer2Description(bdString& description);
		void startCreatePlayer2();
		void pumpCreatePlayer2();

		// Authenticate player1
		void authenticatePlayer1Description(bdString& description);
		void startAuthenticatePlayer1();
		void pumpAuthenticatePlayer1();

		// Authenticate player2
		void authenticatePlayer2Description(bdString& description);
		void startAuthenticatePlayer2();
		void pumpAuthenticatePlayer2();

		// Lobby service connect
		void lobbyServiceConnectDescription(bdString& description);
		void startLobbyServiceConnect();
		void pumpLobbyServiceConnect();

		// Create profile
		void createProfileDescription(bdString& description);
		void startCreateProfile();
		void pumpCreateProfile();

		// Get messages
		void createGetMessagesDescription(bdString& description);
		void startGetMessages();
		void pumpGetMessages();

		// Accept friendship proposal
		void createAcceptProposalDescription(bdString& description);
		void startAcceptProposal();
		void pumpAcceptProposal();

		// Reject friendship proposal
		void createRejectProposalDescription(bdString& description);
		void startRejectProposal();
		void pumpRejectProposal();

		// Get friends
		void createGetFriendsDescription(bdString& description);
		void startGetFriends();
		void pumpGetFriends();

		// Propose friendship
		void createProposeFriendshipDescription(bdString& description);
		void startProposeFriendship();
		void pumpProposeFriendship();

		// Display friendship proposal list
		void createListProposalsDescription(bdString& description);
		void startListProposals();
		void pumpListProposals();

		// Withdraw friendship proposal
		void createWithdrawProposalDescription(bdString& description);
		void startWithdrawProposal();
		void pumpWithdrawProposal();

		// Invite friend to a session
		void createInviteDescription(bdString& description);
		void startInvite();
		void pumpInvite();

		// Accept session Invite
		void createAcceptInviteDescription(bdString& description);
		void startAcceptInvite();
		void pumpAcceptInvite();

		// Reject session Invite
		void createRejectInviteDescription(bdString& description);
		void startRejectInvite();
		void pumpRejectInvite();

		// Send custom message to a friend
		void createSendCustomDescription(bdString& description);
		void startSendCustom();
		void pumpSendCustom();

		// Create friend group
		void createGroupDescription(bdString& description);
		void startGroup();
		void pumpGroup();

		// List groups
		void createListGroupsDescription(bdString& description);
		void startListGroups();
		void pumpListGroups();

		// Add friend to group
		void createAddFriendToGroupDescription(bdString& description);
		void startAddFriendToGroup();
		void pumpAddFriendToGroup();

		// List friends in group
		void createListGroupFriendsDescription(bdString& description);
		void startListGroupFriends();
		void pumpListGroupFriends();

		// delete group
		void createDeleteGroupDescription(bdString& description);
		void startDeleteGroup();
		void pumpDeleteGroup();

		// remove friend
		void createRemoveFriendDescription(bdString& description);
		void startRemoveFriend();
		void pumpRemoveFriend();

		// block user
		void createBlockUserDescription(bdString& description);
		void startBlockUser();
		void pumpBlockUser();

		// list blocked users
		void createListBlockedDescription(bdString& description);
		void startListBlocked();
		void pumpListBlocked();

		// unblock user
		void createUnblockUserDescription(bdString& description);
		void startUnblockUser();
		void pumpUnblockUser();

		// Lobby disconnect
		void lobbyServiceDisconnectDescription(bdString& description);
		void startLobbyServiceDisconnect();
		void pumpLobbyServiceDisconnect();

		// Network stop
		void stopNetworkDescription(bdString& description);
		void stopNetwork();

		// Error checking
		void checkProfilesError();
		void checkFriendsError();
		
	protected:

		// A method to consume and display any messages that have arrived in the
		// message store.
		void checkMessageStore();

		// A method to determine the next Task, based on any proposals or invites
		// present in the message store
		Task determineNextTask(Task currentTask);

		// receives log messages
		bdLogSubscriber m_logSubscriber;

		TaskStatus m_taskStatus;
		Task m_task;
		bdString m_lastTaskDescription;

		bdBool m_changedScreen;
		bdString m_screenText;

		bdInetAddr m_authAddr;
		bdGetHostByName *m_authGetHostByName;

		bdAuthService *m_authService;
		
		bdInetAddr m_lsgAddr;
		bdGetHostByName *m_lsgGetHostByName;

		bdRemoteTask *m_remoteTask;

		bdBool m_pumpLobbyConnection;
		bdLobbyErrorCode m_lobbyErrorCode;

		// friend specific data
		bdString m_messageText;
		bdStopwatch m_messageTimer;
		bdUInt m_playerNumber;
		bdString m_listString;
};

#endif // SIMULATION_H
