using Godot;
namespace IslaApocalypse.Tools
{
///
/// The offshore TAG / HEMISPHERE debug overlay (chat2/05): mainland one tint, offshore-island
/// land tinted by hemisphere, the midline drawn — so the island count,
/// the N/S split and the tag's correctness are all visible at one glance.
///
/// ⚠ A DIAGNOSTIC, NOT A MAP. It draws the tag layer, which is DATA the shape pass set; it is
/// the one artifact in the batch that shows what a downstream consumer of the tag would see.
/// No hypsometry, no hillshade — three flat tints and some rings, on purpose.
///
/// Presentation only: it is handed arrays and returns a PNG. It cannot change them.
///
public static class TagOverlayRenderer
{
private static readonly Color Sea = new(0.055f, 0.110f, 0.235f);
private static readonly Color Mainland = new(0.310f, 0.360f, 0.300f);
private static readonly Color IslandN = new(0.250f, 0.850f, 0.950f); // cool — north
private static readonly Color IslandS = new(0.980f, 0.600f, 0.200f); // warm — south
private static readonly Color Untagged = new(0.950f, 0.150f, 0.800f); // ⚠ land that is neither — must never appear
private static readonly Color Midline = new(0.700f, 0.720f, 0.760f);
private static readonly Color Ink = new(0.941f, 0.949f, 0.961f);
///
/// Per cell, land that is NOT offshore (from the offshore-OFF field, so a tag bug cannot hide
/// by mis-tagging mainland). Null ⇒ derived as "land and not tagged", which is weaker.
///
public static void SavePng(float[,] height, bool[,] tag, byte[,] hemi, int mapSize, float sea,
int countN, int countS, string absolutePath)
{
var img = Image.CreateEmpty(mapSize, mapSize, false, Image.Format.Rgb8);
for (int x = 0; x < mapSize; x++)
{
for (int y = 0; y < mapSize; y++)
{
Color c;
bool land = height[x, y] >= sea;
bool tagged = tag != null && tag[x, y];
if (!land) c = Sea;
else if (!tagged) c = Mainland;
else if (hemi == null) c = Untagged;
else c = hemi[x, y] switch
{
OffshoreAnalysis.HemiNorth => IslandN,
OffshoreAnalysis.HemiSouth => IslandS,
_ => Untagged,
};
img.SetPixel(x, y, c);
}
}
// The hemisphere midline — the tag's convention, drawn where it bites.
int mid = mapSize / 2;
for (int x = 0; x < mapSize; x += 3) img.SetPixel(x, mid, Midline);
// A legend that cannot be separated from the picture.
int s = mapSize >= 4096 ? 4 : 3;
int lh = TinyFont.Height(s) + 6;
TinyFont.Draw(img, "OFFSHORE TAG OVERLAY", 12, 12, s, Ink);
TinyFont.Draw(img, "GREY: MAINLAND CYAN: ISLAND N ORANGE: ISLAND S", 12, 12 + lh, s, Ink);
TinyFont.Draw(img, $"ISLANDS: {countN} NORTH {countS} SOUTH - ALL ORGANIC, NONE FORCED", 12, 12 + lh * 2, s, Ink);
TinyFont.Draw(img, "N ABOVE THE LINE - S BELOW - Y RUNS SOUTH", 12, 12 + lh * 3, s, Ink);
Error err = img.SavePng(absolutePath);
if (err != Error.Ok) GD.PrintErr($"[TagOverlayRenderer] SavePng failed ({err}) for {absolutePath}");
}
}
}