#!/bin/dash

# fsbar4roxdrv v2.1 (formerly ROX_DrivesFreeSpace) for Fatdog64
# Copyright © JakeSFR'2013-2016,2021,2022
# GNU GPL v2 applies

# user settings

INTERVAL=5			# in seconds
FREECOL='22cc22'	# color for free space (rrggbb)
USEDCOL='cc2222'	# color for used space (rrggbb)
OPACITY='0.75'		# 0.0 (fully transparent) ... 1.0 (fully opaque)
FREEMSG="Free:"		# message for available space in tooltip

# end user settings

# -----------------------------------------------------------------------------

LANG=C	# for speed
BB=$(which busybox 2>/dev/null)	# BB df for more accurate fractional part; BB awk is faster

# sanity check
[ "$INTERVAL" -eq "$INTERVAL" -a $INTERVAL -ge 1 ] 2>/dev/null || INTERVAL=5

DRIVE_ICON_ROOT="/tmp/fatdog-drive-icons.$USER.$XSESSION_ID"
[ -d "$DRIVE_ICON_ROOT" ] || exit 1

COMMENT_ID='<!-- FS_BAR -->'	# to identify the line to be replaced

FS_BAR_TMPL='
'"$COMMENT_ID"'
<defs>
	<linearGradient id="fs_grad" x1="100%" x2="0%">
		<stop offset="_PERC_" stop-color="#'${USEDCOL}'"/>
		<stop offset="_PERC_" stop-color="#'${FREECOL}'"/>
	</linearGradient>
</defs>
<rect fill="url(#fs_grad)" stroke="#000000" stroke-width="1" x="2" y="43" width="44" height="5" opacity="'${OPACITY}'"/>
'
FS_BAR_TMPL="$(echo "$FS_BAR_TMPL" | sed -e ':a;N;$!ba;s/\n//g;s/\t//g')"	# minimize template

# -----------------------------------------------------------------------------

main_loop() {

	local error perc name free appinfo diricon line_old line_new df_old df_new

	while true; do

		error=false
	
		while read -r perc name free; do
	
			case "$name" in
				# LUKS savefile/partitions mounted at boot - dmcrypt0, dmcrypt1, ...
				mapper/dmcrypt[0-9]*)
					name="dm-${name##*dmcrypt}"
					;;
				# Truecrypt/Veracrypt/LUKS (dmcrypt_sdXY)
				mapper/*)
					name="$(readlink -f "/dev/disk/by-id/dm-name-${name##*/}")"
					name="${name##*/}"
					;;
			esac
	
			appinfo="${DRIVE_ICON_ROOT}/${name}/AppInfo.xml"
			diricon="${DRIVE_ICON_ROOT}/${name}/.DirIcon"
	
			# update tooltip
			if [ -f "$appinfo" ]; then
				case "$free" in
					*[0-9])	true				;;
					*)		free="${free}iB"	;;
				esac

				line_old="$(grep -om1 "\( ${FREEMSG} .*\)\?</Summary>" "$appinfo")"
				line_new=" ${FREEMSG} ${free}</Summary>"

				if [ "$line_old" != "$line_new" ]; then
					sed -i 's|'"$line_old"'|'"$line_new"'|' "$appinfo"

					# and update icon
					if [ -f "$diricon" ]; then
						line_old="$(grep -E "^</svg>|^${COMMENT_ID}.*</svg>" "$diricon")"
						line_new="$(echo "$FS_BAR_TMPL" | sed 's|_PERC_|'"$perc"'|g')</svg>"
						if [ "$line_old" != "$line_new" ]; then
							sed -i 's|'"$line_old"'|'"$line_new"'|' "$diricon"
							rox -x "${DRIVE_ICON_ROOT}/${name}"	# re-examine icon
						fi
					fi
	
					# check if the AppDir isn't corrupted and if so, fix it and try again next time
					if ! grep -q '</AppInfo>' "$appinfo" ||
					   ! grep -q "^${comment_id}.*</svg>" "$diricon"
					then
						fatdog-drive-icon-refresh-icon.sh "${name}"
						error=true
					fi
				fi
			fi

		done <<- EOF
		$($BB df -hP 2>/dev/null | $BB awk '/^\/dev\// && !/\/dev\/loop/, sub("^/dev/","",$1) {print $5, $1, $4}')
		EOF

		# if AppDir is broken, don't wait $INTERVAL, go to next iter after 1 sec.
		if [ "$error" = 'true' ]; then
			sleep 1
			continue
		fi
	
		# chill out until df output's changed or fifo datestamp is newer than $INTERVAL (+ a couple of seconds) ago
		while true; do
			sleep ${INTERVAL}
			[ $(( $(date +%s) - $(stat -c %Y "${DRIVE_ICON_ROOT}/fifo") )) -le $((INTERVAL+2)) ] && break
			df_new=$($BB df -hP 2>/dev/null | $BB awk '/^\/dev\// && !/\/dev\/loop/, sub("^/dev/","",$1) {print $5, $4}')
			[ "$df_old" != "$df_new" ] && break
		done

		df_old="$df_new"
	
	done
}

# -----------------------------------------------------------------------------

# let's go!
main_loop

# =============================================================================
