#!/usr/bin/perl -w

use strict;

sub Usage($) {
    my $val = shift;
    my $pgm = $0;
    $pgm =~ s|.*/||;
    print
"Name:
	$pgm - make score blocks for midi with different combinations of voices

Synopsis:
	$pgm \[file_prefix\] \[voice_name\]...

Description:
	This program makes files named \[file_prefix\]_xxx.ly where the
	xxx's are either an \"_\" or one of \[voice_name\].

	The files will contain a score block with a combination of Staff's.

Example:
	$pgm pfx Sop Alt Ten Bas

	will create files like \"pfx-_Alt__.ly\":

	\\include \"pfx.ly\"

	\\score {
	  <<
	    \\transpose c \\tpAlt \\new Staff { \\iAlt | \\mAlt | }
	    \\new DrumStaff \\mt
	  >>
	  \\midi {
	    \\midi_tempo
	  }
	}

	where

	pfx.ly the file where the music and the following variables are defined
	tpAlt is which pitch to transpose to
	iAlt  is to give the singer the tone
	mAlt  is the music proper
	mt    is a metronome tick tack
	midi_tempo is the (starting) tempo of the piece
";
    # eg. qw/ s a t b / or qw/ a b c d /
    exit( $val );
}

sub binary($$) {
    my $sz = shift;
    my $v = shift;
    my @binary = ( );

    for (my $ix = 0; $ix < $sz; $ix++) {
	my $b = $v & 1;
	$v >>= 1;
	push @binary, ($b ? 1 : 0 );
    }
    if (@binary < $sz) {
	push @binary, ( 0 ) x ($sz - 1 - @binary);
    }
    @binary;
}

sub mkbinstr($@) {
    my $v = shift;
    my @bstr = @_;

    my $str = "";
    for (my $ix = 0; $ix < @bstr; $ix++) {
	my $b = $v & 1;
	$v >>= 1;
	$str = ($b ? $bstr[@bstr-$ix-1] : "_" ) . $str;
    }

    $str;
}

sub mkscore($$@) {
    my $pfx = shift;
    my $code = shift;
    my @list = @_;

    my @v = reverse(binary(@list, $code));

    my $cnt = 0;
    for (my $ix = 0; $ix < @v; $ix++) {
	my $b = $v[$ix];
	if ($b) {
	    $cnt++;
	}
    }

    my $score = "";
    $score .= "\\include \"$pfx.ly\"\n\n";

    if ($cnt == 1) {
	$score .= "#(set-global-staff-size 22)
\\paper {
  page-count = 1
}
";
    }
    $score .= '\score {
  \new ChoirStaff <<
    \score_pre
';

    for (my $ix = 0; $ix < @v; $ix++) {
	my $b = $v[$ix];
	if ($b) {
	    my $k = $list[$ix];
	    $score .= "        \\transpose c \\tp$k \\new Staff \\m$k\n";
	    $score .= "        \\lyricsto V$k \\l$k\n";
	}
    }
#\\transpose c \\tp$k \\new Staff { \\i$k | \\m$k | }\n
    $score .= "  >>

  \\layout {
    \\context {
      \\Voice
      \\consists \"Ambitus_engraver\" keySignature = #'()
    }
  }
}

";

    $score .= "\\score {\n  <<\n";

    for (my $ix = 0; $ix < @v; $ix++) {
	my $b = $v[$ix];
	if ($b) {
	    my $k = $list[$ix];
	    $score .= "    \\transpose c \\tp$k \\new Staff { \\midi_$k \\i$k | \\m$k | }\n";
	}
    }

    $score .= '    \new DrumStaff \mt
  >>
  \midi {
    \midi_tempo
  }
}
';

    $score;
}

sub main() {
    if (@ARGV < 2) { Usage(0); }

    my $pfx = shift @ARGV;
    my @list = @ARGV;

    for (my $ix = 1; $ix < 16; $ix++) {
	#my $file = mkbinstr($ix, @list);
	#printf "%2d: %s\n", $ix, $file;
	my $file = ${pfx} . "-" . mkbinstr($ix, @list) . ".ly";
	open(FH, ">$file") || next;
	print FH mkscore($pfx, $ix, @list);
	close(FH);
    }
}

####

main();

__END__
