#!/bin/zsh
use notify

DEPENDENCIES+=(i3-msg xdotool xrandr)
#####################################################################

USAGE__description="
	usage: <path-executable> [client-class] [...options...]
	"

USAGE__options="
	  -c, --client <string>   if different from the executable name, xprop CLIENT_CLASS

	  -s, --scale <value>     (default: 0.8 or 0.5 if screen width >3000px)
	  -x, --x-offset <value>  (default: 0.0)
	  -y, --y-offset <value>  (default: 0.0)

	  -a, --always-launch     invoke executable even if client-class exists
	  -n, --no-resize         don't resize the window (ignores -sxy flags)
	  -l, --no-center         leave the window wherever it was last positioned

	  --has-statusbar-icon    (default: false) use if program has a statusbar icon

	  -h, --help              print this message and exit
	  "

USAGE__description="
	Makes it easy to bind appications to key shortcuts without having to
	spin up redundant instances or cycle through the scratchpad queue.

	Performs a variety of tasks based on states:
	  1) starts and application
	  2) adds all instances of the specified application to the scratchpad
	  3) (toggle) hides all visible instances
	  4) (toggle) shows all scratchpad-hidden instances
"

#####################################################################

MAIN() {
	local SCWRYPTS_NOTIFICATION_ENGINES=(echo notify.desktop)
	local APPLICATION CLIENT_CLASS

	local XFFSET=0.0
	local YFFSET=0.0
	local SCALE=0.8
	[[ $(xrandr | grep primary | awk '{print $4;}' | sed 's/x.*//') -gt 3000 ]] \
		&& SCALE=0.5

	local ALWAYS_LAUNCH=0
	local RESIZE=1
	local MOVE=1
	local MIN_ACTIVE=1

	while [[ $# -gt 0 ]]
	do
		case $1 in
			( -c | --client   ) CLIENT_CLASS="$2"; shift 1 ;;
			( -x | --x-offset ) XFFSET=$2; shift 1 ;;
			( -y | --y-offset ) YFFSET=$2; shift 1 ;;
			( -s | --scale    ) SCALE=$2;  shift 1 ;;

			( -a | --always-launch ) ALWAYS_LAUNCH=1 ;;
			( -n | --no-resize     ) RESIZE=0 ;;
			( -l | --no-center     ) MOVE=0 ;;

			( --has-statusbar-icon ) MIN_ACTIVE=2 ;;

			( -h | --help ) USAGE; exit 0 ;;

			( * )
				[ ! $APPLICATION  ] && APPLICATION="$1" \
					|| echo.error "extra positional argument '$1'"
		esac
		shift 1
	done

	[ ! $APPLICATION  ] && echo.error 'path-executable required'
	[ ! $CLIENT_CLASS ] && CLIENT_CLASS=$APPLICATION

	[ $APPLICATION ] && {
		utils.dependencies.check $APPLICATION || {
			notify.error "$APPLICATION not found"
		}
	}

	utils.check-errors --fail

	xrandr | grep primary | awk '{print $4;}' | grep -q '^[0-9x+]\+$' || {
		xrandr --output $(xrandr | grep ' connected' | awk '{print $1;}' | head -n1) --primary
	}

	local CURRENTLY_ACTIVE=$(xdotool search --onlyvisible --classname $CLIENT_CLASS 2>/dev/null | wc -l)

	local LAUNCH_APP=$ALWAYS_LAUNCH
	echo.status "looking for window process ids"
	xdotool search --class $CLIENT_CLASS || LAUNCH_APP=1

	[[ $LAUNCH_APP -eq 1 ]] && {
		echo.status 'launching application'
		i3-msg "exec --no-startup-id $APPLICATION;"
		sleep .5
	}

	echo.status 'getting target window size'
	WINDOW_SIZE=$(\
		xrandr \
			| grep 'connected primary' \
			| sed 's/.*connected primary \([^x]*\)x\([^+]*\).*/\1 \2/' \
			| awk -v f=$SCALE -v x=$XFFSET -v y=$YFFSET \
				'{print int($1*f+x)," ",int($2*f+y);}'\
	)
	echo.debug "window size: $WINDOW_SIZE"

	echo.status 'moving window to scratchpad'
	i3-msg "[class=$CLIENT_CLASS] move scratchpad"

	[[ $RESIZE -eq 1 ]] \
		&& echo.status 'resizing window' \
		&& i3-msg "[class=$CLIENT_CLASS] resize set $WINDOW_SIZE"

	[[ $CURRENTLY_ACTIVE -lt $MIN_ACTIVE ]] && {
		echo.status 'pulling window from scratchpad to foreground'
		i3-msg "[class=$CLIENT_CLASS] scratchpad show"
	}

	echo.status 'moving window to center of current screen'
	[[ $MOVE -eq 1 ]] && i3-msg "[class=$CLIENT_CLASS] move position center"

	return 0
}
