/// <summary>
        /// Opens a chess board for a certain game at a current position.
        /// </summary>
        private StandardChessBoard OpenChessBoard(PgnEditor ownerPgnEditor, Chess.Game game, string white, string black, string whiteElo, string blackElo)
        {
            var newChessBoard = new StandardChessBoard
            {
                Game        = game,
                PieceImages = PieceImages.ImageArray
            };

            newChessBoard.PlayingBoard.ForegroundImageRelativeSize = 0.9f;

            newChessBoard.PlayingBoard.BindActions(new UIActionBindings
            {
                { StandardChessBoard.GotoStart, newChessBoard.TryGotoStart },
                { StandardChessBoard.GotoFirstMove, newChessBoard.TryGotoFirstMove },
                { StandardChessBoard.FastNavigateBackward, newChessBoard.TryFastNavigateBackward },
                { StandardChessBoard.GotoPreviousMove, newChessBoard.TryGotoPreviousMove },
                { StandardChessBoard.GotoNextMove, newChessBoard.TryGotoNextMove },
                { StandardChessBoard.FastNavigateForward, newChessBoard.TryFastNavigateForward },
                { StandardChessBoard.GotoLastMove, newChessBoard.TryGotoLastMove },
                { StandardChessBoard.GotoEnd, newChessBoard.TryGotoEnd },

                { StandardChessBoard.GotoPreviousVariation, newChessBoard.TryGotoPreviousVariation },
                { StandardChessBoard.GotoNextVariation, newChessBoard.TryGotoNextVariation },

                { StandardChessBoard.PromoteActiveVariation, newChessBoard.TryPromoteActiveVariation },
                { StandardChessBoard.DemoteActiveVariation, newChessBoard.TryDemoteActiveVariation },
                { StandardChessBoard.BreakActiveVariation, newChessBoard.TryBreakActiveVariation },
                { StandardChessBoard.DeleteActiveVariation, newChessBoard.TryDeleteActiveVariation },

                { StandardChessBoard.FlipBoard, newChessBoard.TryFlipBoard },
                { StandardChessBoard.TakeScreenshot, newChessBoard.TryTakeScreenshot },

                { SharedUIAction.ZoomIn, newChessBoard.TryZoomIn },
                { SharedUIAction.ZoomOut, newChessBoard.TryZoomOut },
            });

            UIMenu.AddTo(newChessBoard.PlayingBoard);

            if (string.IsNullOrWhiteSpace(white))
            {
                white = "?";
            }
            if (string.IsNullOrWhiteSpace(black))
            {
                black = "?";
            }
            if (!string.IsNullOrWhiteSpace(whiteElo))
            {
                white = $"{white} ({whiteElo})";
            }
            if (!string.IsNullOrWhiteSpace(blackElo))
            {
                black = $"{black} ({blackElo})";
            }

            newChessBoard.DockProperties.CaptionText   = $"{white} - {black}";
            newChessBoard.DockProperties.CaptionHeight = 24;
            newChessBoard.DockProperties.Icon          = Session.Current.ApplicationIcon;

            var newChessBoardForm = new MenuCaptionBarForm <StandardChessBoard>(newChessBoard)
            {
                Owner       = ownerPgnEditor.FindForm(),
                MaximizeBox = false,
                ClientSize  = new Size(400, 400),
            };

            StandardChessBoard.ConstrainClientSize(newChessBoardForm);

            return(newChessBoard);
        }
        public UIActionState TryOpenGame(PgnEditor pgnEditor, bool perform)
        {
            PgnGameSyntax gameSyntax = pgnEditor.GameAtOrBeforePosition(pgnEditor.SelectionStart);

            if (gameSyntax == null)
            {
                return(UIActionVisibility.Disabled);
            }

            if (perform)
            {
                StandardChessBoard chessBoard = OpenGames.GetOrAdd(gameSyntax, key =>
                {
                    const string WhiteTagName    = "White";
                    const string BlackTagName    = "Black";
                    const string WhiteEloTagName = "WhiteElo";
                    const string BlackEloTagName = "BlackElo";

                    // Look in the game's tags for these 4 values.
                    string white    = null;
                    string black    = null;
                    string whiteElo = null;
                    string blackElo = null;

                    foreach (PgnTagPairSyntax tagPairSyntax in gameSyntax.TagSection.TagPairNodes)
                    {
                        string tagName  = null;
                        string tagValue = null;

                        foreach (PgnTagElementSyntax tagElementSyntax in tagPairSyntax.TagElementNodes.Select(x => x.ContentNode))
                        {
                            if (tagElementSyntax is PgnTagNameSyntax tagNameSyntax)
                            {
                                tagName = pgnEditor.GetTextRange(tagNameSyntax.AbsoluteStart, tagNameSyntax.Length);
                            }
                            else if (tagElementSyntax is PgnTagValueSyntax tagValueSyntax)
                            {
                                tagValue = tagValueSyntax.Value;
                            }
                        }

                        if (tagName != null && tagValue != null)
                        {
                            if (tagName.Equals(WhiteTagName, StringComparison.OrdinalIgnoreCase))
                            {
                                white = tagValue;
                            }
                            else if (tagName.Equals(BlackTagName, StringComparison.OrdinalIgnoreCase))
                            {
                                black = tagValue;
                            }
                            else if (tagName.Equals(WhiteEloTagName, StringComparison.OrdinalIgnoreCase))
                            {
                                whiteElo = tagValue;
                            }
                            else if (tagName.Equals(BlackEloTagName, StringComparison.OrdinalIgnoreCase))
                            {
                                blackElo = tagValue;
                            }
                        }
                    }

                    StandardChessBoard newChessBoard = OpenChessBoard(pgnEditor, pgnEditor.CreateGame(gameSyntax), white, black, whiteElo, blackElo);
                    newChessBoard.Disposed          += (_, __) => OpenGames.Remove(gameSyntax);
                    return(newChessBoard);
                });

                chessBoard.EnsureActivated();
            }

            return(UIActionVisibility.Enabled);
        }