// DWBS ------------------------------------------------------------------ DWBS
//
// PLATFORM		: ALL
// PRODUCT		: BIT_DEMON
// VISIBILITY	: PUBLIC
//
// DWBS ------------------------------------------------------------------ DWBS
// PURPOSE: The client-side interface to the teams service.

#ifndef BD_TEAM_MANAGEMENT_H
#define BD_TEAM_MANAGEMENT_H

#include <bdCore/bdCore.h>

#include <bdLobby/bdLobbyCommon/bdLobbyServicesCommon.h>
#include <bdLobby/bdLobbyErrorCode.h>

class bdRemoteTask;
class bdRemoteTaskManager;
class bdQueryResult;
class bdQueryParams;
class bdTeamInfo;
class bdTeamMemberInfo;

// Teams operations
#define	BD_TEAM_CREATE								(1u)
#define BD_TEAM_UPDATE								(2u)
#define BD_TEAM_PROMOTE_MEMBER_TO_ADMIN				(3u)
#define BD_TEAM_KICK_MEMBER							(4u)
#define BD_TEAM_LEAVE								(5u)
#define BD_TEAM_PROPOSE_MEMBERSHIP					(6u)
#define BD_TEAM_REJECT_MEMBERSHIP					(7u)
#define BD_TEAM_ACCEPT_MEMBERSHIP					(8u)
#define BD_TEAM_INVITE_TO_SESSION					(9u)
#define BD_TEAM_REJECT_INVITE						(10u)
#define BD_TEAM_ACCEPT_INVITE						(11u)
#define BD_TEAM_GET_PUBLIC_INFO						(12u)
#define BD_TEAM_GET_PRIVATE_INFO					(13u)
#define BD_TEAM_GET_PUBLIC_MEMBER_INFO				(14u)
#define BD_TEAM_GET_PRIVATE_MEMBER_INFO				(15u)
#define BD_TEAM_SET_PUBLIC_INFO						(16u)
#define BD_TEAM_SET_PRIVATE_INFO					(17u)
#define BD_TEAM_SET_PUBLIC_MEMBER_INFO				(18u)
#define BD_TEAM_SET_PRIVATE_MEMBER_INFO				(19u)
#define BD_TEAM_CHECK_MEMBERSHIP					(20u)
#define BD_TEAM_GET_MEMBERS							(21u)
#define BD_TEAM_SEND_MEMBER_MSG						(22u)
#define BD_TEAM_SEND_ADMIN_MSG						(23u)
#define BD_TEAM_GET_PROPOSALS						(24u)
#define BD_TEAM_WITHDRAW_PROPOSAL					(25u)
#define BD_TEAM_DEMOTE_MEMBER						(26u)
#define BD_TEAM_PROMOTE_MEMBER_TO_OWNER				(27u)
#define BD_TEAM_GET_TEAMID							(28u)


/// The client-side interface to the teams service.
/// This service enables the creation and management of teams of players, 
/// sometimes referred to as 'clans'. It also provides functionality for team-based
/// presence awareness and intra-team messaging, so team-centric community 
/// features can be implemented in-game.
/// Any user is able to create a new team, and can proceed to invite other user
/// to join it. As well has defining owner and ordinary-member roles, an 
/// administrator role is optionally provided. This allows the team owner to 
/// appoint people to help out with the management of the team, most specifically,
/// recruitment of new members.
/// The use of customized team profiles is also supported, as is customized profiles
/// for individual team members, and the tracking of team stats, using the 
/// leaderboards available via the bdStats interface.
/// Use the functions contained in this class to perform operations on the server.
/// Each of these function returns a task handle, which should be pumped to 
/// completion by calling its getStatus() function. When the status of a task is 
/// bdRemoteTask::BD_DONE, you can pass it into the bdTeams::handleTask()
/// function. Once this is done, the error code for the task can be accessed via
/// bdTeams::getErrorCode(). If you expect a result to be returned from
/// the server as a result of the task you started, you must pass a specialized 
/// instance of bdQueryResult into bdTeams::handleTask. The implementation must 
/// match the results you are expecting. Implementations are provided
/// for standard types of result sets, in the same directory as this class.
class bdTeams
{
	public:
		BD_DECLARE_NEW_AND_DELETE_OPERATORS

