Files @ 7117d2e703c8
Branch filter:

Location: ATITD-Tools/Desert-Paint-Codex/ViewModels/MainWindowViewModel.cs

Malkyne
Updated scanner for Tale 10, and fixed several bugs.
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<string> ZipFileExtensions = new() { $"*.zip;" };
        private static readonly FileDialogFilter ZipDialogFilter = new() {Extensions = ZipFileExtensions};
        private static readonly List<FileDialogFilter> ZipDialogFilters = new() { ZipDialogFilter };
        private static readonly List<FileDialogFilter> 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<AboutViewModel, Unit>();
            ShowScreenSettingsDialog = new Interaction<ScreenSettingsViewModel, Unit>();
            
            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<bool> 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<string?> GetLoadFileName(string title, List<FileDialogFilter> 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<string?> GetSaveFileName(string title, List<FileDialogFilter> 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<AboutViewModel, Unit> ShowAboutDialog { get; }
        public Interaction<ScreenSettingsViewModel, Unit> ShowScreenSettingsDialog { get; }

        public ReactiveCommand<Unit, Unit> Exit { get; }
    }
}