#!/usr/bin/perl -w

#
# version of "supporting" engine, not mudela conversions.
# 

$convert_mudela_version = "0.1";

use Getopt::Long;



sub version_string_conv
{
    my ($from_version, $to_version) = @_;
    s/\version \"0.0.$from_version\"/\version \"0.0.$to_version\"/g;
}

################################################################

sub no_conv
{
}
 
sub convert_0_0_52_to_0_0_53
{

    s/include \"/$1\\include \"/g;
}

  
sub convert_0_0_53_to_0_0_54
{
    print STDERR "Not smart enough to convert \\transpose\n"    if (/\\transpose/) ;
}

###############################################################

sub    last_conversion
{
    my @v = &versions;
    return pop @v;
}
sub identify
{
    
    print STDERR "This is convert-mudela " . $convert_mudela_version . 
	" (up to mudela version 0.0.", last_conversion,	")\n";
}
  
  
 sub usage
  {
     print STDERR "Usage: convert-mudela [options] [mudela-file]...\n"
     . "Convert old mudela source from mudela-file or stdin\n\n"
     . "Options:\n"
     . "  -e, --edit             perform in-place conversion\n"
     . "  -f, --from=PATHLEVEL   use source version 0.0.PATCHLEVEL\n"
     . "  -h, --help             print this help\n"
     . "  -o, --output=FILE      name output file\n"
     . "  -s, --show-rules       print all known conversion rules\n"
     . "  -t, --to=PATCHLEVEL    convert to version 0.0.PATCHLEVEL\n"
  }
      
# beware of the year 2000
my %minor_conversions = (50 => \&no_conv,
 			 52 => \&convert_0_0_50_to_0_0_52,
  			 53 => \&convert_0_0_52_to_0_0_53,
  			 54 => \&convert_0_0_53_to_0_0_54
  			 );
 

sub versions 
{
    return  (sort keys %minor_conversions);
}
    

sub    show_rules
{
    print "Rules: ", join(", ", sort keys %minor_conversions), "\n";
    
}

sub do_conversion
{
    my ($from,$to) = @_;

    my @applicable_conversion;
    my @mudela_levels;
    
    die "This is too old  to convert " if $from < 50;
    my @v = versions;
    foreach $a (@v) {
	if ($a > $from && $a <= $to ){ 
	    push @applicable_conversion, $minor_conversions{$a};
	    push @mudela_levels, $a;
	}
    }
    
    print STDERR "Applying following rules: ", join(", ", @mudela_levels) , "\n";

    while (<INLY>) {
	foreach $subroutine (@applicable_conversion) {
	
	    &$subroutine;
	    
	}
	version_string_conv $from, $to;
	print OUTLY;
    }
}

sub get_auto_from
{
    my ($fn)=@_;
    my ($ver);
    open INLY, $fn || die "Can't open";

    while (<INLY>) {
	s/^.*\\version \"([^\"]*)\".*$//;
	if (defined ($1)) {
	    print STDERR "Guessing version: ", $1, ".. ";
	    $ver = $1;
	    last;
	}
    }
    if (!defined($ver)){
	print STDERR "can't determine mudela version in $fn.\n";
	my $u;
	return $u;
    }
    $ver =~ s/0\.0\.// ;
    close INLY;
    return $ver;
}   

sub  set_files 
{
    $infile = "-";
    $outfile = "-";
    $outfile = $opt_output if (defined($opt_output));

    if ($ARGV [0])  {
	$infile = $ARGV[0];
    } 
    if (( ! -f $infile) && (! $infile =~ /\\.ly$/s ) ){
	$infile .= ".ly";
	

    }
    if ($opt_edit && $infile ne "-") {
	$opt_edit = 1;
	$outfile = "$infile.NEW";
	$infile = "$infile";
    }
    print STDERR "Input ", (($infile eq "-") ?"STDIN" : $infile), " .. ";

}

sub do_one_arg
{
    set_files;

    local ($from_version, $to_version);
    $from_version = $opt_from;
    $to_version = $opt_to;
    
    ($from_version = get_auto_from $infile) unless defined($opt_from);
    return if (!defined($from_version));
    
    ($to_version =  last_conversion) unless (defined($opt_to));


    die "can't open \`$infile\'" unless open INLY,$infile ;
    die "can't open \`$outfile\'" unless open OUTLY, ">$outfile";
    
    do_conversion $from_version, $to_version;
    close INLY;
    close OUTLY;

    if ($opt_edit) {
	rename $infile, "$infile~";
	rename $outfile, "$infile";
    }
}

## "main"

identify;

GetOptions ("help", "output=s", "from=i", "to=i", "minor=i", "edit", "show-rules");

if ($opt_help) {
    usage();
    $opt_help = 0;	# to extinguish typo check.
    exit 0;
}

if ($opt_show_rules) { 
    show_rules ;
    $opt_show_rules = 0;	# to extinguish typo check.
    exit 0;
}

local ( $infile,$outfile);
my $processed_one=0;

while (defined($ARGV[0])) {
    do_one_arg;
    shift @ARGV;
    $processed_one = 1;
}
do_one_arg unless ($processed_one);

    