		enum bdMessageDeliveryMethod
		{
			BD_PULL_ONLY,
			BD_PUSH_ONLY,
			BD_PUSH_AND_PULL
		};

		~bdTeams();

		/// Retrieve the bdEntityID teamID of a team given the teams name
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								who need not be a member of the team.
		/// \param teamName[in]			The teams name.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When this task completes, you can obtain the result set by 
		///			invoking bdTeams::handleTask(). Pass an instance of bdCreateTeamResult
		///			to the handleTask function and if task is successful
		///			bdCreateTeamResult.m_teamID will contain the requested teamID.
		bdRemoteTask* getTeamID(bdUByte8 controllerIndex, 
								const bdNChar8 teamName[BD_MAX_TEAMNAME_LENGTH]);



		/// Create a new team.
		/// Team profile information can be set later by calling bdTeams::setPublicInfo
		/// or bdTeams::setPrivateInfo.
		/// \param controllerIndex[in]	The controller index of the requestor, 
		///								who will become the owner of the team.
		/// \param teamName[in]			A string representing the name of the team.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When this task completes, you can obtain the result set by 
		///			invoking bdTeams::handleTask() and passing in an instance
		///			of bdCreateTeamResult, which will then contain the team ID
		///			that was assigned by the server.
		/// \note		When complete, the returned bdRemoteTask will specify:
		///				BD_NO_ERROR - on success. 
		///				BD_TEAMNAME_ALREADY_EXISTS - if an existing team exists  
		///				with this teamname.
		///				BD_NO_MULTIPLE_TEAM_MEMBERSHIP - if the caller is already
		///				a member of another team and this title is configured to
		///				allow membership of just one team.
		///				BD_NO_MULTIPLE_TEAM_OWNERSHIP - if the caller is already
		///				an owner of another team and this title is configured to
		///				allow ownership of just one team.
		bdRemoteTask* createTeam(bdUByte8 controllerIndex, 
								 const bdNChar8 *teamName);


		/// Change the team name.
		/// This changes the team name. If you need to change team profile information,
		/// use the bdTeams::setPublicInfo or bdTeams::setPrivateInfo functions.
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								who must be the team owner.
		/// \param teamID[in]			The team ID.
		/// \param teamName[in]			The new team name.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if the teamID supplied does not exist
		///			BD_NOT_AN_ADMIN_OR_OWNER - if the caller does not have the right
		///			to update the team name.
		///			BD_TEAMNAME_ALREADY_EXISTS - if the new team name is already taken. 
		bdRemoteTask* updateTeam(bdUByte8 controllerIndex, 
								 bdTeamID teamID, 
								 const bdNChar8 *teamName);

		/// Promote an ordinary team member to become an administrator of the team.
		/// This can only be performed by the team owner.
		/// \param controllerIndex[in]	The controller index of the requestor, who
		///								must be the team owner.
		/// \param teamID[in]			The team ID.
		/// \param userID[in]			The user ID of the member to be promoted.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAM_PROMOTION_MSG will be delivered to the user 
		///				specified by userID.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID does not represent a team
		///			BD_NOT_A_TEAM_OWNER - if the caller is not the owner of the
		///			team represented by teamID.
		///			BD_NOT_A_TEAM_MEMBER - if the user specified by userID is not
		///			a member of the team represented by teamID.
		bdRemoteTask* promoteMember(bdUByte8 controllerIndex, 
									bdTeamID teamID, 
									bdOnlineUserID userID);

