#!/bin/sh
#---help---
# Usage:
#   $0 [options] <command> [<value>%]
#   $0 [options] (+|-)[<value>%]
#   $0 [options] [=]<value>%
#   $0 -h
#
# Control device brightness using 'brightnessctl' or 'light' and show
# an on-screen notification using 'avizo-client'.
#
# Commands:
#   + | up          Increase brightness by <value> percents (defaults to 5).
#   - | down        Decrease brightness by <value> percents (defaults to 5).
#   = | set         Set brightness to <value> percents.
#
# Options:
#   -e <exponent>   Change percentage curve to exponential (only for brightnessctl).
#   -D <device>     Specify the device name.
#   -h              Show this message and exit.
#
# This script is part of the avizo package.
#---help---
# This script is POSIX Shell Command Language compliant.
set -eu

PROGNAME='lightctl'

help() {
	local tag='---help---'
	sed -n "/^#$tag/,/^#$tag/{/^#$tag/d; s/^# \\?//; s|\$0|$0|; p}" "$0"
}

die() {
	printf "$PROGNAME: %s\n" "$1" >&2
	exit 1
}

is_integer() {
	expr "$1" : '[0-9]\+$' >/dev/null
}

is_float() {
	expr "$1" : '[0-9]\+\.[0-9]\+$' >/dev/null
}

exp=
dev=
optind=1
while getopts ':e:D:h' OPT; do
	case "$OPT" in
		e) exp=$OPTARG;;
		D) dev=$OPTARG;;
		h) help; exit 0;;
		\?) case "$OPTARG" in
		    	[0-9]*) break;;
		    	*) die "unknown option: -$OPTARG";;
		    esac
		;;
	esac
	optind=$OPTIND  # hack to make -<value>% work correctly
done
shift $((optind -1))

if [ $# -lt 1 ] || [ $# -gt 2 ]; then
	die "invalid number of arguments (see '$0 -h')"
fi

case "$1" in
	[=+-][0-9]*%) cmd=${1%%[0-9]*}; value=${1#[=+-]};;
	[0-9]*%) cmd='='; value=$1;;
	*) cmd=$1; value=${2:-5};;
esac
value=${value%\%}

if ! is_integer "$value"; then
	die "invalid value: '$value'"
fi

# Note: 'raise' and 'lower' are only for backward compatibility with
#  the previous version of this script.
case "$cmd" in
	+ | up | raise) cmd='+';;
	- | down | lower) cmd='-';;
	= | set) cmd='=';;
	*) die "invalid command: $cmd (see '$0 -h')";;
esac


if command -v brightnessctl >/dev/null; then
	prog='brightnessctl'
	opts="${dev:+-d $dev}"
	out=$(brightnessctl $opts ${exp:+-e$exp} -m set "${value}%${cmd}")
	light=$(printf '%s\n' "$out" | cut -d, -f4)
	light=${light%\%}

elif command -v light >/dev/null; then
	prog='light'
	opts="${dev:+-s $dev}"
	case "$cmd" in
		+) light $opts -A "$value";;
		-) light $opts -U "$value";;
		=) light $opts -S "$value";;
	esac

	light=$(light $opts -G)
else
	die 'command not found: brightnessctl or light'
fi

if ! is_integer "$light" && ! is_float "$light"; then
	die "$prog returned invalid brigtness: '$light'"
fi

if is_float "$light"; then
    light=${light%.*}
fi

if [ "$light" -le 33 ]; then
	image='brightness_low'
elif [ "$light" -le 66 ]; then
	image='brightness_medium'
else
	image='brightness_high'
fi

progress=$(echo "$light" | awk '{ printf "%.2f", $1 / 100 }')

avizo-client --image-resource="$image" --progress="$progress"
