#!/usr/bin/perl
#!/home/jmc/bin/perl
#
#SYNOPSIS
# abcpar [+|-]interval [file]..
#
#DESCRIPTION
# Read an abc file (or passage from stdin), and write output that has
# the  same  melody  plus  a  harmony  line  in parallel at the given
# interval.  The default interval is +2, i.e., a third higher.
#
# Note that  the  interval  is  in  scale  steps,  not  the  absolute
# interval, so it will be in the same key.
#
# The interval was originally one less  than  the  musical  interval.
# This  this was changed because it confused some musicians, who like
# their intervals to be one off from the actual difference.  ;-)
#
#AUTHOR
#  John Chambers <jc@trillian.mit.edu> March 2000
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

$| = 1;
($me = $0) =~ s'.*/'';
$V = $ENV{"V_$me"} || $ENV{"T_$me"} || $ENV{"D_$me"} || 1;

@S = (	# Should this be expanded?
	"C,,","D,,","E,,","F,,","G,,","A,,","B,,",
	"C,", "D,", "E,", "F,", "G,", "A,", "B,",
	"C",  "D",  "E",  "F",  "G",  "A",  "B",
	"c",  "d",  "e",  "f",  "g",  "a",  "b",
	"c'", "d'", "e'", "f'", "g'", "a'", "b'",
	"c''","d''","e''","f''","g''","a''","b''",
);
for ($i=0; $i<@S; $i++) {	# Distances above C,,
	$I{$S[$i]} = $i;
}

if  (($dir, $int) = ($ARGV[0] =~ /^([-+])(\d+)/)) {
	if ($dir eq '+') {
		$diff = $int - 1;	# Convert to upward difference.
	} else {
		$diff = 1 - $int;	# Downward difference.
	}
	shift;
} else {
	$diff = 2;	# Up  third.
}

$A = '[\^=_]*';	# Accidental.
$N = '[A-Ga-g][\',]*';	# Note.
$L = '[/\d.\<>]*';				# Length.

line:
for $line (<>) {
	while ($line) {
		if ($line =~ s/^(\s+)//) {print $1}
		if ($line =~ /^([A-Z]:)(\s*)/) {
			print $line;
			next line;
		} elsif ($line =~ s'^("[^"]*"\s*)'') {print $1; next;
		} elsif ($line =~ s'^(\(\d*\s*)'')   {print $1; next;
		} elsif ($line =~ s'^(\)\s*)'')      {print $1; next;
		} elsif ($line =~ s'^(\[\|\s*)'')    {print $1; next;
		} elsif ($line =~ s'^(\|\]*\s*)'')   {print $1; next;
		} elsif ($line =~ s'^(\[.*\]\s*)'')  {print $1; next;
		} elsif ($line =~ s/^($A)($N)($L)(\s*)//) {
			 $a = $1; $n = $2;  $l = $3; $s = $4;
			 $i = $I{$n};
			 $j = $i + $diff;
			 if ($h = $S[$j]) {
#				 if ($l) {
				 	print "[$a$n$l$a$h$l]$s";
#				 } else {
#				 	print "[$a$n$a$h]$l$s";
#				 }
				 next;
			 }
		}
		if ($line =~ s'^(.)'')          {print $1; next;
		}
		print "Left: \"$line\"\n" if $V>1;
	}
}
