/// <summary>
 /// </summary>
 /// <param name="parameter">MapPokemonWrapper containing the Pokemon that we're trying to capture</param>
 /// <param name="mode"></param>
 /// <param name="suspensionState"></param>
 /// <returns></returns>
 public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary <string, object> suspensionState)
 {
     if (suspensionState.Any())
     {
         // Recovering the state
         CurrentEncounter        = new EncounterResponse();
         CurrentLureEncounter    = new DiskEncounterResponse();
         CurrentIncenseEncounter = new IncenseEncounterResponse();
         CurrentCaptureAward     = new CaptureAward();
         SelectedCaptureItem     = new ItemData();
         CurrentPokemon          = JsonConvert.DeserializeObject <IMapPokemon>((string)suspensionState[nameof(CurrentPokemon)]);
         CurrentEncounter.MergeFrom(ByteString.FromBase64((string)suspensionState[nameof(CurrentEncounter)]).CreateCodedInput());
         CurrentLureEncounter.MergeFrom(ByteString.FromBase64((string)suspensionState[nameof(CurrentLureEncounter)]).CreateCodedInput());
         CurrentIncenseEncounter.MergeFrom(ByteString.FromBase64((string)suspensionState[nameof(CurrentIncenseEncounter)]).CreateCodedInput());
         CurrentCaptureAward.MergeFrom(ByteString.FromBase64((string)suspensionState[nameof(CurrentCaptureAward)]).CreateCodedInput());
         SelectedCaptureItem.MergeFrom(ByteString.FromBase64((string)suspensionState[nameof(SelectedCaptureItem)]).CreateCodedInput());
         RaisePropertyChanged(() => CurrentEncounter);
         RaisePropertyChanged(() => CurrentLureEncounter);
         RaisePropertyChanged(() => CurrentIncenseEncounter);
         RaisePropertyChanged(() => CurrentCaptureAward);
         RaisePropertyChanged(() => SelectedCaptureItem);
     }
     else
     {
         // Navigating from game page, so we need to actually load the encounter
         CurrentPokemon = (IMapPokemon)NavigationHelper.NavigationState[nameof(CurrentPokemon)];
         Busy.SetBusy(true, string.Format(Resources.CodeResources.GetString("LoadingEncounterText"), Resources.Pokemon.GetString(CurrentPokemon.PokemonId.ToString())));
         NavigationHelper.NavigationState.Remove(nameof(CurrentPokemon));
         GameClient.CurrentSession.Logger.Info($"Catching {CurrentPokemon.PokemonId}");
         await HandleEncounter();
     }
 }
        //Encounter Incense
        private async Task <MethodResult <IncenseEncounterResponse> > EncounterIncensePokemon(MapPokemon mapPokemon)
        {
            var response = await _client.ClientSession.RpcClient.SendRemoteProcedureCallAsync(new Request
            {
                RequestType    = RequestType.IncenseEncounter,
                RequestMessage = new IncenseEncounterMessage
                {
                    EncounterId       = mapPokemon.EncounterId,
                    EncounterLocation = mapPokemon.SpawnPointId
                }.ToByteString()
            });

            if (response == null)
            {
                return(new MethodResult <IncenseEncounterResponse>());
            }

            IncenseEncounterResponse eResponse = IncenseEncounterResponse.Parser.ParseFrom(response);

            switch (eResponse.Result)
            {
            case IncenseEncounterResponse.Types.Result.IncenseEncounterNotAvailable:
                return(new MethodResult <IncenseEncounterResponse>
                {
                    Message = "Encounter failed. Pokemon Already Happened"
                });

            case IncenseEncounterResponse.Types.Result.IncenseEncounterUnknown:
                LogCaller(new LoggerEventArgs(String.Format("Encounter failed with response {0}", eResponse.Result), LoggerTypes.Warning));

                return(new MethodResult <IncenseEncounterResponse>
                {
                    Message = "Encounter failed"
                });

            case IncenseEncounterResponse.Types.Result.IncenseEncounterSuccess:
                return(new MethodResult <IncenseEncounterResponse>
                {
                    Data = eResponse,
                    Success = true,
                    Message = "Success"
                });

            case IncenseEncounterResponse.Types.Result.PokemonInventoryFull:
                LogCaller(new LoggerEventArgs("Encounter failed. Pokemon inventory full", LoggerTypes.Warning));

                return(new MethodResult <IncenseEncounterResponse>
                {
                    Message = "Encounter failed. Pokemon inventory full"
                });
            }
            return(new MethodResult <IncenseEncounterResponse>());
        }
        //Encounter Incense
        private async Task <MethodResult <IncenseEncounterResponse> > EncounterIncensePokemon(MapPokemon mapPokemon)
        {
            if (!_client.LoggedIn)
            {
                MethodResult result = await AcLogin();

                if (!result.Success)
                {
                    return(new MethodResult <IncenseEncounterResponse>());
                }
            }

            if (mapPokemon == null || mapPokemon.PokemonId == PokemonId.Missingno)
            {
                return(new MethodResult <IncenseEncounterResponse>());
            }

            if (LastedEncountersIds.Contains(mapPokemon.EncounterId))
            {
                return(new MethodResult <IncenseEncounterResponse>());
            }

            if (!CatchDisabled)
            {
                if (RemainingPokeballs() < 1)
                {
                    LogCaller(new LoggerEventArgs("You don't have any pokeball catching pokemon will be disabled during " + UserSettings.DisableCatchDelay.ToString(CultureInfo.InvariantCulture) + " minutes.", LoggerTypes.Info));
                    CatchDisabled = true;
                    TimeAutoCatch = DateTime.Now.AddMinutes(UserSettings.DisableCatchDelay);
                    return(new MethodResult <IncenseEncounterResponse>());
                }
            }

            var response = await _client.ClientSession.RpcClient.SendRemoteProcedureCallAsync(new Request
            {
                RequestType    = RequestType.IncenseEncounter,
                RequestMessage = new IncenseEncounterMessage
                {
                    EncounterId       = mapPokemon.EncounterId,
                    EncounterLocation = mapPokemon.SpawnPointId
                }.ToByteString()
            });

            if (response == null)
            {
                return(new MethodResult <IncenseEncounterResponse>());
            }

            IncenseEncounterResponse eResponse = IncenseEncounterResponse.Parser.ParseFrom(response);

            switch (eResponse.Result)
            {
            case IncenseEncounterResponse.Types.Result.IncenseEncounterNotAvailable:
                break;

            case IncenseEncounterResponse.Types.Result.IncenseEncounterUnknown:
                break;

            case IncenseEncounterResponse.Types.Result.IncenseEncounterSuccess:
                if (LastedEncountersIds.Count > 30)
                {
                    LastedEncountersIds.Clear();
                }

                LastedEncountersIds.Add(eResponse.PokemonData.Id);

                return(new MethodResult <IncenseEncounterResponse>
                {
                    Data = eResponse,
                    Success = true,
                    Message = "Success"
                });

            case IncenseEncounterResponse.Types.Result.PokemonInventoryFull:
                break;
            }

            if (LastedEncountersIds.Count > 30)
            {
                LastedEncountersIds.Clear();
            }

            LastedEncountersIds.Add(mapPokemon.EncounterId);

            LogCaller(new LoggerEventArgs(String.Format("Encounter incense failed with response {0}", eResponse.Result), LoggerTypes.Warning));
            return(new MethodResult <IncenseEncounterResponse>());
        }
 /// <summary>
 /// Provides a safe way to invoke the <see cref="IncenseEncounterReceived" /> event.
 /// </summary>
 /// <param name="value"></param>
 public void RaiseIncenseEncounterReceived(IncenseEncounterResponse value) => IncenseEncounterReceived?.Invoke(this, value);