#!/bin/dash
# Author: jamesbond - License: MIT License
# Originally authored for Puppy Newsletter April 2017 edition
# Made using info from http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html
# step: i18n and --gui option

### i18n
export TEXTDOMAIN=fatdog
export OUTPUT_CHARSET=UTF-8
. gettext.sh

SN=${0##*/}
APPNAME=$(gettext "Video to gif")

### Options

unset opt_gui
case $1 in
	--gui )
		opt_gui=opt_gui
		shift
		export YAD_OPTIONS="
		--title=\"$APPNAME\"
		--window-icon=/usr/share/pixmaps/midi-icons/camera48.png
		--center
		--buttons-layout=center
		--margins=10
		"
		;;
esac

### Configuration

IN=${1}
OUT=${2:-out.gif}
SCALE=${3:-300}
QUALITY=${4:-low}

if [ -z "$IN" -a -z "$opt_gui" ]; then
	eval_gettext "\
Usage: \$SN input [out] [horz-res] [quality]
- out is the output filename, default is '\$OUT'
- horz-res is the horizontal resolution, default is '\$SCALE'
- quality is image quality of conversion, you can choose between
  'low', 'lower', 'high', or 'high2'. Higher quality = bigger file.
  Default is '\$QUALITY'.
"
	exit 1
fi

### Dialog

unset progress_pid
if [ "$opt_gui" ]; then

	choices=$(echo '!low!lower!high!high2!' | sed -e "s/!$QUALITY!/!^$QUALITY!/")
	choices="${choices#!}"; choices="${choices%!}"

	in=$(realpath -m "$IN") out=$(realpath -m "$OUT")

	# The colon in each field label below is a Unicode combining colon &#42889;
	# not an ASCII colon.

	yad \
		--form \
		--separator="\\n" \
		--field="$(gettext "_Input file name")꞉" "$in" \
		--field="$(gettext "_Output file name")꞉" "$out" \
		--field="$(gettext "_Resize width")꞉":NUM "$SCALE" \
		--field="$(gettext "_Quality")꞉":CB "$choices" \
		--button=gtk-ok:0 \
		--button=gtk-quit:1 \
		--columns=2 \
		--field="!gtk-open!\
$(gettext "Choose a video file (MP4, AVI, etc.)")":FBTN \
			'@sh -c "printf 1:%%s \"$(yad --file --save --filename=%1)\""' \
			--field="!gtk-open!\
$(gettext "A gif file will be created")":FBTN \
			'@sh -c "printf 2:%%s \"$(yad --file --save --filename=%2)\""' \
			--field="!gtk-info!\
$(gettext "Enter zero to use the natural width")
$(gettext "Resizing maintains the aspect ratio")
$(gettext "Larger width = bigger file")":BTN "" \
			--field="!gtk-info!\
$(gettext "Higher quality = bigger file")":BTN "" \
		> "/tmp/.sel-$$" && unset cancelled || cancelled=cancelled

	{
		read in
		read out
		read scale
		read quality
	} < "/tmp/.sel-$$"
	rm -f "/tmp/.sel-$$"

	[ "$cancelled" ] && exit

	[ "$in" ] && IN=$in
	[ "$out" ] && OUT=$out
	[ "$scale" ] && SCALE=$scale
	[ "$quality" ] && QUALITY=$quality

	yad \
		--progress --pulsate \
		--progress-text="   $(eval_gettext 'Converting $IN...')   " \
		--no-buttons \
		--no-escape \
		--margins=20 \
		&
	progress_pid=$!

fi

### Conversion

# redirect ffmpeg log from the default stderr; level 32=info
export FFREPORT=file=/tmp/.err-$$:level=32

case $OUT in
	*.gif ) : .gif passed ;;
	* ) OUT="$OUT.gif" ;;
esac

palette="/tmp/palette.png"
filters="fps=10,scale=$SCALE:-1:flags=lanczos"
filters_lower="fps=10,scale=$SCALE:-1"

case $QUALITY in
	low)
		ffmpeg -i "$IN" -vf $filters -y "$OUT"
		;;

	lower)
		ffmpeg -i "$IN" -vf $filters_lower -y "$OUT"
		;;

	high)
		###
		ffmpeg -i "$IN" -vf "$filters,palettegen" -y $palette &&
		ffmpeg -i "$IN" -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y "$OUT"
		;;

	high2)
		###
		ffmpeg -i "$IN" -vf "$filters,palettegen=stats_mode=diff" -y $palette &&
		ffmpeg -i "$IN" -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y "$OUT"
		;;
esac
status=$?

if [ "$progress_pid" ]; then
	kill "$progress_pid" 2>/dev/null
	wait "$progress_pid" 2>/dev/null
fi

# Show result

if [ 0 != $status ]; then

	if [ "$opt_gui" ]; then
		yad \
			--image=gtk-stop --image-on-top \
			--text-info --filename="/tmp/.err-$$" \
			--width=600 --height=400 \
			--button=gtk-quit \
		&
	fi

	sleep 1
	rm -f "/tmp/.err-$$"

else
	rm -f "/tmp/.err-$$"

	if [ "$opt_gui" ]; then
		yad \
			--text="\n$(eval_gettext 'File $OUT successfully created')   \n" \
			--image=gtk-yes \
			--button=gtk-quit:0 \
			--button="$(gettext "_Convert more videos...")!gtk-refresh":10 \
		;
		[ 10 = $? ] && exec "$0" --gui "$IN" "$OUT" "$SCALE" "$QUALITY"
	fi

fi
exit $status

