void DrawUnitAnimations(GameTime gameTime)
        {
            for (int i = unitAnimations.Count - 1; i >= 0; i--)
            {
                UnitCountAnimation unitAnim = unitAnimations[i];

                unitAnim.Draw(gameTime);
            }
        }
        protected override void Update(GameTime gameTime)
        {
            blah += 5 * (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (levelIntroIsFading)
            {
                levelIntroAlpha -= levelIntroFadeRate * (float)gameTime.ElapsedGameTime.TotalSeconds;

                if (levelIntroAlpha <= 0)
                {
                    levelIntroIsFading = false;
                }
            }

            MouseState    ms = Mouse.GetState();
            KeyboardState ks = Keyboard.GetState();

            if (gameEnded)
            {
                if (ksLast.IsKeyDown(Keys.Enter) && ks.IsKeyUp(Keys.Enter))
                {
                    if (gameWon)
                    {
                        level++;
                    }

                    Reset();

                    switch (level)
                    {
                    case 0: FillPiecesLevelZero(); break;

                    default:
                    case 1: {
                        level = 1;

                        FillPiecesLevelOne();
                    } break;

                    case 2: FillPiecesLevelTwo(); break;

                    case 3: FillPiecesLevelThree(); break;

                    case 4: FillPiecesLevelFour(); break;

                    case 5: FillPiecesLevelFive(); break;
                    }
                }
            }

            grid.Projection = projection;
            grid.View       = view;

            grid.Update(gameTime);

            for (int i = unitAnimations.Count - 1; i >= 0; i--)
            {
                UnitCountAnimation unitAnim = unitAnimations[i];

                unitAnim.Update(gameTime);

                if (unitAnim.Ended)
                {
                    unitAnimations.Remove(unitAnim);
                }
            }

            hoveredPiece = null;

            if (grid.IsCursorWithinGridBounds)
            {
                var resultPieces = pieces.Where(
                    p => p.Column == grid.CursorHoveringOnColumn &&
                    p.Row == grid.CursorHoveringOnRow
                    );

                if (resultPieces.Count() > 0)
                {
                    hoveredPiece = resultPieces.ElementAt(0);
                }

                pieceScreenCoordinate = GetScreenSpaceCoordinate(grid.CursorHoveringOnRow, grid.CursorHoveringOnColumn);
            }

            if (gameStarted)
            {
                Piece previousPiece = selectedPiece;

                selectedPiece = playerPieces[playerPieceCurrentIndex];

                if (selectedPiece != previousPiece)
                {
                    FindMovableTiles(selectedPiece);

                    grid.ShowMovableTiles = true;
                }

                if (ksLast.IsKeyDown(Keys.Enter) && ks.IsKeyUp(Keys.Enter))
                {
                    if (!isPlacingPiece)
                    {
                        Debug.WriteLine("Skipping turn..");

                        Turn();
                    }
                }
                else if (selectedPiece is BarracksPiece)
                {
                    BarracksPiece barracks = selectedPiece as BarracksPiece;

                    if (ksLast.IsKeyDown(Keys.D1) && ks.IsKeyUp(Keys.D1))
                    {
                        // only toggle if the piece being placed is the same as the production of this action
                        isPlacingPiece = isPlacingPiece && placingPiece is AttackPiece ? !isPlacingPiece : true;

                        placingPiece = !isPlacingPiece ?
                                       null :
                                       new AttackPiece()
                        {
                            Icon  = iconSword,
                            Units = barracks.ProductionUnits
                        };
                    }
                    else if (ksLast.IsKeyDown(Keys.D2) && ks.IsKeyUp(Keys.D2))
                    {
                        isPlacingPiece = isPlacingPiece && placingPiece is RangedPiece ? !isPlacingPiece : true;

                        placingPiece = !isPlacingPiece ?
                                       null :
                                       new RangedPiece()
                        {
                            Icon  = iconArrow,
                            Units = barracks.ProductionUnits
                        };
                    }
                    else if (ksLast.IsKeyDown(Keys.D3) && ks.IsKeyUp(Keys.D3))
                    {
                        isPlacingPiece = isPlacingPiece && placingPiece is DefendPiece ? !isPlacingPiece : true;

                        placingPiece = !isPlacingPiece ?
                                       null :
                                       new DefendPiece()
                        {
                            Icon  = iconShield,
                            Units = barracks.ProductionUnits
                        };
                    }

                    grid.ShowMovableTiles = !isPlacingPiece;
                }
            }
            else
            {
                if (!gameEnded)
                {
                    if (ksLast.IsKeyDown(Keys.Space) && ks.IsKeyUp(Keys.Space))
                    {
                        Debug.WriteLine("Game started..");

                        grid.ShowMovableTiles = true;

                        gameStarted = true;

                        levelIntroIsFading = true;
                    }
                }
            }

            if (msLast.LeftButton == ButtonState.Pressed && ms.LeftButton == ButtonState.Released)
            {
                if (grid.IsCursorWithinGridBounds)
                {
                    uint targetRow    = grid.CursorHoveringOnRow;
                    uint targetColumn = grid.CursorHoveringOnColumn;

                    if (selectedPiece != null && !(selectedPiece is EnemyPiece))
                    {
                        bool rowInRange    = true;
                        bool columnInRange = true;

                        if (gameStarted)
                        {
                            int tileDistance = selectedPiece is AttackPiece ? (hoveredPiece != null && hoveredPiece is EnemyPiece ? 1 : 2) : 1;

                            if (targetColumn > selectedPiece.Column + tileDistance ||
                                targetColumn < selectedPiece.Column - tileDistance)
                            {
                                columnInRange = false;
                            }

                            if (targetRow > selectedPiece.Row + tileDistance ||
                                targetRow < selectedPiece.Row - tileDistance)
                            {
                                rowInRange = false;
                            }
                        }
                        else
                        {
                            if (targetColumn < 9)
                            {
                                columnInRange = false;
                            }
                        }

                        bool didAct = false;

                        if (hoveredPiece == null)
                        {
                            if (isPlacingPiece)
                            {
                                placingPiece.Row    = targetRow;
                                placingPiece.Column = targetColumn;

                                pieces.Add(placingPiece);
                                playerPieces.Add(placingPiece);

                                placingPiece   = null;
                                isPlacingPiece = false;

                                didAct = true;
                            }
                            else if (rowInRange && columnInRange)
                            {
                                selectedPiece.Row    = targetRow;
                                selectedPiece.Column = targetColumn;

                                didAct = true;
                            }
                        }
                        else
                        {
                            if (gameStarted && !isPlacingPiece)
                            {
                                Piece attacker = selectedPiece;
                                Piece defender = hoveredPiece;

                                if (defender is EnemyPiece)
                                {
                                    if (!(attacker is DefendPiece) && !(attacker is BarracksPiece))
                                    {
                                        bool attackIsAllowed =
                                            (attacker is AttackPiece && (rowInRange && columnInRange)) ||
                                            (attacker is RangedPiece && !(rowInRange && columnInRange));

                                        if (attackIsAllowed)
                                        {
                                            int defenderShouldLoseUnits = 0;

                                            Battle(attacker, defender, out defenderShouldLoseUnits);

                                            unitAnimations.Add(new UnitCountAnimation(-defenderShouldLoseUnits, GetScreenSpaceCoordinate(defender.Row, defender.Column))
                                            {
                                                Font   = uiUnitFont,
                                                Sprite = sprite
                                            });

                                            if (defenderShouldLoseUnits == defender.Units)
                                            {
                                                piecesToRemove.Add(defender);
                                            }
                                            else
                                            {
                                                defender.Units -= defenderShouldLoseUnits;
                                            }

                                            didAct = true;
                                        }
                                    }
                                }
                            }
                            else if (gameStarted && isPlacingPiece)
                            {
                                if (!(hoveredPiece is EnemyPiece))
                                {
                                    if (hoveredPiece.GetType().Equals(placingPiece.GetType()))
                                    {
                                        hoveredPiece.Units += placingPiece.Units;

                                        unitAnimations.Add(new UnitCountAnimation(placingPiece.Units, GetScreenSpaceCoordinate(hoveredPiece.Row, hoveredPiece.Column))
                                        {
                                            Font   = uiUnitFont,
                                            Sprite = sprite
                                        });

                                        isPlacingPiece = false;
                                        placingPiece   = null;

                                        didAct = true;
                                    }
                                }
                            }
                        }

                        if (gameStarted && didAct)
                        {
                            Turn();
                        }
                    }

                    if (!gameStarted && !gameEnded && hoveredPiece != null)
                    {
                        Piece previousPiece = selectedPiece;
                        selectedPiece = hoveredPiece;

                        if (selectedPiece != previousPiece)
                        {
                            FindMovableTiles(selectedPiece);
                        }
                    }
                }
            }

            msLast = ms;
            ksLast = ks;

            base.Update(gameTime);
        }