using System;
using System.Collections.Generic;
namespace AcDream.Core.Items;
///
/// Mutable client-side model of retail ShortCutManager::shortCuts_[18]
/// (acclient.h:36492). Every present entry retains all three raw
/// fields, including non-object records that the object-only
/// gmToolbarUI does not render.
///
public sealed class ShortcutStore
{
public const int SlotCount = 18;
private readonly ShortcutEntry?[] _entries = new ShortcutEntry?[SlotCount];
///
/// Replace all slots from packed entries. Invalid signed indices are rejected exactly
/// like ShortCutManager::AddShortCut @ 0x005D5790; valid entries are retained
/// even when their object id is zero.
///
public void Load(IEnumerable entries)
{
Array.Clear(_entries);
foreach (var entry in entries)
Set(entry);
}
/// Raw entry at , or null for absent/out-of-range.
public ShortcutEntry? GetEntry(int slot)
=> (uint)slot < SlotCount ? _entries[slot] : null;
/// Detached raw snapshot for planning a complete mutation before applying it.
public ShortcutEntry?[] Snapshot() => (ShortcutEntry?[])_entries.Clone();
/// Visible object id at , or zero.
public uint Get(int slot) => GetEntry(slot)?.ObjectId ?? 0u;
///
/// Visual availability used by gmToolbarUI. A retained non-object entry remains
/// invisible and therefore counts as an empty toolbar cell.
///
public bool IsEmpty(int slot) => Get(slot) == 0u;
public void Set(ShortcutEntry entry)
{
if ((uint)entry.Index < SlotCount)
_entries[entry.Index] = entry;
}
/// Create/replace a retail object shortcut; toolbar-created records use spell word zero.
public void SetItem(int slot, uint objectId) => Set(new ShortcutEntry(slot, objectId, 0u));
public void Remove(int slot)
{
if ((uint)slot < SlotCount)
_entries[slot] = null;
}
}