internal LobbyMapPreviewLogic(Widget widget, OrderManager orderManager, LobbyLogic lobby)
        {
            var available = widget.GetOrNull("MAP_AVAILABLE");

            if (available != null)
            {
                available.IsVisible = () => lobby.Map.Status == MapStatus.Available && lobby.Map.RuleStatus == MapRuleStatus.Cached;

                var preview = available.Get <MapPreviewWidget>("MAP_PREVIEW");
                preview.Preview        = () => lobby.Map;
                preview.OnMouseDown    = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
                preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);

                var title = available.GetOrNull <LabelWidget>("MAP_TITLE");
                if (title != null)
                {
                    title.GetText = () => lobby.Map.Title;
                }

                var type = available.GetOrNull <LabelWidget>("MAP_TYPE");
                if (type != null)
                {
                    type.GetText = () => lobby.Map.Type;
                }

                var author = available.GetOrNull <LabelWidget>("MAP_AUTHOR");
                if (author != null)
                {
                    author.GetText = () => "Created by {0}".F(lobby.Map.Author);
                }
            }

            var invalid = widget.GetOrNull("MAP_INVALID");

            if (invalid != null)
            {
                invalid.IsVisible = () => lobby.Map.Status == MapStatus.Available && lobby.Map.RuleStatus == MapRuleStatus.Invalid;

                var preview = invalid.Get <MapPreviewWidget>("MAP_PREVIEW");
                preview.Preview        = () => lobby.Map;
                preview.OnMouseDown    = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
                preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);

                var title = invalid.GetOrNull <LabelWidget>("MAP_TITLE");
                if (title != null)
                {
                    title.GetText = () => lobby.Map.Title;
                }

                var type = invalid.GetOrNull <LabelWidget>("MAP_TYPE");
                if (type != null)
                {
                    type.GetText = () => lobby.Map.Type;
                }
            }

            var download = widget.GetOrNull("MAP_DOWNLOADABLE");

            if (download != null)
            {
                download.IsVisible = () => lobby.Map.Status == MapStatus.DownloadAvailable;

                var preview = download.Get <MapPreviewWidget>("MAP_PREVIEW");
                preview.Preview        = () => lobby.Map;
                preview.OnMouseDown    = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
                preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);

                var title = download.GetOrNull <LabelWidget>("MAP_TITLE");
                if (title != null)
                {
                    title.GetText = () => lobby.Map.Title;
                }

                var type = download.GetOrNull <LabelWidget>("MAP_TYPE");
                if (type != null)
                {
                    type.GetText = () => lobby.Map.Type;
                }

                var author = download.GetOrNull <LabelWidget>("MAP_AUTHOR");
                if (author != null)
                {
                    author.GetText = () => "Created by {0}".F(lobby.Map.Author);
                }

                var install = download.GetOrNull <ButtonWidget>("MAP_INSTALL");
                if (install != null)
                {
                    install.OnClick = () => lobby.Map.Install();
                }
            }

            var progress = widget.GetOrNull("MAP_PROGRESS");

            if (progress != null)
            {
                progress.IsVisible = () => (lobby.Map.Status != MapStatus.Available || lobby.Map.RuleStatus == MapRuleStatus.Unknown) && lobby.Map.Status != MapStatus.DownloadAvailable;

                var preview = progress.Get <MapPreviewWidget>("MAP_PREVIEW");
                preview.Preview        = () => lobby.Map;
                preview.OnMouseDown    = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
                preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);

                var title = progress.GetOrNull <LabelWidget>("MAP_TITLE");
                if (title != null)
                {
                    title.GetText = () => lobby.Map.Title;
                }

                var type = progress.GetOrNull <LabelWidget>("MAP_TYPE");
                if (type != null)
                {
                    type.GetText = () => lobby.Map.Type;
                }

                var statusSearching = progress.GetOrNull("MAP_STATUS_SEARCHING");
                if (statusSearching != null)
                {
                    statusSearching.IsVisible = () => lobby.Map.Status == MapStatus.Searching;
                }

                var statusUnavailable = progress.GetOrNull("MAP_STATUS_UNAVAILABLE");
                if (statusUnavailable != null)
                {
                    statusUnavailable.IsVisible = () => lobby.Map.Status == MapStatus.Unavailable;
                }

                var statusError = progress.GetOrNull("MAP_STATUS_ERROR");
                if (statusError != null)
                {
                    statusError.IsVisible = () => lobby.Map.Status == MapStatus.DownloadError;
                }

                var statusDownloading = progress.GetOrNull <LabelWidget>("MAP_STATUS_DOWNLOADING");
                if (statusDownloading != null)
                {
                    statusDownloading.IsVisible = () => lobby.Map.Status == MapStatus.Downloading;
                    statusDownloading.GetText   = () =>
                    {
                        if (lobby.Map.DownloadBytes == 0)
                        {
                            return("Connecting...");
                        }

                        // Server does not provide the total file length
                        if (lobby.Map.DownloadPercentage == 0)
                        {
                            return("Downloading {0} kB".F(lobby.Map.DownloadBytes / 1024));
                        }

                        return("Downloading {0} kB ({1}%)".F(lobby.Map.DownloadBytes / 1024, lobby.Map.DownloadPercentage));
                    };
                }

                var retry = progress.GetOrNull <ButtonWidget>("MAP_RETRY");
                if (retry != null)
                {
                    retry.IsVisible = () => lobby.Map.Status == MapStatus.DownloadError || lobby.Map.Status == MapStatus.Unavailable;
                    retry.OnClick   = () =>
                    {
                        if (lobby.Map.Status == MapStatus.DownloadError)
                        {
                            lobby.Map.Install();
                        }
                        else if (lobby.Map.Status == MapStatus.Unavailable)
                        {
                            Game.modData.MapCache.QueryRemoteMapDetails(new [] { lobby.Map.Uid });
                        }
                    };

                    retry.GetText = () => lobby.Map.Status == MapStatus.DownloadError ? "Retry Install" : "Retry Search";
                }

                var progressbar = progress.GetOrNull <ProgressBarWidget>("MAP_PROGRESSBAR");
                if (progressbar != null)
                {
                    progressbar.IsIndeterminate = () => lobby.Map.DownloadPercentage == 0;
                    progressbar.GetPercentage   = () => lobby.Map.DownloadPercentage;
                    progressbar.IsVisible       = () => !retry.IsVisible();
                }
            }
        }
        internal LobbyMapPreviewLogic(Widget widget, OrderManager orderManager, LobbyLogic lobby)
        {
            var available = widget.GetOrNull("MAP_AVAILABLE");
            if (available != null)
            {
                available.IsVisible = () => lobby.Map.Status == MapStatus.Available && lobby.Map.RuleStatus == MapRuleStatus.Cached;

                var preview = available.Get<MapPreviewWidget>("MAP_PREVIEW");
                preview.Preview = () => lobby.Map;
                preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
                preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);

                var title = available.GetOrNull<LabelWidget>("MAP_TITLE");
                if (title != null)
                    title.GetText = () => lobby.Map.Title;

                var type = available.GetOrNull<LabelWidget>("MAP_TYPE");
                if (type != null)
                    type.GetText = () => lobby.Map.Type;

                var author = available.GetOrNull<LabelWidget>("MAP_AUTHOR");
                if (author != null)
                    author.GetText = () => "Created by {0}".F(lobby.Map.Author);
            }

            var invalid = widget.GetOrNull("MAP_INVALID");
            if (invalid != null)
            {
                invalid.IsVisible = () => lobby.Map.Status == MapStatus.Available && lobby.Map.RuleStatus == MapRuleStatus.Invalid;

                var preview = invalid.Get<MapPreviewWidget>("MAP_PREVIEW");
                preview.Preview = () => lobby.Map;
                preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
                preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);

                var title = invalid.GetOrNull<LabelWidget>("MAP_TITLE");
                if (title != null)
                    title.GetText = () => lobby.Map.Title;

                var type = invalid.GetOrNull<LabelWidget>("MAP_TYPE");
                if (type != null)
                    type.GetText = () => lobby.Map.Type;
            }

            var download = widget.GetOrNull("MAP_DOWNLOADABLE");
            if (download != null)
            {
                download.IsVisible = () => lobby.Map.Status == MapStatus.DownloadAvailable;

                var preview = download.Get<MapPreviewWidget>("MAP_PREVIEW");
                preview.Preview = () => lobby.Map;
                preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
                preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);

                var title = download.GetOrNull<LabelWidget>("MAP_TITLE");
                if (title != null)
                    title.GetText = () => lobby.Map.Title;

                var type = download.GetOrNull<LabelWidget>("MAP_TYPE");
                if (type != null)
                    type.GetText = () => lobby.Map.Type;

                var author = download.GetOrNull<LabelWidget>("MAP_AUTHOR");
                if (author != null)
                    author.GetText = () => "Created by {0}".F(lobby.Map.Author);

                var install = download.GetOrNull<ButtonWidget>("MAP_INSTALL");
                if (install != null)
                    install.OnClick = () => lobby.Map.Install();
            }

            var progress = widget.GetOrNull("MAP_PROGRESS");
            if (progress != null)
            {
                progress.IsVisible = () => (lobby.Map.Status != MapStatus.Available || lobby.Map.RuleStatus == MapRuleStatus.Unknown) && lobby.Map.Status != MapStatus.DownloadAvailable;

                var preview = progress.Get<MapPreviewWidget>("MAP_PREVIEW");
                preview.Preview = () => lobby.Map;
                preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
                preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);

                var title = progress.GetOrNull<LabelWidget>("MAP_TITLE");
                if (title != null)
                    title.GetText = () => lobby.Map.Title;

                var type = progress.GetOrNull<LabelWidget>("MAP_TYPE");
                if (type != null)
                    type.GetText = () => lobby.Map.Type;

                var statusSearching = progress.GetOrNull("MAP_STATUS_SEARCHING");
                if (statusSearching != null)
                    statusSearching.IsVisible = () => lobby.Map.Status == MapStatus.Searching;

                var statusUnavailable = progress.GetOrNull("MAP_STATUS_UNAVAILABLE");
                if (statusUnavailable != null)
                    statusUnavailable.IsVisible = () => lobby.Map.Status == MapStatus.Unavailable;

                var statusError = progress.GetOrNull("MAP_STATUS_ERROR");
                if (statusError != null)
                    statusError.IsVisible = () => lobby.Map.Status == MapStatus.DownloadError;

                var statusDownloading = progress.GetOrNull<LabelWidget>("MAP_STATUS_DOWNLOADING");
                if (statusDownloading != null)
                {
                    statusDownloading.IsVisible = () => lobby.Map.Status == MapStatus.Downloading;
                    statusDownloading.GetText = () =>
                    {
                        if (lobby.Map.DownloadBytes == 0)
                            return "Connecting...";

                        // Server does not provide the total file length
                        if (lobby.Map.DownloadPercentage == 0)
                            return "Downloading {0} kB".F(lobby.Map.DownloadBytes / 1024);

                        return "Downloading {0} kB ({1}%)".F(lobby.Map.DownloadBytes / 1024, lobby.Map.DownloadPercentage);
                    };
                }

                var retry = progress.GetOrNull<ButtonWidget>("MAP_RETRY");
                if (retry != null)
                {
                    retry.IsVisible = () => lobby.Map.Status == MapStatus.DownloadError || lobby.Map.Status == MapStatus.Unavailable;
                    retry.OnClick = () =>
                    {
                        if (lobby.Map.Status == MapStatus.DownloadError)
                            lobby.Map.Install();
                        else if (lobby.Map.Status == MapStatus.Unavailable)
                            Game.modData.MapCache.QueryRemoteMapDetails(new [] { lobby.Map.Uid });
                    };

                    retry.GetText = () => lobby.Map.Status == MapStatus.DownloadError ? "Retry Install" : "Retry Search";
                }

                var progressbar = progress.GetOrNull<ProgressBarWidget>("MAP_PROGRESSBAR");
                if (progressbar != null)
                {
                    progressbar.IsIndeterminate = () => lobby.Map.DownloadPercentage == 0;
                    progressbar.GetPercentage = () => lobby.Map.DownloadPercentage;
                    progressbar.IsVisible = () => !retry.IsVisible();
                }
            }
        }