#!/bin/bash

if [ $# -lt 1 ]; then

	echo "IM Playlist Player (ver. 0.1.1). Created for BABOOSHKA.TV™ project (https://babooshka.tv)"
	echo "Copyright © 2020 Dmitry Shalnov [interplaymedium.org]"
 	echo "Licensed under the Apache License, Version 2.0"

	echo "Usage: $0 -p <playlist> [options]"
	echo "-v <arg>	volume amp in dB>" 
	echo "-f <arg>	play from Nth file in the playlist"
	echo "-a <erg>	set audio track"
	echo "-m <arg>	video mode in WxH format"
	echo "-t <arg>	subtitle track number"
	echo "-s 		stop after"
	echo "-o 		play list once (make sence if you're not using -s option)"
	echo "Dependences: omxplayer, ttf-freefont"
	echo "Playlist format (using TAB delimiter): <file with path (no escapes)> [comment] [additional options] [position] [state]"
	echo "Use ';' symbol to comment playlist lines if needed"
	exit 1
fi

# BABOOSHKA_HOME=/home/pi	# assigned in start.babooshka.sh

SAVE_PATH=$BABOOSHKA_HOME
DBUS_CTRL_FILE=/tmp/dbuscontrol_command
VOLUME=0
LEDS_CONTROL=/tmp/bbshk_leds
CNT=1

# ------------------- parse commandline ----------------------

parserCnt=0

while [ "$#" -gt 0 ] && [ "$parserCnt" -lt 20 ] ; do
	case "$1" in
#		-i) MEDIAPATH="$2"; shift 2;;		# media file
		-p) PLAYLIST="$2"; shift 2;;		# media file
		-v) VOLUME="$2"; shift 2;;		# volume amp
		-f) START_FROM="$2"; shift 2;;			# from Nth file, 0 is random order
		-a) PREF_LANG="$2"; shift 2;;		# audio track prefered language pattern, e.g. ":ру|:ru"
		-m) VIDEOMODE="$2"; shift 2;;		# video mode
		-t) SUBTITLES="$2"; shift 2;;		# volume amp
		-s) PLAYSINGLE=1; shift 1;;		# play file by file with stops (no parameter required)
		-o) PLAYLISTONCE=1; shift 1;;		# play list once (no parameter required)

		-*) echo "unknown option: $1" >&2; exit 1;;
#		*) handle_argument "$1"; shift 1;;
		*) sleep 0; shift 1;;
	esac
	parserCnt=$(( $parserCnt + 1 ))
done

if [ "$SUBTITLES" != "" ]; then SUBTITLES_SET="-t $SUBTITLES"; fi

if [ -z "$PLAYLIST" ]; then
	echo "Playlist is not assigned. Please use -p option."
	exit 0
fi

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

killCCONTROL() {	# function called by trap (Ctrl-C handler)

	kill -9 $WAIT1_PID 2>/dev/null
	kill -9 $WAIT2_PID 2>/dev/null
	kill -9 $WAIT3_PID 2>/dev/null
	kill -9 $PLAYLIST_CHANGE_PID 2>/dev/null
	echo "Have a nice day..."
	exit 0
}

trap 'killCCONTROL' 2

waiting_for_press_play() {
	echo "waiting for PLAY button press... "; 
	while [ "$DBUS_COMMAND" != "PLAY" ]; do
		DBUS_COMMAND=$(cat $DBUS_CTRL_FILE)
#		echo -n "."
		sleep 1
	done
#	echo ''
}

waiting_for_player_start() {
	echo "waiting for playback starting... "; 
	while ! ./dbuscontrol.sh status 1>/dev/null 2>/dev/null ; do 
#		echo -n "+"
		sleep 1
	done
#	echo ''
}

# check for unwatched / not completed video and turn RED LED on

check_video_complete(){

	if grep -v -P "\tPLAY|\tWATCHED" "$1" | grep "^[^#;]" >/dev/null ; then 

		lastLedState=$(cat $LEDS_CONTROL)
		currentPos=$(cat $SAVE_PATH/currentpos)

		# make new video current (if previous one has not been paused and all videos has been watched)

		if [ "$lastLedState" == "VIDEOCOMPLETE" ] && [ "$currentPos" == '' ]; then 
			newVideo=$(grep -v -P "\tPLAY|\tWATCHED" "$1" | grep "^[^#;]" | head -1 | awk '{split($0,a,"\t"); print a[1]}')
			echo $newVideo > $SAVE_PATH/currenttrack
			echo "Playlist changed: $newVideo"
		fi 

#		echo 'NEWVIDEO'
		echo "NEWVIDEO" > "$LEDS_CONTROL"
	else 
		if grep -P "\tPLAY" "$1" | grep "^[^#;]" >/dev/null ; then
#			echo 'VIDEOSTARTED'
			echo "VIDEOSTARTED" > "$LEDS_CONTROL"
		else 
#			echo 'VIDEOCOMPLETE'
			echo "VIDEOCOMPLETE" > "$LEDS_CONTROL"
		fi
	fi
}

