#!/bin/bash
#===============================================================================
# generate-grub-background.sh — build the Felhom GRUB boot background (scripts v1.22.0, R-38).
#
# Turns Viktor's square brand card (website/assets/og-image_2.png, 1017x1016) into a GRUB-friendly
# 1024x768 PNG. Runs INSIDE the felhom-iso-assistant container (needs ImageMagick); called by
# iso-repack.sh.
#
# THE LAYOUT, AND WHY:
#
#   * 1024x768 canvas — gfxterm-safe. The stock PVE grub.cfg already asks for `gfxmode=1024x768`, so
#     this is the mode the ISO's GRUB is known to get on real firmware. Anything larger risks a
#     fallback to 800x600 and a scaled/cropped background.
#
#   * The card is scaled to 500x500 and composited TOP-CENTERED (y=16). That deliberately leaves the
#     bottom ~250px empty: it is where felhom-theme.txt positions the boot menu (top=70%) and the
#     countdown label (top=84%). Menu text therefore never lands on the cloud/wordmark/tagline. If
#     you change CARD or CARD_Y here, move `boot_menu.top` in felhom-theme.txt to match.
#
#   * THE GRID. The card carries a subtle background grid (4px lines of #0D131A on #0D1117, every
#     131px) and Viktor asked for it to stay visible. Two things could destroy it: the downscale
#     (handled — at 500/1017 the lines land at ~2px, still legible), and the letterbox fill. A flat
#     navy fill would leave an obvious 500px square of grid floating in a plain field.
#
#     So the grid is drawn across the WHOLE canvas first, PHASE-LOCKED to where the card's own grid
#     will land, in the card's own line color — then the card is composited on top. Inside the card
#     region the card's real grid shows; outside, the drawn continuation lines up exactly. The seam
#     is invisible because the card's background (#0D1117) is also the canvas fill.
#
#     The phase-lock math: source line centers are x=81.5+n*131, y=21.5+n*131 (measured, not guessed
#     — sampled from og-image_2.png). Scale s=CARD/SRC_W maps them onto the canvas, offset by the
#     card's origin. Line width scales the same way.
#
# Usage: generate-grub-background.sh <source.png> <out.png>
#===============================================================================
set -euo pipefail

SRC="${1:?source card PNG required}"
OUT="${2:?output PNG path required}"

# --- canvas ---------------------------------------------------------------------------------------
CW=1024; CH=768
BG="#0D1117"        # the card's own background — the letterbox must be seamless, not merely "navy"
GRID="#0D131A"      # the card's own grid line color (sampled)

# --- card placement (keep in sync with felhom-theme.txt boot_menu.top) ------------------------------
CARD=500; CARD_X=262; CARD_Y=16

# --- measured properties of og-image_2.png ----------------------------------------------------------
SRC_W=1017          # source width; the card is square (1017x1016)
PITCH=131           # grid pitch in source px
V0=81.5             # center of the first vertical grid line, source px
H0=21.5             # center of the first horizontal grid line, source px
LINE=4              # grid line width in source px

command -v magick >/dev/null && IM=magick || IM=convert
[[ -f "$SRC" ]] || { echo "generate-grub-background: source card not found: $SRC" >&2; exit 2; }

# Refuse a source whose geometry no longer matches the measured constants above — a silently swapped
# asset would misplace every grid line, and the result only shows up on a boot screen nobody re-checks.
GEOM="$($IM identify -format '%wx%h' "$SRC")"
[[ "$GEOM" == "1017x1016" ]] || {
    echo "generate-grub-background: source card is ${GEOM}, expected 1017x1016." >&2
    echo "  The grid phase-lock constants (PITCH/V0/H0/LINE) were measured against that geometry." >&2
    echo "  Re-measure them for the new asset before changing this check." >&2
    exit 3
}

S=$(awk -v c="$CARD" -v w="$SRC_W" 'BEGIN{printf "%.6f", c/w}')      # card scale factor
P=$(awk -v p="$PITCH" -v s="$S" 'BEGIN{printf "%.4f", p*s}')          # canvas grid pitch
LW=$(awk -v l="$LINE" -v s="$S" 'BEGIN{printf "%.2f", l*s}')          # canvas grid line width

# Walk n outward far enough to cover the canvas in both axes from the card-anchored origin.
draw=""
for n in $(seq -20 40); do
    x=$(awk -v a="$CARD_X" -v v="$V0" -v s="$S" -v p="$P" -v n="$n" 'BEGIN{printf "%.2f", a+v*s+n*p}')
    if awk -v x="$x" -v w="$CW" 'BEGIN{exit !(x>-2 && x<w+2)}'; then
        draw="$draw line $x,0 $x,$CH"
    fi
    y=$(awk -v a="$CARD_Y" -v v="$H0" -v s="$S" -v p="$P" -v n="$n" 'BEGIN{printf "%.2f", a+v*s+n*p}')
    if awk -v y="$y" -v h="$CH" 'BEGIN{exit !(y>-2 && y<h+2)}'; then
        draw="$draw line 0,$y $CW,$y"
    fi
done
[[ -n "$draw" ]] || { echo "generate-grub-background: grid draw list came out empty" >&2; exit 4; }

# PNG24 (no palette, no alpha): GRUB's png module reads plain 8-bit RGB reliably; an indexed or
# 16-bit PNG is where "the background silently doesn't render" comes from.
$IM -size "${CW}x${CH}" xc:"$BG" \
    -stroke "$GRID" -strokewidth "$LW" -draw "$draw" -stroke none \
    \( "$SRC" -resize "${CARD}x${CARD}!" \) -geometry "+${CARD_X}+${CARD_Y}" -composite \
    -depth 8 "PNG24:$OUT"

[[ -s "$OUT" ]] || { echo "generate-grub-background: produced no output" >&2; exit 5; }
OGEOM="$($IM identify -format '%wx%h %[channels] %[depth]' "$OUT")"
echo "generate-grub-background: $OUT ($OGEOM, $(stat -c%s "$OUT") bytes)"
