using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;
using System.Windows.Forms;
using Microsoft.VisualBasic;
using Tesla.Net;
using TeslaConsole.Properties;

namespace TeslaConsole;

public class SiteManagement : Form
{
	private class PodData
	{
		public Pod Pod;

		public PodInfo Conn;

		public string Squad;

		public PingReply PingReply;

		public int pings;

		public Size? Install_CustomResolution;

		public List<PodInstallType> Install_HostTypes = new List<PodInstallType>();

		public bool OperationInProgress;

		public int PercentProgress = -1;

		public string Status = "";

		public Exception Error;

		private SiteManagement Parent;

		private Thread PingThread;

		private bool Running = true;

		public PodData(Pod pod, string squad, SiteManagement parent)
		{
			Pod = pod;
			Squad = squad;
			if (pod.IsLocal)
			{
				Conn = new PodInfo(pod);
				Conn.ConnectCompleted += parent.PodInfo_ConnectCompleted;
				Conn.InstallProductCompleted += parent.PodInfo_InstallProductCompleted;
				Conn.UninstallProductCompleted += parent.PodInfo_UninstallProductCompleted;
			}
			Parent = parent;
			PingThread = new Thread(Ping);
			PingThread.Name = pod.Name + " - Ping Thread";
			PingThread.IsBackground = true;
		}

		public void StartPing()
		{
			PingThread.Start();
		}

		public void StopPing()
		{
			Running = false;
		}

		private void Ping()
		{
			Ping ping = new Ping();
			while (Running)
			{
				if (!OperationInProgress)
				{
					PingReply = ping.Send(Pod.IPAddress, 5000);
					pings++;
					Parent.Pod_PingCompleted(this);
				}
				Thread.Sleep(1000);
			}
		}
	}

	private enum PodInstallType
	{
		GameClient,
		LiveCamera,
		MissionReview
	}

	private IContainer components;

	private DataGridView dgvPods;

	private ContextMenuStrip cmnuDataGrid;

	private ToolStripMenuItem installProductToolStripMenuItem;

	private ToolStripMenuItem registerProductToolStripMenuItem;

	private ToolStripMenuItem importSiteConfigurationToolStripMenuItem;

	private ToolStripMenuItem exportSiteConfigurationToolStripMenuItem;

	private OpenFileDialog dlgOpenFile;

	private SaveFileDialog dlgSaveFile;

	private OpenFileDialog dlgSelectPackage;

	private FlowLayoutPanel flpPodsToConfigure;

	private ToolStripMenuItem deletePodToolStripMenuItem;

	private ToolStripMenuItem resendPodConfigurationToolStripMenuItem;

	private DataGridViewCheckBoxColumn colIsLocal;

	private DataGridViewTextBoxColumn colPodName;

	private DataGridViewComboBoxColumn colSquad;

	private DataGridViewComboBoxColumn colType;

	private DataGridViewTextBoxColumn colMacAddress;

	private DataGridViewTextBoxColumn colIPAddress;

	private DataGridViewTextBoxColumn colSubnet;

	private DataGridViewTextBoxColumn colGateway;

	private DataGridViewTextBoxColumn colDNSServer;

	private DataGridViewTextBoxColumn colHostName;

	private DataGridViewTextBoxColumn colOperationProgress;

	private ToolStripMenuItem uninstallProductToolStripMenuItem;

	public static readonly Guid RPAppGuid = new Guid("7D241B1F-AB6D-4e08-9C20-12294E743D94");

	public static readonly Guid RPMRAppGuid = new Guid("8F71D5C2-38E4-413c-8E22-88CAD08774D2");

	public static readonly Guid RPLCAppGuid = new Guid("57A0B3C2-D5CF-46d6-ABED-A8F4A26AB086");

	public static readonly Guid MW4AppGuid = new Guid("CC8500ED-A653-45a7-BEF8-C332D30371A6");

	public static readonly Guid MW4LCAppGuid = new Guid("8EE93A6C-F16A-49be-B867-37FAE9087FFF");

	private Site mSite;

	private List<PodData> mPods = new List<PodData>();

	private PodData mPodInEdit;

	private int mRowInEdit = -1;

	private Dictionary<Guid, Pod> mReconfiguringPods = new Dictionary<Guid, Pod>();

	private Dictionary<string, Button> mConfigureButtons = new Dictionary<string, Button>();

	private Dictionary<Guid, Label> mConfigureLabels = new Dictionary<Guid, Label>();

	private static bool mIsOpen = false;

	public static bool IsOpen => mIsOpen;

	protected override void Dispose(bool disposing)
	{
		if (disposing && components != null)
		{
			components.Dispose();
		}
		base.Dispose(disposing);
	}

