#!/bin/sh
set -e

# based on https://github.com/carrot69/keep-presence/

test -n "$XJIGGLER_DELAY_ACTION" \
	|| XJIGGLER_DELAY_ACTION=300	# seconds
test -n "$XJIGGLER_DELAY_DETECTION" \
	|| XJIGGLER_DELAY_DETECTION=60	# seconds
test -n "$XJIGGLER_KEYBOARD_ENABLED" \
	|| XJIGGLER_KEYBOARD_ENABLED=''	# zero-len nonzero-len
test -n "$XJIGGLER_MOUSE_DIRECTION" \
	|| XJIGGER_MOUSE_DIRECTION=DIAGONAL # "CIRCULAR" "DIAGONAL"
test -n "$XJIGGLER_MOUSE_DISTANCE" \
	|| XJIGGLER_MOUSE_DISTANCE=1	# pixels
test -n "$XJIGGLER_MOUSE_ENABLED" \
	|| XJIGGLER_MOUSE_ENABLED=yes	# zero-len nonzero-len

# eval is scary but this use was mentioned in the man page
getmouselocation(){
	eval $(xdotool getmouselocation --shell | sed 's/^/XJIGGLER_/g')
	XJIGGLER_T="$(date '+%s')"
}

jiggle(){
	test -z "$XJIGGLER_MOUSE_ENABLED" \
		|| xdotool mousemove_relative "$XJIGGLER_MOUSE_dX" \
			"$XJIGGLER_MOUSE_dY"
}

pushmouselocation(){
	XJIGGLER_lastT="$XJIGGLER_T"
	XJIGGLER_lastX="$XJIGGLER_X"
	XJIGGLER_lastY="$XJIGGLER_Y"
}

printdebug(){
	printf "XJIGGLER_T=%s\n" "$XJIGGLER_T"	# seconds since epoch
	printf "XJIGGLER_X=%s\n" "$XJIGGLER_X"	# pixels
	printf "XJIGGLER_Y=%s\n" "$XJIGGLER_Y"	# pixels
	printf "XJIGGLER_lastT=%s\n" "$XJIGGLER_lastT"
	printf "XJIGGLER_lastX=%s\n" "$XJIGGLER_lastX"
	printf "XJIGGLER_lastY=%s\n" "$XJIGGLER_lastY"
}

rotatemousedirection(){
	case "$XJIGGLER_MOUSE_DIRECTION" in
	up)	XJIGGLER_MOUSE_DIRECTION=right
		XJIGGLER_MOUSE_dX="$XJIGGLER_MOUSE_DISTANCE"
		XJIGGLER_MOUSE_dY=0
		return;	;;
	right)	XJIGGLER_MOUSE_DIRECTION=down
		XJIGGLER_MOUSE_dX=0
		XJIGGLER_MOUSE_dY="$XJIGGLER_MOUSE_DISTANCE"
		return;	;;
	down)	XJIGGLER_MOUSE_DIRECTION=left
		XJIGGLER_MOUSE_dX=-"$XJIGGLER_MOUSE_DISTANCE"
		XJIGGLER_MOUSE_dY=0
		return;	;;
	CIRCULAR | left)
		XJIGGLER_MOUSE_DIRECTION=up
		XJIGGLER_MOUSE_dX=0
		XJIGGLER_MOUSE_dY=-"$XJIGGLER_MOUSE_DISTANCE"
	DIAGONAL | *)
		XJIGGLER_MOUSE_dX="$XJIGGLER_MOUSE_DISTANCE"
		XJIGGLER_MOUSE_dY="$XJIGGLER_MOUSE_DISTANCE"
		return;	;;
		return; ;;
	esac
}

usage(){
	printf 'Usage: %s (-chm) (-d [distance]) %s\n' \
		"$0" '(-s [action delay seconds])'>&2
	exit 64 # sysexits(3) EX_USAGE
}

while getopts :cd:hms: OPTION
do
	case "$OPTION" in
	c)	XJIGGLER_MOUSE_DIRECTION=DIAGONAL	;;
	d)	XJIGGLER_MOUSE_DISTANCE="$OPTARG)"	;;
	m)	XJIGGLER_MOUSE_ENABLED=''	;;
	s)	XJIGGLER_DELAY_ACTION="$(OPTARG)"	;;
	*)	usage	;;
	esac
done

getmouselocation; pushmouselocation

while true
do

	sleep "$XJIGGLER_DELAY_DETECTION"
	getmouselocation
	if test "$XJIGGLER_lastX" = "$XJIGGLER_X" \
			&& test "$XJIGGLER_lastY" = "$XJIGGLER_Y"
	then	# no movement
		command -v xprintidle \
			&& test "$(xprintidle \
					| sed -e 's/^/0/' -e 's/...$//')" \
				-gt "$XJIGGLER_DELAY_ACTION" \
			|| test "$(printf '%s\n%s\n-\np\n' "$XJIGGLER_T" \
					"$XJIGGLER_lastT" \
				| dc)" -gt "$XJIGGLER_DELAY_ACTION" \
			|| continue	# hasn't been long enough
		rotatemousedirection; jiggle
		printf '%s: Jiggled:\n' "$0"
		printdebug | sed 's/^/\t/g'
		getmouselocation
	else	# movement
		printf '%s: Movement detected:\n' "$0"
		printdebug | sed 's/^/\t/g'
	fi
	pushmouselocation
done >&2
