#!/usr/bin/perl
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
#DESCRIPTION
#  abcjoin - combine ABC files
#
#SYNOPSIS
#  abcjoin file...
#
#DESCRIPTION
#  Join a list of ABC files into a single file.  The  tunes  will  be
#  separated  by  a blank line, and will be numbered consecutively if
#  they don't have distinct X: index numbers already.
#
#  The result is written to standard output.
#
#OPTIONS
#
# +H<name>
#    Incorporate the header file <name>.  If it exists, we will read
#    it in, and we will also generate %% directives that tell abc2ps
#    to center its title and then put subsequent titles at the left.
#    
# +R
#     Renumber the tunes.
#     The tunes will be renumbered consecutively, starting from  X:1.
#     The  default  is  -R,  which  also renumbers, but only when the
#     input X: indexes aren't increasing.  So if the input tunes  are
#     already  numbered  in  increasing  order,  the default will use
#     their numbers.
#
# +S  
#     Generate separator lines.
#     This is done with the abc2ps %%sep directive. At present, there
#     is no way to specify the parameters.
#
#BUGS
#  The output X: numbers will be distinct.  This is a feature.
#
#  We never read from standard input.  Maybe we should add an  option
#  to do this.
#
#AUTHOR
#  John Chambers <jc@trillian.mit.edu> http://trillian.mit.edu/~jc/
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

$| = 1;
$V = 1;
$Xlast = -1;

for $f (@ARGV) {
	&outtune("#$0: arg='$f'") if $V>3;
	if (($flg,$opts) = ($f =~ /^([-+])(.*)/i)) {
		&outtune("#$0: flg=$flg' opts='$opts'") if $V>2;
		while ($opts =~ s/^(.)//) {
			$opt = uc($1);
			&outtune("#$0: opt='$opt'") if $V>2;
			if ($opt eq 'S') {
				$sep = ($flg eq '+') ? 1 : 0;		# Generate separators.
				&outtune("#$0: sep=$sep.") if $V>1;
			} elsif ($opt eq 'H') {
				$hopt = ($flg eq '-') ? 0 : 1;		# Look for header file.
				&outtune("#$0: hopt=$hopt.") if $V>2;
				if (open(F,$opts)			# Look for the header file.
				||  open(F,"hdr/$opts.hdr")
				||  open(F,"$opts.hdr")) {	# Can we read it?
					$hfile = 1;
					&onefile();			# Copy it to output.
					$hfile = 0;
					$opts = '';
				} else {
					print STDERR "#$0: Can't read \"$opts\" ($!)\n" if $V>1;
				}
			} elsif ($opt eq 'N' || $opt eq 'R') {
				$ren = ($flg eq '+') ? 1 : 0;		# Renumber the tunes.
				&outtune("#$0: ren=$ren.") if $V>2;
			} else {
				print STDERR "#$0: Unknown option '$opt'\n" if $V>0;
			}
		}
	} elsif (open(F,$f)) {
		if ($last && $files) {
			&outtune("") unless $hopt;
		}
		&onefile();
	} else {
		print STDERR "#$0: Can't read \"$f\" [$~]\n";
	}
}
exit 0;

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Read one file and copy it to output.  It must be the file F.
#
sub onefile {
	local($l,$T,$X);
	$last = '';
	for $l (<F>) {
		$l =~ s/\s+$//;;				# Trim trailing white space
		if ($l || $last) {
			$l =~ s/^(\w:)\s*/$1 /;		# Adjust spacing after :
			if ($l =~ /^X:\s*(\d+)/) {	# X: line
				$X = $1;
				$Xnext = $ren ? 1 : $X;	# The input tune's number, if renumbering
				&outtune("% Xnext=$Xnext Xlast=$Xlast") if $V>3;
				if ($Xnext <= $Xlast) {$Xnext = $Xlast + 1}
				&outtune("% Xnext=$Xnext Xlast=$Xlast") if $V>2;
				&outtune("\n%%sep 0 1 8cm") if $sep && $tunes;
				$l = "X: $Xnext";
				&outtune("\n$l") unless $hopt && $tunes;
				++$tunes;
				$Xlast = $Xnext;		# Remember this tune index
			} elsif ($l =~ /^T:\s*(.+)/) {	# T: line
				if (!defined($X)) {
					$X = 0;
					&outtune("\nX: 0");
				}
				&outtune("%T $1") if $V>2;
				if (!defined($T) || (!$hopt) || $hfile) {
					&outtune("% Copy title because T not defined.") if !defined($T) && $V>2;
					&outtune("% Copy title in header file.")        if $hfile && $V>2;
					&outtune("% Copy title because no H option.")   if !$hopt && $V>2;
					$T = $1;				# Only do first title for non-header files.
					if ($hfile || !$hopt) {
						&outtune("T: $T");	# Use regular title line.
					} else {
						&outtune("P: $T");	# Convert title to "part" name.
					}
				}
			} else {
				&outtune("$l");
			}
		}
		$last = $l;
	}
	++$files;
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
sub outtune {
	local($l);
	for $l (@_) {
		$l = '%' if $hopt && !$l;
		print "$l\n";
	}
}