	private void InitializeComponent()
	{
		this.components = new System.ComponentModel.Container();
		System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle = new System.Windows.Forms.DataGridViewCellStyle();
		this.dgvPods = new System.Windows.Forms.DataGridView();
		this.colIsLocal = new System.Windows.Forms.DataGridViewCheckBoxColumn();
		this.colPodName = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.colSquad = new System.Windows.Forms.DataGridViewComboBoxColumn();
		this.colType = new System.Windows.Forms.DataGridViewComboBoxColumn();
		this.colMacAddress = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.colIPAddress = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.colSubnet = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.colGateway = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.colDNSServer = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.colHostName = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.colOperationProgress = new System.Windows.Forms.DataGridViewTextBoxColumn();
		this.cmnuDataGrid = new System.Windows.Forms.ContextMenuStrip(this.components);
		this.deletePodToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
		this.installProductToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
		this.uninstallProductToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
		this.resendPodConfigurationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
		this.importSiteConfigurationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
		this.exportSiteConfigurationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
		this.dlgOpenFile = new System.Windows.Forms.OpenFileDialog();
		this.dlgSaveFile = new System.Windows.Forms.SaveFileDialog();
		this.dlgSelectPackage = new System.Windows.Forms.OpenFileDialog();
		this.flpPodsToConfigure = new System.Windows.Forms.FlowLayoutPanel();
		((System.ComponentModel.ISupportInitialize)this.dgvPods).BeginInit();
		this.cmnuDataGrid.SuspendLayout();
		base.SuspendLayout();
		this.dgvPods.AllowUserToResizeRows = false;
		dataGridViewCellStyle.BackColor = System.Drawing.Color.FromArgb(225, 225, 255);
		this.dgvPods.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle;
		this.dgvPods.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
		this.dgvPods.BackgroundColor = System.Drawing.Color.White;
		this.dgvPods.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
		this.dgvPods.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.Disable;
		this.dgvPods.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
		this.dgvPods.Columns.AddRange(this.colIsLocal, this.colPodName, this.colSquad, this.colType, this.colMacAddress, this.colIPAddress, this.colSubnet, this.colGateway, this.colDNSServer, this.colHostName, this.colOperationProgress);
		this.dgvPods.ContextMenuStrip = this.cmnuDataGrid;
		this.dgvPods.Location = new System.Drawing.Point(12, 12);
		this.dgvPods.Name = "dgvPods";
		this.dgvPods.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
		this.dgvPods.Size = new System.Drawing.Size(1106, 395);
		this.dgvPods.TabIndex = 0;
		this.dgvPods.VirtualMode = true;
		this.dgvPods.UserDeletingRow += new System.Windows.Forms.DataGridViewRowCancelEventHandler(dgvPods_UserDeletingRow);
		this.dgvPods.CellMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(dgvPods_CellMouseClick);
		this.dgvPods.CancelRowEdit += new System.Windows.Forms.QuestionEventHandler(dgvPods_CancelRowEdit);
		this.dgvPods.CellValueNeeded += new System.Windows.Forms.DataGridViewCellValueEventHandler(dgvPods_CellValueNeeded);
		this.dgvPods.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(dgvPods_CellFormatting);
		this.dgvPods.CellValidating += new System.Windows.Forms.DataGridViewCellValidatingEventHandler(dgvPods_CellValidating);
		this.dgvPods.RowValidated += new System.Windows.Forms.DataGridViewCellEventHandler(dgvPods_RowValidated);
		this.dgvPods.CellPainting += new System.Windows.Forms.DataGridViewCellPaintingEventHandler(dgvPods_CellPainting);
		this.dgvPods.CellValuePushed += new System.Windows.Forms.DataGridViewCellValueEventHandler(dgvPods_CellValuePushed);
		this.dgvPods.NewRowNeeded += new System.Windows.Forms.DataGridViewRowEventHandler(dgvPods_NewRowNeeded);
		this.colIsLocal.HeaderText = "Local";
		this.colIsLocal.MinimumWidth = 40;
		this.colIsLocal.Name = "colIsLocal";
		this.colIsLocal.ReadOnly = true;
		this.colIsLocal.Resizable = System.Windows.Forms.DataGridViewTriState.False;
		this.colIsLocal.Width = 40;
		this.colPodName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
		this.colPodName.HeaderText = "Pod";
		this.colPodName.MinimumWidth = 100;
		this.colPodName.Name = "colPodName";
		this.colSquad.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
		this.colSquad.HeaderText = "Squad";
		this.colSquad.MinimumWidth = 75;
		this.colSquad.Name = "colSquad";
		this.colSquad.Width = 75;
		this.colType.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
		this.colType.HeaderText = "Type";
		this.colType.MinimumWidth = 100;
		this.colType.Name = "colType";
		this.colMacAddress.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
		this.colMacAddress.HeaderText = "MAC Address";
		this.colMacAddress.MinimumWidth = 75;
		this.colMacAddress.Name = "colMacAddress";
		this.colMacAddress.ReadOnly = true;
		this.colMacAddress.Width = 88;
		this.colIPAddress.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
		this.colIPAddress.HeaderText = "IP Address";
		this.colIPAddress.MinimumWidth = 75;
		this.colIPAddress.Name = "colIPAddress";
		this.colIPAddress.ReadOnly = true;
		this.colIPAddress.Width = 77;
		this.colSubnet.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
		this.colSubnet.HeaderText = "Subnet Mask";
		this.colSubnet.MinimumWidth = 75;
		this.colSubnet.Name = "colSubnet";
		this.colSubnet.ReadOnly = true;
		this.colSubnet.Width = 88;
		this.colGateway.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
		this.colGateway.HeaderText = "Default Gateway";
		this.colGateway.MinimumWidth = 75;
		this.colGateway.Name = "colGateway";
		this.colGateway.ReadOnly = true;
		this.colGateway.Width = 102;
		this.colDNSServer.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
		this.colDNSServer.HeaderText = "DNS Server";
		this.colDNSServer.MinimumWidth = 75;
		this.colDNSServer.Name = "colDNSServer";
		this.colDNSServer.ReadOnly = true;
		this.colDNSServer.Width = 82;
		this.colHostName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
		this.colHostName.HeaderText = "Host Name";
		this.colHostName.MinimumWidth = 75;
		this.colHostName.Name = "colHostName";
		this.colHostName.ReadOnly = true;
		this.colHostName.Width = 79;
		this.colOperationProgress.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
		this.colOperationProgress.HeaderText = "Operation Progress";
		this.colOperationProgress.MinimumWidth = 150;
		this.colOperationProgress.Name = "colOperationProgress";
		this.colOperationProgress.ReadOnly = true;
		this.colOperationProgress.Resizable = System.Windows.Forms.DataGridViewTriState.True;
		this.colOperationProgress.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
		this.cmnuDataGrid.Items.AddRange(new System.Windows.Forms.ToolStripItem[6] { this.deletePodToolStripMenuItem, this.installProductToolStripMenuItem, this.uninstallProductToolStripMenuItem, this.resendPodConfigurationToolStripMenuItem, this.importSiteConfigurationToolStripMenuItem, this.exportSiteConfigurationToolStripMenuItem });
		this.cmnuDataGrid.Name = "cmnuDataGrid";
		this.cmnuDataGrid.Size = new System.Drawing.Size(219, 136);
		this.cmnuDataGrid.Opening += new System.ComponentModel.CancelEventHandler(cmnuDataGrid_Opening);
		this.deletePodToolStripMenuItem.Image = TeslaConsole.Properties.Resources.DeleteHS;
		this.deletePodToolStripMenuItem.Name = "deletePodToolStripMenuItem";
		this.deletePodToolStripMenuItem.Size = new System.Drawing.Size(218, 22);
		this.deletePodToolStripMenuItem.Text = "Delete";
		this.deletePodToolStripMenuItem.Click += new System.EventHandler(deletePodToolStripMenuItem_Click);
		this.installProductToolStripMenuItem.Image = TeslaConsole.Properties.Resources.install;
		this.installProductToolStripMenuItem.Name = "installProductToolStripMenuItem";
		this.installProductToolStripMenuItem.Size = new System.Drawing.Size(218, 22);
		this.installProductToolStripMenuItem.Text = "Install Product";
		// Install Product children are built dynamically from AppRegistry (see BuildInstallProductMenu).
		this.uninstallProductToolStripMenuItem.Name = "uninstallProductToolStripMenuItem";
		this.uninstallProductToolStripMenuItem.Size = new System.Drawing.Size(218, 22);
		this.uninstallProductToolStripMenuItem.Text = "Uninstall Product";
		this.resendPodConfigurationToolStripMenuItem.Name = "resendPodConfigurationToolStripMenuItem";
		this.resendPodConfigurationToolStripMenuItem.Size = new System.Drawing.Size(218, 22);
		this.resendPodConfigurationToolStripMenuItem.Text = "Reconfigure...";
		this.resendPodConfigurationToolStripMenuItem.Visible = false;
		this.resendPodConfigurationToolStripMenuItem.Click += new System.EventHandler(resendPodConfigurationToolStripMenuItem_Click);
		this.importSiteConfigurationToolStripMenuItem.Image = TeslaConsole.Properties.Resources.openHS;
		this.importSiteConfigurationToolStripMenuItem.Name = "importSiteConfigurationToolStripMenuItem";
		this.importSiteConfigurationToolStripMenuItem.Size = new System.Drawing.Size(218, 22);
		this.importSiteConfigurationToolStripMenuItem.Text = "Import Site Configuration...";
		this.importSiteConfigurationToolStripMenuItem.Click += new System.EventHandler(importSiteConfigurationToolStripMenuItem_Click);
		this.exportSiteConfigurationToolStripMenuItem.Image = TeslaConsole.Properties.Resources.saveHS;
		this.exportSiteConfigurationToolStripMenuItem.Name = "exportSiteConfigurationToolStripMenuItem";
		this.exportSiteConfigurationToolStripMenuItem.Size = new System.Drawing.Size(218, 22);
		this.exportSiteConfigurationToolStripMenuItem.Text = "Export Site Configuration...";
		this.exportSiteConfigurationToolStripMenuItem.Click += new System.EventHandler(exportSiteConfigurationToolStripMenuItem_Click);
		this.dlgOpenFile.DefaultExt = "siteconfig";
		this.dlgOpenFile.Filter = "Site Configuration Files (*.siteconfig)|*.siteconfig|All Files (*.*)|*.*";
		this.dlgOpenFile.Title = "Import Configuration";
		this.dlgSaveFile.DefaultExt = "siteconfig";
		this.dlgSaveFile.Filter = "Site Configuration Files (*.siteconfig)|*.siteconfig|All Files (*.*)|*.*";
		this.dlgSaveFile.Title = "Export Configuration";
		this.dlgSelectPackage.Filter = "VWE Install Archive (*.zip)|*.zip|All Files (*.*)|*.*";
		this.dlgSelectPackage.Title = "Select Package to Install";
		this.flpPodsToConfigure.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
		this.flpPodsToConfigure.Location = new System.Drawing.Point(12, 413);
		this.flpPodsToConfigure.Name = "flpPodsToConfigure";
		this.flpPodsToConfigure.Size = new System.Drawing.Size(1106, 27);
		this.flpPodsToConfigure.TabIndex = 1;
		base.AutoScaleDimensions = new System.Drawing.SizeF(6f, 13f);
		base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
		base.ClientSize = new System.Drawing.Size(1130, 452);
		base.Controls.Add(this.flpPodsToConfigure);
		base.Controls.Add(this.dgvPods);
		base.Name = "SiteManagement";
		base.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
		this.Text = "Site Management";
		base.Load += new System.EventHandler(SiteManagement_Load);
		base.FormClosing += new System.Windows.Forms.FormClosingEventHandler(SiteManagement_FormClosing);
		((System.ComponentModel.ISupportInitialize)this.dgvPods).EndInit();
		this.cmnuDataGrid.ResumeLayout(false);
		base.ResumeLayout(false);
	}

