context: #region Copyright & License Information
  /*
   * Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
   * This file is part of OpenRA, which is free software. It is made
   * available to you under the terms of the GNU General Public License
   * as published by the Free Software Foundation, either version 3 of
   * the License, or (at your option) any later version. For more
   * information, see COPYING.
   */
  #endregion
  
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.IO;
  using System.Linq;
  using OpenRA.Network;
  using OpenRA.Widgets;
  
  namespace OpenRA.Mods.Common.Widgets.Logic
  {
  	public class MainMenuLogic : ChromeLogic
  	{
  		protected enum MenuType { Main, Singleplayer, Extras, MapEditor, StartupPrompts, None }
  
  		protected enum MenuPanel { None, Missions, Skirmish, Multiplayer, MapEditor, Replays, GameSaves }
  
  		protected MenuType menuType = MenuType.Main;
  		readonly Widget rootMenu;
  		readonly ScrollPanelWidget newsPanel;
  		readonly Widget newsTemplate;
  		readonly LabelWidget newsStatus;
  
  		// Update news once per game launch
  		static bool fetchedNews;
  
  		protected static MenuPanel lastGameState = MenuPanel.None;
  
  		bool newsOpen;
  
  		void SwitchMenu(MenuType type)
  		{
  			menuType = type;
  
  			DiscordService.UpdateStatus(DiscordState.InMenu);
  
  			// Update button mouseover
  			Game.RunAfterTick(Ui.ResetTooltips);
  		}
  
  		[ObjectCreator.UseCtor]
  		public MainMenuLogic(Widget widget, World world, ModData modData)
  		{
  			rootMenu = widget;
  			rootMenu.Get<LabelWidget>("VERSION_LABEL").Text = modData.Manifest.Metadata.Version;
  
  			// Menu buttons
  			var mainMenu = widget.Get("MAIN_MENU");
  			mainMenu.IsVisible = () => menuType == MenuType.Main;
  
  			mainMenu.Get<ButtonWidget>("SINGLEPLAYER_BUTTON").OnClick = () => SwitchMenu(MenuType.Singleplayer);
  
  			mainMenu.Get<ButtonWidget>("MULTIPLAYER_BUTTON").OnClick = OpenMultiplayerPanel;
  
  			mainMenu.Get<ButtonWidget>("CONTENT_BUTTON").OnClick = () =>
  			{
  				// Switching mods changes the world state (by disposing it),
  				// so we can't do this inside the input handler.
  				Game.RunAfterTick(() =>
  				{
  					var content = modData.Manifest.Get<ModContent>();
  					Game.InitializeMod(content.ContentInstallerMod, new Arguments(new[] { "Content.Mod=" + modData.Manifest.Id }));
  				});
  			};
  
  			mainMenu.Get<ButtonWidget>("SETTINGS_BUTTON").OnClick = () =>
  			{
  				SwitchMenu(MenuType.None);
  				Game.OpenWindow("SETTINGS_PANEL", new WidgetArgs
  				{
  					{ "onExit", () => SwitchMenu(MenuType.Main) }
  				});
  			};
  
  			mainMenu.Get<ButtonWidget>("EXTRAS_BUTTON").OnClick = () => SwitchMenu(MenuType.Extras);
  
  			mainMenu.Get<ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;
  
  			// Singleplayer menu
  			var singleplayerMenu = widget.Get("SINGLEPLAYER_MENU");
  			singleplayerMenu.IsVisible = () => menuType == MenuType.Singleplayer;
  
  			var missionsButton = singleplayerMenu.Get<ButtonWidget>("MISSIONS_BUTTON");
  			missionsButton.OnClick = OpenMissionBrowserPanel;
  
  			var hasCampaign = modData.Manifest.Missions.Any();
  			var hasMissions = modData.MapCache
  				.Any(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.MissionSelector));
  
  			missionsButton.Disabled = !hasCampaign && !hasMissions;
  
  			var hasMaps = modData.MapCache.Any(p => p.Visibility.HasFlag(MapVisibility.Lobby));
  			var skirmishButton = singleplayerMenu.Get<ButtonWidget>("SKIRMISH_BUTTON");
  			skirmishButton.OnClick = StartSkirmishGame;
  			skirmishButton.Disabled = !hasMaps;
  
  			var loadButton = singleplayerMenu.Get<ButtonWidget>("LOAD_BUTTON");
  			loadButton.IsDisabled = () => !GameSaveBrowserLogic.IsLoadPanelEnabled(modData.Manifest);
  			loadButton.OnClick = OpenGameSaveBrowserPanel;
  
  			singleplayerMenu.Get<ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Main);
  
  			// Extras menu
  			var extrasMenu = widget.Get("EXTRAS_MENU");
  			extrasMenu.IsVisible = () => menuType == MenuType.Extras;
  
  			extrasMenu.Get<ButtonWidget>("REPLAYS_BUTTON").OnClick = OpenReplayBrowserPanel;
  
  			extrasMenu.Get<ButtonWidget>("MUSIC_BUTTON").OnClick = () =>
  			{
  				SwitchMenu(MenuType.None);
  				Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
  				{
  					{ "onExit", () => SwitchMenu(MenuType.Extras) },
  					{ "world", world }
  				});
  			};
  
  			extrasMenu.Get<ButtonWidget>("MAP_EDITOR_BUTTON").OnClick = () => SwitchMenu(MenuType.MapEditor);
  
  			var assetBrowserButton = extrasMenu.GetOrNull<ButtonWidget>("ASSETBROWSER_BUTTON");
  			if (assetBrowserButton != null)
  				assetBrowserButton.OnClick = () =>
  				{
  					SwitchMenu(MenuType.None);
  					Game.OpenWindow("ASSETBROWSER_PANEL", new WidgetArgs
  					{
  						{ "onExit", () => SwitchMenu(MenuType.Extras) },
  					});
  				};
  
  			extrasMenu.Get<ButtonWidget>("CREDITS_BUTTON").OnClick = () =>
  			{
  				SwitchMenu(MenuType.None);
  				Ui.OpenWindow("CREDITS_PANEL", new WidgetArgs
  				{
  					{ "onExit", () => SwitchMenu(MenuType.Extras) },
  				});
  			};
  
  			extrasMenu.Get<ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Main);
  
  			// Map editor menu
  			var mapEditorMenu = widget.Get("MAP_EDITOR_MENU");
  			mapEditorMenu.IsVisible = () => menuType == MenuType.MapEditor;
  
  			// Loading into the map editor
  			Game.BeforeGameStart += RemoveShellmapUI;
  
  			var onSelect = new Action<string>(uid => LoadMapIntoEditor(modData.MapCache[uid].Uid));
  
  			var newMapButton = widget.Get<ButtonWidget>("NEW_MAP_BUTTON");
  			newMapButton.OnClick = () =>
  			{
  				SwitchMenu(MenuType.None);
  				Game.OpenWindow("NEW_MAP_BG", new WidgetArgs()
  				{
  					{ "onSelect", onSelect },
  					{ "onExit", () => SwitchMenu(MenuType.MapEditor) }
  				});
  			};
  
  			var loadMapButton = widget.Get<ButtonWidget>("LOAD_MAP_BUTTON");
  			loadMapButton.OnClick = () =>
  			{
  				SwitchMenu(MenuType.None);
  				Game.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
  				{
  					{ "initialMap", null },
  					{ "initialTab", MapClassification.User },
  					{ "onExit", () => SwitchMenu(MenuType.MapEditor) },
  					{ "onSelect", onSelect },
  					{ "filter", MapVisibility.Lobby | MapVisibility.Shellmap | MapVisibility.MissionSelector },
  				});
  			};
  
  			loadMapButton.Disabled = !hasMaps;
  
  			mapEditorMenu.Get<ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Extras);
  
  			var newsBG = widget.GetOrNull("NEWS_BG");
  			if (newsBG != null)
  			{
  				newsBG.IsVisible = () => Game.Settings.Game.FetchNews && menuType != MenuType.None && menuType != MenuType.StartupPrompts;
  
  				newsPanel = Ui.LoadWidget<ScrollPanelWidget>("NEWS_PANEL", null, new WidgetArgs());
  				newsTemplate = newsPanel.Get("NEWS_ITEM_TEMPLATE");
  				newsPanel.RemoveChild(newsTemplate);
  
  				newsStatus = newsPanel.Get<LabelWidget>("NEWS_STATUS");
  				SetNewsStatus("Loading news");
  			}
  
  			Game.OnRemoteDirectConnect += OnRemoteDirectConnect;
  
  			// Check for updates in the background
  			var webServices = modData.Manifest.Get<WebServices>();
  			if (Game.Settings.Debug.CheckVersion)
  				webServices.CheckModVersion();
  
  			var updateLabel = rootMenu.GetOrNull("UPDATE_NOTICE");
  			if (updateLabel != null)
  				updateLabel.IsVisible = () => !newsOpen && menuType != MenuType.None &&
  					menuType != MenuType.StartupPrompts &&
  					webServices.ModVersionStatus == ModVersionStatus.Outdated;
  
  			var playerProfile = widget.GetOrNull("PLAYER_PROFILE_CONTAINER");
  			if (playerProfile != null)
  			{
  				Func<bool> minimalProfile = () => Ui.CurrentWindow() != null;
  				Game.LoadWidget(world, "LOCAL_PROFILE_PANEL", playerProfile, new WidgetArgs()
  				{
  					{ "minimalProfile", minimalProfile }
  				});
  			}
  
  			menuType = MenuType.StartupPrompts;
  
  
gt: 			Action onIntroductionComplete = () =>