#!/usr/bin/perl -w
#
#NAME
#  abcmedley - combine abc tunes into medley page
#
#SYNOPSIS
#  abcmedley "Title" file..
#
#DESCRIPTION
#  Read a list of abc files (or passage from stdin), and write output that is
#  a  titled medley.  The title will be at the top of the first page, and the
#  titles of the tunes will be converted to part names.  Also, we modify  the
#  X: lines, making an X:0 title section plus sequentially numbered X: parts.
#
#  If the title is the name of a file, it will be read and used for  the  X:1
#  part  of  the  medley.  It probably shouldn't contain music.  If the title
#  isn't a file name, we will generate an X:0 initial portion of  the  output
#  with the minimum needed to satisfy abc2ps (and its descendants).
#
#  We then read the tune files, converting their T: titles to P:  part names.
#  Only  the  first  title  will  be  used,  because  abc2ps refuses to print
#  multiple part names for a single tune.
#
#HEADERS
#  As a special kludge, you may include M and L header fields on the  command
#  line, and they will override the corresponding lines in the files. This is
#  mostly used to convert between C| and 2/4 time.
#
#AUTHOR
#  John Chambers <jc@trillian.mit.edu>

$| = 1;
($P = $0) =~ s"^.*/"";
$V = $ENV{"V_$P"} || 1;
print "\%$P: V=$V.\n" if $V>1;
$X = 0;			# Number of tunes we've seen so far
$Xopt   = 1;	# Whether to produce X: lines in tunes
$files  = 0;	# Number of files read so far
$sep    = 0;	# How many separators (%%sep ...) to produce
$titles = 0;	# How many titles to show (0=all)
$ucfirst = 0;	# Whether to capitalize the first word in titles

for $arg (@ARGV) {
	if (($flg,$a) = ($arg =~ /^([-+])(.*)/)) {
		print "\%$P: flg=\"$flg\" a=\"$a\"\n" if $V>1;
		$A = uc($a);
		print "\%$P: flg=\"$flg\" A=\"$A\"\n" if $V>2;
		if ($A eq 'A') {			# Joining first tunes (obsolete?)
			$alltitles = ($flg eq '+');
			print "\%$P: alltitles=\"$alltitles\"\n" if $V>2;
		} elsif ($A eq 'C') {		# Capitalize first letter of titles
			$ucfirst = $X = ($flg eq '+');	
			print "\% Upper-Case Titles\n" if $V>0;
		} elsif ($A eq 'J') {		# Joining first tunes
			$join = $X = ($flg eq '+');	# Join first and second "tunes"
		} elsif ($A =~ /^S(\d*)$/) {	# Generate separators.
            print "% $flg$A option with arg '$1'\n" if $V>2;
			if ($1) {
				$sep = int($1);	    	# Generate several separators
			} else {
				$sep = ($flg eq '+') ? 1 : 0;	# Generate separators
			}
		} elsif ($A =~ /^T(\d*)$/) {	# Number of titles
			$titles = int($1) || 0;
			print "\%$P: $titles titles.\n" if $V>1;
		} elsif ($A =~ /^V(\d*)$/) {	# Verbose level
			$V = int($1) || $V++;
			print "\%$P: V=$V.\n" if $V>1;
		} elsif ($A eq 'X') {		# Including X: headers in P: tunes?
			$Xopt = ($flg eq '+');	# Join first and second "tunes"
			print "\%$P: Xopt=$Xopt.\n" if $V>0;
		} else {
			print STDERR "$P: Arg \"$a\" not recognized.\n" if $V>0;
		}
	} elsif (-f $arg) {
		push @files, $arg;
	} elsif ($arg =~ /^M:(.*)/) {
		$Mhdr = $1;
	} elsif ($arg =~ /^L:(.*)/) {
		$Lhdr = $1;
	} elsif (!$Title) {
		$Title = $arg;
	} else {
		print STDERR "$P: Unknown arg \"$arg\" ignored.\n";
	}
}
$Title = 'Medley' unless defined $Title;
($hdr1 = "$Title.hdr") =~ s/\s+//g;
($hdr2 = "hdr/$Title.hdr") =~ s/\s+//g;

print STDERR "Exists: $hdr1\n" if -f $hdr1 && $V>1;
print STDERR "Exists: $hdr2\n" if -f $hdr2 && $V>1;

if  ( -f ($hdr = $hdr1) ||  -f ($hdr = $hdr2)) {	# Header file exists?
	open(T,$hdr) ||
		die "$P: Can't read \"$hdr1\" [$!]\n";
	while ($l = <T>) {
		$l =~ s/[\s\r]*$//;		# Trim away trailing white stuff
		print "\%$P: l=\"$l\"\n" if $V>1;
		if ($join) {
			if ($l =~ /^X:/) {	# Convert index to zero
				print "X: 0\n";
			} elsif ($l) {
				print "\%$P: Line: \"$l\"\n" if $V>1;
				print "$l\n";
			}
		} elsif ($l =~ /^(T:\s*)(.*)/) {	# Title?
			print "\%$P: Title \"$2\"\n" if $V>1;
			$Lbl = $1;		# T: and spaces
			$Ttl = $2;		# the title
			$Ttl =~ s/(\w)/\U$1/ if $ucfirst;
			print "$Lbl$Ttl\n";
		} else {
			print "$l\n";;
		}
	}
} else {
	$Title =~ s/(\w)/\U$1/ if $ucfirst;
	print "X: $X\n";		# Generate title lines.
	print "T: $Title\n";
	print "K:\n";
	print STDERR "X: $X T: $Title\n" if $V>1;
#	print "\n" if $Xopt;	# Extra space if generating multiple ABC "tunes"
}
++$tunes;
$files = 0;

file:
for $file (@files) {
	unless (open(F,$file)) {
		print STDERR "$P: Can'd read \"$file\" [$!]\n";
		next file;
	}
	$Tcount = 0;	# Title count for this tune
line:
	for $line (<F>) {
		if ($line) {
			if ($line =~ s/^(X:\s*)(\d*)\s*//) {
				if ($2 > $X) {$X = $2} else {++$X}	# New part encountered.
				if ($join) {
					--$join;	
				} else {
                    if ($tunes) {
                        print "\n" if $Xopt;
                        print "% Produce $sep separators...\n" if $V>1;
                        for ($i=0; $i<$sep; ++$i) {
                            print "%%sep 1 1 500\n";
                        }
                    }
					print "\nX: $X\n" if $Xopt;
					++$tunes;
				}
				next line;
			} elsif ($line =~ /^(T:)\s*(.*)/) {	# Title.
				$Ttl = $2;
				$Ttl =~ s/(\w)/\U$1/ if $ucfirst;
				if (!$P{$X}) {
					$P{$X} = $Ttl;
					$T = "P: $Ttl";		# Convert to part name.
					$Tcount++;			# Count the titles used
					print "\%$P: Title $Tcount of $titles ($Ttl)\n" if $V>1;
				} elsif ($titles == 0 || $Tcount < $titles) {
					$P{$X} .= "  ($Ttl)";
					$T .= "  ($Ttl)";	# Convert to part name.
					$Tcount++;			# Count the titles used
					print "\%$P: Title $Tcount of $titles ($Ttl)\n" if $V>1;
				}
				next line;
			} elsif ($line =~ /^(M:)\s*(.*)/) {
				$line = "M:$Mhdr\n" if $Mhdr;
			} elsif ($line =~ /^(L:)\s*(.*)/) {
				$line = "L:$Lhdr\n" if $Lhdr;
			} else {
				if ($T) {print "$T\n"; $T = ''}
			}
			print $line;
		}
	}
}
print "\n";
