/// <summary>
        /// Event fired when the Change Button is pushed on the App Settings Tab
        /// </summary>
        private void ChangeButton_Click(object sender, EventArgs e)
        {
            using (ModalOverlay overlay = new ModalOverlay(this, 0.2))
            {
                overlay.Show(this);
                string OrigLocation = Program.Config.Bf2InstallDir;
                if (SetupManager.ShowInstallForm(overlay))
                {
                    // Load the BF2 Server
                    try
                    {
                        BF2Client.SetInstallPath(Program.Config.Bf2InstallDir);
                    }
                    catch (Exception E)
                    {
                        MetroMessageBox.Show(this, E.Message, "Battlefield 2 Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        Program.Config.Bf2InstallDir = OrigLocation;
                        Program.Config.Save();
                    }
                }
                overlay.Close();
            }

            this.Focus();
        }
        /// <summary>
        /// Shows the Provider editor form
        /// </summary>
        /// <param name="selectedProvider"></param>
        private void ShowProviderEditor(ServiceProvider selectedProvider = null)
        {
            // Show overlay first, which provides the smokey (Modal) background
            using (ModalOverlay overlay = new ModalOverlay(this))
                using (ProviderEditorForm f = new ProviderEditorForm(selectedProvider))
                {
                    overlay.Show(this);
                    DialogResult Res = f.ShowDialog(overlay);
                    if (Res == DialogResult.OK)
                    {
                        if (selectedProvider == null)
                        {
                            selectedProvider = ClientSettings.ServiceProviders.Last();
                            ProviderComboBox.Items.Add(selectedProvider);
                            ProviderManageComboBox.Items.Add(selectedProvider);
                            ProviderManageComboBox.SelectedIndex = ProviderManageComboBox.Items.Count - 1;
                        }

                        // Reload comboboxes
                        ReloadProviders(selectedProvider);
                    }

                    overlay.Close();
                }

            // Bring back focus to this form
            this.Focus();
        }
        /// <summary>
        /// Shows the Server Editor form
        /// </summary>
        /// <param name="selectedServer"></param>
        private void ShowServerEditor(Server selectedServer = null)
        {
            // Show overlay first, which provides the smokey (Modal) background
            using (ModalOverlay overlay = new ModalOverlay(this))
                using (ServerEditorForm f = new ServerEditorForm(selectedServer))
                {
                    overlay.Show(this);
                    DialogResult Res = f.ShowDialog(overlay);
                    if (Res == DialogResult.OK)
                    {
                        if (selectedServer == null)
                        {
                            Server server = ClientSettings.SavedServers.Last();
                            ServerComboBox.Items.Add(server);
                            ServerManageComboBox.Items.Add(server);
                            ServerManageComboBox.SelectedIndex = ServerManageComboBox.Items.Count - 1;
                        }
                        else
                        {
                            ServerAddressLabel.Text  = selectedServer.Address;
                            ServerPortLabel.Text     = selectedServer.Port.ToString();
                            ServerProviderLabel.Text = selectedServer.Provider;
                        }

                        // Reload comboboxes
                        ReloadServers(null, selectedServer);
                    }

                    overlay.Close();
                }

            // Bring back focus to this form
            this.Focus();
        }
        /// <summary>
        /// Event fired when the Server is changed on the Launcher Tab
        /// </summary>
        private void ServerComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Make sure we have an item selected
            if (ServerComboBox.SelectedIndex == 0)
            {
                return;
            }

            // Grab our selected server
            Server selectedServer = ServerComboBox.SelectedItem as Server;

            // Try and fetch the provider service
            ServiceProvider Provider = (
                from x in ClientSettings.ServiceProviders
                where x.Name == selectedServer.Provider
                select x
                ).FirstOrDefault();

            // Can't find the provider? Uh-oh..
            if (Provider == null)
            {
                // Show overlay first, which provides the smokey (Modal) background
                using (ModalOverlay overlay = new ModalOverlay(this, 0.2))
                {
                    overlay.Show(this);
                    DialogResult Res = MetroMessageBox.Show(overlay,
                                                            "The selected Service Provider for this server does not exist in the list of Service Providers you have configured! "
                                                            + "Please update the server or add the Service Provider for this server to prevent future errors. Would you like me "
                                                            + "to remove the Service Provider entry for this server?",
                                                            "Provider Not Found", MessageBoxButtons.YesNo,
                                                            MessageBoxIcon.Warning, 175
                                                            );

                    // If the user wants us to remove the provider entry
                    if (Res == DialogResult.Yes)
                    {
                        selectedServer.Provider = "";
                        ClientSettings.Save();
                    }
                }

                // Focus the mainform again
                this.Focus();
            }
            else
            {
                ProviderComboBox.SelectedIndexChanged -= ProviderComboBox_SelectedIndexChanged;
                ProviderComboBox.SelectedItem          = Provider;
                ProviderComboBox.SelectedIndexChanged += ProviderComboBox_SelectedIndexChanged;
            }
        }
        private void LaunchParamsButton_Click(object sender, EventArgs e)
        {
            // Reload any changes in the params box
            Params.Reload(LaunchParamsTextBox.Text);

            // Display params editor
            using (LaunchParamsForm f = new LaunchParamsForm(Params))
                using (ModalOverlay overlay = new ModalOverlay(this))
                {
                    overlay.Show(this);
                    DialogResult Res = f.ShowDialog(overlay);
                    if (Res == DialogResult.OK)
                    {
                        LaunchParamsTextBox.Text = Params.BuildString(false);
                    }

                    overlay.Close();
                }

            LaunchButton.Focus();
        }
        /// <summary>
        /// Event fired when the Launch Battlefield 2 button is pushed on the Launcher Tab
        /// </summary>
        private async void LaunchButton_Click(object sender, EventArgs args)
        {
            // Lock button to prevent spam
            LaunchButton.Enabled = false;

            // Close the app
            if (BF2Client.IsRunning)
            {
                BF2Client.Stop();
                return;
            }

            // Show overlay first, which provides the smokey (Modal) background
            using (ModalOverlay overlay = new ModalOverlay(this, 0.3))
            {
                // Show overlay
                overlay.Show(this);

                // Make sure a mod is selected
                if (ModComboBox.SelectedIndex < 1)
                {
                    MetroMessageBox.Show(overlay,
                                         "Please select a Bf2 Mod before attempting to start the game!",
                                         "No Mod Selected", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, 150
                                         );
                    overlay.Close();

                    // Reset button
                    BF2Client_Exited();

                    // Focus the mod select
                    ModComboBox.Focus();
                    return;
                }

                // Grab our mod and provider
                BF2Mod          Mod      = ModComboBox.SelectedItem as BF2Mod;
                ServiceProvider Provider = ProviderComboBox.SelectedItem as ServiceProvider;
                Server          Server   = ServerComboBox.SelectedItem as Server;

                // Remove old redirects
                Redirector.RemoveRedirects();

                // If we arent using a provider, skip to just launching the game
                if (Provider == null)
                {
                    goto StartClient;
                }

                // Apply redirects in a new thread
                SyncProgress <TaskStep> MyProgress = new SyncProgress <TaskStep>(RedirectStatusUpdate);
                bool Success = await Redirector.ApplyRedirectsAsync(Provider, MyProgress);

                if (!Success)
                {
                    // Show error
                    MetroMessageBox.Show(overlay, ErrorStep.Description, "Redirect Error", MessageBoxButtons.OK, MessageBoxIcon.Error, 180);
                    overlay.Close();

                    // Reset button
                    BF2Client_Exited();
                    return;
                }

                // Show the Task Form
                TaskForm.Show(this, "Launching Battlefield 2", $"Starting Battlefield 2 with mod \"{Mod.Title}\"", false, ProgressBarStyle.Marquee, 0);

                // Our goto to start the game
StartClient:
                {
                    try
                    {
                        // ===
                        // ALWAYS Remove all temporary keys before this next point
                        // ===
                        Params.Reload(LaunchParamsTextBox.Text);
                        Params.ClearTempParams();

                        // If we are auto joining a server, we must login!
                        if (Provider != null && (Server != null || CredentialsCheckBox.Checked))
                        {
                            // Prompt user to login!
                            using (LoginForm f = new LoginForm(Provider))
                            {
                                DialogResult Res = f.ShowDialog(overlay);
                                if (Res == DialogResult.Cancel)
                                {
                                    // Reset button
                                    TaskForm.CloseForm();
                                    BF2Client_Exited();
                                    return;
                                }

                                // Set server params
                                if (Server != null)
                                {
                                    Params.AddOrSet("joinServer", Server.Address);
                                    Params.AddOrSet("port", Server.Port.ToString());
                                }

                                // Set login params
                                Params.AddOrSet("playerName", f.UsernameTextBox.Text);
                                Params.AddOrSet("playerPassword", f.PasswordTextBox.Text);
                            }
                        }

                        // Start the client executable
                        BF2Client.Start(Mod, Params.BuildString(true));
                    }
                    catch (Exception e)
                    {
                        // Show error
                        MetroMessageBox.Show(overlay, e.Message, "Failure to Launch", MessageBoxButtons.OK, MessageBoxIcon.Error, 180);
                        BF2Client_Exited();
                    }
                }

                // Close the task form
                TaskForm.CloseForm();

                // Close Task form and overlay
                using (RunningOverlay = new GameRunningForm(this))
                {
                    RunningOverlay.ShowDialog(overlay);
                }

                // Close Overlay
                overlay.Close();
                LaunchButton.Focus();
            }
        }
        private async void ProgramUpdater_CheckCompleted(object sender, EventArgs e)
        {
            if (ProgramUpdater.UpdateAvailable)
            {
                // Show overlay first, which provides the smokey (Modal) background
                using (ModalOverlay overlay = new ModalOverlay(this, 0.3))
                {
                    // Show overlay
                    overlay.Show(this);

                    // Make sure a mod is selected
                    DialogResult r = MetroMessageBox.Show(overlay,
                                                          "An Update for this program is avaiable for download (" + ProgramUpdater.NewVersion + ")."
                                                          + Environment.NewLine.Repeat(1)
                                                          + "Would you like to download and install this update now?",
                                                          "Update Available",
                                                          MessageBoxButtons.YesNo, MessageBoxIcon.Question, 150
                                                          );

                    // Apply update
                    if (r == DialogResult.Yes)
                    {
                        bool success = false;
                        try
                        {
                            success = await ProgramUpdater.DownloadUpdateAsync(overlay);
                        }
                        catch (Exception ex)
                        {
                            // Create Exception Log
                            TraceLog.TraceWarning("Unable to Download new update archive :: Generating Exception Log");
                            ExceptionHandler.GenerateExceptionLog(ex);

                            // Alert User
                            MetroMessageBox.Show(overlay,
                                                 "Failed to download update archive! Reason: " + ex.Message
                                                 + Environment.NewLine.Repeat(1)
                                                 + "An exception log has been generated and created inside the My Documents/BF2Statistics folder.",
                                                 "Download Failed",
                                                 MessageBoxButtons.OK,
                                                 MessageBoxIcon.Error
                                                 );
                        }

                        // If the file downloaded successfully
                        if (success)
                        {
                            try
                            {
                                ProgramUpdater.RunUpdate();
                            }
                            catch (Exception ex)
                            {
                                MetroMessageBox.Show(overlay,
                                                     "An Occured while trying to install the new update. You will need to manually apply the update."
                                                     + Environment.NewLine.Repeat(1) + "Error Message: " + ex.Message,
                                                     "Installation Error",
                                                     MessageBoxButtons.OK,
                                                     MessageBoxIcon.Error
                                                     );
                            }
                        }
                    }

                    // Close overlay
                    overlay.Close();

                    // Focus the mod select
                    ModComboBox.Focus();
                }
            }
        }