# check_video_complete "$PLAYLIST"

# background checking for external playlist changes

{	
	while [ 1 ]; do 
		check_video_complete "$PLAYLIST"
		sleep 10
	done
} &
PLAYLIST_CHANGE_PID=$!

# ----------------------- crash / reboot handler --------------------

touch "$DBUS_CTRL_FILE"
touch $SAVE_PATH/currenttrack
touch $SAVE_PATH/currentpos

currentTrack=$(cat $SAVE_PATH/currenttrack)
currentPos=$(cat $SAVE_PATH/currentpos)

echo "Saved track: $currentPos, $currentTrack"

if [ "$START_FROM" == '' ]; then 

	if [ "$currentTrack" != '' ]; then 

		currentTrackNum=$( cat $PLAYLIST | grep "^[^#;]" | grep -Fn "$currentTrack" | cut -f1 -d: )	# looking for current track in playlist and return number of it

		if [ "$currentTrackNum" != "" ]; then 	# playlist has been updated
			CNT=$currentTrackNum; 
			echo "Current track number: $CNT"
		fi

		if [ "$currentTrackNum" != '' ] && [ "$currentPos" != '' ]; then 

			currentPos=$(( $currentPos / 60 ))
			echo "restarting from $currentPos min : $CNT : $currentTrack"
			POSITION_SET="-s $currentPos"

			{
				echo "waiting for player start.."
				waiting_for_player_start
				
				# trick to make still picture visible 

				./dbuscontrol.sh pause 
				echo "paused"
				sleep 10
				./dbuscontrol.sh pause 
				sleep 0.1
				./dbuscontrol.sh pause

			} &
			WAIT1_PID=$!
		else 
			waiting_for_press_play
		fi
	else 
		waiting_for_press_play
	fi 
else 
	CNT=$START_FROM
	waiting_for_press_play
fi

# --------------------- main loop start -----------------------------

while [ 1 ]; do

	totalLines=$(cat $PLAYLIST | grep "^[^#;]" | wc -l)
	playlistLine=$(cat $PLAYLIST | grep "^[^#;]" | head -$CNT | tail -1)

	echo "playlistLine: $CNT, $playlistLine"

	if echo $playlistLine | grep "^[^#;]" >/dev/null; then 

		fileState=$(echo "$playlistLine" | awk '{split($0,a,"\t"); print a[5]}')

		# show splash 

		case "$fileState" in 
			"PLAY") 
				sudo fbi -T 3 -d /dev/fb0 --once -noverbose splash_loading_pause.png &>/dev/null
			;;
			'')
				sudo fbi -T 3 -d /dev/fb0 --once -noverbose splash_loading_new.png &>/dev/null
			;;
			*) 
				sudo fbi -T 3 -d /dev/fb0 --once -noverbose splash_loading.png &>/dev/null
			;;
		esac

		file=$(echo "$playlistLine" | awk '{split($0,a,"\t"); print a[1]}')
		fileComment=$(echo "$playlistLine" | awk '{split($0,a,"\t"); print a[2]}')
		fileOptions=$(echo "$playlistLine" | awk '{split($0,a,"\t"); print a[3]}')

		echo "Loading: $CNT/$totalLines : $file"
		echo "Commentary: $fileComment"
		echo "Additional options: $POSITION_SET $fileOptions"

		echo $file > $SAVE_PATH/currenttrack

		if [ "$PREF_LANG" != "" ]; then
			{
				echo "prefered language (pattern): $PREF_LANG"
				waiting_for_player_start
				audioTracks=$( $BABOOSHKA_HOME/dbuscontrol.sh audiolist 2>/dev/null )
				prefAudioTrackNum=$( echo "$audioTracks" | awk -v var=$PREF_LANG 'tolower($0) ~ var {print NR; exit }' )

				if [ "$prefAudioTrackNum" != "" ]; then 
					i=1
					while [ "$i" -lt "$prefAudioTrackNum" ] ; do
						i=$(( $i + 1 ))
						$BABOOSHKA_HOME/dbuscontrol.sh audiop
					done 
					targetTrackName=$(echo "$audioTracks" | head -$prefAudioTrackNum | tail -1 )
					echo "audio track $prefAudioTrackNum : $targetTrackName"
				else 
					echo "probably single audiotrack detected:"
					echo "$audioTracks"
				fi 
			} &
			WAIT2_PID=$!
		fi

		{
			waiting_for_player_start
			sudo fbi -T 3 -d /dev/fb0 --once -noverbose splash.png &>/dev/null
		} &
		WAIT3_PID=$!

		# set playlist marker before playing

		if cat "$PLAYLIST" | grep "^[^#;]" | grep "$file" | grep -v -P "\tWATCHED" >/dev/null; then 

			sed -i "s|\tPLAY||g" "$PLAYLIST"
			newPlaylistLine=$(cat "$PLAYLIST" | grep "^[^#;]" | grep "$file" | awk -F"\t" -v pbState="PLAY" '{print $1"\t"$2"\t"$3"\t"$4"\t"pbState}')
			sed -i "s|^$file.*|${newPlaylistLine}|g" "$PLAYLIST"
		fi 

		# playing

		echo "VIDEOSTARTED" > "$LEDS_CONTROL"
		echo 'playing...'

		playerOutput=$(./playmovie.sh -i "$file" -v $VOLUME -a 1 -m "$VIDEOMODE" $POSITION_SET $SUBTITLES_SET -r letterbox $fileOptions)

		# set playlist markers after playing

		if cat "$PLAYLIST" | grep "^[^#;]" | grep "$file" | grep -v -P "\tWATCHED" >/dev/null; then 

			playbackPos=$(echo "$playerOutput" | grep "Playback duration" | awk -F: '{print $2}' | xargs)	# whether it was stopped and what time

			ct=$(echo $playbackPos | awk -F'/' '{print $1}')
			tt=$(echo $playbackPos | awk -F'/' '{print $2}')

			if [ "$ct" -ge "$tt" ]; then watched='WATCHED'; else watched=''; fi

			newPlaylistLine=$(cat "$PLAYLIST" | grep "^[^#;]" | grep "$file" | awk -v pbPos="$playbackPos" -v pbState="$watched" -F"\t" '{print $1"\t"$2"\t"$3"\t"pbPos"\t"pbState}')
			sed -i "s|^$file.*|${newPlaylistLine}|g" "$PLAYLIST"

			echo "playlist line updated: $newPlaylistLine"
		fi 

		# check for unwatched / not completed video and turn RED LED on
		
		check_video_complete "$PLAYLIST"

		: > $SAVE_PATH/currentpos
		POSITION_SET=''

		DBUS_COMMAND=$(cat "$DBUS_CTRL_FILE")

		if [ "$PLAYSINGLE" != "" ] && [ "$DBUS_COMMAND" != "NEXT" ]; then 
			echo "play single STOP"
			echo "STOP" > "$DBUS_CTRL_FILE";
			DBUS_COMMAND="STOP"
			CNT=$(( $CNT + 1 ));
		fi

	else 
