using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using CommunityToolkit.Diagnostics;
using OwlCore;
using OwlCore.WinUI.Controls;
using StrixMusic.Sdk.CoreModels;
using StrixMusic.Sdk.ViewModels;
using StrixMusic.Sdk.ViewModels.Notifications;
using StrixMusic.Sdk.WinUI.Services.Localization;
using StrixMusic.Sdk.WinUI.Services.NotificationService;
using StrixMusic.Services;
using StrixMusic.Services.CoreManagement;
using Windows.ApplicationModel.Resources;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace StrixMusic.Shared
{
///
/// A top-level frame that holds all other app content.
///
public sealed partial class AppFrame : UserControl
{
private SuperShell? _superShell;
///
/// The backing dependency property for .
///
public static readonly DependencyProperty NotificationsProperty =
DependencyProperty.Register(nameof(Notifications), typeof(NotificationsViewModel), typeof(AppFrame), new PropertyMetadata(null));
///
/// Creates a new instance of .
///
public AppFrame()
{
InitializeComponent();
Guard.IsNotNull(SynchronizationContext.Current, nameof(SynchronizationContext.Current));
Threading.SetPrimarySynchronizationContext(SynchronizationContext.Current);
var window = Window.Current;
Threading.SetPrimaryThreadInvokeHandler(a => window.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => a()).AsTask());
NotificationService = new NotificationService();
Notifications = new NotificationsViewModel(NotificationService);
LocalizationService = new()
{
Startup = ResourceLoader.GetForCurrentView(nameof(LocalizationResourceLoader.Startup)),
SuperShell = ResourceLoader.GetForCurrentView(nameof(LocalizationResourceLoader.SuperShell)),
Common = ResourceLoader.GetForCurrentView(nameof(LocalizationResourceLoader.Common)),
Time = ResourceLoader.GetForCurrentView(nameof(LocalizationResourceLoader.Time)),
Music = ResourceLoader.GetForCurrentView(nameof(LocalizationResourceLoader.Music)),
Quips = ResourceLoader.GetForCurrentView(nameof(LocalizationResourceLoader.Quips)),
};
AttachEvents();
AttachEvents(NotificationService);
}
///
/// A ViewModel for notifications displayed to the user.
///
public NotificationsViewModel Notifications
{
get => (NotificationsViewModel)GetValue(NotificationsProperty);
set => SetValue(NotificationsProperty, value);
}
///
/// The content overlay used as a popup dialog for the entire app.
///
public ContentOverlay? ContentOverlay { get; private set; }
///
/// A service that facilitates raising notifications.
///
public NotificationService NotificationService { get; }
///
/// A service for getting localized strings from providers.
///
public LocalizationResourceLoader LocalizationService { get; }
///
/// Navigates top the primary app content to the given .
///
///
public void Present(FrameworkElement element)
{
PART_ContentPresenter.Content = element;
}
private void AttachEvents()
{
Loaded += AppFrame_Loaded;
Unloaded += AppFrame_Unloaded;
}
private void AppFrame_Loaded(object sender, RoutedEventArgs e)
{
Loaded -= AppFrame_Loaded;
ContentOverlay = OverlayPresenter;
}
private void AttachEvents(NotificationService notificationService)
{
notificationService.NotificationMarginChanged += NotificationService_NotificationMarginChanged;
notificationService.NotificationAlignmentChanged += NotificationService_NotificationAlignmentChanged;
}
private void DetachEvents(NotificationService notificationService)
{
notificationService.NotificationMarginChanged -= NotificationService_NotificationMarginChanged;
notificationService.NotificationAlignmentChanged -= NotificationService_NotificationAlignmentChanged;
}
private void DetachEvents()
{
Unloaded -= AppFrame_Unloaded;
if (!(NotificationService is null))
DetachEvents(NotificationService);
}
///
/// Displays the AbstractUI panel for the given core.
///
public void DisplayAbstractUIPanel(ICore core, AppSettings appSettings, IReadOnlyList loadedCores, ICoreManagementService coreManagementService)
{
_ = Threading.OnPrimaryThread(() =>
{
_superShell ??= new SuperShell(appSettings, coreManagementService);
_superShell.LoadedCores = loadedCores.ToList();
_superShell.CurrentCoreConfig = new CoreViewModel(core);
_superShell.SelectedTabIndex = 1;
OverlayPresenter.Show(_superShell, LocalizationService.Common?.GetString("Settings") ?? string.Empty);
});
}
///
/// Opens the SuperShell.
///
public void DisplaySuperShell(AppSettings appSettings, IReadOnlyList loadedCores, ICoreManagementService coreManagementService)
{
_ = Threading.OnPrimaryThread(() =>
{
_superShell ??= new SuperShell(appSettings, coreManagementService);
_superShell.LoadedCores = loadedCores.ToList();
OverlayPresenter.Show(_superShell, LocalizationService.Common?.GetString("Settings") ?? string.Empty);
});
}
private void NotificationService_NotificationMarginChanged(object? sender, Thickness e)
{
NotificationItems.Margin = e;
}
private void NotificationService_NotificationAlignmentChanged(object? sender, (HorizontalAlignment Horizontal, VerticalAlignment Vertical) e)
{
NotificationItems.HorizontalAlignment = e.Horizontal;
NotificationItems.VerticalAlignment = e.Vertical;
}
private void AppFrame_Unloaded(object? sender, RoutedEventArgs e) => DetachEvents();
private void AppFrame_OnLoaded(object? sender, RoutedEventArgs e) => Present(new AppLoadingView());
}
}