using CopaData.FileInspector.GUI.Models;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace Qrakhen.TilingFrames.Models;
///
/// Host node that by paradigm is located only at the very end of the tree's branches.
/// Hosts may contain at least one central control, or multiple tabs of controls.
/// Note that tab contents must _not_ be any tiling controls, as that would break hierarchy and branching logic.
/// Everything above a will be a by definition.
///
public class TilingHost : TilingNode
{
public ObservableCollection Frames { get; } = [];
private HostFrame? _activeFrame;
public HostFrame? ActiveFrame {
get => _activeFrame;
set => SetField(ref _activeFrame, value);
}
public bool ShowTabs => Frames.Count > 1;
public bool IsEmpty => Frames.Count == 0;
public TilingHost(params HostFrame[] frames)
{
if (frames != null && frames.Length > 0) {
Frames = new ObservableCollection(frames);
ActiveFrame = Frames[^1];
}
Frames.CollectionChanged += OnTabsChanged;
}
private void OnTabsChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null && e.NewItems.Count > 0) {
// Make the last item active
ActiveFrame = e.NewItems[^1] as HostFrame;
} else if (e.OldItems != null && e.OldItems.Count > 0) {
if (ActiveFrame != null && !Frames.Contains(ActiveFrame)) {
// Previous active tab got removed, revert back to the most recent tab or set ActiveTab to null if tabs are empty.
if (Frames.Count > 0) {
ActiveFrame = Frames[^1];
} else {
ActiveFrame = null;
}
}
}
}
///
/// Inserts into as a new tab
/// after being dropped in the center region by the user.
/// If the previous host only had one frame inside it, it will be detached from its parent.
/// Otherwise, only the frame will be removed and inserted into 's frames.
///
public static void InsertHost(TilingPanel rootPanel, TilingHost targetHost, TilingHost newHost)
{
HostFrame? frame = newHost.ActiveFrame;
if (frame == null) {
throw new InvalidOperationException($"No active frame to be inserted could be found within {newHost}'s frames.");
}
if (newHost.Frames.Count == 1) {
TilingPanel.Detach(rootPanel, newHost);
} else {
newHost.Frames.Remove(frame);
}
targetHost.Frames.Add(frame);
}
}