	public SiteManagement()
	{
		InitializeComponent();
		LoadConfiguration(TeslaConsole.Site.Active);
		BuildInstallProductMenu();
		foreach (string activeConfigRequest in PodManager.ActiveConfigRequests)
		{
			PodManager_PodReadyForConfig(activeConfigRequest, PodManager.GetMacAddressForRequest(activeConfigRequest));
		}
		PodManager.PodReadyForConfig += PodManager_PodReadyForConfig;
		PodManager.PodConfigured += PodManager_PodConfigured;
	}

	protected override void OnClosing(CancelEventArgs e)
	{
		if (dgvPods.IsCurrentCellInEditMode)
		{
			MessageBox.Show("You can not close this window while a cell is being edited.", "Currently Editing", MessageBoxButtons.OK);
			e.Cancel = true;
		}
		base.OnClosing(e);
	}

	private void PodManager_PodReadyForConfig(string requestId, byte[] macAddress)
	{
		if (base.InvokeRequired)
		{
			Invoke(new PodManager.PodReadyConfigHandler(PodManager_PodReadyForConfig), requestId, macAddress);
			return;
		}
		PodData podData = null;
		foreach (PodData mPod in mPods)
		{
			if (mPod.Pod.MacAddressEquals(macAddress))
			{
				podData = mPod;
				break;
			}
		}
		Button button = new Button();
		button.Image = Resources.PodOffline16;
		if (podData == null)
		{
			button.Text = "Configure " + requestId;
			button.Tag = new Tuple<string, byte[]>(requestId, macAddress);
		}
		else
		{
			button.Text = "Configure " + podData.Pod.Name;
			button.Tag = new Tuple<string, PodData>(requestId, podData);
		}
		button.ImageAlign = ContentAlignment.MiddleLeft;
		button.TextAlign = ContentAlignment.MiddleLeft;
		button.TextImageRelation = TextImageRelation.ImageBeforeText;
		button.AutoSize = true;
		button.AutoSizeMode = AutoSizeMode.GrowAndShrink;
		button.Click += ConfigureButton_Click;
		flpPodsToConfigure.Controls.Add(button);
	}

	private void PodManager_PodConfigured(string requestId, byte[] macAddress)
	{
		if (mConfigureButtons.ContainsKey(requestId))
		{
			Button value = mConfigureButtons[requestId];
			mConfigureButtons.Remove(requestId);
			flpPodsToConfigure.Controls.Remove(value);
		}
	}

