private void courtRoundsPanel_MouseClick(object sender, MouseEventArgs e)
        {
            if (gameRectangles == null)
            {
                return;
            }

            GamePosition ClickedGamePosition  = null;
            RectangleF   ClickedGameRectangle = new RectangleF();

            PointF clickPoint = new PointF(e.Location.X, e.Location.Y);

            for (int courtRoundNum = 0; courtRoundNum < gameRectangles.GetLength(0); courtRoundNum++)
            {
                for (int courtNum = 0; courtNum < gameRectangles.GetLength(1); courtNum++)
                {
                    RectangleF rect = gameRectangles[courtRoundNum, courtNum];
                    if (rect.Contains(clickPoint))
                    {
                        ClickedGameRectangle = rect;
                        ClickedGamePosition  = GamePosition.GetGamePosition(courtRoundNum + 1, courtNum + 1);
                        break;
                    }
                }
            }

            //We figured out what game was clicked on
            if (ClickedGamePosition != null)
            {
                if (assignScoreKeeperCmb.SelectedItem != null)
                {
                    if (assignScoreKeeperCmb.SelectedItem is ScoreKeeper)
                    {
                        ScoreKeeper currentScoreKeeper = (ScoreKeeper)assignScoreKeeperCmb.SelectedItem;
                        Controller.ScoreKeepersAssignment[ClickedGamePosition] = currentScoreKeeper;
                        Controller.TriggerScoreKeepersAssignmentChanged();
                    }
                    else
                    {
                        Controller.ScoreKeepersAssignment.Remove(ClickedGamePosition);
                        Controller.TriggerScoreKeepersAssignmentChanged();
                    }
                    //Redraw the court round
                    courtRoundsPaintable.Invalidate(
                        new Rectangle(
                            0,
                            (int)ClickedGameRectangle.Y,
                            courtRoundsPaintable.Width,
                            (int)ClickedGameRectangle.Height));
                }
            }
        }
        private void courtRoundsPanel_MouseMove(object sender, MouseEventArgs e)
        {
            if (gameRectangles == null)
            {
                return;
            }

            GamePosition HoveredGamePosition  = null;
            RectangleF   HoveredGameRectangle = new RectangleF();

            PointF mouseLocation = new PointF(e.Location.X, e.Location.Y);

            for (int courtRoundNum = 0; courtRoundNum < gameRectangles.GetLength(0); courtRoundNum++)
            {
                for (int courtNum = 0; courtNum < gameRectangles.GetLength(1); courtNum++)
                {
                    RectangleF rect = gameRectangles[courtRoundNum, courtNum];
                    if (rect.Contains(mouseLocation))
                    {
                        HoveredGameRectangle = rect;
                        HoveredGamePosition  = GamePosition.GetGamePosition(courtRoundNum + 1, courtNum + 1);
                        break;
                    }
                }
            }

            if (currentHoveredGamePosition != null && currentHoveredGamePosition != HoveredGamePosition)
            {
                courtRoundsPaintable.Invalidate(RectangleFToRectangle(currentHoveredGameRectangle));
            }

            //We figured out what game the mouse is over
            if (HoveredGamePosition != null)
            {
                if (currentHoveredGamePosition != HoveredGamePosition)
                {
                    currentHoveredGamePosition  = HoveredGamePosition;
                    currentHoveredGameRectangle = HoveredGameRectangle;
                    courtRoundsPaintable.Invalidate(RectangleFToRectangle(HoveredGameRectangle));
                    courtRoundsPaintable.Cursor = Cursors.Hand;
                }
            }
            else
            {
                currentHoveredGamePosition  = null;
                currentHoveredGameRectangle = new RectangleF();
                courtRoundsPaintable.Cursor = Cursors.Default;
            }
        }
        private void courtRoundsPanel_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.Clip = new Region(e.ClipRectangle);
            e.Graphics.Clear(courtRoundsPaintable.BackColor);
            if (Tournament != null)
            {
                int drawTop  = 0;
                int drawLeft = 0;

                gameRectangles = new RectangleF[NumRounds, Tournament.NumCourts];

                //Court rounds
                StringFormat roundNumberStringFormat = new StringFormat();
                roundNumberStringFormat.Alignment     = StringAlignment.Center;
                roundNumberStringFormat.LineAlignment = StringAlignment.Center;

                for (int courtRoundNum = 0; courtRoundNum < NumRounds; courtRoundNum++)
                {
                    drawLeft = 0;

                    Dictionary <ScoreKeeper, int> timesScoreKeeperInCourtRound = new Dictionary <ScoreKeeper, int>();
                    foreach (KeyValuePair <GamePosition, ScoreKeeper> pair in Controller.GetScoreKeepersForCourtRound(courtRoundNum + 1))
                    {
                        if (!timesScoreKeeperInCourtRound.ContainsKey(pair.Value))
                        {
                            timesScoreKeeperInCourtRound.Add(pair.Value, 1);
                        }
                        else
                        {
                            timesScoreKeeperInCourtRound[pair.Value]++;
                        }
                    }

                    //Round number
                    RectangleF roundNumberRect =
                        new RectangleF(
                            drawLeft,
                            drawTop,
                            roundColumnWidth,
                            courtRoundHeight);
                    RectangleF roundNumberTextRect = roundNumberRect;

                    e.Graphics.DrawString((courtRoundNum + 1).ToString(), roundNumberFont, textBrush, roundNumberTextRect, roundNumberStringFormat);
                    e.Graphics.DrawLine(headerHighlightPen, new PointF(roundNumberRect.Left, roundNumberRect.Top), new PointF(roundNumberRect.Right - 1, roundNumberRect.Top));
                    e.Graphics.DrawLine(headerShadowPen, new PointF(roundNumberRect.Left, roundNumberRect.Bottom - 1), new PointF(roundNumberRect.Right - 1, roundNumberRect.Bottom - 1));
                    e.Graphics.DrawLine(headerShadowPen, new PointF(roundNumberRect.Right - 1, roundNumberRect.Top), new PointF(roundNumberRect.Right - 1, roundNumberRect.Bottom - 1));
                    drawLeft += roundColumnWidth;

                    //Games
                    for (int courtNum = 0; courtNum < Tournament.NumCourts; courtNum++)
                    {
                        GamePosition gamePosition  = GamePosition.GetGamePosition(courtRoundNum + 1, courtNum + 1);
                        RectangleF   gameRectangle =
                            new RectangleF(
                                drawLeft,
                                drawTop,
                                courtColumnWidth,
                                courtRoundHeight);
                        gameRectangles[courtRoundNum, courtNum] = gameRectangle;

                        string scoreKeeperName      = "Not Assigned";
                        Color  gameFillColor        = gameScoreKeeperNotAssignedFillColor;
                        Brush  scoreKeeperTextBrush = scoreKeeperNotAssignedTextBrush;
                        if (Controller.ScoreKeepersAssignment.ContainsKey(gamePosition))
                        {
                            ScoreKeeper scoreKeeper = Controller.ScoreKeepersAssignment[gamePosition];
                            scoreKeeperName = scoreKeeper.Name;
                            if (timesScoreKeeperInCourtRound[scoreKeeper] <= 1)
                            {
                                scoreKeeperTextBrush = textBrush;
                                gameFillColor        = gameScoreKeeperAssignedFillColor;
                            }
                            //Score keeper is assigned to more than one in the same court round
                            else
                            {
                                scoreKeeperTextBrush = scoreKeeperDuplicateTextBrush;
                                gameFillColor        = gameDuplicateScoreKeeperFillColor;
                            }
                        }

                        e.Graphics.FillRectangle(new SolidBrush(gameFillColor), gameRectangle);
                        if (gamePosition == currentHoveredGamePosition)
                        {
                            e.Graphics.FillRectangle(new SolidBrush(gameHoverOverlayColor), gameRectangle);
                        }

                        int gameWidth  = courtColumnWidth - gamePadding.Top - gamePadding.Bottom;
                        int gameHeight = courtRoundHeight - gamePadding.Left - gamePadding.Right;

                        //Draw score keeper name
                        RectangleF scoreKeeperNameRect =
                            new RectangleF(
                                gameRectangle.Left + gamePadding.Left,
                                gameRectangle.Top + gamePadding.Top,
                                gameRectangle.Width - gamePadding.Left - gamePadding.Right,
                                gameRectangle.Height - gamePadding.Top - gamePadding.Bottom);
                        StringFormat scoreKeeperStringFormat = new StringFormat();
                        scoreKeeperStringFormat.Alignment     = StringAlignment.Center;
                        scoreKeeperStringFormat.LineAlignment = StringAlignment.Center;
                        scoreKeeperStringFormat.Trimming      = StringTrimming.EllipsisCharacter;

                        e.Graphics.DrawString(scoreKeeperName, scoreKeeperNameFont, scoreKeeperTextBrush, scoreKeeperNameRect, scoreKeeperStringFormat);


                        e.Graphics.DrawLine(gamesSeparatorPen, new PointF(gameRectangle.Right - 1, gameRectangle.Top), new PointF(gameRectangle.Right - 1, gameRectangle.Bottom - 1));
                        e.Graphics.DrawLine(gamesSeparatorPen, new PointF(gameRectangle.Left, gameRectangle.Bottom - 1), new PointF(gameRectangle.Right - 1, gameRectangle.Bottom - 1));
                        drawLeft += courtColumnWidth;
                    }
                    drawTop += courtRoundHeight;
                }
            }
        }