private void HandleInvitationAccepted(Dictionary <string, string> data)
        {
            // If we have a selected opponent we are inviting and the data matches
            if ((RequestIsFromSelectedOpponent(data)) && (RequestIsForUs(data)))
            {
                if (Active)
                {
                    // Accepted our invitation - flag that the invitation has been accepted
                    _selectedOpponent.State = OpponentSelector.OpponentSelectionState.HasAcceptedInvite;

                    // ... and start sending "acknowledge" messages back
                    _communicator.Message = string.Concat("cmd=inv-ack&target=", _selectedOpponent.ID);

                    _communicator.OtherPlayerAvatarSlot = _selectedOpponent.AvatarSlot;
                    _communicator.OtherPlayerName       = _selectedOpponent.Name;
                    DismissWithReturnValue(_selectedOpponent.ID);
                }
            }
            else
            {
                // Either this is not our selected opponent or they have sent the accept to someone else - either way, remove from list
                _opponents.Remove(data["id"]);

                // If this is our selected opponent accepting someone else's invite, return us to waiting state
                if (RequestIsFromSelectedOpponent(data))
                {
                    _selectedOpponent = null;
                    ReturnToWaitingForInvite();
                }
            }
        }
        public override void Activate()
        {
            base.Activate();

            _selectedOpponent = null;
            _communicator.CommsEventCallback = HandleCommunicationData;

            if (!_communicator.Active) { _timer.NextActionDuration = Communicator_Activation_Delay; }
        }
        private void HandleOpponentSelection(OpponentSelector selected)
        {
            switch (selected.State)
            {
            case OpponentSelector.OpponentSelectionState.WaitingForInvite: SetSelectionState(selected); break;

            case OpponentSelector.OpponentSelectionState.HasBeenInvited: SetSelectionState(selected); break;

            case OpponentSelector.OpponentSelectionState.IsInviting: AcceptInvitation(selected); break;
            }
        }
        public override void Activate()
        {
            base.Activate();

            _selectedOpponent = null;
            _communicator.CommsEventCallback = HandleCommunicationData;

            if (!_communicator.Active)
            {
                _timer.NextActionDuration = Communicator_Activation_Delay;
            }
        }
        private void AcceptInvitation(OpponentSelector selected)
        {
            // Touched an opponent who has invited - mark as our selected opponent and set state to accepted
            _selectedOpponent       = selected;
            _selectedOpponent.State = OpponentSelector.OpponentSelectionState.InvitationAccepted;

            // ... and start sending "accept" messages back
            _communicator.Message = string.Concat("cmd=accept&target=", _selectedOpponent.ID);

            // ... and switch off all other possibles (no changing selection once accepted unless it all falls through)
            foreach (KeyValuePair <string, OpponentSelector> kvp in _opponents)
            {
                if (kvp.Value != _selectedOpponent)
                {
                    kvp.Value.Suspended = true;
                }
            }
        }
 private void HandleInvitationAcknowledged(Dictionary <string, string> data)
 {
     if (RequestIsFromSelectedOpponent(data))
     {
         if (RequestIsForUs(data))
         {
             if (Active)
             {
                 _communicator.OtherPlayerAvatarSlot = _selectedOpponent.AvatarSlot;
                 _communicator.OtherPlayerName       = _selectedOpponent.Name;
                 DismissWithReturnValue(_selectedOpponent.ID);
             }
         }
         else
         {
             _selectedOpponent.State = OpponentSelector.OpponentSelectionState.WaitingForInvite;
             _selectedOpponent       = null;
             ReturnToWaitingForInvite();
         }
     }
 }
        public override void Draw(SpriteBatch spriteBatch)
        {
            base.Draw(spriteBatch);

            if (_opponents.Count > 0)
            {
                foreach (KeyValuePair <string, OpponentSelector> kvp in _opponents)
                {
                    kvp.Value.Draw(spriteBatch);
                }
            }
            else
            {
                DrawStatusMessage(spriteBatch);
            }

            if ((_selectedOpponent != null) && (!_selectedOpponent.Active))
            {
                _selectedOpponent = null;
                ReturnToWaitingForInvite();
            }
        }
        private void SetSelectionState(OpponentSelector selected)
        {
            if (_selectedOpponent == selected)
            {
                // If we have touched our current invited opponent, switch back to waiting
                _selectedOpponent = null;
                ReturnToWaitingForInvite();
            }
            else
            {
                // otherwise, start sending invites to the selected opponent
                _selectedOpponent     = selected;
                _communicator.Message = string.Format("cmd=invite&target={0}&name={1}&slot={2}",
                                                      _selectedOpponent.ID,
                                                      Data.Profile.Settings.RaceName,
                                                      Data.Profile.Settings.SelectedAvatarSlot);

                // Some stuff to allow testing...
                if ((Data.Profile.Settings.TestingRaceMode) && (selected.Name == "test-opp"))
                {
                    DismissWithReturnValue(selected.ID);
                }
            }

            // Switch invited (if any) to has been invited state, all others to waiting
            foreach (KeyValuePair <string, OpponentSelector> kvp in _opponents)
            {
                if (kvp.Value == _selectedOpponent)
                {
                    kvp.Value.State = OpponentSelector.OpponentSelectionState.HasBeenInvited;
                }
                else
                {
                    kvp.Value.State = OpponentSelector.OpponentSelectionState.WaitingForInvite;
                }
            }
        }
        private void HandleInvitationRequest(Dictionary <string, string> data)
        {
            if ((JoinerDataIsValid(data)) && (RequestIsForUs(data)) && (!_opponents.ContainsKey(data["id"])))
            {
                AddOpponentToList(data["id"], data["name"], GetAvatarSlot(data));
            }

            // Request is valid and targeting us, switch inviting opponent to "is inviting" state
            if ((RequestIsForUs(data)) && (!RequestIsFromSelectedOpponent(data)))
            {
                _opponents[data["id"]].State = OpponentSelector.OpponentSelectionState.IsInviting;
            }

            // If request is from an opponent we are trying to accept an invite from but NOT targeting us, switch back to waiting and clear selection
            if ((RequestIsNotForUs(data)) && (_opponents[data["id"]].State != OpponentSelector.OpponentSelectionState.WaitingForInvite))
            {
                _opponents[data["id"]].State = OpponentSelector.OpponentSelectionState.WaitingForInvite;
                if (_opponents[data["id"]] == _selectedOpponent)
                {
                    _selectedOpponent = null;
                }
                ReturnToWaitingForInvite();
            }
        }
        public override void Draw(SpriteBatch spriteBatch)
        {
            base.Draw(spriteBatch);

            if (_opponents.Count > 0)
            {
                foreach (KeyValuePair<string, OpponentSelector> kvp in _opponents) { kvp.Value.Draw(spriteBatch); }
            }
            else
            {
                DrawStatusMessage(spriteBatch);
            }

            if ((_selectedOpponent != null) && (!_selectedOpponent.Active))
            {
                _selectedOpponent = null;
                ReturnToWaitingForInvite();
            }
        }
        private void SetSelectionState(OpponentSelector selected)
        {
            if (_selectedOpponent == selected)
            {
                // If we have touched our current invited opponent, switch back to waiting
                _selectedOpponent = null;
                ReturnToWaitingForInvite();
            }
            else
            {
                // otherwise, start sending invites to the selected opponent
                _selectedOpponent = selected;
                _communicator.Message = string.Format("cmd=invite&target={0}&name={1}&slot={2}",
                    _selectedOpponent.ID,
                    Data.Profile.Settings.RaceName,
                    Data.Profile.Settings.SelectedAvatarSlot);

                // Some stuff to allow testing...
                if ((Data.Profile.Settings.TestingRaceMode) && (selected.Name == "test-opp")) { DismissWithReturnValue(selected.ID); }
            }

            // Switch invited (if any) to has been invited state, all others to waiting
            foreach (KeyValuePair<string, OpponentSelector> kvp in _opponents)
            {
                if (kvp.Value == _selectedOpponent) { kvp.Value.State = OpponentSelector.OpponentSelectionState.HasBeenInvited; }
                else { kvp.Value.State = OpponentSelector.OpponentSelectionState.WaitingForInvite; }
            }
        }
 private void HandleOpponentSelection(OpponentSelector selected)
 {
     switch (selected.State)
     {
         case OpponentSelector.OpponentSelectionState.WaitingForInvite: SetSelectionState(selected); break;
         case OpponentSelector.OpponentSelectionState.HasBeenInvited: SetSelectionState(selected); break;
         case OpponentSelector.OpponentSelectionState.IsInviting: AcceptInvitation(selected); break;
     }
 }
        private void HandleInvitationRequest(Dictionary<string, string> data)
        {
            if ((JoinerDataIsValid(data)) && (RequestIsForUs(data)) && (!_opponents.ContainsKey(data["id"])))
            {
                AddOpponentToList(data["id"], data["name"], GetAvatarSlot(data));
            }

            // Request is valid and targeting us, switch inviting opponent to "is inviting" state
            if ((RequestIsForUs(data)) && (!RequestIsFromSelectedOpponent(data)))
            {
                _opponents[data["id"]].State = OpponentSelector.OpponentSelectionState.IsInviting;
            }

            // If request is from an opponent we are trying to accept an invite from but NOT targeting us, switch back to waiting and clear selection
            if ((RequestIsNotForUs(data)) && (_opponents[data["id"]].State != OpponentSelector.OpponentSelectionState.WaitingForInvite))
            {
                _opponents[data["id"]].State = OpponentSelector.OpponentSelectionState.WaitingForInvite;
                if (_opponents[data["id"]] == _selectedOpponent) { _selectedOpponent = null; }
                ReturnToWaitingForInvite();
            }
        }
 private void HandleInvitationAcknowledged(Dictionary<string, string> data)
 {
     if (RequestIsFromSelectedOpponent(data))
     {
         if (RequestIsForUs(data))
         {
             if (Active)
             {
                 _communicator.OtherPlayerAvatarSlot = _selectedOpponent.AvatarSlot;
                 _communicator.OtherPlayerName = _selectedOpponent.Name;
                 DismissWithReturnValue(_selectedOpponent.ID);
             }
         }
         else
         {
             _selectedOpponent.State = OpponentSelector.OpponentSelectionState.WaitingForInvite;
             _selectedOpponent = null;
             ReturnToWaitingForInvite();
         }
     }
 }
        private void HandleInvitationAccepted(Dictionary<string, string> data)
        {
            // If we have a selected opponent we are inviting and the data matches
            if ((RequestIsFromSelectedOpponent(data)) && (RequestIsForUs(data)))
            {
                if (Active)
                {
                    // Accepted our invitation - flag that the invitation has been accepted
                    _selectedOpponent.State = OpponentSelector.OpponentSelectionState.HasAcceptedInvite;

                    // ... and start sending "acknowledge" messages back
                    _communicator.Message = string.Concat("cmd=inv-ack&target=", _selectedOpponent.ID);

                    _communicator.OtherPlayerAvatarSlot = _selectedOpponent.AvatarSlot;
                    _communicator.OtherPlayerName = _selectedOpponent.Name;
                    DismissWithReturnValue(_selectedOpponent.ID);
                }
            }
            else
            {
                // Either this is not our selected opponent or they have sent the accept to someone else - either way, remove from list
                _opponents.Remove(data["id"]);

                // If this is our selected opponent accepting someone else's invite, return us to waiting state
                if (RequestIsFromSelectedOpponent(data))
                {
                    _selectedOpponent = null;
                    ReturnToWaitingForInvite();
                }
            }
        }
        private void AcceptInvitation(OpponentSelector selected)
        {
            // Touched an opponent who has invited - mark as our selected opponent and set state to accepted
            _selectedOpponent = selected;
            _selectedOpponent.State = OpponentSelector.OpponentSelectionState.InvitationAccepted;

            // ... and start sending "accept" messages back
            _communicator.Message = string.Concat("cmd=accept&target=", _selectedOpponent.ID);

            // ... and switch off all other possibles (no changing selection once accepted unless it all falls through)
            foreach (KeyValuePair<string, OpponentSelector> kvp in _opponents)
            {
                if (kvp.Value != _selectedOpponent) { kvp.Value.Suspended = true; }
            }
        }