#!/bin/dash

# toggle-touchpad - License: GNU GPL2 - Copyright (C) James Budiono 2016-2022, step 2023

WORKDIR="$XDG_RUNTIME_DIR/toggle-touchpad"
FIFOIN="$WORKDIR/${0##*/}.in"
ICON_ENABLED='/usr/share/icons/hicolor/48x48/apps/touchpad.png'
ICON_DISABLED="$WORKDIR/${0##*/}.png"
EMBLEM_DISABLED='/usr/share/icons/Adwaita/24x24/status/dialog-error.png'
TRAY_TITLE="tray:${0##*/}"
YAD=yad

export TEXTDOMAIN=fatdog OUTPUT_CHARSET=UTF-8

###
i18n_table() {
# i18n_table.sh - Copyright (C) 2016-2023, step - https://github.com/step-/i18n-table
	{
read i18n_click_to_toggle
read i18n_touchpad_enabled
read i18n_touchpad_disabled
read i18n_cannot_detect_touchpad
	} << EOF
$(gettext -es -- \
"Click icon to toggle touchpad.\n" \
"Touchpad is enabled.\n" \
"Touchpad is disabled.\n" \
"Cannot detect a touchpad.\n" \
)
EOF
}

die() {
	if [ -n "$DISPLAY" ] && ! [ -t 0 ]; then
		env YAD_OPTIONS="
		--text=\"\n$*\n\"
		--window-icon=\"$ICON_ENABLED\"
		--button=gtk-ok --buttons-layout=spread
		--borders=10 --center --timeout 10
		" $YAD --title "${0##*/}" &
	else
		echo "$@"
	fi
	exit 1
}

enable() {
	# currently disabled, so enable it
	xinput enable $TOUCHPAD_ID
	echo "Touchpad enabled"
	update_tray_state 1
}

disable() {
	# currently enabled, so disable it
	xinput disable $TOUCHPAD_ID
	echo "Touchpad disabled"
	update_tray_state 0
}

quiet_status() {
# return 0(enabled) 1(disabled) 127(error)
# $TOUCHPAD_ENABLED==1(enabled) $TOUCHPAD_ENABLED=""(disabled/error)
	TOUCHPAD_ENABLED=$(xinput list-props $TOUCHPAD_ID | sed -n "/Device Enabled/ {s/^.*://;p}")
	[ -z "$TOUCHPAD_ENABLED" ] && return 127
	[ $TOUCHPAD_ENABLED -eq 1 ]
}

toggle() {
	# enabled status
	quiet_status
	[ $? -eq 127 ] && exit
	if [ $TOUCHPAD_ENABLED -eq 1 ]; then
		disable
	else
		enable
	fi
}

start_tray() {
	[ -d "$WORKDIR" ] || mkdir -p "$WORKDIR"
	quiet_status
	status=$?
	rm -f "$FIFOIN" "$ICON_DISABLED" "${ICON_DISABLED}[abe]"
	mkfifo "$FIFOIN" || return 1
	exec 3<>"$FIFOIN"
	env YAD_OPTIONS="
	--icon-size=24 `# icon-size does not work for themed icons`
	--image=\"$ICON_ENABLED\"
	--listen
	--command=\"toggle-touchpad -t\"
	--menu=\"\
	gtk-quit!sh -c \\\"exec kill \$YAD_PID\\\"\
	\"
	--text=\"$i18n_click_to_toggle\"
	" $YAD --title="$TRAY_TITLE" --notification <&3 &

	sleep 0.2
	update_tray_state $((!$status))
}

update_tray_state() { # $1-{1(enabled),0(disabled)}
	[ -n "$opt_tray" ] || return 0
	if [ "$1" -eq 1 ]; then
		printf '%s\n' > "$FIFOIN" \
			"tooltip:$i18n_click_to_toggle\n$i18n_touchpad_enabled"
	else
		printf '%s\n' > "$FIFOIN" \
			"tooltip:$i18n_click_to_toggle\n$i18n_touchpad_disabled"
	fi
	update_icon_state $1
}

update_icon_state() { # $1-{1(enabled),0(disabled)}
	# fall back to enabled icon
	echo > "$FIFOIN" "icon:$ICON_ENABLED"
	if [ "$1" -ne 1 ]; then
		# create disabled icon
		if ! [ -s "$ICON_DISABLED" ]; then
			# EMBLED_DISABLED over ICON_ENABLED -> ICON_DISABLED
			pngtopam -alphapam "$EMBLEM_DISABLED" > "${ICON_DISABLED}e" &&
			pngtopam -alphapam "$ICON_ENABLED" > "${ICON_DISABLED}b" &&
			pamcomp -align=center -valign=middle \
				"${ICON_DISABLED}e" "${ICON_DISABLED}b" |
				pamtopng > "$ICON_DISABLED"

			# alternative: invert_color(ICONS_ENABLED) -> ICON_DISABLED
			# pngtopam -alpha "$ICON_ENABLED" > "${ICON_DISABLED}a" &&
			# 	pngtopam "$ICON_ENABLED" | pnminvert |
			# 	pnmtopng -alpha "${ICON_DISABLED}a" > "$ICON_DISABLED"
		fi &&
			# update disabled icon
			echo > "$FIFOIN" "icon:$ICON_DISABLED"
	fi
}

detect_touchpad_or_die () {
	# bcm5974 for MacbookPro9,2
	TOUCHPAD_ID=$(xinput |
		sed -En '/([Tt]ouch[Pp]ad|bcm5974).* pointer |[Tt]ouch[Pp]ad/ {s/^.*id=//; s/[\t\s].*//; p}')
	[ -n "$TOUCHPAD_ID" ] || die "$i18n_cannot_detect_touchpad"
}

### main
if ! i18n_table; then
	printf >&2 '%s\n' "${0##*/}: error in i18n_table: possible causes:" \
	'- invalid syntax' '- missing MSGID' "- MSGID doesn't end with \n"
fi
: "1($1)" "2($2)"
opt_tray=
case $1 in
	help|--help|-h) die "Usage: ${0##*/} [-t,--tray] [enable|disable]" ;;
	-t|--tray) shift; opt_tray=tray
		if ! pgrep -f -- "--title=$TRAY_TITLE" > /dev/null; then
			detect_touchpad_or_die
			start_tray
			[ $# -eq 0 ] && exit
		fi
		;;
esac

detect_touchpad_or_die
case $1 in
	enable|enabled)  enable ;;
	disable|disabled) disable ;;
	"") toggle ;;
esac
