using CommunityToolkit.Mvvm.ComponentModel; using GsaEditor.Core.Models; namespace GsaEditor.ViewModels; /// /// Wraps a for display in the details panel. /// public partial class EntryViewModel : ViewModelBase { private readonly GsaEntry _entry; [ObservableProperty] private string _alias = string.Empty; [ObservableProperty] private bool _isCompressed; /// /// Callback invoked when entry data is modified (compression toggle, alias change). /// public Action? OnModified { get; set; } public EntryViewModel(GsaEntry entry) { _entry = entry; _alias = entry.Alias; _isCompressed = entry.IsCompressed; } /// /// The underlying . /// public GsaEntry Entry => _entry; /// /// Original (decompressed) file size in bytes. /// public uint OriginalSize => _entry.OriginalLength; /// /// Compressed file size in bytes. /// public uint CompressedSize => _entry.CompressedLength; /// /// Compression ratio as a percentage (0–100). Higher means more compression. /// public string CompressionRatio => OriginalSize > 0 ? $"{(1.0 - (double)CompressedSize / OriginalSize) * 100.0:F1}%" : "0.0%"; /// /// Human-readable original size string. /// public string OriginalSizeText => FormatSize(OriginalSize); /// /// Human-readable compressed size string. /// public string CompressedSizeText => FormatSize(CompressedSize); partial void OnAliasChanged(string value) { if (_entry.Alias != value) { _entry.Alias = value; OnModified?.Invoke(); } } partial void OnIsCompressedChanged(bool value) { if (_entry.IsCompressed != value) { var decompressed = _entry.GetDecompressedData(); _entry.SetData(decompressed, value); OnPropertyChanged(nameof(OriginalSize)); OnPropertyChanged(nameof(CompressedSize)); OnPropertyChanged(nameof(CompressionRatio)); OnPropertyChanged(nameof(OriginalSizeText)); OnPropertyChanged(nameof(CompressedSizeText)); OnModified?.Invoke(); } } private static string FormatSize(long bytes) { if (bytes < 1024) return $"{bytes} B"; if (bytes < 1024 * 1024) return $"{bytes / 1024.0:F1} KB"; return $"{bytes / (1024.0 * 1024.0):F1} MB"; } }