#!/bin/bash
# Usage: shot_input.sh <output.png> [action ...]
# Launches rspektrum under Xvfb, runs input actions, captures the screen, cleans up.
#
# Actions (each runs in order):
#   "sleep N"            sleep N seconds locally (let the app settle / animate).
#                        Capture at "sleep 12" for a SETTLED render: the background
#                        high-res STFT fill runs over the first several seconds, so
#                        earlier grabs are nondeterministic run-to-run.
#   "click X Y"          left-click at (X,Y): move, press, hold ~0.2s, release.
#   "drag X1 Y1 X2 Y2"   left-drag from (X1,Y1) to (X2,Y2).
#   "rdrag X1 Y1 X2 Y2"  same but with Alt held (the app's pan gesture).
#   "key NAME"           xdotool keysym, e.g. "key F1", "key p", "key Home".
#   anything else        passed verbatim to xdotool (mousemove, mousedown, ...).
#
# IMPORTANT timing note: a left button's press and release MUST land in different
# 60 Hz frames or raylib's IsMouseButtonPressed edge-detect (current && !previous)
# never fires. The click/drag helpers below insert that gap; a bare "click 1" via
# xdotool is too fast and silently no-ops. Keys reach GLFW fine under Xvfb; so do
# synthetic mouse buttons (the pointer just has to be over a live target).
#
# Layout cheat-sheet at the default 1280x800 window (UI scale = 1.0):
#   spectrogram viewport ~ x:[385,1242] y:[50,468]   (drags/selections go here)
#   sidebar              ~ x:[0,320]                  (buttons; click centers)
#   a selection box needs a >5 px drag or it reverts to "no selection".
set -u
OUT="${1:-/tmp/rspek_shot.png}"; shift || true
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DISP=:99
WAV="${RSPEK_WAV:-/tmp/mlink_bulk_drop.wav}"

pkill -f "Xvfb $DISP" 2>/dev/null
sleep 1
Xvfb $DISP -screen 0 1280x800x24 >/tmp/xvfb.log 2>&1 &
XVFB=$!
sleep 1

cd "$REPO" || exit 1
DISPLAY=$DISP ./bin/Debug/rspektrum "$WAV" >/tmp/rspek.log 2>&1 &
APP=$!
sleep 5  # initial load

# Make sure the app window is focused so key events land on it.
WID=$(DISPLAY=$DISP xdotool search --name "Spectrogram" | head -1)
[ -n "$WID" ] && DISPLAY=$DISP xdotool windowactivate "$WID" 2>/dev/null
sleep 0.3

xd() { DISPLAY=$DISP xdotool "$@" 2>>/tmp/xdotool.log; }

for act in "$@"; do
    # shellcheck disable=SC2086
    set -- $act
    case "$1" in
        sleep) sleep "$2" ;;
        click)
            xd mousemove "$2" "$3"; sleep 0.1
            xd mousedown 1;         sleep 0.2   # hold across >=1 frame
            xd mouseup 1;           sleep 0.15
            ;;
        drag)
            xd mousemove "$2" "$3"; sleep 0.1
            xd mousedown 1;         sleep 0.1
            xd mousemove "$4" "$5"; sleep 0.2
            xd mouseup 1;           sleep 0.15
            ;;
        rdrag)
            xd keydown alt;         sleep 0.05
            xd mousemove "$2" "$3"; sleep 0.1
            xd mousedown 1;         sleep 0.1
            xd mousemove "$4" "$5"; sleep 0.2
            xd mouseup 1;           sleep 0.1
            xd keyup alt;           sleep 0.15
            ;;
        wheel)
            # "wheel X Y N [mod]" — N wheel clicks at (X,Y); N<0 scrolls down.
            # X11 maps wheel up/down to buttons 4/5. Each click needs its own
            # frame, same edge-detect reason as the click helper above.
            xd mousemove "$2" "$3"; sleep 0.1
            _n="$4"; _btn=4
            if [ "$_n" -lt 0 ]; then _btn=5; _n=$(( -_n )); fi
            _mod="${5:-}"
            [ -n "$_mod" ] && { xd keydown "$_mod"; sleep 0.05; }
            _i=0
            while [ "$_i" -lt "$_n" ]; do
                xd click "$_btn"; sleep 0.05
                _i=$(( _i + 1 ))
            done
            [ -n "$_mod" ] && { xd keyup "$_mod"; sleep 0.05; }
            sleep 0.15
            ;;
        *) xd "$@"; sleep 0.15 ;;
    esac
done
sleep 0.3

DISPLAY=$DISP import -window root "$OUT" 2>/tmp/import.log
RC=$?
kill $APP 2>/dev/null
kill $XVFB 2>/dev/null
wait 2>/dev/null
echo "capture rc=$RC -> $OUT"
ls -la "$OUT" 2>/dev/null