		/// Promote an ordinary team member to become the owner of the team.
		/// This can only be performed by the team owner, who is demoted to an
		/// administrator of the team, if the promotion is sucessful. 
		/// \param controllerIndex[in]	The controller index of the requestor, who
		///								must be the team owner.
		/// \param teamID[in]			The team ID.
		/// \param userID[in]			The user ID of the member to be promoted.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAM_PROMOTION_TO_OWNER_MSG will be delivered to the user 
		///				specified by userID.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID does not represent a team
		///			BD_NOT_A_TEAM_OWNER - if the caller is not the owner of the
		///			team represented by teamID.
		///			BD_NOT_A_TEAM_MEMBER - if the user specified by userID is not
		///			a member of the team represented by teamID.
		bdRemoteTask* promoteMemberToOwner(bdUByte8 controllerIndex, 
										   bdTeamID teamID, 
										   bdOnlineUserID userID);

		/// Demote a team administrator to an ordinary member of the team.
		/// This can only be performed by the team owner.
		/// \param controllerIndex[in]	The controller index of the requestor, 
		///								who must be the owner of the team.
		/// \param teamID[in]			The team ID.
		/// \param userID[in]			The user ID of the administrator to be demoted.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAMMEMBER_DEMOTED_TO_ORDINARY will be delivered to 
		///				the user specified by userID.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID does not represent a team
		///			BD_NOT_A_TEAM_OWNER - if the caller is not the owner of the
		///			team represented by teamID.
		///			BD_NOT_A_TEAM_MEMBER - if the user specified by userID is not
		///			a member of the team represented by teamID.
		bdRemoteTask* demoteMember(bdUByte8 controllerIndex, 
								   bdTeamID teamID, 
								   bdOnlineUserID userID);

		/// Removes a member from the team. 
		/// Only the owner and team administrators can kick a team member.
		/// \param controllerIndex[in] The controller index of the requestor, who
		///								must be the owner or an administrator.
		/// \param teamID[in]			The team ID.
		/// \param userID[in]			The user ID of the member to be kicked.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAM_KICK_MSG will be delivered to the user 
		///				specified by userID.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID does not represent a team
		///			BD_NOT_A_TEAM_OWNER - if the caller is not the owner of the
		///			team represented by teamID and is attempting to kick an administrator.
		///			BD_NOT_AN_ADMIN_OR_OWNER - if the caller is not an administrator or owner.
		bdRemoteTask* kickMember(bdUByte8 controllerIndex, 
								 bdTeamID teamID, 
								 bdOnlineUserID userID);

		/// Cancel the local user's membership of a team.
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								who must be a member of the specified team.
		/// \param teamID[in]			The team ID
		/// \param userID[in]			(Optional, specify only if the user leaving is the owner of the team). 
		///								If specifed by an owner user leaving the team, 
		///								and userID is a member of the team, userID becomes the new owner.
		/// 							If no userID is specified and the owner is leaving the team, 
		///								the team will be disbanded & deleted - regardless of 
		///								how many members are left on the team.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAM_LEAVE_MSG will be delivered to all team members.
		/// \note		A BD_TEAM_PROMOTION_TO_OWNER_MSG will be delivered to the 
		///				user specified by newOwnerID, if any.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_NOT_A_TEAM_MEMBER - if the user specified by newOwnerID
		///			is not a member of the team specified by teamID.
		bdRemoteTask* leaveTeam(bdUByte8 controllerIndex, 
								bdTeamID teamID, 
								bdOnlineUserID newOwnerID = BD_NULL);

		/// Propose team membership to a user. 
		/// This can only be performed by the owner or an administrator of the team.
		/// The user that receives the proposal must accept or reject it for the
		/// process to complete, using the bdTeams::acceptMembership or 
		/// bdTeams::rejectMembership functions.
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								who must be an owner of administrator of
		///								the team.
		/// \param teamID[in]			The team ID.
		/// \param newUserID[in]		The user ID to send the proposal to.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAM_INVITATION_MSG will be delivered to the user 
		///				specified by newUserID.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		///			BD_NOT_AN_ADMIN_OR_OWNER - if the caller is not an administrator
		///			or owner of this team.
		///			BD_MEMBER_EXISTS - if newUserID is already a member of the team.
		///			BD_USERID_BANNED - if newUserID has a fully blocked the caller
		///			by calling bdFriends::setBlockedStatus
		bdRemoteTask* proposeMembership(bdUByte8 controllerIndex, 
										bdTeamID teamID, 
										bdOnlineUserID newUserID,
										bdByteBuffer * const attachment = BD_NULL);
		
