/* @brief   Moves a card from a tableau to a foundation.
         * @param   SrcTableauIdx - Index of the source tableau.
         * @param   DestFoundationIdx - Foundation to put the card into.
         * @return  Boolean indicating if the move was valid or invalid. */
        public bool MoveToFoundation(int SrcTableauIdx, int DestFoundationIdx)
        {
            bool    validMove  = false;
            Tableau SrcTableau = tableaus[SrcTableauIdx];
            Card    srcCard    = SrcTableau.Cards[SrcTableau.Cards.Count - 1];

            /* If this foundation is empty, check if the source card is an ace.*/
            if (foundations[DestFoundationIdx].Count == 0 && srcCard.Value == 1)
            {
                foundations[DestFoundationIdx].Add(srcCard);
                validMove = true;
            }
            /* If the foundation is not empty, check if same suit and value is one higher*/
            else
            {
                Card destCard = foundations[DestFoundationIdx][0];
                if (CheckSuit(srcCard, destCard, false) &&
                    CheckCardValue(srcCard, destCard, false))
                {
                    AddToFoundation(srcCard, DestFoundationIdx);
                    validMove = true;
                }
            }

            if (validMove)
            {
                if (SrcTableau.RemoveCards(1))
                {
                    points += 5;
                }
                points += 10;
            }
            return(validMove);
        }
        /* @brief   Moves cards from one tableau to another.
         * @param   SrcTableauIdx - Index of the source tableau.
         * @param   Depth - How many cards to move in the source tableau.
         * @param   DestTableauIdx - Index of the destination tableau.
         * @return  Boolean indicating if the move was valid or invalid. */
        public bool MoveCards(int SrcTableauIdx, int Depth, int DestTableauIdx)
        {
            bool    validMove   = false;
            Tableau SrcTableau  = tableaus[SrcTableauIdx];
            Tableau DestTableau = tableaus[DestTableauIdx];
            Card    srcCard     = SrcTableau.Cards[(SrcTableau.Cards.Count - 1) - (Depth - 1)];

            /* Check if we can even move from the source */
            if ((SrcTableau.HiddenDepth + Depth) <= (SrcTableau.Cards.Count))
            {
                /* Check if destination tableau is empty, only a king can go in there */
                if (DestTableau.Cards.Count == 0 &&
                    srcCard.Value == 13)
                {
                    MoveBetweenTableaus(SrcTableau, Depth, DestTableau);
                    validMove = true;
                }
                /* Check if different suit color and the value is 1 lower. */
                else
                {
                    Card destCard = DestTableau.Cards[DestTableau.Cards.Count - 1];
                    if (CheckSuit(srcCard, destCard, true) &&
                        CheckCardValue(srcCard, destCard, true))
                    {
                        MoveBetweenTableaus(SrcTableau, Depth, DestTableau);
                        validMove = true;
                    }
                }
            }

            return(validMove);
        }
        /* @brief Performs the move of one or more cards from one tableau to another.
         * @param SrcTableau - Tableau where the cards are moving from.
         * @param Depth - How many cards are being moved.
         * @param DestTableau - Tableau where the cards are moving to.
         * */
        private void MoveBetweenTableaus(Tableau SrcTableau, int Depth, Tableau DestTableau)
        {
            List <Card> cardsToMove = new List <Card>();

            cardsToMove = SrcTableau.GetCards(Depth);

            foreach (Card card in cardsToMove)
            {
                DestTableau.InsertCard(card);
            }

            if (SrcTableau.RemoveCards(Depth))
            {
                points += 5;
            }
        }
        /* @brief   Starts a new game. */
        private void NewGame()
        {
            int cardCount = 0;

            for (int tableau = 0; tableau < 7; tableau++)
            {
                tableaus[tableau] = new Tableau(tableau);
                for (int tableauCard = 0; tableauCard < tableau + 1; tableauCard++)
                {
                    tableaus[tableau].InsertCard(deck.Deck[cardCount++]);
                }
            }

            for (; cardCount < deck.Deck.Length; cardCount++)
            {
                stock.Add(deck.Deck[cardCount]);
            }
        }
        /* @brief   Moves all stacked cards from one tableau to another.
         * @param   SrcTableauIdx - Index of the source tableau.
         * @param   DestTableauIdx - Index of the destination tableau.
         * @return  Boolean indicating if the move was valid or invalid. */
        public bool MoveWholeTableau(int SrcTableauIdx, int DestTableauIdx)
        {
            bool    validMove   = false;
            Tableau SrcTableau  = tableaus[SrcTableauIdx];
            Tableau DestTableau = tableaus[DestTableauIdx];
            Card    srcCard;
            int     depth = 0;

            if (SrcTableau.HiddenDepth == -1)
            {
                srcCard = SrcTableau.Cards[0];
                depth   = SrcTableau.Cards.Count;
            }
            else
            {
                srcCard = SrcTableau.Cards[SrcTableau.HiddenDepth];
                depth   = SrcTableau.Cards.Count - SrcTableau.HiddenDepth;
            }


            /* Check if destination tableau is empty, only a king can go in there */
            if (DestTableau.Cards.Count == 0 &&
                srcCard.Value == 13)
            {
                MoveBetweenTableaus(SrcTableau, depth, DestTableau);
                validMove = true;
            }
            /* Check if different suit color and the value is 1 lower. */
            else
            {
                Card destCard = DestTableau.Cards[DestTableau.Cards.Count - 1];
                if (CheckSuit(srcCard, destCard, true) &&
                    CheckCardValue(srcCard, destCard, true))
                {
                    MoveBetweenTableaus(SrcTableau, depth, DestTableau);
                    validMove = true;
                }
            }

            return(validMove);
        }
        /* @brief Moves a card from the waste pile to a tableau
         * @param DestTableauIdx - Index to destination tableau.
         * @return  Boolean indicating if the move was valid or invalid. */
        public bool MoveFromWaste(int DestTableauIdx)
        {
            bool    validMove   = false;
            Tableau DestTableau = tableaus[DestTableauIdx];
            Card    srcCard     = waste[0];

            /* Check if we can even move from the source */
            if (waste.Count > 0 && wasteVisible > 0)
            {
                if (DestTableau.Cards.Count == 0 &&
                    srcCard.Value == 13)
                {
                    validMove = true;
                }
                /* Check if different suit color and the value is 1 lower. */
                else
                {
                    Card destCard = DestTableau.Cards[DestTableau.Cards.Count - 1];
                    if (CheckSuit(srcCard, destCard, true) &&
                        CheckCardValue(srcCard, destCard, true))
                    {
                        validMove = true;
                    }
                }
            }

            if (validMove)
            {
                points += 5;
                DestTableau.InsertCard(waste[0]);
                waste.RemoveAt(0);

                if (wasteVisible > 0)
                {
                    wasteVisible--;
                }
            }
            return(validMove);
        }
        /* @brief Moves a card from the foundation to a tableau
         * @param SrcFoundationIdx - Index of source foundation to move a card from.
         * @param DestTableauIdx - Index to destination tableau.
         * @return  Boolean indicating if the move was valid or invalid. */
        public bool MoveFromFoundation(int SrcFoundationIdx, int DestTableauIdx)
        {
            bool    validMove   = false;
            Tableau DestTableau = tableaus[DestTableauIdx];

            /* Check if we can even move from the source */
            if (foundations[SrcFoundationIdx].Count > 0)
            {
                Card srcCard = foundations[SrcFoundationIdx][0];

                /* Check if destination tableau is empty, only a king can go in there */
                if (DestTableau.Cards.Count == 0 &&
                    srcCard.Value == 13)
                {
                    DestTableau.InsertCard(srcCard);
                    validMove = true;
                }
                /* Check if different suit color and the value is 1 lower. */
                else
                {
                    Card destCard = DestTableau.Cards[DestTableau.Cards.Count - 1];
                    if (CheckSuit(srcCard, destCard, true) &&
                        CheckCardValue(srcCard, destCard, true))
                    {
                        DestTableau.InsertCard(srcCard);
                        validMove = true;
                    }
                }
            }

            if (validMove)
            {
                points -= 15;
                foundations[SrcFoundationIdx].RemoveAt(0);
            }
            return(validMove);
        }