using System;
using System.Collections.Generic;
using System.IO;
using AcDream.App.UI.Layout;
using DatReaderWriter;
using DatReaderWriter.Options;
namespace AcDream.App.Tests.UI.Layout;
///
/// 2026-08-17 morning gate finding 3 installed-DAT pins: the map town-hotspot
/// template's OWN authored tooltip locator + rollover-highlight mechanism,
/// re-derived after the user's retail screenshot (green marker highlight on
/// hover, parchment-banner tooltip in a special font) refuted the earlier
/// "template authors no locator of its own" recon. Follows
/// 's [InstalledDatFact] pattern.
///
///
/// The derivation chain (raw-DAT-dumped + MapHousePanelSlotProbeTests):
/// m_pMap (0x100001EC) authors P0x47=0x100001F0/
/// P0x48=0x21000026 — the note CONSTRUCTION template
/// (gmMapUI::AddMapNote @0x004a1bb0's CreateChildElement args).
/// The template's DirectState then authors the note's OWN tooltip popup
/// locator P0x47=0x10000398/P0x48=0x21000041, a zero
/// per-element tooltip delay (P0x50=0.0), P0x4B TooltipOn, and
/// P0x13 RolloverEnabled; its Normal/Normal_rollover
/// states are PassToChildren descriptors driving the highlight child
/// 0x100001F1 (base 0x100002B7@0x21000042 — a
/// four-piece frame of pure-green 0x06004CC9, byte-decoded
/// A=FF R=00 G=FF B=00) via per-state P0x3B.
///
///
public sealed class MapNoteLiveDatTests
{
private static string DatDirectory =>
System.Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR")
?? Path.Combine(
System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile),
"Documents",
"Asheron's Call");
private const uint TemplateLayoutId = 0x21000026u;
private const uint TemplateElementId = 0x100001F0u;
private const uint HighlightChildId = 0x100001F1u;
private const uint MapNoteSkinRootId = 0x10000398u;
private const uint TooltipCatalogLayoutId = 0x21000041u;
private const uint TooltipTextChildId = 0x10000396u;
private const uint MapNoteFontDid = 0x40000015u;
private const uint GenericSkinFontDid = 0x40000002u;
private const uint GreenFrameSurfaceId = 0x06004CC9u;
[InstalledDatFact]
public void HotspotTemplate_AuthorsItsOwnPopupLocator_ZeroDelay_AndRollover()
{
using var dats = new DatCollection(DatDirectory, DatAccessType.Read);
ElementInfo? template = LayoutImporter.ImportInfos(dats, TemplateLayoutId, TemplateElementId);
Assert.NotNull(template);
// The note's own popup locator — NOT the generic shared skin the
// pre-fix code hardcoded.
Assert.Equal(MapNoteSkinRootId, template!.TooltipRootElementId);
Assert.Equal(TooltipCatalogLayoutId, template.TooltipLayoutDid);
Assert.True(template.TooltipEnabled); // P0x4B
Assert.True(template.TooltipDelaySeconds.HasValue); // P0x50 authored
Assert.Equal(0f, template.TooltipDelaySeconds!.Value); // = 0.0
// P0x13 RolloverEnabled — drives UiButtonStateMachine's
// NormalRollover request on pointer-over.
Assert.True(template.TryGetEffectiveBool(0x13u, out bool rollover) && rollover);
// The two PassToChildren cascade descriptors.
Assert.True(template.States.TryGetValue(1u, out UiStateInfo? normal));
Assert.True(template.States.TryGetValue(2u, out UiStateInfo? normalRollover));
Assert.Equal("Normal", normal!.Name);
Assert.Equal("Normal_rollover", normalRollover!.Name);
Assert.True(normal.PassToChildren);
Assert.True(normalRollover.PassToChildren);
}
[InstalledDatFact]
public void HotspotTemplate_HighlightChild_FlipsPerStateInvisible_WithGreenFrameMedia()
{
using var dats = new DatCollection(DatDirectory, DatAccessType.Read);
ElementInfo? template = LayoutImporter.ImportInfos(dats, TemplateLayoutId, TemplateElementId);
Assert.NotNull(template);
ElementInfo highlight = Assert.Single(template!.Children, c => c.Id == HighlightChildId);
// Per-state P0x3B: hidden in Normal, shown in Normal_rollover.
Assert.True(highlight.States.TryGetValue(1u, out UiStateInfo? normal));
Assert.True(highlight.States.TryGetValue(2u, out UiStateInfo? rollover));
Assert.True(normal!.Properties.TryGetValue(0x3Bu, out var normalInvisible));
Assert.True(rollover!.Properties.TryGetValue(0x3Bu, out var rolloverInvisible));
Assert.Equal(UiPropertyKind.Bool, normalInvisible.Kind);
Assert.Equal(UiPropertyKind.Bool, rolloverInvisible.Kind);
Assert.True(normalInvisible.BoolValue);
Assert.False(rolloverInvisible.BoolValue);
// The base-chain frame (0x100002B7@0x21000042): four edge pieces,
// every one drawing the pure-green line surface 0x06004CC9.
Assert.Equal(4, highlight.Children.Count);
foreach (ElementInfo edge in highlight.Children)
{
Assert.True(edge.StateMedia.TryGetValue("", out var media));
Assert.Equal(GreenFrameSurfaceId, media.File);
}
}
[InstalledDatFact]
public void MapNoteSkin_TextChild_FontsTheSpecialFont_UnlikeTheGenericSkins()
{
using var dats = new DatCollection(DatDirectory, DatAccessType.Read);
// The four popup skins in 0x21000041 share structure and the SAME
// incorporated text child id — but each skin's child-table merge
// gives 0x10000396 its own effective font, and the map-note skin
// 0x10000398 is the odd one out (0x40000015 vs 0x40000002) — the
// "special/blackletter-style font" of the user's retail screenshot.
var fonts = new Dictionary();
foreach (uint skinId in new[] { 0x10000487u, 0x10000395u, 0x10000397u, MapNoteSkinRootId })
{
ElementInfo? skin = LayoutImporter.ImportInfos(dats, TooltipCatalogLayoutId, skinId);
Assert.NotNull(skin);
ElementInfo text = Assert.Single(skin!.Children, c => c.Id == TooltipTextChildId);
fonts[skinId] = text.FontDid;
}
Assert.Equal(MapNoteFontDid, fonts[MapNoteSkinRootId]);
Assert.Equal(GenericSkinFontDid, fonts[0x10000487u]);
Assert.Equal(GenericSkinFontDid, fonts[0x10000395u]);
Assert.Equal(GenericSkinFontDid, fonts[0x10000397u]);
}
}