using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using Wabbajack.Common;
using Wabbajack.Common.StatusFeed;
using Wabbajack.Lib;
namespace Wabbajack
{
///
/// Main View Model for the application.
/// Keeps track of which sub view is being shown in the window, and has some singleton wiring like WorkQueue and Logging.
///
public class MainWindowVM : ViewModel
{
public MainWindow MainWindow { get; }
public MainSettings Settings { get; }
[Reactive]
public ViewModel ActivePane { get; set; }
public ObservableCollectionExtended Log { get; } = new ObservableCollectionExtended();
public readonly Lazy Compiler;
public readonly Lazy Installer;
public readonly Lazy Gallery;
public readonly ModeSelectionVM ModeSelectionVM;
public readonly UserInterventionHandlers UserInterventionHandlers;
public readonly LoginManagerVM LoginManagerVM;
public readonly List NavigationTrail = new List();
public Dispatcher ViewDispatcher { get; set; }
public ICommand CopyVersionCommand { get; }
public ICommand ShowLoginManagerVM { get; }
public ICommand GoBackCommand { get; }
public string VersionDisplay { get; }
public MainWindowVM(MainWindow mainWindow, MainSettings settings)
{
MainWindow = mainWindow;
ViewDispatcher = MainWindow.Dispatcher;
Settings = settings;
Installer = new Lazy(() => new InstallerVM(this));
Compiler = new Lazy(() => new CompilerVM(this));
Gallery = new Lazy(() => new ModListGalleryVM(this));
ModeSelectionVM = new ModeSelectionVM(this);
UserInterventionHandlers = new UserInterventionHandlers(this);
LoginManagerVM = new LoginManagerVM(this);
// Set up logging
Utils.LogMessages
.ObserveOn(RxApp.TaskpoolScheduler)
.ToObservableChangeSet()
.Buffer(TimeSpan.FromMilliseconds(250), RxApp.TaskpoolScheduler)
.Where(l => l.Count > 0)
.ObserveOn(RxApp.MainThreadScheduler)
.FlattenBufferResult()
.Bind(Log)
.Subscribe()
.DisposeWith(CompositeDisposable);
Utils.LogMessages
.OfType()
.ObserveOnGuiThread()
.SelectTask(msg => UserInterventionHandlers.Handle(msg))
.Subscribe()
.DisposeWith(CompositeDisposable);
if (IsStartingFromModlist(out var path))
{
Installer.Value.ModListLocation.TargetPath = path;
ActivePane = Installer.Value;
}
else
{
// Start on mode selection
ActivePane = ModeSelectionVM;
}
try
{
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
VersionDisplay = $"v{fvi.FileVersion}";
}
catch (Exception ex)
{
Utils.Error(ex);
VersionDisplay = "ERROR";
}
CopyVersionCommand = ReactiveCommand.Create(() =>
{
Clipboard.SetText($"Wabbajack {VersionDisplay}\n{ThisAssembly.Git.Sha}");
});
}
private static bool IsStartingFromModlist(out string modlistPath)
{
string[] args = Environment.GetCommandLineArgs();
if (args.Length != 3 || !args[1].Contains("-i"))
{
modlistPath = default;
return false;
}
modlistPath = args[2];
return true;
}
public void OpenInstaller(string path)
{
if (path == null) return;
var installer = Installer.Value;
Settings.Installer.LastInstalledListLocation = path;
ActivePane = installer;
installer.ModListLocation.TargetPath = path;
}
public void NavigateBack()
{
var prev = NavigationTrail.Last();
NavigationTrail.RemoveAt(NavigationTrail.Count - 1);
ActivePane = prev;
}
public void NavigateTo(ViewModel vm)
{
NavigationTrail.Add(ActivePane);
ActivePane = vm;
}
public void ShutdownApplication()
{
Dispose();
Settings.PosX = MainWindow.Left;
Settings.PosY = MainWindow.Top;
Settings.Width = MainWindow.Width;
Settings.Height = MainWindow.Height;
MainSettings.SaveSettings(Settings);
Application.Current.Shutdown();
}
}
}