	private void ConfigureButton_Click(object sender, EventArgs e)
	{
		Button button = sender as Button;
		if (button.Tag is Tuple<string, PodData>)
		{
			Tuple<string, PodData> tuple = button.Tag as Tuple<string, PodData>;
			string text = Interaction.InputBox("Enter passphrase for " + tuple.B.Pod.Name, "Configure " + tuple.B.Pod.Name);
			if (!string.IsNullOrEmpty(text))
			{
				Label label = new Label();
				label.Text = "Configuring " + tuple.B.Pod.Name + "...";
				label.AutoSize = false;
				label.Size = new Size((int)((double)button.Width * 1.5), button.Height);
				label.BorderStyle = BorderStyle.FixedSingle;
				label.BackColor = Color.SkyBlue;
				label.TextAlign = ContentAlignment.MiddleLeft;
				flpPodsToConfigure.Controls.Remove(button);
				mConfigureButtons.Remove(tuple.A);
				flpPodsToConfigure.Controls.Add(label);
				mConfigureLabels.Add(tuple.B.Pod.ID, label);
				ConfigurePod(tuple.A, text.ToUpper(), tuple.B.Pod, tuple.B.Squad);
			}
		}
		else
		{
			if (!(button.Tag is Tuple<string, byte[]>))
			{
				return;
			}
			Tuple<string, byte[]> tuple2 = button.Tag as Tuple<string, byte[]>;
			Pod pod = new Pod();
			pod.MacAddress = tuple2.B;
			SetupPod setupPod;
			string text2;
			while (true)
			{
				setupPod = new SetupPod(tuple2.A, pod, TeslaConsole.Site.Active.Squads);
				if (setupPod.ShowDialog(this) == DialogResult.OK)
				{
					Label label2 = new Label();
					label2.Text = "Configuring " + pod.Name + "...";
					label2.AutoSize = false;
					label2.Size = new Size((int)((double)button.Width * 1.5), button.Height);
					label2.BorderStyle = BorderStyle.FixedSingle;
					label2.BackColor = Color.SlateBlue;
					flpPodsToConfigure.Controls.Remove(button);
					mConfigureButtons.Remove(tuple2.A);
					flpPodsToConfigure.Controls.Add(label2);
					mConfigureLabels.Add(pod.ID, label2);
					text2 = setupPod.Squad.Name;
					if (!(setupPod.Squad.Guid == Guid.Empty))
					{
						break;
					}
					text2 = Interaction.InputBox("Enter the name of the new squad:", "New Squad");
					if (!string.IsNullOrEmpty(text2))
					{
						Squad squad = new Squad(setupPod.Squad.Name);
						TeslaConsole.Site.Active.Squads.Add(squad);
						colSquad.Items.Add(squad.Name);
						break;
					}
				}
			}
			ConfigurePod(tuple2.A, setupPod.Passphrase, setupPod.Pod, text2);
		}
	}

	private void ConfigurePod(string requestId, string passphrase, Pod pod, string squadName)
	{
		BackgroundWorker backgroundWorker = new BackgroundWorker();
		backgroundWorker.DoWork += ConfigureWorker_DoWork;
		backgroundWorker.RunWorkerCompleted += ConfigureWorker_RunWorkerCompleted;
		backgroundWorker.RunWorkerAsync(new Tuple<string, string, Pod, string>(requestId, passphrase, pod, squadName));
	}

	private void ConfigureWorker_DoWork(object sender, DoWorkEventArgs e)
	{
		Tuple<string, string, Pod, string> tuple = (Tuple<string, string, Pod, string>)e.Argument;
		tuple.C.Key = PodManager.ConfigurePod(tuple.A, tuple.B, tuple.C);
		if (tuple.C.Key == null)
		{
			e.Result = new PodConfigurationException("Passphrase was incorrect.", tuple.C);
		}
		else
		{
			e.Result = new Tuple<Pod, string>(tuple.C, tuple.D);
		}
	}

