#!/bin/bash
# focus-dir.sh - focus the nearest window in a given direction (h/j/k/l)
# Usage: focus-dir.sh h|j|k|l   (or left/down/up/right)

DIR=$1

if [ -z "$DIR" ]; then
    echo "Usage: $0 h|j|k|l"
    exit 1
fi

# --- get current desktop ---
CUR_DESKTOP=$(xdotool get_desktop)

# --- get focused window geometry ---
FOCUSED=$(xdotool getactivewindow)
read -r FX FY FW FH < <(xdotool getwindowgeometry --shell "$FOCUSED" | awk -F= '
    /^X=/ {x=$2} /^Y=/ {y=$2} /^WIDTH=/ {w=$2} /^HEIGHT=/ {h=$2}
    END {print x, y, w, h}
')
FCX=$((FX + FW / 2))
FCY=$((FY + FH / 2))

# --- get list of normal windows on current desktop ---
ALL_WINDOWS=$(wmctrl -l -x | awk '$2!="-1" {print $1}')

BEST=""
BEST_DIST=""

for w in $ALL_WINDOWS; do
    wid=$(printf "%d" "$w")

    [ "$wid" = "$FOCUSED" ] && continue

    win_desktop=$(xdotool get_desktop_for_window "$wid" 2>/dev/null) || continue
    [ "$win_desktop" = "$CUR_DESKTOP" ] || continue

    read -r WX WY WW WH < <(xdotool getwindowgeometry --shell "$wid" | awk -F= '
        /^X=/ {x=$2} /^Y=/ {y=$2} /^WIDTH=/ {w=$2} /^HEIGHT=/ {h=$2}
        END {print x, y, w, h}
    ')
    WCX=$((WX + WW / 2))
    WCY=$((WY + WH / 2))

    DX=$((WCX - FCX))
    DY=$((WCY - FCY))

    case "$DIR" in
        h|left)
            [ "$DX" -ge 0 ] && continue
            ;;
        l|right)
            [ "$DX" -le 0 ] && continue
            ;;
        k|up)
            [ "$DY" -ge 0 ] && continue
            ;;
        j|down)
            [ "$DY" -le 0 ] && continue
            ;;
        *)
            echo "Invalid direction: $DIR"
            exit 1
            ;;
    esac

    # Manhattan distance, weighted to prefer windows roughly in line
    DIST=$(( (DX<0?-DX:DX) + (DY<0?-DY:DY) ))

    if [ -z "$BEST_DIST" ] || [ "$DIST" -lt "$BEST_DIST" ]; then
        BEST_DIST=$DIST
        BEST=$wid
    fi
done

if [ -n "$BEST" ]; then
    xdotool windowactivate "$BEST"
fi
