using ModVersionChecker.data.model; using ModVersionChecker.managers.interfaces; using ModVersionChecker.utils; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Intrinsics.Arm; using System.Windows.Forms; namespace ModVersionChecker.forms { public class MainForm : Form { private readonly IConfigManager _configManager; private readonly IAppsManager _appsManager; private readonly IFormFactory _formFactory; private readonly IAppStatusManager _appStatusManager; private readonly IFlightSimsManager _fsManager; private readonly TableLayoutPanel _mainLayout; private readonly GlobalConfig _globalConfig; private List _apps = new List(); private ListView _listView; private ImageList _statusImageList = new ImageList(); public event EventHandler OnConfigChanged; public event EventHandler OnRecheck; private EventHandler onAppChangedHandler; private MenuStrip _menuStrip; private List _fsMods; private readonly Dictionary _fsModPathTextBoxes = new Dictionary(); public MainForm(IConfigManager configManager, IAppsManager appsManager, IFormFactory formFactory, IAppStatusManager appStatusManager, IFlightSimsManager fsManager) { _configManager = configManager ?? throw new ArgumentNullException(nameof(configManager)); _appsManager = appsManager ?? throw new ArgumentNullException(nameof(appsManager)); _formFactory = formFactory ?? throw new ArgumentNullException(nameof(formFactory)); _appStatusManager = appStatusManager ?? throw new ArgumentNullException(nameof(appStatusManager)); _fsManager = fsManager ?? throw new ArgumentNullException(nameof(fsManager)); _fsMods = _fsManager.Load(); _statusImageList.Images.Add("none", new Icon("Resources/ok-icon.ico")); _statusImageList.Images.Add("update", new Icon("Resources/up-icon.ico")); _statusImageList.Images.Add("error", new Icon("Resources/error-icon.ico")); Text = "Update Checker Configuration"; Size = new Size(600, 800); StartPosition = FormStartPosition.CenterScreen; _globalConfig = configManager.Load() ?? new GlobalConfig(); _mainLayout = GetMainLayout(); _mainLayout.Controls.Add(GetPathsPanel(), 0, 0); _listView = GetListView(); _listView.SmallImageList = _statusImageList; _mainLayout.Controls.Add(_listView , 0, 1); _mainLayout.Controls.Add(GetButtonsPanel(), 0, 2); onAppChangedHandler = (s2, e) => { UpdateListView(); OnConfigChanged?.Invoke(this, EventArgs.Empty); }; InitializeMenu(); } private TableLayoutPanel GetMainLayout() { // Initialize the main layout panel var mainLayout = new TableLayoutPanel { Dock = DockStyle.Fill, RowCount = 3, ColumnCount = 1 }; mainLayout.RowStyles.Add(new RowStyle(SizeType.Absolute, 150)); // Paths panel height mainLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 70)); // ListView takes remaining space mainLayout.RowStyles.Add(new RowStyle(SizeType.Absolute, 50)); // Button panel height Controls.Add(mainLayout); return mainLayout; } private FlowLayoutPanel GetPathsPanel() { var pathPanel = new FlowLayoutPanel { Dock = DockStyle.Fill, FlowDirection = FlowDirection.TopDown }; foreach (var fsMod in _fsMods) { var singlePathPanel = new FlowLayoutPanel { FlowDirection = FlowDirection.LeftToRight, AutoSize = true }; singlePathPanel.Controls.Add(new Label { Text = $"{fsMod.Name} Path:", Width = 100 }); var pathField = new TextBox { Text = fsMod.Path ?? "", Width = 300 }; singlePathPanel.Controls.Add(pathField); _fsModPathTextBoxes.Add(fsMod.ShortName, pathField); pathPanel.Controls.Add(singlePathPanel); } //var pathPanel2024 = new FlowLayoutPanel { FlowDirection = FlowDirection.LeftToRight, AutoSize = true }; //pathPanel2024.Controls.Add(new Label { Text = "MSFS 2024 Path:", Width = 100 }); //var msfs2024PathField = new TextBox { Text = _globalConfig.FsModPaths.ContainsKey("msfs2024") ? _globalConfig.FsModPaths["msfs2024"].Path : "", Width = 300 }; //pathPanel2024.Controls.Add(msfs2024PathField); //pathPanel.Controls.Add(pathPanel2024); var savePathsButton = new Button { Text = "Save Paths" }; savePathsButton.Click += (s, e) => { foreach (var fsMod in _fsMods) { fsMod.Path = _fsModPathTextBoxes[fsMod.ShortName].Text; _fsManager.Save(fsMod); } _fsMods = _fsManager.Load(); }; pathPanel.Controls.Add(savePathsButton); return pathPanel; } private ListView GetListView() { var listView = new ListView { Dock = DockStyle.Fill, View = View.Details, FullRowSelect = true, MultiSelect = false, Visible = true, Sorting = SortOrder.Ascending }; listView.Columns.Add("Name", 150); listView.Columns.Add("MSFS Versions", 100); listView.Columns.Add("Current", 80); listView.Columns.Add("Latest", 80); listView.Columns.Add("Last Checked", 150); listView.DoubleClick += (s, e) => { if (listView.SelectedItems.Count > 0) { ListViewItem selectedItem = listView.SelectedItems[0]; AppConfig? app = selectedItem.Tag as AppConfig; if (app == null) return; if (_appStatusManager.GetAppStatus(app.Id) == AppStatus.UpdateAvailable) { if (string.IsNullOrEmpty(app.DownloadUrl)) { MessageBox.Show("No download URL specified for this app."); return; } System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo { FileName = app.DownloadUrl, UseShellExecute = true }); } else { var form = _formFactory.CreateAppDetailsForm(app, true, onAppChangedHandler); form.FormClosed += (s2, e) => { UpdateListView(); }; UpdateListView(); form.ShowDialog(); form.BringToFront(); } } }; return listView; } private FlowLayoutPanel GetButtonsPanel() { var buttonPanel = new FlowLayoutPanel { Dock = DockStyle.Fill }; var addButton = new Button { Text = "Add App" }; var editButton = new Button { Text = "Edit App", Enabled = false }; var deleteButton = new Button { Text = "Delete App", Enabled = false }; var recheckButton = new Button { Text = "Recheck Versions" }; addButton.Click += (s, e) => { var form = _formFactory.CreateAppDetailsForm(null, true, onAppChangedHandler); // Use factory form.ShowDialog(); }; editButton.Click += (s, e) => { if (_listView.SelectedItems.Count > 0) { ListViewItem selectedItem = _listView.SelectedItems[0]; AppConfig app = selectedItem.Tag as AppConfig; var form = _formFactory.CreateAppDetailsForm(app, true, onAppChangedHandler); // Use factory form.ShowDialog(); } }; deleteButton.Click += (s, e) => { if (_listView.SelectedItems.Count > 0 && _listView.SelectedItems[0].Tag != null) { _appsManager.Delete((_listView.SelectedItems[0].Tag as AppConfig).Id); UpdateListView(); OnConfigChanged?.Invoke(this, EventArgs.Empty); } }; _listView.SelectedIndexChanged += (s, e) => { editButton.Enabled = deleteButton.Enabled = _listView.SelectedItems.Count > 0; }; // Add recheck logic here recheckButton.Click += async (s, e) => { recheckButton.Enabled = false; OnRecheck.Invoke(this, "User initiated recheck from ConfigForm"); recheckButton.Enabled = true; }; buttonPanel.Controls.AddRange(new[] { addButton, editButton, deleteButton, recheckButton }); return buttonPanel; } public void UpdateListView() { _apps = _appsManager.Load(); _listView.Items.Clear(); foreach (var app in _apps) { var item = new ListViewItem(app.Name); item.Tag = app; item.SubItems.Add(string.Join(", ", app.MsfsVersions)); try { var fsMod = _fsMods.FirstOrDefault(fs => fs.ShortName == "msfs2024"); // Pass the FsModPathConfig object directly, not its Path property var currentVersion = app.CurrentVersion; var latestVersion = app.LatestVersion; var lastChecked = TimeUtils.ToFriendlyTime(app.LastCheckedAt); item.SubItems.Add(currentVersion); item.SubItems.Add(latestVersion); item.SubItems.Add(lastChecked); } catch (Exception ex) { item.SubItems.Add($"Error: {ex.Message}"); } switch (_appStatusManager.GetAppStatus(app.Id)) { case AppStatus.UpdateAvailable: item.ImageKey = "update"; break; case AppStatus.Error: item.ImageKey = "error"; break; default: item.ImageKey = "none"; break; } _listView.Items.Add(item); } Console.WriteLine($"UpdateListView item count: {_listView.Items.Count}"); } private void InitializeMenu() { _menuStrip = new MenuStrip(); // Create top-level menu var configMenu = new ToolStripMenuItem("Configuration"); // Add sub-menu items var globalConfigItem = new ToolStripMenuItem("Global Settings"); globalConfigItem.Click += (s, e) => ShowGlobalConfigDialog(); var sourcesConfigItem = new ToolStripMenuItem("Sources"); sourcesConfigItem.Click += (s, e) => ShowSourcesConfigDialog(); var FlightSimsConfigItem = new ToolStripMenuItem("Flight Sims"); FlightSimsConfigItem.Click += (s, e) => MessageBox.Show("Flight Sims configuration dialog would open here."); configMenu.DropDownItems.Add(globalConfigItem); configMenu.DropDownItems.Add(sourcesConfigItem); configMenu.DropDownItems.Add(FlightSimsConfigItem); _menuStrip.Items.Add(configMenu); // Add the menu to the form Controls.Add(_menuStrip); MainMenuStrip = _menuStrip; } private void ShowGlobalConfigDialog() { // Show your global config form/dialog here var globalConfigForm = _formFactory.CreateGlobalConfigForm(); globalConfigForm.ShowDialog(); } private void ShowSourcesConfigDialog() { EventHandler onSourcesChanged = (s, e) => MessageBox.Show("Sources Changed"); var form = _formFactory.CreateSourcesConfigForm(onSourcesChanged); form.ShowDialog(); } } }