#		if [ "$DBUS_COMMAND" == "PLAY" ]; then  CNT=$(( $CNT + 1 )); fi 
		DBUS_COMMAND="NEXT"
	fi 

	# check playlist for finishing

	echo "DBus command: $DBUS_COMMAND"

	totalLines=$(cat $PLAYLIST | grep "^[^#;]" | wc -l)

	if [ "$PLAYLISTONCE" != '' ] && [ "$CNT" -ge "$totalLines" ] && [ "$DBUS_COMMAND" != "PREV" ]; then 
		echo "play once STOP"
		echo "STOP" > "$DBUS_CTRL_FILE"
		DBUS_COMMAND="STOP"
		CNT=$(( $CNT + 1 ));
	fi

	# handle and pass dbus command (original or assigned forcibly)

	echo "DBus command: $DBUS_COMMAND"

	if [ "$DBUS_COMMAND" != "" ]; then 
		case "$DBUS_COMMAND" in
			"NEXT")
				CNT=$(( $CNT + 1 ));
			;;
			"STOP")
				waiting_for_press_play
				
				# check for possibly new video in playlist

				currentLEDState=$(cat $LEDS_CONTROL)

				if [ "$currentLEDState" == "NEWVIDEO" ]; then
					newVideo=$(grep -v -P "\tPLAY|\tWATCHED" "$PLAYLIST" | grep "^[^#;]" | head -1 | awk '{split($0,a,"\t"); print a[1]}')
					echo $newVideo > $SAVE_PATH/currenttrack

					CNT=$( cat "$PLAYLIST" | grep "^[^#;]" | grep -Fn "$newVideo" | cut -f1 -d: )
					totalLines=$(cat "$PLAYLIST" | grep "^[^#;]" | wc -l)
					echo "New track detected: $CNT, $newVideo"
				fi 
				
			;;
			"PREV")
				CNT=$(( $CNT - 1 ));
			;;
		esac
		: > "$DBUS_CTRL_FILE"
	else 
		CNT=$(( $CNT + 1 ))
	fi 

	# playlist next line counter

	if [ "$CNT" -gt "$totalLines" ]; then CNT=1; fi
	if [ "$CNT" -lt "1" ]; then CNT=$totalLines; fi
done 

exit 0

