#!/bin/bash -x

# Fonction de réinitialisation en cas de perte de la connexion
self-reset() {
	echo "<span foreground=\"#515151\">[--:-- --:-- --:--]</span>"
	sleep 1
	exec "$0"
}

trap self-reset PIPE

# Initialisation de la connexion au serveur
# coproc nc -U /home/breizh/.mpd/socket
coproc socat -T 5 stdio /home/breizh/.mpd/socket
IN=${COPROC[1]}
OUT=${COPROC[0]}
#echo "password xxx" >&"${IN}"

# Initialisation des valeurs par défaut et des fonctions
declare -i SCROLL=50 I=0
declare -- artist song
declare -A old

human_time() {
	local seconds="${1}"
	if [[ -z "$seconds" || "$seconds" -lt 0 ]]
	then
		echo "--:--"
		return
	fi
	local minutes=$(( seconds / 60 ))
	seconds=$(( seconds % 60 ))
	if [[ "$minutes" -ge 90 ]]
	then
		local hours=$(( minutes / 60 ))
		minutes=$(( minutes % 60 ))
		printf "%2dh%02d\n" "$hours" "$minutes"
	else
		printf "%2d:%02d\n" "$minutes" "$seconds"
	fi
	return
}

# Initialisation de l’état
echo "status" >&"$IN"
while read -t 0.1 -u "$OUT" output
do
	[[ "$output" =~ : ]] && o[${output%%:*}]="${output#*: }"
done

# Boucle principale
while [[ -n "$COPROC_PID" ]]
do
	# Gestion du clic, fait office de délai si aucune action (une seconde).
	# En cas de clic, l’actualisation de l’affichage sera instantanné.
	read -t 0.85 BLOCK_BUTTON

	case $BLOCK_BUTTON in
		1|3)
			if [[ "${o["state"]}" == stop ]]
			then
				echo "play" >&"${IN}" || self-reset
				sed '/^OK$/q' <&"$OUT" &>/dev/null
			fi
		;;&
		2)
			if [[ "${o["state"]}" == stop ]]
			then
				echo "play" >&"${IN}" || self-reset
			else
				echo "pause" >&"${IN}" || self-reset
			fi
		;;&
		1) echo "previous" >&"${IN}" || self-reset ;;&
		3) echo "next" >&"${IN}" || self-reset ;;&
		1|2|3) sed '/^OK$/q' <&"$OUT" &>/dev/null ;;
		4) I="I-2"; [[ "$I" -lt 0 ]] && I=0 ;;
	esac

	# Réinitialisation de l’état
	unset o output
	declare -A o

	# Récupération de l’état et des informations du morceau en cours
	echo "status" >&"$IN" || self-reset
	echo "currentsong" >&"$IN" || self-reset
	while read -t 0.1 -u "$OUT" output
	do
		[[ "$output" =~ : ]] && o[${output%%:*}]="${output#*: }"
	done

	# Choix des couleurs selon l’état
	case "${o["state"]}" in
		play ) status="<span foreground=\"#99CC99\">" ;;
		pause ) status="<span foreground=\"#FFCC66\">" ;;
		stop ) status="<span foreground=\"#F2777A\">" ;;
	esac

	# En cas de changement de morceau,
	# on réinitialise l’affichage défilant
	if [[ "${o["file"]}" != "${old["file"]}" || "${o["Title"]}" != "${old["Title"]}" || "${o["Name"]}" != "${old["Name"]}" ]]
	then
		artist="${o["Artist"]:-${o["Name"]}}"
		song="${o["Title"]}"
		if [[ -z "$artist" ]]
		then
			if [[ -z "$song" ]]
			then
				song="$(basename "${o["file"]}")"
			else
				song="$song ❮$(basename "${o["file"]}")❯"
			fi
		fi
		
		if [[ "$(( ${#song} + ${#artist} + 1 ))" -gt "$SCROLL" ]]
		then
			scroll=true
			song=" $song     "
		else
			unset scroll
			song=" $song"
		fi

		old["file"]="${o["file"]}"
		old["Title"]="${o["Title"]}"
		old["Name"]="${o["Name"]}"
		I=0
	fi

	# Gestion du défilement
	if [[ -n "$scroll" ]]
	then
		unset bloc1 bloc2 bloc3 bloc4
		declare -- bloc1 bloc2 bloc3 bloc4
		bloc1="${artist:$I:$SCROLL}"
		if [[ "${#bloc1}" -eq 0 ]]
		then
			bloc2="${song:$(( I - ${#artist} )):$SCROLL}"
			if [[ "$(( ${#bloc1} + ${#bloc2} ))" -lt "$SCROLL" ]]
			then
				bloc3="${artist:0:$(( SCROLL - ${#bloc2} ))}"
				if [[ "$(( ${#bloc1} + ${#bloc2} + ${#bloc3} ))" -lt "$SCROLL" ]]
				then
					bloc4="${song:0:$(( SCROLL - ${#bloc1} - ${#bloc2} - ${#bloc3} ))}"
				fi
			fi
		else
			bloc2="${song:0:$(( SCROLL - ${#bloc1} ))}"
			if [[ "$(( ${#bloc1} + ${#bloc2} ))" -lt "$SCROLL" ]]
			then
				bloc3="${artist:0:$(( SCROLL - ${#bloc2} - ${#bloc1} ))}"
			fi
		fi

		I+=1
		[[ "$I" -ge "$(( ${#artist} + ${#song} ))" ]] && I=0
	else
		unset bloc1 bloc2 bloc3 bloc4
		bloc1="$artist"
		bloc2="$song"
	fi

	# Gestion du temps

	declare -i time_elapsed time_total time_left

	time_total="${o["time"]#*:}"
	[[ "$time_total" -eq 0 ]] && time_total="${o["Time"]}"
	[[ "$time_total" -eq 0 ]] && time_total=-1
	if [[ "${o["state"]}" == "stop" ]]
	then
		time_elapsed=-1
		time_left=-1
	else
		time_elapsed="${o["time"]%:*}"
		time_left="${time_total} - ${time_elapsed}"
	fi

	time="[$(human_time "${time_elapsed}") $(human_time "${time_left}") $(human_time "${time_total}")]"

	# Nettoyage des chaînes de caractère pour pango
	bloc1="${bloc1//&/&amp;}"
	bloc2="${bloc2//&/&amp;}"
	bloc3="${bloc3//&/&amp;}"
	bloc4="${bloc4//&/&amp;}"

	# DEBUG
	printf '<b>%s</b>%s<b>%s</b>%s%s\n' "$bloc1" "$bloc2" "$bloc3" "$bloc4" " $status$time</span>"
done

self-reset

