using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; using ByteSizeLib; using CommunityToolkit.Mvvm.ComponentModel; using LANCommander.SDK.Enums; namespace LANCommander.Launcher.ViewModels; public partial class InstallOptionsViewModel : ViewModelBase { // ── Install directory ────────────────────────────────────────────────────── [ObservableProperty] private ObservableCollection _installDirectories = new(); [ObservableProperty] [NotifyPropertyChangedFor(nameof(HasMultipleDirectories))] private string _selectedInstallDirectory = string.Empty; [ObservableProperty] private string _gameTitle = string.Empty; /// Title shown at the top of the dialog (e.g. "Install GameTitle" or "Modify GameTitle"). [ObservableProperty] private string _dialogTitle = string.Empty; /// Label for the confirm button (e.g. "Install" or "Apply"). [ObservableProperty] private string _confirmButtonText = "Install"; /// When true, always show the install directory picker (e.g. for Modify). [ObservableProperty] [NotifyPropertyChangedFor(nameof(ShowInstallDirectory))] private bool _alwaysShowDirectory; public bool HasMultipleDirectories => InstallDirectories.Count > 1; public bool ShowInstallDirectory => AlwaysShowDirectory || HasMultipleDirectories; // ── Addons ──────────────────────────────────────────────────────────────── [ObservableProperty] [NotifyPropertyChangedFor(nameof(HasAddons))] private ObservableCollection _addons = new(); public bool HasAddons => Addons.Count > 0; // ── Tools ───────────────────────────────────────────────────────────────── [ObservableProperty] [NotifyPropertyChangedFor(nameof(HasTools))] private ObservableCollection _tools = new(); public bool HasTools => Tools.Count > 0; // ── Size info ──────────────────────────────────────────────────────────── /// Base game compressed archive size in bytes. public long BaseDownloadSize { get; set; } /// Base game uncompressed archive size in bytes. public long BaseSpaceRequired { get; set; } public string DownloadSizeText => ByteSize.FromBytes(TotalDownloadSize).ToString("0.##"); public string SpaceRequiredText => ByteSize.FromBytes(TotalSpaceRequired).ToString("0.##"); public bool HasSizeInfo => HasAddons || HasTools; private long TotalDownloadSize => BaseDownloadSize + Addons.Where(a => a.IsSelected).Sum(a => a.DownloadSize) + Tools.Where(t => t.IsSelected).Sum(t => t.DownloadSize); private long TotalSpaceRequired => BaseSpaceRequired + Addons.Where(a => a.IsSelected).Sum(a => a.SpaceRequired) + Tools.Where(t => t.IsSelected).Sum(t => t.SpaceRequired); public void RefreshSizes() { OnPropertyChanged(nameof(DownloadSizeText)); OnPropertyChanged(nameof(SpaceRequiredText)); } // ── Result ──────────────────────────────────────────────────────────────── /// The addons the user chose to install. public SDK.Models.Game[] SelectedAddons => Addons.Where(a => a.IsSelected).Select(a => a.Game).ToArray(); /// The tools the user chose to install. public SDK.Models.Tool[] SelectedTools => Tools.Where(t => t.IsSelected).Select(t => t.Tool).ToArray(); } public partial class InstallToolItemViewModel : ViewModelBase { public SDK.Models.Tool Tool { get; } public string Title => Tool.Name ?? "Unknown"; public long DownloadSize { get; } public long SpaceRequired { get; } [ObservableProperty] private bool _isSelected; public InstallToolItemViewModel(SDK.Models.Tool tool, bool selectedByDefault = false) { Tool = tool; IsSelected = selectedByDefault; var archives = tool.Archives?.ToArray() ?? []; DownloadSize = archives.Sum(a => a.CompressedSize); SpaceRequired = archives.Sum(a => a.UncompressedSize); } } public partial class InstallAddonItemViewModel : ViewModelBase { public SDK.Models.Game Game { get; } public string Title => Game.Title ?? "Unknown"; public string TypeLabel => Game.Type switch { GameType.Expansion => "Expansion", GameType.Mod => "Mod", _ => Game.Type.ToString() }; public int TypeSortOrder => Game.Type switch { GameType.Expansion => 0, GameType.Mod => 1, _ => 2 }; public long DownloadSize { get; } public long SpaceRequired { get; } [ObservableProperty] private bool _isSelected; public InstallAddonItemViewModel(SDK.Models.Game game, bool selectedByDefault = false) { Game = game; IsSelected = selectedByDefault; var archives = game.Archives?.ToArray() ?? []; DownloadSize = archives.Sum(a => a.CompressedSize); SpaceRequired = archives.Sum(a => a.UncompressedSize); } }