		/// Revoke a membership proposal that has yet been accepted or rejected.
		/// This allows an owner or administrator to cancel outstanding membership
		/// proposals that he/she has sent. This list can be obtained using
		/// bdTeams::getProposalList.
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								who must be the owner or administrator
		///								that previously sent the proposal.
		/// \param userID[in]			The user to which the original proposal 
		///								was addressed.
		/// \param teamID[in]			The team ID.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAMMEMBERSHIP_PROPOSAL_CANCEL_MSG will be delivered
		///				to the user specified by userID.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		///			BD_MEMBER_NO_PROPOSAL - if no membership proposal exists.
		bdRemoteTask *withdrawProposal(bdUByte8 controllerIndex, 
									   bdOnlineUserID userID,
									   bdTeamID teamID);

		/// Reject a team membership proposal.
		/// This function can be called by a user who has received a team membership
		/// proposal, but does not wish to accept it.
		/// \param controllerIndex[in]	The controller index of the requestor, who
		///								received a team membership proposal.
		/// \param teamID[in]			The team ID.
		/// \param inviter[in]			The user ID of the owner or administrator
		///								that sent the proposal.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAM_REJECT_MSG will be delivered to the original
		///				inviter.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		///			BD_MEMBER_NO_PROPOSAL - if no membership proposal exists.
		bdRemoteTask* rejectMembership(bdUByte8 controllerIndex, 
									   bdTeamID teamID, 
									   bdOnlineUserID inviter);

		/// Accept a team membership proposal.
		/// This function can be called by a user who has received a team membership
		/// proposal, and wishes to accept it. After calling this function, the
		/// user will be a member of the team.
		/// \param controllerIndex[in]	The controller index of the requestor, who
		///								received the team membership proposal.
		/// \param teamID[in]			The team ID.
		/// \param inviter[in]			The user ID of the owner or administrator
		///								that sent the proposal.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAM_ACCEPT_MSG will be delivered to the original
		///				inviter, and a BD_TEAMMEMBER_STATUS_ONLINE will be delivered
		///				to all team members.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		///			BD_MEMBER_NO_PROPOSAL - if no membership proposal exists.
		bdRemoteTask* acceptMembership(bdUByte8 controllerIndex, 
									   bdTeamID teamID, 
									   bdOnlineUserID inviter);
        
		/// Get a list of outstanding team membership proposals that have been 
		/// issued by the local user, and which have not yet been accepted or 
		/// rejected.
		/// bdTeams::withdrawProposal can be called on any of the proposals obtained
		/// via this function.
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								who must be the owner or an administrator.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When this task completes, you can obtain the result set by 
		///			invoking bdTeams::handleTask() and passing in an instance
		///			of bdGetTeamsProposalListResult, which will then contain 
		///			information about each outstanding proposal.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		bdRemoteTask *getProposalList(bdUByte8 controllerIndex);

		/// Invite a team member to a game session.
		/// Use this function to implement game invites between team members.
		/// The member that receives this invite must call either 
		/// bdTeams::acceptInvitation or bdTeams::rejectInvitation to deal with it.
		/// \param controllerIndex[in]	The controller index of the requestor.
		/// \param memberID[in]			The user IDs of the team member to send
		///								the invite to.
		/// \param securityID[in]		The securityID of the game session, as 
		///								obtained via the bdMatchMaking interface.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAM_SESSION_INVITATION_MSG will be delivered to user
		///				specified by memberID.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_NOT_A_TEAM_MEMBER - if memberID is not a member of the
		///			same team as the caller.
		///			BD_USERID_BANNED - if memberID has blocked the caller by calling
		///			bdFriends::setBlockedStatus
		bdRemoteTask *inviteMember(bdUByte8 controllerIndex,
								   bdOnlineUserID memberID,
								   const bdSecurityID &securityID,
								   bdByteBuffer * const attachment = BD_NULL);

