#!/bin/bash

# blob:summary=Run the Blob screensaver using random effects from TTE.

effect_command=$(blob-screensaver-effect) || exit 1

effect_args() {
  local input="$HOME/.config/blob/branding/screensaver.txt"

  if [[ $effect_command == "ttfx" ]]; then
    printf '%s\n' -i "$input" --frame-rate 120 --canvas-width 0 --canvas-height 0 \
      --reuse-canvas --anchor-canvas c --anchor-text c --random-effect --no-eol \
      --no-restore-cursor
    return 0
  fi

  local effects=(
    beams binarypath blackhole bouncyballs bubbles burn colorshift crumble
    decrypt errorcorrect expand fireworks middleout orbittingvolley overflow
    pour print rain randomsequence rings scattered slice slide spotlights
    spray swarm sweep synthgrid unstable vhstape waves wipe
  )

  printf '%s\n' -i "$input" --frame-rate 120 --canvas-width 0 --canvas-height 0 \
    --anchor-canvas c --anchor-text c --no-color \
    "${effects[RANDOM % ${#effects[@]}]}"
}

screensaver_in_focus() {
  hyprctl activewindow -j | jq -e '.class == "org.blob.screensaver"' >/dev/null 2>&1
}

exit_screensaver() {
  hyprctl eval 'hl.config({ cursor = { invisible = false } })' &>/dev/null || hyprctl keyword cursor:invisible false &>/dev/null || true
  pkill -x "$effect_command" 2>/dev/null
  pkill -f '[o]rg.blob.screensaver' 2>/dev/null
  exit 0
}

# Exit the screensaver on signals and input from keyboard and mouse
trap exit_screensaver SIGINT SIGTERM SIGHUP SIGQUIT

printf '\033]11;rgb:00/00/00\007'  # Set background color to black

hyprctl eval 'hl.config({ cursor = { invisible = true } })' &>/dev/null || hyprctl keyword cursor:invisible true &>/dev/null

tty=$(tty 2>/dev/null)

# Terminals allocate the pty at the default 80x24 and only resize it once the
# compositor has told the window how big it is. ttfx measures the terminal once,
# at startup, so starting it before the resize lands sizes an 80x24 canvas and
# paints it into the corner of a fullscreen window.
wait_for_terminal_resize() {
  local deadline=$((SECONDS + 2))
  while ((SECONDS < deadline)) && [[ $(stty size 2>/dev/null) == "24 80" ]]; do
    sleep 0.02
  done
}

wait_for_terminal_resize

while true; do
  mapfile -t effect_arguments < <(effect_args)
  "$effect_command" "${effect_arguments[@]}" &

  while pgrep -t "${tty#/dev/}" -x "$effect_command" >/dev/null; do
    if read -n1 -t 1 || ! screensaver_in_focus; then
      exit_screensaver
    fi
  done
done
