/// <summary>
        /// Shuffles the specified exclusion list.
        /// </summary>
        /// <param name="exclusionList">The exclusion list.</param>
        public void Shuffle(Card[] exclusionList)
        {
            this.Shuffle();

            int num = 0;
            for (int i = 0; i < exclusionList.Length; i++)
            {
                Card card = exclusionList[i];
                this.checkSequence = card.SequenceNumber;
                int num2 = Array.FindIndex<int>(this.CardArray, new Predicate<int>(this.IsSame));
                if (num2 != -1)
                {
                    int num3 = this.CardArray[num2];
                    this.CardArray[num2] = this.CardArray[num];
                    this.CardArray[num] = num3;
                    num++;
                }
            }
        }
 private void BurnCard(Card drawCard)
 {
     // find a spot in middle of deck
     // we should put card there
 }
        private void OpponentTurn(CrazyEightDeckManager deckManager, Card[] opponentHands, CardSuit suitOverride )
        {
            AIManager.MoveInfo info;

            //SetPrompt();
            //_prompt = string.Format(Properties.Resources.Text_OpponentTurn, _playerNames[_currentPlayer - 1]);

            // move into UI
            //ClearMouseButtons();
            //ClearSelectedCard();
            //_deckSelected = false;

            //Invalidate();

            // wait - simulate thinking
            //Thread.Sleep(WAIT_LENGTH);

            // send table to ai, with current hand
            // to evaluate next move, which will be added
            // to the table by the ai
            //if (_wildCard)
             //   info = AIManager.EvaluateMove(_data.DeckManager, _data.OpponentsHands[_currentPlayer - 1], _suitOverride);
            //else
            //    info = AIManager.EvaluateMove(_data.DeckManager, _data.OpponentsHands[_currentPlayer - 1], CardSuit.None);

            //if (info.DrawCard)
            //{
            //    if (DrawCard(_currentPlayer))
            //    {
            //        _currentPlayer = NextPlayer();

            //        SetPrompt();

            //        //// player has to pass
            //        //if (_currentPlayer == 0)
            //        //{
            //        //    // wrap around to player
            //        //    _prompt = Properties.Resources.Caption_YourTurn;
            //        //}
            //    }
            //}
            //else
            //{
            //    PlayCard(info.SelectedCard, _data.OpponentsHands[_currentPlayer - 1]);
            //    _wildCard = false;

            //    // check if this guy won
            //    if (_data.OpponentsHands[_currentPlayer - 1].Cards.Count == 0)
            //    {
            //        EndHand();
            //    }
            //    else
            //    {
            //        _currentPlayer = NextPlayer();
            //        SetPrompt();

            //        //if (_currentPlayer == 0)
            //        //{
            //        //    _prompt = Properties.Resources.Caption_YourTurn;
            //        //    if (info.WildCardUsed)
            //        //    {
            //        //        ShowWildcardDialog(info.OverrideSuit);
            //        //    }
            //        //}
            //    }

            //    if (info.WildCardUsed)
            //    {
            //        _wildCard = true;
            //        _suitOverride = info.OverrideSuit;

            //        if (_currentPlayer == 0)
            //        {
            //            ShowWildcardDialog(info.OverrideSuit);
            //        }
            //    }

            //}
        }
        //private bool IsPlayerTurnNext()
        //{
        //    if (_direction == PlayDirection.Left)
        //    {
        //        return _currentPlayer == _data.OpponentsHands.Length;
        //    }
        //    else
        //    {
        //        return _currentPlayer == 1;
        //    }
        //}
        private int GetCardColumn(Card[] hand, int mouseX, int mouseY)
        {
            //Point deckTLC = new Point(258, 225);
            //deckTLC.X = _tableCenter - CardCanvas.DefaultWidth - CardSpacing / 2;

            //Point tableTLC = new Point(339, 225);
            //tableTLC.X = _tableCenter + CardSpacing / 2;

            int column = -1;

            if (_state == GameState.Playing)
            {
                Point playerCardPoint = new Point();

                int center = _tableCenter; // tableTLC.X + (CardCanvas.DefaultWidth / 2);

                playerCardPoint.X = center - ((((_data.PlayerHand.Cards.Count - 1) * CardSpacing) + CardCanvas.DefaultWidth) / 2);
                playerCardPoint.Y = PLAYER_ROW;

                // special case if on last card
                if ((mouseX > (CardSpacing * hand.Length) + playerCardPoint.X) && (mouseX < (CardSpacing * (hand.Length - 1) + playerCardPoint.X) + CardCanvas.DefaultWidth))
                    column = hand.Length - 1;
                else if ((mouseX >= playerCardPoint.X) && (mouseX <= (CardSpacing * hand.Length) + playerCardPoint.X))
                    column = ((mouseX - playerCardPoint.X) / CardSpacing);

                if (column >= _data.PlayerHand.Cards.Count)
                {
                    column = -1;
                }

                if (column != -1 && _data.PlayerHand.Cards.Count > 0)
                {
                    if (_data.PlayerHand.Cards[column].Selected)
                    {
                        if ((mouseY < playerCardPoint.Y - SELECTED_OFFSET) || (mouseY > playerCardPoint.Y + CardCanvas.DefaultHeight - SELECTED_OFFSET))
                        {
                            column = -1;
                        }
                    }
                    else
                    {
                        if ((mouseY < playerCardPoint.Y) || (mouseY > playerCardPoint.Y + CardCanvas.DefaultHeight - SELECTED_OFFSET))
                        {
                            column = -1;
                        }
                    }
                }
            }

            return column;
        }
 /// <summary>
 /// Shuffles the specified exclusion list.
 /// </summary>
 /// <param name="exclusionList">The exclusion list.</param>
 public void Shuffle(Card[] exclusionList)
 {
     DiscardPile.Clear();
     Table.Clear();
     Cards.Shuffle(exclusionList);
     currentDrawCard = exclusionList.Length;
 }
 private void ClearSelectedCard()
 {
     if (_lastSelectedCard != null)
     {
         _lastSelectedCard.Selected = false;
         _lastSelectedCard = null;
     }
 }
        private bool DrawCard(int player, out Card card)
        {
            bool pass = false;

            card = null;
            if (player == 0)
            {
                card = _data.DeckManager.DrawCard();
                if (card != null)
                {
                    _data.PlayerHand.Cards.Add(card);
                }
            }
            else
            {
                card = _data.DeckManager.DrawCard();
                if (card != null)
                {
                    _data.OpponentsHands[player - 1].Cards.Add(card);
                }
            }

            if (card == null)
            {
                //ReShuffle();

                //if (_data.DeckManager.IsEmpty)
                //{
                //    pass = true;
                //}
                //else
                //{
                //    DrawCard(player);
                //}

                pass = true;
            }

            return pass;
        }
        private bool CheckValidCard(Card cardToPlay)
        {
            bool validPlay = false;

            Card topCard = _data.DeckManager.Table[_data.DeckManager.Table.Count - 1];

            // if there is only one top card, then we match normal
            if (_data.DeckManager.Table.Count == 1)
            {
                // if an eight, make sure we don't have any other suits
                if (cardToPlay.Rank == CardRank.Eight)
                {
                    var suitCount = _data.PlayerHand.Cards.Count(c => c.Suit == topCard.Suit && c.Rank != CardRank.Eight);

                    // if there are no other suits but the eight, then we have a valid play
                    // otherwise, we should play one of the other suits
                    if (suitCount == 0)
                    {
                        validPlay = true;
                    }
                }
                else
                {
                    // otherwise see if it matches suit and rank
                    if (cardToPlay.Suit == topCard.Suit || cardToPlay.Rank == topCard.Rank)
                    {
                        validPlay = true;
                    }
                }
            }
            // if top card is an eight, rules are different, can only match rank or _suitOverride suit
            else if (topCard.Rank == CardRank.Eight)
            {
                if (cardToPlay.Rank == CardRank.Eight || cardToPlay.Suit == _suitOverride)
                {
                    validPlay = true;
                }
            }
            else if (topCard.Rank == CardRank.Two && !_playerHasDrawn)
            {
                if (cardToPlay.Rank == CardRank.Two)
                {
                    validPlay = true;
                }
            }
            else
            {
                if (cardToPlay.Rank == CardRank.Eight)
                {
                    var suitCount = _data.PlayerHand.Cards.Count(c => c.Suit == topCard.Suit && c.Rank != CardRank.Eight);

                    // if there are no other suits but the eight, then we have a valid play
                    // otherwise, we should play one of the other suits
                    if (suitCount == 0)
                    {
                        validPlay = true;
                    }
                }
                else
                {
                    if (_suitOverride == CardSuit.None)
                    {
                        // normal check
                        if (cardToPlay.Suit == topCard.Suit || cardToPlay.Rank == topCard.Rank)
                        {
                            validPlay = true;
                        }
                    }
                    else
                    {
                        if (cardToPlay.Suit == _suitOverride)
                        {
                            validPlay = true;
                        }
                    }
                }
            }
            return validPlay;
        }
        private void CheckMouseOver()
        {
            Point deckTLC = new Point(258, 225);
            deckTLC.X = _tableCenter - CardCanvas.DefaultWidth - CardSpacing / 2;

            Point tableTLC = new Point(339, 225);
            tableTLC.X = _tableCenter + CardSpacing / 2;

            Card[] hand = _data.PlayerHand.Cards.ToArray();
            int column = GetCardColumn(hand, _lastMouseX, _lastMouseY);

            if (column >= 0 && column < hand.Length)
            {
                if (_lastSelectedCard != null)
                {
                    _lastSelectedCard.Selected = false;
                }
                _lastSelectedCard = null;

                _lastSelectedCard = _data.PlayerHand.Cards[column];
                _lastSelectedCard.Selected = true;
            }
            else
            {
                if (_lastSelectedCard != null)
                {
                    _lastSelectedCard.Selected = false;
                }
                _lastSelectedCard = null;

            }

            // check for deck hit
            if (_lastMouseX >= deckTLC.X && _lastMouseX <= deckTLC.X + CardCanvas.DefaultWidth && _lastMouseY >= deckTLC.Y && _lastMouseY <= deckTLC.Y + CardCanvas.DefaultHeight)
            {
                // if so, make deck selected
                _deckSelected = true;
            }
            else
            {
                _deckSelected = false;
            }

            Invalidate();
        }
        private void ReShuffle()
        {
            // make exlusion list
            int exlusionLength = _data.PlayerHand.Cards.Count;

            for (int i = 0; i < _numOpponents; i++)
            {
                exlusionLength += _data.OpponentsHands[i].Cards.Count;
            }

            Card topCard = null;
            if (_data.DeckManager.Table.Count > 0)
            {
                topCard = _data.DeckManager.Table[_data.DeckManager.Table.Count - 1];
                exlusionLength += 1;
            }

            if (exlusionLength > 0)
            {

                Card[] exlusionList = new Card[exlusionLength];
                int copyIndex = 0;

                Array.Copy(_data.PlayerHand.Cards.ToArray(), exlusionList, _data.PlayerHand.Cards.Count);

                copyIndex += _data.PlayerHand.Cards.Count;
                for (int i = 0; i < _numOpponents; i++)
                {
                    Array.Copy(_data.OpponentsHands[i].Cards.ToArray(), 0, exlusionList, copyIndex, _data.OpponentsHands[i].Cards.Count);
                    copyIndex += _data.OpponentsHands[i].Cards.Count;
                }

                if (topCard != null)
                {
                    Card[] topCardArray = new Card[1] { topCard };

                    Array.Copy(topCardArray, 0, exlusionList, copyIndex, 1);
                }

                _data.DeckManager.Shuffle(exlusionList);

            }
            else
            {
                _data.DeckManager.Shuffle();
            }

            if (topCard != null)
            {
                _data.DeckManager.Table.Add(topCard);
            }
        }
        private void PlayCard(Card cardToPlay, CrazyEightsHand hand)
        {
            // put card onto table
            _data.DeckManager.Table.Add(cardToPlay);

            // remove from player hand
            //_data.OpponentsHands[_currentPlayer - 1].Cards.Remove(cardToPlay);
            hand.Cards.Remove(cardToPlay);

            if (_undoPointer < _lastCardsPlayed.Count - 1)
            {
                // prune list past _redoPointer
                _lastCardsPlayed.RemoveRange(_undoPointer + 1, _lastCardsPlayed.Count - (_undoPointer + 1));
            }

            _lastCardsPlayed.Add(cardToPlay);
            _undoPointer = _lastCardsPlayed.Count - 1;

            if (cardToPlay.Rank == CardRank.Ace)
            {
                if (_direction == Hand.PlayDirection.Forward)
                {
                    _direction = Hand.PlayDirection.Reverse;
                }
                else
                {
                    _direction = Hand.PlayDirection.Forward;
                }
            }
            else if (cardToPlay.Rank == CardRank.Two && !_data.DeckManager.IsEmpty)
            {
                _playerHasDrawn = false;

                // increment the two's count
                _dueceCount++;

                // draw two
                int nextPlayer = NextPlayer();

                // get hand of next player
                CrazyEightsHand nextPlayerHand = null;
                if (nextPlayer == 0)
                {
                    nextPlayerHand = _data.PlayerHand;
                }
                else
                {
                    nextPlayerHand = _data.OpponentsHands[nextPlayer - 1];
                }

                if (nextPlayerHand.Cards.Find(c => c.Rank == CardRank.Two) == null)
                {
                    _lastDrawnCards.Clear();

                    for (int i = 0; i < _dueceCount; i++)
                    {
                        Card drawCard;

                        DrawCard(nextPlayer, out drawCard);

                        _lastDrawnCards.Add(drawCard);

                        DrawCard(nextPlayer, out drawCard);

                        _lastDrawnCards.Add(drawCard);
                    }

                    _playerHasDrawn = true;

                    // if next is player and player doesn't have any two's
                    if (nextPlayer == 0)
                    {
                        ShowDrawTwoDialog();
                    }

                    _dueceCount = 0;
                }
            }
            else if (cardToPlay.Rank == CardRank.Queen)
            {
                // trick here, increment player so when
                // we increment next player, it will skip
                _skipFlag = true;
            }

            //_redoPointer = _lastCardsPlayed.Count;
        }
        private void PaintHand(Card[] hand, Point TLC, bool showCard, int maxWidth)
        {
            int currentX = TLC.X;
            int currentY = TLC.Y;
            for (int i = 0; i < hand.Length; i++)
            {
                if (maxWidth >= 0 && Math.Abs((currentX + CardCanvas.DefaultWidth)- TLC.X) > maxWidth)
                {
                    currentY += CardSpacing;
                    currentX = TLC.X;
                }

                Point cardPoint = new Point(currentX, currentY);
                if (showCard)
                {
                    if (hand[i].Selected)
                    {
                        cardPoint.Y -= SELECTED_OFFSET;
                    }
                    _cardCanvas.DrawCard(cardPoint, hand[i].CardIndex);
                }
                else
                {
                    _cardCanvas.DrawCardBack(cardPoint, GetSelectedBack());
                }

                currentX += CardSpacing;
            }
        }