		/// Accept an invite to a game session, received from a team member that
		/// called bdTeams::inviteMember.
		/// \param controllerIndex[in]	The controller index of the requestor, who
		///								received the invitation.
		/// \param inviter[in]			The User ID of the team member that issued 
		///								the invite.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAM_SESSION_ACCEPT_MSG will be delivered to the original
		///				inviter.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		bdRemoteTask* acceptInvitation(bdUByte8 controllerIndex, 
									   bdOnlineUserID inviter);

		/// Reject an invite to a game session, received from a team member that
		/// called bdTeams::inviteMember.
		/// \param controllerIndex[in]	The controller index of the requestor, who
		///								received the invitation.
		/// \param inviter[in]			The User ID of the team member that issued 
		///								the invite.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAM_SESSION_REJECT_MSG will be delivered to the original
		///				inviter.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		bdRemoteTask* rejectInvitation(bdUByte8 controllerIndex,
									   bdOnlineUserID inviter);

		/// Retrieve the public team profile.
		/// This retrieves publicly accessible profile information about a team
		/// that has been created by the team owner using bdTeams::setPublicInfo.
		/// \param controllerIndex[in]	The controller index of the requestor, who
		///								need not be a member of the team.
		/// \param teamID[in]			The team ID.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When this task completes, you can obtain the result set by 
		///			invoking bdTeams::handleTask(). An instance of a class
		///			derived from bdQueryResult, which matches the results
		///			expected from the server, should be passed into it to receive
		///			the results.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		bdRemoteTask* getPublicInfo(bdUByte8 controllerIndex, 
									bdTeamID teamID);

		/// Retrieve the private team profile.
		/// This retrieves private profile information about a team
		/// that has been created by the team owner using bdTeams::setPrivateInfo.
		/// This can only be performed by a team member.
		/// \param controllerIndex[in]	The controller index of the requestor, who
		///								must be a member of the team.
		/// \param teamID[in]			The team ID.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When this task completes, you can obtain the result set by 
		///			invoking bdTeams::handleTask(). An instance of a class
		///			derived from bdQueryResult, which matches the results
		///			expected from the server, should be passed into it to receive
		///			the results.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		bdRemoteTask* getPrivateInfo(bdUByte8 controllerIndex, 
									 bdTeamID teamID);
		
		/// Set all fields of the public team profile.  
		/// This may only be performed by the team owner.
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								who must be the team owner.
		/// \param teamID[in]			The team ID.
		/// \param teamInfo[in]			An instance of a class derived from 
		///								bdQueryParams that represents the public 
		///								profile info.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		///			BD_PARAM_MISMATCHED_TYPE - if the format of teamInfo did not
		///			match the format of the database.
		bdRemoteTask* setPublicInfo(bdUByte8 controllerIndex, 
									bdTeamID teamID, 
									bdTeamInfo *const teamInfo);
		
		/// Set all fields of the private team profile.  
		/// This may only be performed by the team owner.
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								who must be the team owner.
		/// \param teamID[in]			The team ID.
		/// \param teamInfo[in]			An instance of a class derived from 
		///								bdQueryParams that represents the private 
		///								profile info.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		///			BD_PARAM_MISMATCHED_TYPE - if the format of teamInfo did not
		///			match the format of the database.
		bdRemoteTask* setPrivateInfo(bdUByte8 controllerIndex, 
									 bdTeamID teamID, 
									 bdTeamInfo *const teamInfo);
		
		/// Retrieve the public team profile of a team member.
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								who need not be a member of the team.
		/// \param teamID[in]			The team ID.
		/// \param userID[in]			The user ID of the team member to
		///								return the public team profile of.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When this task completes, you can obtain the result set by 
		///			invoking bdTeams::handleTask(). An instance of a class
		///			derived from bdQueryResult, which matches the results
		///			expected from the server, should be passed into it to receive
		///			the results.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		///			BD_NOT_A_TEAM_MEMBER - if the caller is not a member of the 
		///			team specified by teamID.
		bdRemoteTask* getPublicMemberInfo(bdUByte8 controllerIndex, 
										  bdTeamID teamID, 
										  bdOnlineUserID userID);
		
		/// Retrieve the private team profile of a team member.
		/// This can only be performed by a team member.
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								who must be a member of the team.
		/// \param teamID[in]			The team ID.
		/// \param userID[in]			The user ID of the team member to
		///								return the private team profile of.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When this task completes, you can obtain the result set by 
		///			invoking bdTeams::handleTask(). An instance of a class
		///			derived from bdQueryResult, which matches the results
		///			expected from the server, should be passed into it to receive
		///			the results.
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		///			BD_NOT_A_TEAM_MEMBER - if the caller is not a member of the 
		///			team specified by teamID.
		bdRemoteTask* getPrivateMemberInfo(bdUByte8 controllerIndex, 
										   bdTeamID teamID, 
										   bdOnlineUserID userID);
		
		/// Set all fields of the public profile of a team member.  
		/// To avoid overwriting previous changes, first call bdTeams::getPublicMemberInfo() 
		/// to retrieve the current public team member data.
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								who must be the owner of the profile.
		/// \param teamID[in]			The team ID.
		/// \param teamInfo[in]			An instance of a class derived from 
		///								bdQueryParams that represents the public 
		///								profile info.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		///			BD_NOT_A_TEAM_MEMBER - if the caller is not a member of the 
		///			team specified by teamID.
		///			BD_PARAM_MISMATCHED_TYPE - if the format of teamInfo did not
		///			match the format of the database.
		bdRemoteTask* setPublicMemberInfo(bdUByte8 controllerIndex, 
										  bdTeamID teamID, 
										  bdTeamMemberInfo *const teamMemberInfo);
		
		/// Set all fields of the private profile of a team member.  
		/// To avoid overwriting previous changes, first call bdTeams::getPrivateMemberInfo() 
		/// to retrieve the current private team member data.
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								who must be the owner of the profile.
		/// \param teamID[in]			The team ID.
		/// \param teamInfo[in]			An instance of a class derived from 
		///								bdQueryParams that represents the private 
		///								profile info.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		///			BD_NOT_A_TEAM_MEMBER - if the caller is not a member of the 
		///			team specified by teamID.
		///			BD_PARAM_MISMATCHED_TYPE - if the format of teamInfo did not
		///			match the format of the database.
		bdRemoteTask* setPrivateMemberInfo(bdUByte8 controllerIndex, 
										   bdTeamID teamID, 
										   bdTeamMemberInfo *const teamMemberInfo);

		/// Get the list of teams that a user is a member of.
		/// \param controllerIndex[in]	The controller index of the requestor,
		///								whose team memberships will be returned.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When this task completes, you can obtain the result set by 
		///			invoking bdTeams::handleTask() with an instance of 
		///			bdCheckTeamMembershipResult.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		bdRemoteTask* checkMemberships(bdUByte8 controllerIndex);

		/// Get the list of members of a specified team.
		/// \param controllerIndex[in]	The controller index of the requestor.
		/// \param teamID[in]			The team ID to retrieve the members of.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note	When this task completes, you can obtain the result set by 
		///			invoking bdTeams::handleTask() with an instance of 
		///			bdGetTeamMembersResult.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_INVALID_TEAM_ID - if teamID is invalid.
		bdRemoteTask* getMembers(bdUByte8 controllerIndex,
								 bdTeamID teamID);

		/// Send a message to a team member.
		/// The format and contents of the message that you send is up to you, 
		/// and is not interpreted by the teams service.
		/// This can only be performed by a fellow team member.
		/// \param controllerIndex[in]		The controller index of the sender.
		/// \param teamMemberID[in]			The user ID of the recipient.
		/// \param payload[in]				The message payload, contained in a 
		///									byte buffer.
		/// \param deliveryMethod[in]		An enumerated value specifying whether
		///									the message should be pushed to the 
		///									user, if the user should pull the message,
		///									or both.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAM_MEMBER_CUSTOM_MSG will be delivered to the user
		///				specified by teamMemberID.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_PARAM_PARSE_ERROR - if teamMemberID also represents the caller.
		///			BD_USERID_BANNED - if teamMemberID has blocked the caller.
		///			BD_NOT_A_TEAM_MEMBER - if teamMemberID and the caller are not members
		///			of the same team.
		bdRemoteTask* sendMemberMessage(bdUByte8 controllerIndex, 
										bdOnlineUserID teamMemberID,
										bdByteBuffer& payload,
										bdMessageDeliveryMethod deliveryMethod);

		/// Send an administrator message to a team.
		/// This send a message to an entire team, and can only be performed by
		/// the team owner or administrator.
		/// The format and contents of the message that you send is up to you, 
		/// and is not interpreted by the teams service.
		/// \param controllerIndex[in]		The controller index of the sender,
		///									who must be an owner or administrator
		///									of the team.
		/// \param teamID[in]				The team ID.
		/// \param payload[in]				The message payload, contained in a 
		///									byte buffer.
		/// \param deliveryMethod[in]		An enumerated value specifying whether
		///									the message should be pushed to the 
		///									user, if the user should pull the message,
		///									or both.
		/// \return	A pointer to the task handle that should be pumped to completion,
		///			or BD_NULL if the operation could not be performed (message 
		///			could not be sent, or maximum number of tasks was exceeded).
		/// \note		A BD_TEAM_ADMIN_CUSTOM_MSG will be delivered to all team
		///				members.
		/// \note	When complete, the returned bdRemoteTask will specify:
		///			BD_NO_ERROR - on success. 
		///			BD_NOT_AN_ADMIN_OR_OWNER - if the caller is not an administrator
		///			or owner of teamID.
		bdRemoteTask* sendAdminMessage(bdUByte8 controllerIndex, 
									   bdTeamID teamID,
									   bdByteBuffer& payload,
									   bdMessageDeliveryMethod deliveryMethod);

		/// Handle a completed task. 
		/// This retrieves the error code returned from the server, and fills out
		/// a result set of data, if appropriate. The specified task must have 
		/// been created by this class. 
		/// If the task is expected to return results, the second parameter should
		/// be specified. bdQueryResult is the base-class for classes that handle
		/// result sets returned from the server. Specialized implementations
		/// of bdQueryResult exist in the same directory as this class for each
		/// kind of teams task that can be started.
		/// \param remoteTask[in]	A pointer to the remote task to handle.
		/// \param queryResult[in]	An optional pointer to an object that handles 
		///							the expected type of result data.
		/// \return - True if the task was successfully handled.
		///			- False otherwise. Call bdTeams::getErrorCode() to get the 
		///			  error condition.
		bdBool handleTask(const bdRemoteTask *const remoteTask, 
						  bdQueryResult *const queryResult = BD_NULL);

		/// Return the error code of the last operation that failed.
		/// \return The last error code
		bdLobbyErrorCode getErrorCode() const;

	protected:

		friend class bdLobbyServiceImpl;

		/// Constructs a team manager with the given task handler.
		/// Note: never call this constructor directly, use bdLobbyService::getTeams() instead.
		/// \param remoteTaskManager[in] A pointer to the remote task manager that handles
		/// requests and replies
		bdTeams(bdRemoteTaskManager *const remoteTaskManager);

		/// remote task manager
		bdRemoteTaskManager *m_remoteTaskManager;

		/// error code store for look up
		bdLobbyErrorCode m_errorCode;
};

#endif // BD_TEAM_MANAGEMENT_H