	private void ConfigureWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
	{
		if (e.Result is PodConfigurationException)
		{
			PodConfigurationException ex = e.Result as PodConfigurationException;
			MessageBox.Show(this, "There was an error configuring " + ex.Pod.Name + ":" + Environment.NewLine + ex.Message, "Configure " + ex.Pod.Name, MessageBoxButtons.OK, MessageBoxIcon.Hand);
			Label value = mConfigureLabels[ex.Pod.ID];
			flpPodsToConfigure.Controls.Remove(value);
			mConfigureLabels.Remove(ex.Pod.ID);
		}
		else
		{
			if (!(e.Result is Tuple<Pod, string>))
			{
				return;
			}
			Tuple<Pod, string> tuple = e.Result as Tuple<Pod, string>;
			MessageBox.Show(this, tuple.A.Name + " successfully configured!", "Configure " + tuple.A.Name, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
			Label value2 = mConfigureLabels[tuple.A.ID];
			flpPodsToConfigure.Controls.Remove(value2);
			mConfigureLabels.Remove(tuple.A.ID);
			foreach (PodData mPod in mPods)
			{
				if (mPod.Pod.ID == tuple.A.ID)
				{
					return;
				}
			}
			PodData podData = new PodData(tuple.A, tuple.B, this);
			podData.StartPing();
			mPods.Add(podData);
			List<PodData> list = new List<PodData>(mPods);
			dgvPods.Rows.Clear();
			mPods.Clear();
			mPods = list;
			dgvPods.RowCount = mPods.Count + 1;
		}
	}

	private void SiteManagement_Load(object sender, EventArgs e)
	{
		mIsOpen = true;
	}

	private void SiteManagement_FormClosing(object sender, FormClosingEventArgs e)
	{
		foreach (PodData mPod in mPods)
		{
			if (e.CloseReason == CloseReason.UserClosing && mPod.OperationInProgress && mPod.Status.StartsWith("Installing"))
			{
				MessageBox.Show(this, "Site Management cannot be closed while installations are in progress.", "Site Management", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				e.Cancel = true;
				return;
			}
		}
		PodManager.PodReadyForConfig -= PodManager_PodReadyForConfig;
		foreach (Squad squad in mSite.Squads)
		{
			squad.Pods.Clear();
		}
		foreach (PodData mPod2 in mPods)
		{
			mPod2.StopPing();
			foreach (Squad squad2 in mSite.Squads)
			{
				if (squad2.Name == mPod2.Squad)
				{
					squad2.Pods.Add(mPod2.Pod);
				}
			}
		}
		mSite.Save();
		mIsOpen = false;
	}

	private void dgvPods_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
	{
		if (colOperationProgress.Index != e.ColumnIndex || e.RowIndex < 0 || e.RowIndex >= mPods.Count || (string)e.FormattedValue != "draw_progress")
		{
			return;
		}
		e.Handled = true;
		e.PaintBackground(e.ClipBounds, cellsPaintSelectionBackground: false);
		PodData podData = mPods[e.RowIndex];
		Rectangle rectangle = Rectangle.Inflate(e.CellBounds, -3, -3);
		Rectangle rectangle2 = new Rectangle(rectangle.Location, rectangle.Size);
		rectangle2.Inflate(-1, -1);
		if (podData.PercentProgress >= 0)
		{
			rectangle2.Width = (int)Math.Round((double)podData.PercentProgress / 100.0 * (double)rectangle2.Width);
			if (ProgressBarRenderer.IsSupported)
			{
				ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rectangle);
				ProgressBarRenderer.DrawHorizontalChunks(e.Graphics, rectangle2);
			}
			else
			{
				e.Graphics.FillRectangle(Brushes.LightGray, rectangle);
				e.Graphics.FillRectangle(Brushes.Green, rectangle2);
				e.Graphics.DrawRectangle(Pens.Black, rectangle);
			}
		}
		StringFormat stringFormat = new StringFormat(StringFormatFlags.NoWrap);
		stringFormat.Alignment = StringAlignment.Near;
		stringFormat.LineAlignment = StringAlignment.Center;
		e.Graphics.DrawString(podData.Status, Font, Brushes.Black, rectangle, stringFormat);
	}

	private void dgvPods_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
	{
		if (e.RowIndex < 0)
		{
			return;
		}
		if (colMacAddress.Index == e.ColumnIndex)
		{
			if (e.Value is byte[] array)
			{
				string[] array2 = new string[array.Length];
				for (int i = 0; i < array2.Length; i++)
				{
					array2[i] = array[i].ToString("x2");
				}
				e.Value = string.Join("-", array2);
				e.FormattingApplied = true;
			}
		}
		else
		{
			if (colOperationProgress.Index != e.ColumnIndex)
			{
				return;
			}
			if (e.RowIndex < mPods.Count && mPods[e.RowIndex].Pod.IsLocal)
			{
				PodData podData = mPods[e.RowIndex];
				if (podData.Error != null)
				{
					e.Value = "Install Failed";
					e.CellStyle.BackColor = Color.Red;
					e.CellStyle.ForeColor = Color.White;
				}
				else if (!podData.OperationInProgress)
				{
					if (podData.PingReply == null)
					{
						e.Value = "Idle. [pinging...]";
					}
					else if (podData.PingReply.Status == IPStatus.Success)
					{
						if (!podData.Conn.IsConnected)
						{
							e.Value = "Could not connect to pod service.";
						}
						else
						{
							e.Value = $"Idle [{podData.PingReply.RoundtripTime} ms]";
						}
					}
					else
					{
						e.Value = $"Pod unreachable. Ping result: {podData.PingReply.Status}";
					}
				}
				else
				{
					e.Value = "draw_progress";
				}
			}
			else
			{
				e.Value = "";
			}
			e.FormattingApplied = true;
		}
	}

	private void dgvPods_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
	{
		if (e.ColumnIndex < 0 || e.RowIndex < 0 || e.RowIndex >= dgvPods.Rows.Count)
		{
			return;
		}
		DataGridViewRow dataGridViewRow = dgvPods.Rows[e.RowIndex];
		if (e.ColumnIndex >= dataGridViewRow.Cells.Count)
		{
			return;
		}
		DataGridViewCell dataGridViewCell = dataGridViewRow.Cells[e.ColumnIndex];
		if (e.ColumnIndex == colPodName.Index)
		{
			if (!dgvPods.Rows[e.RowIndex].IsNewRow && (e.FormattedValue == null || (string)e.FormattedValue == ""))
			{
				dataGridViewCell.ErrorText = "Pod name cannot be blank";
			}
			else
			{
				dataGridViewCell.ErrorText = "";
			}
		}
	}

	private void dgvPods_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
	{
		if (e.Button == MouseButtons.Right && e.RowIndex >= 0 && e.RowIndex < dgvPods.Rows.Count && e.RowIndex != dgvPods.NewRowIndex)
		{
			if (dgvPods.SelectedRows.Count > 0)
			{
				dgvPods.SelectedRows[0].Selected = false;
			}
			dgvPods.Rows[e.RowIndex].Selected = true;
			int num = ((e.ColumnIndex >= 0) ? dgvPods.GetColumnDisplayRectangle(e.ColumnIndex, cutOverflow: true).X : (num = e.Location.X));
			int num2 = dgvPods.GetRowDisplayRectangle(e.RowIndex, cutOverflow: true).Y;
			cmnuDataGrid.Show(dgvPods, num + e.X, num2 + e.Y);
		}
	}

	private void dgvPods_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
	{
		if (e.RowIndex != dgvPods.Rows.Count - 1)
		{
			PodData podData = ((e.RowIndex != mRowInEdit) ? mPods[e.RowIndex] : mPodInEdit);
			if (e.ColumnIndex == colIsLocal.Index)
			{
				e.Value = podData.Pod.IsLocal;
			}
			else if (e.ColumnIndex == colPodName.Index)
			{
				e.Value = podData.Pod.Name;
			}
			else if (e.ColumnIndex == colSquad.Index)
			{
				e.Value = podData.Squad;
			}
			else if (e.ColumnIndex == colType.Index)
			{
				e.Value = (HostTypeHelper)podData.Pod.HostType;
			}
			else if (e.ColumnIndex == colMacAddress.Index)
			{
				e.Value = podData.Pod.MacAddress;
			}
			else if (e.ColumnIndex == colIPAddress.Index)
			{
				e.Value = podData.Pod.IPAddress;
				dgvPods.Rows[e.RowIndex].Cells[e.ColumnIndex].ReadOnly = podData.Pod.IsLocal;
			}
			else if (e.ColumnIndex == colSubnet.Index)
			{
				e.Value = podData.Pod.Subnet;
			}
			else if (e.ColumnIndex == colGateway.Index)
			{
				e.Value = podData.Pod.Gateway;
			}
			else if (e.ColumnIndex == colDNSServer.Index)
			{
				e.Value = podData.Pod.DNS;
			}
			else if (e.ColumnIndex == colHostName.Index)
			{
				e.Value = podData.Pod.HostName;
			}
		}
	}

	private void dgvPods_CellValuePushed(object sender, DataGridViewCellValueEventArgs e)
	{
		PodData podData = null;
		if (e.RowIndex < mPods.Count)
		{
			if (mPodInEdit == null)
			{
				mPodInEdit = new PodData(mPods[e.RowIndex].Pod.Clone(), mPods[e.RowIndex].Squad, this);
			}
			podData = mPodInEdit;
			mRowInEdit = e.RowIndex;
		}
		else
		{
			podData = mPodInEdit;
		}
		if (e.ColumnIndex == colPodName.Index)
		{
			podData.Pod.Name = (string)e.Value;
		}
		else if (e.ColumnIndex == colSquad.Index)
		{
			podData.Squad = (string)e.Value;
		}
		else if (e.ColumnIndex == colType.Index)
		{
			podData.Pod.HostType = ((e.Value is string) ? HostTypeHelper.Parse((string)e.Value).HostType : ((HostTypeHelper)e.Value).HostType);
		}
		else if (e.ColumnIndex == colIPAddress.Index)
		{
			if (IPAddress.TryParse((string)e.Value, out var address))
			{
				podData.Pod.IPAddress = address;
			}
			else
			{
				MessageBox.Show("Address could not be parsed.", "Parsing Error", MessageBoxButtons.OK);
			}
		}
	}

	private void dgvPods_NewRowNeeded(object sender, DataGridViewRowEventArgs e)
	{
		mPodInEdit = new PodData(new Pod(), (mSite.Squads.Count > 0) ? mSite.Squads[0].Name : "", this);
		mRowInEdit = dgvPods.Rows.Count - 1;
		e.Row.Cells[colIPAddress.Index].ReadOnly = false;
	}

	private void dgvPods_RowValidated(object sender, DataGridViewCellEventArgs e)
	{
		if (e.RowIndex >= mPods.Count && e.RowIndex != dgvPods.Rows.Count - 1)
		{
			if (mPodInEdit.Pod.IsLocal)
			{
				mPodInEdit.StartPing();
			}
			mPods.Add(mPodInEdit);
			mPodInEdit = null;
			mRowInEdit = -1;
		}
		else if (mPodInEdit != null && e.RowIndex < mPods.Count)
		{
			if (mPodInEdit.Pod.IsLocal)
			{
				mPodInEdit.StartPing();
			}
			if (mPods[e.RowIndex] != null)
			{
				mPods[e.RowIndex].StopPing();
			}
			mPods[e.RowIndex] = mPodInEdit;
			mPodInEdit = null;
			mRowInEdit = -1;
		}
		else if (dgvPods.ContainsFocus)
		{
			mPodInEdit = null;
			mRowInEdit = -1;
		}
	}

	private void dgvPods_CancelRowEdit(object sender, QuestionEventArgs e)
	{
		if (mRowInEdit == dgvPods.Rows.Count - 2 && mRowInEdit == mPods.Count)
		{
			mPodInEdit = new PodData(new Pod(), mSite.Squads[0].Name, this);
			return;
		}
		mPodInEdit = null;
		mRowInEdit = -1;
	}

	private void dgvPods_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
	{
		if (e.Row.Index < mPods.Count)
		{
			if (mPods[e.Row.Index].OperationInProgress)
			{
				e.Cancel = true;
				return;
			}
			Pod pod = mPods[e.Row.Index].Pod;
			if (MessageBox.Show(this, "Are you sure you want to delete " + pod.Name + "?", "Site Management", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
			{
				e.Cancel = true;
				return;
			}
			mPods[e.Row.Index].StopPing();
			mPods.RemoveAt(e.Row.Index);
		}
		if (e.Row.Index == mRowInEdit)
		{
			mRowInEdit = -1;
			mPodInEdit = null;
		}
	}

	private void cmnuDataGrid_Opening(object sender, CancelEventArgs e)
	{
		int num = 0;
		int num2 = 0;
		List<LaunchData> list = null;
		foreach (DataGridViewRow selectedRow in dgvPods.SelectedRows)
		{
			if (selectedRow.Index >= mPods.Count)
			{
				continue;
			}
			if (mPods[selectedRow.Index].Pod.IsLocal && !mPods[selectedRow.Index].OperationInProgress && mPods[selectedRow.Index].PingReply != null && mPods[selectedRow.Index].PingReply.Status == IPStatus.Success && mPods[selectedRow.Index].Conn.IsConnected)
			{
				num++;
			}
			if (!mPods[selectedRow.Index].OperationInProgress)
			{
				num2++;
			}
			if (list == null)
			{
				list = new List<LaunchData>();
				if (mPods[selectedRow.Index].Pod.IsLocal)
				{
					LaunchData[] allApplications = mPods[selectedRow.Index].Conn.AllApplications;
					if (allApplications != null)
					{
						list.AddRange(allApplications);
					}
				}
			}
			else if (mPods[selectedRow.Index].Pod.IsLocal)
			{
				for (int num3 = list.Count - 1; num3 >= 0; num3--)
				{
					bool flag = false;
					LaunchData[] allApplications2 = mPods[selectedRow.Index].Conn.AllApplications;
					for (int i = 0; i < allApplications2.Length; i++)
					{
						LaunchData launchData = allApplications2[i];
						if (list[num3].LaunchPair.LaunchKey == launchData.LaunchPair.LaunchKey)
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						list.RemoveAt(num3);
					}
				}
			}
			else
			{
				list.Clear();
			}
		}
		deletePodToolStripMenuItem.Enabled = num2 > 0;
		installProductToolStripMenuItem.Enabled = num > 0;
		if (registerProductToolStripMenuItem != null)
		{
			registerProductToolStripMenuItem.Enabled = num > 0;
		}
		resendPodConfigurationToolStripMenuItem.Enabled = num > 0;
		uninstallProductToolStripMenuItem.Enabled = list != null && list.Count > 0;
		uninstallProductToolStripMenuItem.DropDownItems.Clear();
		if (list == null)
		{
			return;
		}
		foreach (LaunchData item in list)
		{
			ToolStripMenuItem toolStripMenuItem = new ToolStripMenuItem();
			toolStripMenuItem.Text = item.LaunchPair.DisplayName;
			toolStripMenuItem.Tag = item;
			toolStripMenuItem.Click += UninstallProduct_Click;
			uninstallProductToolStripMenuItem.DropDownItems.Add(toolStripMenuItem);
		}
	}

	/// <summary>
	/// Rebuilds the product-related context menus from the data-driven catalog (<see cref="AppRegistry"/>):
	///   • "Install Product"  → transfer a package and register its launch entries
	///   • "Register Product"  → push launch entries to pods over the network, no file install
	/// plus the "Add New Product..." management action.
	/// </summary>
	private void BuildInstallProductMenu()
	{
		// Lazily create the "Register Product" parent and place it after "Install Product".
		if (registerProductToolStripMenuItem == null)
		{
			registerProductToolStripMenuItem = new ToolStripMenuItem("Register Product on Pods");
			int insertAt = cmnuDataGrid.Items.IndexOf(installProductToolStripMenuItem) + 1;
			cmnuDataGrid.Items.Insert(insertAt, registerProductToolStripMenuItem);
		}

		installProductToolStripMenuItem.DropDownItems.Clear();
		registerProductToolStripMenuItem.DropDownItems.Clear();
		foreach (ProductDefinition product in AppRegistry.Products)
		{
			ToolStripMenuItem installItem = new ToolStripMenuItem(product.MenuText) { Tag = product };
			installItem.Click += InstallProduct_Click;
			installProductToolStripMenuItem.DropDownItems.Add(installItem);

			ToolStripMenuItem registerItem = new ToolStripMenuItem(product.Name) { Tag = product };
			registerItem.Click += RegisterProduct_Click;
			registerProductToolStripMenuItem.DropDownItems.Add(registerItem);
		}

		installProductToolStripMenuItem.DropDownItems.Add(new ToolStripSeparator());
		ToolStripMenuItem addItem = new ToolStripMenuItem("Add New Product...");
		addItem.Click += AddProduct_Click;
		installProductToolStripMenuItem.DropDownItems.Add(addItem);
	}

	/// <summary>Defines a new catalog product, persists it, and optionally pushes it to the selected pods.</summary>
	private void AddProduct_Click(object sender, EventArgs e)
	{
		using dlgAddProduct dialog = new dlgAddProduct();
		if (dialog.ShowDialog(this) != DialogResult.OK)
		{
			return;
		}
		AppRegistry.AddProduct(dialog.Product);
		BuildInstallProductMenu();

		if (!dialog.PushNow)
		{
			return;
		}
		if (dialog.PackagePath != null)
		{
			// Package supplied → full install (file transfer + entry registration on completion).
			foreach (int podIndex in SelectedInstallablePodIndices())
			{
				mPods[podIndex].Install_CustomResolution = null;
				mPods[podIndex].Install_HostTypes = new List<PodInstallType>();
				InstallProduct(podIndex, dialog.Product.Id, dialog.PackagePath);
			}
		}
		else
		{
			RegisterProductOnSelectedPods(dialog.Product);
		}
	}

	/// <summary>Pushes a catalog product's launch entries to selected connected pods without installing files.</summary>
	private void RegisterProduct_Click(object sender, EventArgs e)
	{
		ProductDefinition product = (ProductDefinition)((ToolStripMenuItem)sender).Tag;
		RegisterProductOnSelectedPods(product);
	}

	private void RegisterProductOnSelectedPods(ProductDefinition product)
	{
		int pushed = 0;
		int skipped = 0;
		foreach (int podIndex in SelectedInstallablePodIndices())
		{
			PodData pod = mPods[podIndex];
			if (!pod.Conn.IsConnected)
			{
				skipped++;
				continue;
			}
			foreach (LaunchEntryDefinition entry in product.Entries)
			{
				pod.Conn.AddApp(entry.ToLaunchData(null));
			}
			pod.Status = "Registered " + product.Name;
			dgvPods.InvalidateCell(colOperationProgress.Index, podIndex);
			pushed++;
		}
		if (skipped > 0)
		{
			MessageBox.Show(this,
				$"Registered \"{product.Name}\" on {pushed} pod(s). {skipped} selected pod(s) were skipped because they are not connected.",
				"Register Product", MessageBoxButtons.OK, MessageBoxIcon.Information);
		}
	}

	/// <summary>Indices of selected rows that are local, idle pods eligible for install/registration.</summary>
	private IEnumerable<int> SelectedInstallablePodIndices()
	{
		foreach (DataGridViewRow selectedRow in dgvPods.SelectedRows)
		{
			if (selectedRow.Index < mPods.Count && mPods[selectedRow.Index].Pod.IsLocal && !mPods[selectedRow.Index].OperationInProgress)
			{
				yield return selectedRow.Index;
			}
		}
	}

	/// <summary>Generic install handler: selects a package, optionally prompts for roles/resolution, installs to selected local pods.</summary>
	private void InstallProduct_Click(object sender, EventArgs e)
	{
		ProductDefinition product = (ProductDefinition)((ToolStripMenuItem)sender).Tag;
		dlgSelectPackage.Title = "Select " + product.Name + " Install Package";
		if (dlgSelectPackage.ShowDialog(this) != DialogResult.OK)
		{
			return;
		}
		Size? resolution = null;
		List<PodInstallType> hostTypes = new List<PodInstallType>();
		if (product.HostTypeDialog)
		{
			using dlgOptionalStartParams startParams = new dlgOptionalStartParams();
			if (startParams.ShowDialog(this) != DialogResult.OK)
			{
				return;
			}
			resolution = startParams.Resolution;
			if (startParams.IsGameClient)
			{
				hostTypes.Add(PodInstallType.GameClient);
			}
			if (startParams.IsLiveCam)
			{
				hostTypes.Add(PodInstallType.LiveCamera);
			}
			if (startParams.IsMissionReview)
			{
				hostTypes.Add(PodInstallType.MissionReview);
			}
		}
		foreach (int podIndex in SelectedInstallablePodIndices())
		{
			mPods[podIndex].Install_CustomResolution = resolution;
			mPods[podIndex].Install_HostTypes = new List<PodInstallType>(hostTypes);
			InstallProduct(podIndex, product.Id, dlgSelectPackage.FileName);
		}
	}

	private void Pod_PingCompleted(object sender, PingCompletedEventArgs e)
	{
		PodData podData = e.UserState as PodData;
		podData.OperationInProgress = false;
		podData.Error = e.Error;
		podData.PingReply = e.Reply;
		if (e.Reply.Status == IPStatus.Success)
		{
			podData.Conn.ConnectAsync(podData);
		}
		podData.StartPing();
		int num = mPods.IndexOf(podData);
		if (num >= 0 && num < dgvPods.Rows.Count)
		{
			dgvPods.InvalidateRow(num);
		}
	}

	private void Pod_PingCompleted(PodData pod)
	{
		if (base.InvokeRequired)
		{
			BeginInvoke(new Action<PodData>(Pod_PingCompleted), pod);
			return;
		}
		if (!pod.Conn.IsConnecting && !pod.Conn.IsConnected && pod.PingReply != null && pod.PingReply.Status == IPStatus.Success)
		{
			pod.Conn.ConnectAsync(pod);
		}
		int num = mPods.IndexOf(pod);
		if (num >= 0 && num < dgvPods.Rows.Count)
		{
			dgvPods.InvalidateRow(num);
		}
	}

	private void PodInfo_InstallProductProgress(InstallProductProgressEventArgs e)
	{
		Tuple<PodData, Guid> tuple = e.UserState as Tuple<PodData, Guid>;
		tuple.A.PercentProgress = e.ProgressPercentage;
		ProductDefinition product = AppRegistry.GetProduct(tuple.B);
		tuple.A.Status = "Installing " + (product?.Name ?? "product") + ": " + e.Status;
		dgvPods.InvalidateCell(colOperationProgress.Index, mPods.IndexOf(tuple.A));
	}

	private void PodInfo_InstallProductCompleted(object sender, InstallProductCompletedEventArgs e)
	{
		Tuple<PodData, Guid> tuple = e.UserState as Tuple<PodData, Guid>;
		PodData a = tuple.A;
		foreach (LaunchData appData in BuildLaunchData(tuple.B, a))
		{
			a.Conn.AddApp(appData);
		}
		a.OperationInProgress = false;
		a.Error = e.Error;
		dgvPods.InvalidateCell(colOperationProgress.Index, mPods.IndexOf(a));
	}

	/// <summary>
	/// Builds the launch entries a product registers on a pod, honoring (for host-type products)
	/// the roles selected during install. Returns empty if the product is unknown.
	/// </summary>
	private static List<LaunchData> BuildLaunchData(Guid productId, PodData pod)
	{
		List<LaunchData> list = new List<LaunchData>();
		ProductDefinition product = AppRegistry.GetProduct(productId);
		if (product == null)
		{
			return list;
		}
		foreach (LaunchEntryDefinition entry in product.Entries)
		{
			if (product.HostTypeDialog && entry.HostType != AppHostType.None
				&& !pod.Install_HostTypes.Contains(ToInstallType(entry.HostType)))
			{
				continue;
			}
			list.Add(entry.ToLaunchData(pod.Install_CustomResolution));
		}
		return list;
	}

	private static PodInstallType ToInstallType(AppHostType hostType)
	{
		return hostType switch
		{
			AppHostType.LiveCamera => PodInstallType.LiveCamera,
			AppHostType.MissionReview => PodInstallType.MissionReview,
			_ => PodInstallType.GameClient,
		};
	}

	private void PodInfo_UninstallProductCompleted(object sender, AsyncCompletedEventArgs e)
	{
		PodData podData = (PodData)e.UserState;
		podData.OperationInProgress = false;
		podData.Error = e.Error;
		podData.Status = "Uninstall completed!";
		dgvPods.InvalidateCell(colOperationProgress.Index, mPods.IndexOf(podData));
	}

	private void PodInfo_ConnectCompleted(object sender, AsyncCompletedEventArgs e)
	{
		PodData podData = e.UserState as PodData;
		if (e.Error != null)
		{
			podData.Error = e.Error;
			if (podData.PingReply != null && podData.PingReply.Status == IPStatus.Success)
			{
				new System.Threading.Timer(delegate(object state)
				{
					PodData podData2 = (PodData)state;
					if (!podData2.Conn.IsConnected && !podData2.Conn.IsConnecting)
					{
						((PodData)state).Conn.ConnectAsync((PodData)state);
					}
				}, podData, 5000, -1);
			}
		}
		else
		{
			podData.OperationInProgress = false;
		}
		int num = mPods.IndexOf(podData);
		if (num >= 0 && num < dgvPods.Rows.Count)
		{
			dgvPods.InvalidateRow(num);
		}
	}

	private void UninstallProduct_Click(object sender, EventArgs e)
	{
		ToolStripMenuItem toolStripMenuItem = (ToolStripMenuItem)sender;
		LaunchData launchData = (LaunchData)toolStripMenuItem.Tag;
		foreach (DataGridViewRow selectedRow in dgvPods.SelectedRows)
		{
			if (selectedRow.Index < mPods.Count && mPods[selectedRow.Index].Pod.IsLocal && !mPods[selectedRow.Index].OperationInProgress)
			{
				UninstallProduct(selectedRow.Index, launchData.LaunchPair.LaunchKey);
			}
		}
	}

	private void InstallProduct(int podIndex, Guid appId, string packageFilename)
	{
		PodInfo conn = mPods[podIndex].Conn;
		mPods[podIndex].OperationInProgress = true;
		mPods[podIndex].Error = null;
		mPods[podIndex].PercentProgress = 0;
		mPods[podIndex].Status = "";
		conn.InstallProductAsync(packageFilename, new Tuple<PodData, Guid>(mPods[podIndex], appId), PodInfo_InstallProductProgress);
	}

	private void UninstallProduct(int podIndex, Guid appId)
	{
		PodInfo conn = mPods[podIndex].Conn;
		mPods[podIndex].OperationInProgress = true;
		mPods[podIndex].Error = null;
		mPods[podIndex].PercentProgress = 0;
		mPods[podIndex].Status = "Uninstalling product(s)...";
		dgvPods.InvalidateCell(colOperationProgress.Index, podIndex);
		conn.UninstallProductAsync(appId, mPods[podIndex]);
	}

	private void LoadConfiguration(Site site)
	{
		mSite = site;
		dgvPods.Rows.Clear();
		mPods.Clear();
		foreach (Squad squad in site.Squads)
		{
			colSquad.Items.Add(squad.Name);
			foreach (Pod pod in squad.Pods)
			{
				PodData podData = new PodData(pod, squad.Name, this);
				mPods.Add(podData);
				if (pod.IsLocal)
				{
					podData.PercentProgress = -1;
					podData.OperationInProgress = true;
					podData.Status = "Pinging pod...";
					Ping ping = new Ping();
					ping.PingCompleted += Pod_PingCompleted;
					ping.SendAsync(pod.IPAddress, 10000, podData);
				}
			}
		}
		colType.Items.Add((HostTypeHelper)HostType.GameMachineHostType);
		colType.Items.Add((HostTypeHelper)HostType.MissionReviewHostType);
		dgvPods.RowCount = mPods.Count + 1;
		dgvPods.AutoResizeColumns();
	}

	private void importSiteConfigurationToolStripMenuItem_Click(object sender, EventArgs e)
	{
		if (MessageBox.Show(this, "Importing a site configuration will replace the current configuration. Are you sure you want to continue?", "Site Management", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes && dlgOpenFile.ShowDialog(this) == DialogResult.OK)
		{
			LoadConfiguration(TeslaConsole.Site.LoadFromFile(dlgOpenFile.FileName));
		}
	}

	private void exportSiteConfigurationToolStripMenuItem_Click(object sender, EventArgs e)
	{
		if (dlgSaveFile.ShowDialog(this) == DialogResult.OK)
		{
			mSite.SaveAs(dlgSaveFile.FileName);
		}
	}

	private void DeletePod(int rowIndex)
	{
		if (rowIndex < mPods.Count && !mPods[rowIndex].OperationInProgress)
		{
			dgvPods.Rows.RemoveAt(rowIndex);
			mPods[rowIndex].StopPing();
			mPods.RemoveAt(rowIndex);
		}
	}

	private void deletePodToolStripMenuItem_Click(object sender, EventArgs e)
	{
		if (dgvPods.SelectedRows.Count > 1)
		{
			if (MessageBox.Show(this, "Are you sure you want to delete these pods?", "Site Management", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
			{
				return;
			}
		}
		else if (dgvPods.CurrentRow.Index < mPods.Count && MessageBox.Show(this, "Are you sure you want to delete " + mPods[dgvPods.CurrentRow.Index].Pod.Name + "?", "Site Management", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
		{
			return;
		}
		for (int num = dgvPods.SelectedRows.Count - 1; num >= 0; num--)
		{
			DeletePod(dgvPods.SelectedRows[num].Index);
		}
	}

	private void resendPodConfigurationToolStripMenuItem_Click(object sender, EventArgs e)
	{
		if (dgvPods.SelectedRows.Count == 1)
		{
			if (MessageBox.Show(this, "Reconfiguring this pod will remove it from your site, allowing you to reconfigure it. Are you sure you want to continue?", "Reconfigure", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
			{
				return;
			}
		}
		else if (MessageBox.Show(this, "Reconfiguring these pods will remove them from your site, allowing you to reconfigure them. Are you sure you want to continue?", "Reconfigure", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
		{
			return;
		}
		List<PodData> list = new List<PodData>();
		foreach (DataGridViewRow selectedRow in dgvPods.SelectedRows)
		{
			if (selectedRow.Index >= mPods.Count)
			{
				continue;
			}
			PodData podData = mPods[selectedRow.Index];
			list.Add(podData);
			DeletePod(selectedRow.Index);
			foreach (Squad squad in mSite.Squads)
			{
				if (!(squad.Name == podData.Squad))
				{
					continue;
				}
				for (int num = squad.Pods.Count - 1; num >= 0; num--)
				{
					if (squad.Pods[num].ID == podData.Pod.ID)
					{
						squad.Pods.RemoveAt(num);
					}
				}
			}
		}
		mSite.Save();
		foreach (PodData item in list)
		{
			try
			{
				item.Conn.ClearStore();
			}
			catch (ConnectionLostException)
			{
				MessageBox.Show($"The data store on {item.Pod.Name} could not be cleared because the connection has been lost.  Please try again.", "Connection Lost");
			}
		}
	}
}
