private async Task SetState(GameState state)
        {
            if (_gameState == GameState.GameOver)
            {
                return; // need to create a new game...
            }

            _gameState = state;

            MainPage.Current.EnableSaveGame(false); // default is you can't save the amge
            string enterLogString = "";

            for (int i = 0; i < _tabDepth; i++)
            {
                enterLogString += "\t";
            }
            enterLogString += String.Format("Setting State to:{0}", state);
            MainPage.LogTrace.TraceMessageAsync(enterLogString);
            _tabDepth++;

            switch (_gameState)
            {
            case GameState.PickCard:

                _dealer = _view.OnPickCard();

                await SetState(GameState.Deal);

                break;

            case GameState.Deal:
                _totalCardsDropped       = 0;
                _nPlayerCountingPoint    = 0;
                _nComputerCountingPoint  = 0;
                _nPlayerPointsThisTurn   = 0;
                _nComputerPointsThisTurn = 0;
                _nCribPointsThisTurn     = 0;
                HandsFromService         = _game.ShuffleAndReturnAllCards();
                Debug.Assert(_game.Dealer == _dealer);
                await _view.OnDeal(HandsFromService);
                await SetState(GameState.GiveToCrib);

                break;

            case GameState.GiveToCrib:
                await SetState(GameState.ComputerGiveToCrib);
                await SetState(GameState.PlayerGiveToCrib);

                break;

            case GameState.ComputerGiveToCrib:
                Debug.Assert(_crib.Count == 0);
                _crib = _game.GetSuggestedCrib(PlayerType.Computer, Settings.Difficulty);
                await _view.OnComputerGiveToCrib(_crib);

                break;

            case GameState.PlayerGiveToCrib:
                MainPage.Current.EnableSaveGame(true);
                PlayerType cribOwner = (_dealer == PlayerType.Player ? PlayerType.Player : PlayerType.Computer);
                _boardUi.Crib = cribOwner;
                _boardUi.Turn = PlayerType.Player;
                await _view.OnPlayerGiveToCrib(2 - _totalCardsDropped, cribOwner);

                break;

            case GameState.Count:

                if (_dealer == PlayerType.Player)
                {
                    await SetState(GameState.ComputerCountCard);
                }
                else
                {
                    await SetState(GameState.PlayerCountCard);
                }
                break;

            case GameState.ComputerCountCard:
            {
                _totalCardsDropped = await CountComputerCards();

                if (_totalCardsDropped == 8)
                {
                    await SetState(GameState.CountingEnded);
                }
                else
                {
                    await SetState(GameState.PlayerCountCard);
                }
                break;
            }

            case GameState.PlayerCountCard:
            {
                _view.OnPlayerCountCard();

                MainPage.Current.EnableSaveGame(true);
                break;
            }

            case GameState.CountingEnded:
                await _view.OnCountingEnded(_nPlayerCountingPoint, _nComputerCountingPoint);

                MainPage.Current.StatsView.Stats.Stat(StatName.TotalCountingSessions).UpdateStatistic(PlayerType.Player, 1);
                MainPage.Current.StatsView.Stats.Stat(StatName.TotalCountingSessions).UpdateStatistic(PlayerType.Computer, 1);
                await SetState(GameState.ScoreHands);

                break;

            case GameState.ScoreHands:
                if (_dealer == PlayerType.Player)
                {
                    await SetState(GameState.ComputerScoreHand);
                    await SetState(GameState.PlayerScoreHand);
                    await SetState(GameState.ShowCrib);
                    await SetState(GameState.PlayerScoreCrib);
                }
                else
                {
                    await SetState(GameState.PlayerScoreHand);
                    await SetState(GameState.ComputerScoreHand);
                    await SetState(GameState.ShowCrib);
                    await SetState(GameState.ComputerScoreCrib);
                }

                await SetState(GameState.EndOfHand);

                break;

            case GameState.ComputerScoreHand:
                ScoreCollection story = _game.UpdateScore(PlayerType.Computer, HandType.Regular, 0, Settings.Difficulty);     // service ignores what computer sends
                _nComputerPointsThisTurn = story.Total;
                await _view.OnComputerScoreHand(story.Total, Settings.OKAfterHand, story);

                if (_game.GetCurrentScore(PlayerType.Computer) > WINNING_SCORE)
                {
                    await SetState(GameState.GameOver);

                    return;
                }

                MainPage.Current.StatsView.Stats.Stat(StatName.TotalHandsPlayed).UpdateStatistic(PlayerType.Computer, 1);
                break;

            case GameState.ComputerScoreCrib:
            {
                ScoreCollection cribStory = _game.UpdateScore(PlayerType.Computer, HandType.Crib, 0, Settings.Difficulty);         // service ignores what computer sends
                _nCribPointsThisTurn = cribStory.Total;
                await _view.OnComputerScoreCrib(cribStory.Total, cribStory);

                if (_game.GetCurrentScore(PlayerType.Computer) > WINNING_SCORE)
                {
                    await SetState(GameState.GameOver);

                    return;
                }
            }
                MainPage.Current.StatsView.Stats.Stat(StatName.TotalCribsPlayed).UpdateStatistic(PlayerType.Computer, 1);
                break;

            case GameState.PlayerScoreHand:

                MainPage.Current.EnableSaveGame(true);
                int             scoreGuess      = int.MaxValue;
                ScoreCollection playerHandStory = null;
                do
                {
                    if (Settings.AutoSetScore)
                    {
                        playerHandStory = _game.UpdateScore(PlayerType.Player, HandType.Regular, 0, Settings.Difficulty);
                        scoreGuess      = playerHandStory.ActualScore;
                    }

                    scoreGuess = await _view.OnGetPlayerHandScore(scoreGuess);

                    playerHandStory = _game.UpdateScore(PlayerType.Player, HandType.Regular, scoreGuess, Settings.Difficulty);
                    if (playerHandStory.Accepted == false)
                    {
                        // if you aren't doing muggins and got the score wrong, you just try again
                        await _view.ShowUserMessage("That guess was close, but not quite right.  Try again.");
                    }
                    else     // you got the score right!
                    {
                        break;
                    }
                } while (true);

                await _view.OnUpdateScoreUi(PlayerType.Player, scoreGuess, playerHandStory);     // update the UI for the score the user gets

                MainPage.Current.StatsView.Stats.Stat(StatName.TotalHandsPlayed).UpdateStatistic(PlayerType.Player, 1);

                _nPlayerPointsThisTurn = scoreGuess;

                if (_game.GetCurrentScore(PlayerType.Player) > WINNING_SCORE)
                {
                    await SetState(GameState.GameOver);

                    return;
                }

                break;

            case GameState.ShowCrib:
                await _view.OnShowCrib(_dealer);

                break;

            case GameState.PlayerScoreCrib:

                MainPage.Current.EnableSaveGame(true);
                int scoreCribGuess = int.MaxValue;
                if (Settings.AutoSetScore)
                {
                    scoreCribGuess = _game.GetScore(PlayerType.Player, HandType.Crib);
                }

                ScoreCollection playerCribStory = null;
                do
                {
                    scoreCribGuess = await _view.OnGetPlayerCribScore(scoreCribGuess);

                    playerCribStory = _game.UpdateScore(PlayerType.Player, HandType.Crib, scoreCribGuess, Settings.Difficulty);
                    scoreCribGuess  = playerCribStory.Total;
                    if (playerCribStory.Accepted == false)
                    {
                        await _view.ShowUserMessage("That guess was close, but not quite right.  Try again.");
                    }
                } while (playerCribStory.Accepted == false);
                await _view.OnUpdateScoreUi(PlayerType.Player, playerCribStory.Total, playerCribStory);

                MainPage.Current.StatsView.Stats.Stat(StatName.TotalCribsPlayed).UpdateStatistic(PlayerType.Player, 1);
                _nCribPointsThisTurn = playerCribStory.Total;
                if (_game.GetCurrentScore(PlayerType.Player) > WINNING_SCORE)
                {
                    await SetState(GameState.GameOver);

                    return;
                }
                break;

            case GameState.EndOfHand:
                await _view.OnEndOfHand(_dealer, _nCribPointsThisTurn, _nComputerCountingPoint, _nPlayerCountingPoint, _nComputerPointsThisTurn, _nPlayerPointsThisTurn);

                if (_dealer == PlayerType.Player)
                {
                    _dealer = PlayerType.Computer;
                }
                else
                {
                    _dealer = PlayerType.Player;
                }

                await SetState(GameState.Deal);

                break;

            case GameState.GameOver:
            {
                int playerScore   = _game.GetCurrentScore(PlayerType.Player);
                int computerScore = _game.GetCurrentScore(PlayerType.Computer);

                if (computerScore > 121)
                {
                    computerScore = 121;
                }
                if (playerScore > 121)
                {
                    playerScore = 121;
                }

                PlayerType winner = PlayerType.Player;
                if (playerScore < computerScore)
                {
                    winner = PlayerType.Computer;
                }

                int winMargin = Math.Abs(playerScore - computerScore);

                MainPage.Current.StatsView.Stats.Stat(StatName.GamesWon).UpdateStatistic(winner, 1);
                MainPage.Current.StatsView.Stats.Stat(StatName.GamesLost).UpdateStatistic(winner == PlayerType.Player ? PlayerType.Computer : PlayerType.Player, 1);
                MainPage.Current.StatsView.Stats.Stat(StatName.SmallestWinMargin).UpdateStatistic(winner, winMargin);
                MainPage.Current.StatsView.Stats.Stat(StatName.LargestWinMargin).UpdateStatistic(winner, winMargin);
                if (winMargin >= 30)
                {
                    MainPage.Current.StatsView.Stats.Stat(StatName.SkunkWins).UpdateStatistic(winner, 1);
                }

                await _view.OnGameOver(winner, Math.Abs(playerScore - computerScore));
            }
            break;
            }

            string leaveLogString = "";

            for (int i = 0; i < _tabDepth; i++)
            {
                leaveLogString += "\t";
            }
            leaveLogString += String.Format("Returning from SetState. Current State {0}  Depth:{1}", state, _tabDepth);
            MainPage.LogTrace.TraceMessageAsync(leaveLogString);
            _tabDepth--;
        }