private JigsawPuzzlePiece GetPieceByCursor()
        {
            if (EngineApp.Instance.MouseRelativeMode)
            {
                return(null);
            }

            Ray ray = RendererWorld.Instance.DefaultCamera.GetCameraToViewportRay(
                EngineApp.Instance.MousePosition);

            if (float.IsNaN(ray.Direction.X))
            {
                return(null);
            }

            JigsawPuzzlePiece piece = null;

            Map.Instance.GetObjects(ray, delegate(MapObject obj, float scale)
            {
                piece = obj as JigsawPuzzlePiece;
                if (piece != null)
                {
                    //found. stop finding
                    return(false);
                }

                //continue finding
                return(true);
            });

            return(piece);
        }
        protected override bool OnMouseUp(EMouseButtons button)
        {
            //If atop openly any window to not process
            if (Controls.Count != 1)
            {
                return(base.OnMouseUp(button));
            }

            switch (button)
            {
            case EMouseButtons.Left:
                if (tryingToMovePiece != null)
                {
                    UpdateShouldSendMovingPiecePositionToServer(true);

                    if (EntitySystemWorld.Instance.IsServer() || EntitySystemWorld.Instance.IsSingle())
                    {
                        tryingToMovePiece.ServerOrSingle_MoveFinish();
                    }
                    else
                    {
                        tryingToMovePiece.Client_MoveTryToFinish();
                    }

                    tryingToMovePiece = null;

                    return(true);
                }
                break;
            }

            return(base.OnMouseUp(button));
        }
        private void RenderPieceSelectionBorder(JigsawPuzzlePiece piece, bool selected)
        {
            Camera camera = RendererWorld.Instance.DefaultCamera;

            if (selected)
            {
                camera.DebugGeometry.Color = new ColorValue(0, 1, 0);
            }
            else
            {
                camera.DebugGeometry.Color = new ColorValue(1, 1, 0);
            }

            camera.DebugGeometry.AddBounds(piece.MapBounds);
        }
        protected override bool OnMouseDown(EMouseButtons button)
        {
            //If atop openly any window to not process
            if (Controls.Count != 1)
            {
                return(base.OnMouseDown(button));
            }

            switch (button)
            {
            case EMouseButtons.Left:
            {
                tryingToMovePiece = GetPieceByCursor();
                if (tryingToMovePiece != null)
                {
                    if (EntitySystemWorld.Instance.IsServer())
                    {
                        //server
                        GameNetworkServer server = GameNetworkServer.Instance;
                        tryingToMovePiece.Server_MoveBegin(server.UserManagementService.ServerUser);
                    }
                    else if (EntitySystemWorld.Instance.IsClientOnly())
                    {
                        //client
                        tryingToMovePiece.Client_MoveTryToBegin();
                    }
                    else
                    {
                        //single mode
                        tryingToMovePiece.Single_MoveBegin();
                    }

                    Vec2 cursorPosition;
                    GetGameAreaCursorPosition(out cursorPosition);
                    tryingToMovePieceOffset = tryingToMovePiece.Position.ToVec2() - cursorPosition;
                    return(true);
                }
            }
            break;
            }

            return(base.OnMouseDown(button));
        }
        protected override void OnRenderUI(GuiRenderer renderer)
        {
            base.OnRenderUI(renderer);

            UpdateHUD();

            //render user names for moving pieces by users
            foreach (Entity entity in Map.Instance.Children)
            {
                JigsawPuzzlePiece piece = entity as JigsawPuzzlePiece;
                if (piece != null)
                {
                    string userName = null;

                    if (EntitySystemWorld.Instance.IsServer())
                    {
                        if (piece.Server_MovingByUser != null)
                        {
                            userName = piece.Server_MovingByUser.Name;
                        }
                    }
                    if (EntitySystemWorld.Instance.IsClientOnly())
                    {
                        if (piece.Client_MovingByUser != null)
                        {
                            userName = piece.Client_MovingByUser.Name;
                        }
                    }

                    if (!string.IsNullOrEmpty(userName))
                    {
                        Vec2 screenPosition;
                        if (RendererWorld.Instance.DefaultCamera.ProjectToScreenCoordinates(
                                piece.Position, out screenPosition))
                        {
                            renderer.AddText(userName,
                                             screenPosition, HorizontalAlign.Left, VerticalAlign.Top,
                                             new ColorValue(0, 1, 0, .75f));
                        }
                    }
                }
            }

            //show list of users
            if (GameNetworkServer.Instance != null || GameNetworkClient.Instance != null)
            {
                List <string> lines = new List <string>();

                lines.Add("Players:");

                if (GameNetworkServer.Instance != null)
                {
                    UserManagementServerNetworkService userService =
                        GameNetworkServer.Instance.UserManagementService;

                    foreach (UserManagementServerNetworkService.UserInfo user in userService.Users)
                    {
                        string line = "  " + user.Name;
                        if (user == userService.ServerUser)
                        {
                            line += " (you)";
                        }
                        lines.Add(line);
                    }
                }

                if (GameNetworkClient.Instance != null)
                {
                    UserManagementClientNetworkService userService =
                        GameNetworkClient.Instance.UserManagementService;

                    foreach (UserManagementClientNetworkService.UserInfo user in userService.Users)
                    {
                        string line = "  " + user.Name;
                        if (user == userService.ThisUser)
                        {
                            line += " (you)";
                        }
                        lines.Add(line);
                    }
                }

                renderer.AddTextLines(lines, new Vec2(.01f, .15f), HorizontalAlign.Left, VerticalAlign.Top,
                                      0, new ColorValue(1, 1, 0));
            }

            //screenMessages
            {
                Vec2 pos = new Vec2(.01f, .9f);
                for (int n = screenMessages.Count - 1; n >= 0; n--)
                {
                    ScreenMessage message = screenMessages[n];

                    ColorValue color = new ColorValue(1, 1, 1, message.timeRemaining);
                    if (color.Alpha > 1)
                    {
                        color.Alpha = 1;
                    }

                    renderer.AddText(message.text, pos, HorizontalAlign.Left, VerticalAlign.Top,
                                     color);
                    pos.Y -= renderer.DefaultFont.Height;
                }
            }

            //Game is paused on server
            if (EntitySystemWorld.Instance.IsClientOnly() && !EntitySystemWorld.Instance.Simulation)
            {
                renderer.AddText("Game is paused on server", new Vec2(.5f, .5f),
                                 HorizontalAlign.Center, VerticalAlign.Center, new ColorValue(1, 0, 0));
            }
        }
        protected override void OnRender()
        {
            base.OnRender();

            bool thisUserIsMovingPiece = false;

            //render borders for moving pieces by users
            foreach (Entity entity in Map.Instance.Children)
            {
                JigsawPuzzlePiece piece = entity as JigsawPuzzlePiece;

                if (piece != null)
                {
                    //server
                    if (EntitySystemWorld.Instance.IsServer())
                    {
                        if (piece.Server_MovingByUser != null)
                        {
                            GameNetworkServer server = GameNetworkServer.Instance;
                            if (server.UserManagementService.ServerUser == piece.Server_MovingByUser)
                            {
                                thisUserIsMovingPiece = true;
                            }
                            RenderPieceSelectionBorder(piece, true);
                        }
                    }

                    //client
                    if (EntitySystemWorld.Instance.IsClientOnly())
                    {
                        if (piece.Client_MovingByUser != null)
                        {
                            GameNetworkClient client = GameNetworkClient.Instance;
                            if (client.UserManagementService.ThisUser == piece.Client_MovingByUser)
                            {
                                thisUserIsMovingPiece = true;
                            }
                            RenderPieceSelectionBorder(piece, true);
                        }
                    }

                    //single mode
                    if (EntitySystemWorld.Instance.IsSingle())
                    {
                        if (piece.ServerOrSingle_Moving)
                        {
                            thisUserIsMovingPiece = true;
                            RenderPieceSelectionBorder(piece, true);
                        }
                    }
                }
            }

            //render border for mouse over piece
            if (!thisUserIsMovingPiece)
            {
                JigsawPuzzlePiece piece = GetPieceByCursor();
                if (piece != null)
                {
                    RenderPieceSelectionBorder(piece, false);
                }
            }
        }