#!/usr/bin/perl

# Utility to extract one or more parts from a mtx source file

use Getopt::Long;

sub read_opts {
    my($usage,$item,@opt_v,@tmparray,$i); 

    $usage = "Usage: exmtx.pl -opt ..\n";
    $usage .= " -i input file\n";
    $usage .= " -o output file\n";
    $usage .= " -v voice numbers to extract a:b-b+n:c ...\n";

    &GetOptions('i=s','o=s','v=s') || die "$usage\n";
    ($opt_i && $opt_o && $opt_v) || die "$usage\n";

    # initially separate -v argument items (separated by ":")
    @opt_v = split /:/,$opt_v;
    
    foreach $item(@opt_v) {
	if ($item =~ /-/) {
	    @tmparray = split /-/,$item;
	    $#tmparray == 1 || die "$usage\n";
	    $tmparray[0] < $tmparray[1] || die "$usage\n";
	    push @extr_voices, ($tmparray[0] .. $tmparray[1]);
	}
	else {
	    push @extr_voices,$item;
	}
    }

} # sub read_opts

sub voice_to_extract {
    my($voice_no) = @_;
    local($curr_voice,$result);
    $result=0;
    foreach $curr_voice (@extr_voices) {
      if ($curr_voice == $voice_no) {
	$result = 1;
	last;
      }
    }
    $result;
} # sub voice_to_extract

sub std_uptext_line {
    my($line) = @_;
    # Line must start with "U:"
    return $line =~ /^u\:/i;
} # sub std_uptext_line

sub lbl_uptext_line {
    my($line) = @_;
    # Line must start with "U" followed by a voice label and ":"
    return $line =~ /^u\w+\:/i;
} # sub lbl_uptext_line

sub chord_line {
    my($line) = @_;
    # Line must start with "C:"
    return $line =~ /^c\:/i;
} # sub chord_line

sub lyr_pgf_line {
    my($line) = @_;
    # Line must start with braced lyrics lable
    return $line =~ /^\{\w+\}/;
} # sub lyr_pgf_line 

sub lyr_line {
    my($line) = @_;
    # Line must start with L:
    return $line =~ /^l\:/i;
} # sub lyr_line 

sub preamble_line {
    my($line) = @_;
    # Line must have a leading word ended by ":"
    return $line =~ /^\w+\:/i;
} # sub preamble_line

sub comment_line {
    my($line) = @_;
    # Line must have a leading "%"
    return $line =~ /^%/;
} # sub comment_line

sub empty_line {
    my($line) = @_;
    # Line must have zero length
    !length($line);
} # sub empty_line 

sub print_paragraph {
    my(@curr_pgf) = @_;
    my($line);
    foreach $line(@curr_pgf) {
	print OUTFILE "$line\n";
    }
    print OUTFILE "\n";
} # print_paragraph

#
# Main program
#

read_opts;

open (INFILE, "<$opt_i") || die "Can't open $opt_i\n";
open (OUTFILE, ">$opt_o") || die "Can't open $opt_o\n";
#open (LOGFILE, ">exmtx.log") || die "Can't open exmtx.log\n";

$voice_number = 0;
$lyr_pgf_started = 0;

while (<INFILE>) {
  # Remove EOL and leading  blanks
  chop; s/^\s*//;
  if (($#paragraph>-1) and empty_line($_)) {
    print_paragraph(@paragraph);
    undef @paragraph;
    $lyr_pgf_started = 0;
    $voice_number = 0;
  }
  elsif ((lyr_pgf_line($_)) or ($lyr_pgf_started)) {
    $lyr_pgf_started = 1;
    push @paragraph,$_;
  }
  else {
      if (comment_line($_) or preamble_line($_)) {
	  if (lyr_line($_)) {
	      next if (!grep /$voice_number/,@extr_voices);
	  } # if (lyr_line($_) and grep /$voice_number/,@extr_voices) 
	  
	  next if ((chord_line($_)) and 
		   (! grep /$voice_number/,@extr_voices));
	  next if ((lbl_uptext_line($_)) and 
		   (! grep /$voice_number/,@extr_voices));
	  next if ((std_uptext_line($_)) and 
		   (! grep /$nxt_voice_number/,@extr_voices));
	  
	  push @paragraph,$_;
      }
      else {
	  $voice_number++;
	  $lyr_line_copied = 0;
	  $nxt_voice_number = $voice_number + 1;
	  next if (! voice_to_extract($voice_number));
	  push @paragraph,$_;
      } # if (comment_line($_) or preamble_line($_)) 
  } # if (($#paragraph>-1) and empty_line($_))
} # while (<INFILE>)

print_paragraph(@paragraph);

exit;
