#!/usr/bin/env sh

# Description: File preview
#
# Dependencies:
#   - Image preview: chafa
#   - PDF preview: poppler-utils
#   - Video thumbnail preview: ffmpegthumbnailertar
#
# Usage:
#   When sff is running inside tmux:
#     Enabling preview will split a new pane for display.
#
#   When sff is running outside tmux:
#     If SFF_PV_TERM is set, enabling preview will launch the terminal emulator
#     specified by this variable as the previewer.
#
#     If SFF_PV_TERM is not set, enabling preview will prompt you to enter
#     the name of a terminal emulator to use temporarily as the previewer.
#
#   The SFF_PV_TERM environment variable defines the default terminal emulator
#   to be used as the previewer. You can set SFF_PV_TERM like this:
#     $ export SFF_PV_TERM=xterm
#
#   Note: This plugin cannot handle paths containing line breaks.
#
# Shell: POSIX compliant
#
# Author: Shi Yanling

sffpipe=$1
sffdir=${sffpipe%/*}
pvfifo="${sffpipe}.pv"
tmpdir=${TMPDIR:-/tmp}
[ ! -w "$tmpdir" ] && tmpdir=$sffdir
tmppvfile="${tmpdir}/sff-tmppv-$(id -u)"

preview_loop_tui()
{
	mkfifo "$pvfifo" || exit 0
	while IFS='' read -r _path; do
		while _x=$(timeout 0.005 sh -c 'IFS="" read -r _x && printf "%s" "$_x"'); do
			_path=$_x
		done
		clear
		_dest=''
		_mime=$(file -bL --mime-type "$_path")

		case "$_mime" in
		image/*) _dest=$_path
			;;
		application/pdf) _dest=$tmppvfile
			pdftoppm -jpeg -f 1 -singlefile -scale-to 800 "$_path" "$_dest" >/dev/null 2>&1 \
			&& _dest="${_dest}.jpg" || _dest=''
			;;
		video/*) _dest="${tmppvfile}.jpg"
			ffmpegthumbnailer -m -s 0 -i "$_path" -o "$_dest" >/dev/null 2>&1 \
			|| _dest=''
			;;
		*) _rows=$(tput lines); _cols=$(tput cols)
			case "$_mime" in
			text/*) { printf "    --- %s ---\n" "$_mime"; head -n "$_rows" "$_path"; } | less -SX +gq
				continue ;;
			inode/directory) { printf "    --- %s ---  (%s files)\n" "$_mime" \
					$(find "$_path"/ -mindepth 1 -maxdepth 1 ! -name . ! -name .. 2>/dev/null | wc -l); \
					ls -1Ap "$_path"; } | head -n "$((_rows - 1))" | cut -c 1-"$_cols"
				continue ;;
			esac
			;;
		esac

		if [ "$_dest" ]; then
			chafa "$_dest"
			tput civis
		else
			printf "    --- %s ---" "$_mime"
		fi
	done <"$pvfifo"
}

check_fifo()
{
	if [ -p "$pvfifo" ]; then
		printf "#q" >"$sffpipe"
		rm -f "$pvfifo"
		exit 0
	fi
}

wait_for_fifo()
{
	_i=1
	while [ ! -p "$pvfifo" ]; do
		sleep 0.1
		_i=$((_i + 1))
		[ "$_i" -gt 20 ] && exit 0
	done
}

case "$2" in
'tui') check_fifo
	if [ "$TMUX" ]; then
		[ $(($(tput lines) * 2)) -gt "$(tput cols)" ] && _layout='v' || _layout='h'
		tmux split-window -d"$_layout" "$0" "$sffpipe" 'loop'
	else
		if [ -z "$SFF_PV_TERM" ]; then
			printf "\nSFF_PV_TERM: not set\n"
			printf "Terminal emulator for preview (empty to cancel): "; read -r _x
			[ -z "$_x" ] && exit 0
			SFF_PV_TERM=$_x
		fi

		case "$SFF_PV_TERM" in
		'kitty'|'gnome-terminal') "$SFF_PV_TERM" -- "$0" "$sffpipe" 'loop' &
			;;
		'xfce4-terminal'|'terminator') "$SFF_PV_TERM" -e "\"$0\" \"$sffpipe\" loop" &
			;;
		*) "$SFF_PV_TERM" -e "$0" "$sffpipe" 'loop' &
			;;
		esac
	fi
	wait_for_fifo
	printf "#p" >"$sffpipe"
	;;

'gui') :
	;;
'loop') tput civis
	preview_loop_tui
	;;
esac
