#!/bin/sh

# Control the input devices
# Depends: xinput, setxkbmap

help() {
	B=$(tput bold)
	U=$(tput smul)
	N=$(tput sgr0)

	cat << EOF
${B}NAME${N}
	inputctl - control the input devices

${B}SYNOPSIS${N}
	${B}inputctl${N} ${U}OPTION${N} [${U}ARG${N}]

${B}OPTIONS${N}
	${B}-h${N}	Display usage message and exit.

	${B}-d${N} ${U}STATE${N}
		Set touchpad state, possible values: toggle, on/off, 1/0.

	${B}-k${N} ${U}STATE${N}
		Set keyboard state, possible values: toggle, on/off, 1/0.

	${B}-s${N} ${U}STATE${N}
		Set touchscreen state, possible values: toggle, on/off, 1/0.

	${B}-t${N} ${U}STATE${N}
		Set tablet state, possible values: ccw/normal/reset
EOF
}

setxkbmap -option caps:swapescape

# Exit if no option is provided
[ "$#" -eq 0 ] && help && exit 1

# Set required X variables
export DISPLAY=:0
export XAUTHORITY="$XDG_DATA_HOME/xorg/Xauthority"

# Option handling
SCRIPT="$(basename "$0")"
while getopts ':h?d:k:s:t:' opt; do
	case $opt in
		h)
			help
			exit 0
			;;
		d)
			OPTION="d"
			ARG="$OPTARG"
			DEV="SYNA3602:00 0911:5288 Touchpad"
			;;
		k)
			OPTION="k"
			ARG="$OPTARG"
			;;
		s)
			OPTION="s"
			ARG="$OPTARG"
			DEV="pointer:04F3200A:00 04F3:2373"
			;;
		t)
			OPTION="t"
			ARG="$OPTARG"
			DEV="HUION Huion Tablet_HS64 Pen stylus"
			;;
		:)
			echo "$SCRIPT: option requires an argument '$OPTARG'"
			echo "Try '$SCRIPT -h' for more information."
			exit 1
			;;
		\?)
			echo "$SCRIPT: invalid option '$OPTARG'"
			echo "Try '$SCRIPT -h' for more information."
			exit 1
			;;
	esac
done

# Enable mathematics in POSIX shell
calc() { awk "BEGIN{print $*}"; }

toggle_device() {
	STATUS=$(xinput --list-props "$2" | awk '/Device Enabled/ { print $4 }')
	[ "$STATUS" -eq 1 ] && xinput --disable "$2" || xinput --enable "$2"
}

device() {
	case "$1" in
		1 | on)
			xinput --enable "$2"
			;;
		0 | off)
			xinput --disable "$2"
			;;
		t*)
			toggle_device "$2"
			;;
		*)
			echo "$SCRIPT: invalid argument '$1'"
			echo "Try '$SCRIPT -h' for more information."
			exit 1
			;;
	esac
}

keyboard() {
	[ -z "$1" ] && return 1

	if [ "$1" = "toggle" ]; then
		if setxkbmap -query | grep -q options; then
			keyboard "off"
		else
			keyboard "on"
		fi

	elif [ "$1" = "on" ]; then
		# Swap caps lock with escape
		setxkbmap -option caps:swapescape

		# Swap left crtl with left alt
		# setxkbmap -option ctrl:swap_lalt_lctl

		# Set touchpad toggle keyboard symbol
		# xmodmap -e "keycode 93 = XF86iTouch"

	elif [ "$1" = "off" ]; then
		# Clear all key mappings
		setxkbmap -option ''
	fi
}

tablet() {
	case "$1" in
		ccw | normal)
			;;
		reset)
			xsetwacom set "$2" ResetArea
			xsetwacom set "$2" Rotate none
			xsetwacom set "$2" MapToOutput "desktop"
			exit 0
			;;
		*)
			echo "$SCRIPT: invalid argument '$1'"
			echo "Try '$SCRIPT -h' for more information."
			exit 1
			;;
	esac

	screenDimensions=$(xrandr -q | grep primary | awk '{ print substr($4, 0, index($4, "+") - 1) }')
	screenWidth=$(echo "$screenDimensions" | cut -d 'x' -f 1)
	screenHeight=$(echo "$screenDimensions" | cut -d 'x' -f 2)

	inputctl -t reset

	tabletDimensions=$(xsetwacom get "$2" Area)
	tabletWidth=$(echo "$tabletDimensions" | cut -d ' ' -f 3)
	tabletHeight=$(echo "$tabletDimensions" | cut -d ' ' -f 4)

	case "$1" in
	ccw)
		calculatedWidth=$(calc "$tabletHeight * $screenHeight / $screenWidth")
		offsetWidth=$(calc "($tabletWidth - $calculatedWidth) / 2" | cut -d '.' -f 1)
		calculatedWidth=$(calc "$calculatedWidth + $offsetWidth" | cut -d '.' -f 1)

		xsetwacom set "$2" Area "$offsetWidth" 0 "$calculatedWidth" "$tabletHeight"
		xsetwacom set "$2" Rotate ccw
		;;
	normal)
		calculatedHeight=$(calc "$tabletWidth * $screenHeight / $screenWidth" | cut -d '.' -f 1)
		offsetHeight=$(calc "($tabletHeight - $calculatedHeight) / 2" | cut -d '.' -f 1)

		xsetwacom set "$2" Area 0 "$offsetHeight" "$tabletWidth" "$calculatedHeight"
		;;
	esac

	xsetwacom set "$2" MapToOutput "${screenWidth}x${screenHeight}+0+0"
}

# Option execution
# if [ "$DEV" = "Keyboard" ]; then
# 	keyboard "$ARG"
# else
case "$OPTION" in
	d | s)
		device "$ARG" "$DEV"
		;;
	k)
		keyboard "$ARG"
		;;
	t)
		tablet "$ARG" "$DEV"
		;;
esac

# Useful input diagnostics packages:
# - xinput
# - xev
# - evtest
#
# - setxkbmap -query
# - xmodmap -pke

# https://superuser.com/questions/437053/firefox-doesnt-recognize-my-alt-keys-anymore
# https://www.x.org/releases/X11R7.7/doc/xorg-docs/input/XKB-Config.html