#	splitvoices [ -s stafflist ] mup_input_file
#
#	This command looks for Mup input lines for music data on the specified
#	staffs, or all staffs if no list is given.  These lines must not be
#	specifying voice numbers, and must not be continued onto the next line
#	by using a backslash.
#
#	The program duplicates these lines, separating them into lines for
#	voice 1 and voice 2.  (It passes other lines through unchanged.)  For
#	chords with one note, both lines get the note.
#	For chords that have more than one note,
#	voice 2 gets the first note and voice 1 gets the rest.  The program
#	also outputs lines to set vscheme to 2o for these staffs.
#
#	The program reads the given file name and writes to standard output.
#	It is not bulletproof.  For one thing, it gets confused by notes with
#	slur angle brackets.  But it gets most of the lines right.

function usage()
{
	echo "Usage:  $0 [ -s comma_separated_list_of_staffs ] mup_input_file" >&2
	exit 1
}

# Parse the command line options, setting up SL (staff list) and Mup FILE name.
case $# in
1)	SL=$(gawk '
		BEGIN {
			for (n = 1; n < 32; n++)
				printf("%d,", n)
			printf("32")
		}
		' /dev/null
	)
	FILE="$1"
	;;

2)	if [ $(expr "$1" : '-s[0-9][0-9,]*') -eq 0 ]
	then
		usage
	fi
	SL=$(echo "$1" | sed -e 's/..//')
	FILE="$2"
	;;

3)	if [ "$1" != "-s" ]
	then
		usage
	fi
	SL="$2"
	FILE="$3"
	;;

*)	usage
	;;
esac

# Enforce the comma separated list of staff numbers (although we don't try to
# block 0 or numbers greater than 40).
if [ $(expr "$SL" : '[0-9][0-9,]*') -eq 0  -o  $(expr "$SL" : '.*,$') -ne 0  \
		-o $(expr "$SL" : '.*,,.*') -ne 0 ]
then
	usage
fi

if [ ! -f "$FILE"  -o  ! -r "$FILE" ]
then
	echo "$0: file $FILE is not readable" >&2
	exit 1
fi

if [ $(grep -c '^[ 	]*[0-9][0-9]*[ 	]*:.*<[^>]*[a-g]' "$FILE") -ne 0 ]
then
	echo "$0: warning: the results may be bad; we can't handle slurs using '< >' with a note letter inside" >&2
fi

# Find the first staffs=X line, if any.  Hopefully there won't be more than
# one, since things might gets hosed later.  Store the number.  If no lines
# are found, use 0.
MAXSTAFF=$(grep 'staffs[ 	]*=[ 	]*[0-9]' "$FILE" | head -1 |
	sed -e 's/.*staffs[ 	]*=[ 	]*//' -e 's/[^0-9].*//')
if [ -z "$MAXSTAFF" ]
then
	MAXSTAFF=0
fi

# Prefix music lines that should be split, with "VOICE1" and "VOICE2".  Also
# try to output settings of vscheme at an appropriate place.
gawk '
	BEGIN {
		# get the maximum staff number
		maxstaff = '$MAXSTAFF'
		if (maxstaff == 0) {
			# none found, so there is really just one staff, and
			# we can set vscheme right here at the start
			print "score"
			print "	vscheme = 2o"
			print "music"
			didit = 1
			allstaff = 1
		} else {
			# load the si array so that it is indexed by all the
			# valid staff numbers in $SL
			split("'$SL'", staff, ",")
			for (s in staff) {
				if (staff[s] <= maxstaff) {
					si[staff[s]] = 1
				}
			}
		}
	}

	# remember that we have seen this line; after this it is safe to set
	# vscheme for the needed staffs
	/staffs[ 	]*=[ 	]*[0-9]/ {
		gotstaffs = 1
	}

	# at the first "music" after the staffs line, if we have not yet done
	# this, set the vschemes
	/^[ 	]*music/ && gotstaffs && ! didit {
		for (s in si) {
			print "staff " s
			print "	vscheme = 2o"
		}
		didit = 1
	}

	# match a line of music data for some staff
	/^[ 	]*[0-9][0-9]*[ 	]*:/ {
		# get the staff number in sn
		sn = $0
		sub(/[^0-9]*/, "", sn)
		sub(/[^0-9].*/, "", sn)

		# if it is one of the ones we are to split, duplicate the line,
		# putting labels on it for sed; otherwise print unchanged
		if (sn in si || allstaff) {
			print "VOICE1:" $0
			print "VOICE2:" $0
		} else {
			print
		}
		next
	}

	# Pass all other lines through unchanged.
	{
		print
	}
' "$FILE" |

# Try to strip the appropriate note(s) and associated things from each chord.
# We translate "tie" to "tiE" and back to avoid getting confused by the "e".
sed \
	-e 's/tie/tiE/g' \
	-e '/^VOICE1:/s/\([a-g][^a-g;]*\)\([a-g][^;]*\)/\2/g' \
	-e '/^VOICE1:/s/VOICE1:\([^:]*\)/\1 1/' \
	-e '/^VOICE2:/s/\([a-g][^a-g;]*\)\([a-g][^st;]*\)/\1/g' \
	-e '/^VOICE2:/s/VOICE2:\([^:]*\)/\1 2/' \
	-e 's/tiE/tie/g'

exit 0
