#!/bin/sh

tmpdir=/tmp/$$_lilypondview
mkdir "$tmpdir" || exit 1

trap "rm -rf \"$tmpdir\"" 0

# Requirements, actual or potential:
# 
# lilypond (that actually runs, of course)
# kghostview OR kpdf OR xpdf OR ghostview OR gs
# Xdialog OR konsole OR rxvt OR xterm [for graphical mode only]

prog_lilypond=""
prog_xdialog=""
prog_terminal=""
prog_ghostview=""

if [ "$1" == "-v" ]; then
    echo "rosegarden-lilypondview v1.2" 1>&2
    shift
fi

lilypond_version="`lilypond --version`"
if [ "$?" != "0" ]; then
    echo "rosegarden-lilypondview: LilyPond unavailable" 1>&2
else
    lilypond_version="`lilypond --version | grep LilyPond | head -1 | sed 's/^.* //'`"
    case "$lilypond_version" in
	1.*|2.0.*)
	    echo "rosegarden-lilypondview: Unsupported LilyPond version ($lilypond_version)" 1>&2;;
	*)
	    prog_lilypond=lilypond;;
    esac
fi

for x in kghostview ggv ghostview; do
    if [ -x "`type -path $x`" ]; then
	prog_ghostview=$x
	break;
    fi
done

if [ -z "$prog_ghostview" ]; then
    echo "rosegarden-lilypondview: No PostScript viewer found" 1>&2
fi

if [ -x "`type -path Xdialog`" ]; then
    prog_xdialog=Xdialog
fi

if [ -x "`type -path xterm`" ]; then
    prog_terminal=xterm
fi

if [ -z "$prog_terminal" ]; then
    echo "rosegarden-lilypondview: No terminal emulator found" 1>&2
fi

[ -z "$prog_lilypond" ] && exit 1
[ -z "$prog_ghostview" ] && exit 1
[ -z "$prog_terminal" ] && exit 1

if [ "$1" == "--conftest" ]; then
    exit 0
fi

graphical=""
if [ "$1" == "-g" ]; then
    graphical=true
    shift
    if [ -z "$prog_xdialog" ]; then
	# can't do graphical mode
	echo "rosegarden-lilypondview: Graphical progress dialog requires Xdialog utility" 1>&2
	graphical=""
    fi
fi

input="$1"

if [ -z "$1" ]; then
    echo "Usage: rosegarden-lilypondview [-g] input.ly" 1>&2
    exit 2
fi

if [ ! -f "$input" ]; then
    input="$input.ly"
    if [ ! -f "$input" ]; then
	echo "Error: Can't open \"$1\" or \"$input\" for reading" 1>&2
	exit 1
    fi
fi

cp "$input" "$tmpdir/" || exit 1

(
	dir=`dirname "$input"`
	base=`basename "$input"`
	cd "$tmpdir"

	if file "$base" | grep -q gzip; then
		gunzip "$base"
		base=`basename "$base" .gz`
	fi

	includes=`\
		grep '\\include ' "$base" | \
		sed -e 's/\\include//' \
		    -e 's/^.*[^a-zA-Z0-9-]\([a-zA-Z0-9-][a-zA-Z0-9-]*.ly\).*$/\1/'`

	for include in $includes; do
		if [ -r "$dir/$include" ]; then
			cp "$dir/$include" .
		elif [ -r "$dir/$include.gz" ]; then
			gunzip -c "$dir/$include" > ./"$include"
		fi
	done

	fileversion=`grep '\\version ' "$base" | head -1 | \
	    sed -e 's/\\version //' -e 's/[^0-9.]//g'`

	args=""
	convert=""
echo "LilyPond version is $lilypond_version, file version is $fileversion"
	case "$lilypond_version" in
	    2.2.*)
		args="--no-pdf"
		case "$fileversion" in
		    1.*) convert=true;;
		esac;;
	    2.6.*)
		args="--formats=ps"
		case "$fileversion" in
		    1.*|2.[012].*) convert=true;;
		esac;;
	esac

	logfile="lilypond-output.log"
	cat </dev/null >"$logfile"

	if [ -n "$convert" ]; then
	    echo "File version is $fileversion against LilyPond version $version -- converting..." 1>&2
	    for srcfile in "$base" $includes; do
		if [ -n "$graphical" ]; then
		    convert-ly "$srcfile" > "${srcfile}_converted" 2> "$logfile" && mv "${srcfile}_converted" "$srcfile"
		else
		    convert-ly "$srcfile" > "${srcfile}_converted" && mv "${srcfile}_converted" "$srcfile"
		fi
	    done
	fi

	if [ -n "$graphical" ] ; then

	    # special bar comment syntax RG exports -- hopefully benign if absent
	    bars=`grep '^%% [0-9][0-9]*$' "$base" | sort -k 1 -n | tail -1 | awk '{ print $2; }'`
	
	    if [ -z "$bars" ]; then
		staffs=`grep 'Staff *[=<]' "$base" | wc -l`
		[ "$staffs" -eq 0 ] && staffs=1
		bars=`grep -v '^ *%' "$base" | wc -l`
		bars=$(($bars / $staffs))
	    fi
		
	    bars=$(($bars + 5))
	    count=$(($bars * 7 / 3))
	
	    indev=/dev/pts/0
	    if [ ! -c "$indev" ]; then indev=/dev/ptya0; fi

#	    echo "Running $prog_lilypond $args \"$base\""
	    $prog_lilypond $args "$base" <$indev 2>&1 | tee -a "$logfile" | \
	      perl -e '
		$| = 1;
		print "0\n";
		$state = 0;
		$n = "";
		$m = "";
		$base = 0;
		while (defined ($key = getc)) {
		    if ($key eq "[") {
			if ($state == 3) {
			    print "XXX\nProcessing LilyPond file...\n\\n\n$m\nXXX\n";
			}
			$state = 1;
	            } elsif ($key eq "]") {
			$state = 2;
			$val = int( ($base + $n) * 100 / '$count' );
			if ($val > 100) { $val = 100; }
			print "$val";
			print "\n";
			$n = "";
		    } elsif ($key eq "\n") {
			if ($state == 2) {
			    $base = $base + '$bars'; $state = 0;
			}
			$m = "";
			$state = 3;
		    } elsif ($state == 1) {
			$n = $n . $key;
		    } elsif ($state == 3) {
			$m = $m . $key;
	            }
		}' |  \
	      $prog_xdialog --title "Processing" --gauge "Processing LilyPond file..." 10 60
	else
#	    echo "running $prog_lilypond $args \"$base\"..."
	    $prog_lilypond $args "$base"
	fi

	target="${base%.*}.ps"

	if [ -f "$target" ]; then
	    $prog_ghostview "$target"
	    exit 0
	elif [ -n "$graphical" ]; then
	    cat $logfile 1>&2
	    echo 1>&2
	    echo "LilyPond failed" 1>&2
	    if [ -n "$graphical" ]; then
		( echo 
		  echo "  ERROR: LilyPond processing failed."
		  echo "  LilyPond output follows:"
		  echo 
		  cat "$logfile" ) | $prog_xdialog --no-cancel --fixed-font --textbox - 0 0
	    fi
	else
	    echo 1>&2
	    echo "LilyPond processing failed." 1>&2
	fi
	exit 1
)

