using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reactive; using System.Reactive.Linq; using System.Threading.Tasks; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Input.Platform; using DesertPaintCodex.Models; using DesertPaintCodex.Services; using ReactiveUI; namespace DesertPaintCodex.ViewModels { public class MainWindowViewModel : ViewModelBase { private string _statusText = string.Empty; public string StatusText { get => _statusText; private set => this.RaiseAndSetIfChanged(ref _statusText, value); } private static readonly List ZipFileExtensions = new() { $"*.zip;" }; private static readonly FileDialogFilter ZipDialogFilter = new() {Extensions = ZipFileExtensions}; private static readonly List ZipDialogFilters = new() { ZipDialogFilter }; private static readonly List NoFilters = new(); public MainWindowViewModel() { if (!ProfileManager.HasProfileLoaded && ProfileManager.HasProfiles()) { ProfileManager.LoadProfile(ProfileManager.GetProfileList()[0]); } Debug.Assert(ProfileManager.HasProfileLoaded); PaletteService.Initialize(); ReactionTestService.Initialize(); ShowAboutDialog = new Interaction(); ShowScreenSettingsDialog = new Interaction(); StatusText = "USER PROFILE: " + ProfileManager.CurrentProfile?.Name; Exit = ReactiveCommand.Create(() => { }); } public async void ManageProfiles() { if (Application.Current is not App app) return; if (await ValidateSafeExit()) { ProfileManager.UnloadProfile(); app.ReturnToWelcome(); } } public static async void ImportProfile() { string? fileName = await GetLoadFileName("Open Zipped Profile", ZipDialogFilters); if (!string.IsNullOrEmpty(fileName)) { ProfileManager.CurrentProfile?.Import(fileName); } } public static async void ExportProfile() { string? fileName = await GetSaveFileName("Save Zipped Profile", ZipDialogFilters); if (!string.IsNullOrEmpty(fileName)) { ProfileManager.CurrentProfile?.Import(fileName); } } public static async void ExportForPP() { string? fileName = await GetSaveFileName("Save Practical Paint File", NoFilters); if (!string.IsNullOrEmpty(fileName)) { ProfileManager.CurrentProfile?.SaveToPP(fileName); } } public static async void ExportPaintRecipes() { string? fileName = await GetSaveFileName("Export Paint Recipes", NoFilters); if (!string.IsNullOrEmpty(fileName)) { ProfileManager.CurrentProfile?.ExportWikiRecipes(fileName); } } public static async void ExportRibbonRecipes() { string? fileName = await GetSaveFileName("Export Ribbon Recipes", NoFilters); if (!string.IsNullOrEmpty(fileName)) { ProfileManager.CurrentProfile?.ExportWikiRibbons(fileName); } } public static async void CopyPaintRecipes() { StringWriter writer = new(); ProfileManager.CurrentProfile?.ExportWikiRecipes(writer); IClipboard clipboard = Application.Current.Clipboard; await writer.FlushAsync(); await clipboard.SetTextAsync(writer.ToString()); writer.Close(); } public static async void CopyRibbonRecipes() { StringWriter writer = new(); ProfileManager.CurrentProfile?.ExportWikiRibbons(writer); IClipboard clipboard = Application.Current.Clipboard; await writer.FlushAsync(); await clipboard.SetTextAsync(writer.ToString()); writer.Close(); } public async Task ShowScreenSettings() { await ShowScreenSettingsDialog.Handle(new ScreenSettingsViewModel()); } public async Task ShowAbout() { await ShowAboutDialog.Handle(new AboutViewModel()); } public async Task ValidateSafeExit() { // TODO: Determine if there's unsaved stuff we need to deal with. // return await ShowYesNoBox("Leaving so Soon?", "[A potential reason not to quit goes here]"); await Task.Delay(1); // Stub to prevent warnings. return true; } private static async Task GetLoadFileName(string title, List filters) { if (Application.Current.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop) return null; // TODO: Figure out why the file filters aren't working. OpenFileDialog dialog = new() { Title = title, Filters = NoFilters, // filters, AllowMultiple = false }; string[] files = await dialog.ShowAsync(desktop.MainWindow); return files.Length > 0 ? files[0] : null; } private static async Task GetSaveFileName(string title, List filters) { if (Application.Current.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop) return null; // TODO: Figure out why the file filters aren't working. SaveFileDialog dialog = new() { Title = title, Filters = NoFilters, // filters }; return await dialog.ShowAsync(desktop.MainWindow); } public Interaction ShowAboutDialog { get; } public Interaction ShowScreenSettingsDialog { get; } public ReactiveCommand Exit { get; } } }