// Copyright (c) Arlo Godfrey. All Rights Reserved.
// Licensed under the GNU Lesser General Public License, Version 3.0 with additional terms.
// See the LICENSE, LICENSE.LESSER and LICENSE.ADDITIONAL files in the project root for more information.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using OwlCore.Events;
using StrixMusic.Sdk.AdapterModels;
using StrixMusic.Sdk.AppModels;
using StrixMusic.Sdk.CoreModels;
using StrixMusic.Sdk.Plugins.Model;
namespace StrixMusic.Sdk.PluginModels
{
///
/// Wraps an instance of with the provided plugins.
///
public class StrixDataRootPluginWrapper : IStrixDataRoot, IPluginWrapper
{
private readonly IStrixDataRoot _strixDataRoot;
private readonly SdkModelPlugin[] _plugins;
///
/// Initializes a new instance of the class.
///
/// An existing instance to wrap around and provide plugins on top of.
/// The plugins to import and apply to everything returned from this wrapper.
public StrixDataRootPluginWrapper(IStrixDataRoot strixDataRoot, params SdkModelPlugin[] plugins)
{
foreach (var plugin in plugins)
ActivePlugins.Import(plugin);
ActivePlugins = GlobalModelPluginConnector.Create(ActivePlugins);
_strixDataRoot = ActivePlugins.StrixDataRoot.Execute(strixDataRoot);
Library = new LibraryPluginWrapper(_strixDataRoot.Library, plugins);
if (_strixDataRoot.Search is not null)
Search = new SearchPluginWrapper(_strixDataRoot.Search, plugins);
if (_strixDataRoot.Pins is not null)
Pins = new PlayableCollectionGroupPluginWrapper(_strixDataRoot.Pins, plugins);
if (_strixDataRoot.Discoverables is not null)
Discoverables = new DiscoverablesPluginWrapper(_strixDataRoot.Discoverables, plugins);
if (_strixDataRoot.RecentlyPlayed is not null)
RecentlyPlayed = new RecentlyPlayedPluginWrapper(_strixDataRoot.RecentlyPlayed, plugins);
_plugins = plugins;
AttachEvents(_strixDataRoot);
}
private void AttachEvents(IStrixDataRoot strixDataRoot)
{
strixDataRoot.SourcesChanged += OnSourcesChanged;
strixDataRoot.DevicesChanged += OnDevicesChanged;
strixDataRoot.DevicesChanged += OnDevicesChanged;
strixDataRoot.PinsChanged += OnPinsChanged;
strixDataRoot.RecentlyPlayedChanged += OnRecentlyPlayedChanged;
strixDataRoot.DiscoverablesChanged += OnDiscoverablesChanged;
strixDataRoot.SearchChanged += OnSearchChanged;
}
private void DetachEvents(IStrixDataRoot strixDataRoot)
{
strixDataRoot.SourcesChanged -= OnSourcesChanged;
strixDataRoot.DevicesChanged -= OnDevicesChanged;
strixDataRoot.DevicesChanged -= OnDevicesChanged;
strixDataRoot.PinsChanged -= OnPinsChanged;
strixDataRoot.RecentlyPlayedChanged -= OnRecentlyPlayedChanged;
strixDataRoot.DiscoverablesChanged -= OnDiscoverablesChanged;
strixDataRoot.SearchChanged -= OnSearchChanged;
}
private void OnDiscoverablesChanged(object sender, IDiscoverables e)
{
Discoverables = new DiscoverablesPluginWrapper(e, _plugins);
DiscoverablesChanged?.Invoke(this, Discoverables);
}
private void OnRecentlyPlayedChanged(object sender, IRecentlyPlayed e)
{
RecentlyPlayed = new RecentlyPlayedPluginWrapper(e, _plugins);
RecentlyPlayedChanged?.Invoke(this, RecentlyPlayed);
}
private void OnPinsChanged(object sender, IPlayableCollectionGroup e)
{
Pins = new PlayableCollectionGroupPluginWrapper(e, _plugins);
PinsChanged?.Invoke(this, Pins);
}
private void OnSearchChanged(object sender, ISearch e)
{
Search = new SearchPluginWrapper(e, _plugins);
SearchChanged?.Invoke(this, Search);
}
private void OnSourcesChanged(object sender, EventArgs e) => SourcesChanged?.Invoke(sender, e);
private void OnDevicesChanged(object sender, IReadOnlyList> addedItems, IReadOnlyList> removedItems) => DevicesChanged?.Invoke(this, addedItems, removedItems);
///
public SdkModelPlugin ActivePlugins { get; } = new(PluginModelWrapperInfo.Metadata);
///
public event EventHandler? SourcesChanged;
///
public event CollectionChangedEventHandler? DevicesChanged;
///
public event EventHandler? PinsChanged;
///
public event EventHandler? DiscoverablesChanged;
///
public event EventHandler? SearchChanged;
///
public event EventHandler? RecentlyPlayedChanged;
///
public MergedCollectionConfig MergeConfig => _strixDataRoot.MergeConfig;
///
public IReadOnlyList Devices => _strixDataRoot.Devices;
///
public ILibrary Library { get; }
///
public IPlayableCollectionGroup? Pins { get; private set; }
///
public ISearch? Search { get; private set; }
///
public IRecentlyPlayed? RecentlyPlayed { get; private set; }
///
public IDiscoverables? Discoverables { get; private set; }
///
public IReadOnlyList Sources => _strixDataRoot.Sources;
///
public bool IsInitialized => _strixDataRoot.IsInitialized;
///
public bool Equals(ICore other) => _strixDataRoot.Equals(other);
///
public Task InitAsync(CancellationToken cancellationToken = default) => _strixDataRoot.InitAsync(cancellationToken);
///
public ValueTask DisposeAsync()
{
DetachEvents(_strixDataRoot);
return _strixDataRoot.DisposeAsync();
}
}
}