#!/bin/bash

# omarchy:summary=Pick a screen region over frozen screen content
# omarchy:args=[region|windows|smart|fullscreen] [--keep-freeze] [--match-monitor]
# omarchy:hidden=true

# Prints the picked geometry in slurp's "X,Y WxH" format, or exits 1 when the
# pick is cancelled. Shared by screenshot and screen recording so the picker
# UX stays identical.
#
#   region          freeform selection
#   windows         snap selection to a monitor or window rectangle
#   smart           freeform with window/monitor rects hinted; a bare click
#                   (area < 20px^2) snaps to the rectangle it landed in
#   fullscreen      the focused monitor, no interaction
#
#   --keep-freeze   leave the hyprpicker screen freeze running and print its
#                   PID as the first output line (empty when no freeze was
#                   started); the caller owns killing it
#   --match-monitor print "monitor:NAME" instead when the picked geometry
#                   exactly matches a monitor

FULLSCREEN_MARKER="${XDG_RUNTIME_DIR:-/tmp}/omarchy-capture-region-fullscreen"

# Pressing Return while slurp is open captures the entire focused monitor:
# a bind scoped to slurp's layer surface (default/hypr/bindings/utilities.lua)
# invokes this mode, which flags the intent and dismisses slurp.
if [[ ${1:-} == "--take-fullscreen" ]]; then
  pgrep -x slurp >/dev/null || exit 0
  touch "$FULLSCREEN_MARKER"
  pkill -x slurp
  exit 0
fi

MODE=smart
KEEP_FREEZE=false
MATCH_MONITOR=false

for arg in "$@"; do
  case $arg in
  --keep-freeze) KEEP_FREEZE=true ;;
  --match-monitor) MATCH_MONITOR=true ;;
  *) MODE=$arg ;;
  esac
done

# accounting for portrait/transformed displays
JQ_MONITOR_GEO='
  def format_geo:
    .x as $x | .y as $y |
    (.width / .scale | floor) as $w |
    (.height / .scale | floor) as $h |
    .transform as $t |
    if $t == 1 or $t == 3 then
      "\($x),\($y) \($h)x\($w)"
    else
      "\($x),\($y) \($w)x\($h)"
    end;
'

get_rectangles() {
  local active_workspace=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .activeWorkspace.id')
  hyprctl monitors -j | jq -r --arg ws "$active_workspace" "${JQ_MONITOR_GEO} .[] | select(.activeWorkspace.id == (\$ws | tonumber)) | format_geo"
  hyprctl clients -j | jq -r --arg ws "$active_workspace" '.[] | select(.workspace.id == ($ws | tonumber)) | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"'
}

focused_monitor_geo() {
  hyprctl monitors -j | jq -r "${JQ_MONITOR_GEO} .[] | select(.focused == true) | format_geo"
}

# Runs slurp; an empty result with the fullscreen marker present means Return
# was pressed, so the focused monitor is the selection.
pick() {
  local selection
  rm -f "$FULLSCREEN_MARKER"
  selection=$(slurp "$@" 2>/dev/null)

  if [[ -z $selection && -e $FULLSCREEN_MARKER ]]; then
    rm -f "$FULLSCREEN_MARKER"
    selection=$(focused_monitor_geo)
  fi

  printf '%s' "$selection"
}

FREEZE_PID=""
freeze_screen() {
  hyprpicker -r -z >/dev/null 2>&1 &
  FREEZE_PID=$!
  sleep .1
}

cleanup_freeze() {
  [[ $KEEP_FREEZE == true ]] && return
  [[ -n $FREEZE_PID ]] && kill $FREEZE_PID 2>/dev/null
}
trap cleanup_freeze EXIT

case "$MODE" in
region)
  freeze_screen
  SELECTION=$(pick)
  ;;
windows)
  freeze_screen
  SELECTION=$(get_rectangles | pick -r)
  ;;
fullscreen)
  SELECTION=$(focused_monitor_geo)
  ;;
smart | *)
  RECTS=$(get_rectangles)
  freeze_screen
  SELECTION=$(echo "$RECTS" | pick)

  # A bare click (area < 20px^2) snaps to whichever rectangle it landed in,
  # so users don't end up with accidental 2px captures. X and Y can be
  # negative (Hyprland monitor positions in multi-display layouts).
  if [[ $SELECTION =~ ^(-?[0-9]+),(-?[0-9]+)[[:space:]]([0-9]+)x([0-9]+)$ ]] && ((BASH_REMATCH[3] * BASH_REMATCH[4] < 20)); then
    click_x=${BASH_REMATCH[1]}
    click_y=${BASH_REMATCH[2]}

    while IFS= read -r rect; do
      [[ $rect =~ ^(-?[0-9]+),(-?[0-9]+)[[:space:]]([0-9]+)x([0-9]+)$ ]] || continue
      rect_x=${BASH_REMATCH[1]}
      rect_y=${BASH_REMATCH[2]}
      rect_width=${BASH_REMATCH[3]}
      rect_height=${BASH_REMATCH[4]}

      if ((click_x >= rect_x && click_x < rect_x + rect_width && click_y >= rect_y && click_y < rect_y + rect_height)); then
        SELECTION="${rect_x},${rect_y} ${rect_width}x${rect_height}"
        break
      fi
    done <<<"$RECTS"
  fi
  ;;
esac

[[ $KEEP_FREEZE == true ]] && echo "$FREEZE_PID"

[[ -n $SELECTION ]] || exit 1

if [[ $MATCH_MONITOR == true ]]; then
  monitor=$(hyprctl monitors -j | jq -r --arg geo "$SELECTION" "${JQ_MONITOR_GEO} .[] | select(format_geo == \$geo) | .name" | head -1)
  if [[ -n $monitor ]]; then
    echo "monitor:$monitor"
    exit 0
  fi
fi

echo "$SELECTION"
