#!/usr/bin/env perl
use strict;
use Getopt::Std;

# Create Fortran source from the template provided

# Retrieve command line options
my %options={};
getopts('h',\%options);

# Check for required wrapper name
my $print_help = (++$#ARGV < 1) ? 1 : 0;

# Print usage for help
if (defined $options{h} or $print_help){
  print "USAGE: ".$0." [options] WRAPPER\n";
  exit;
}

# Retrieve wrapper name
my $wrapper_name = $ARGV[0];

# Read template file
open TEMPLATE, '<', $wrapper_name.'.tmpl' or die $!;
my @tmpl = <TEMPLATE>;
close TEMPLATE;

# Read and parse include file to get list of symbols
my ($mass_name,@args,@adds);
open INC_FILE, '<', '../include/'.$wrapper_name.'.inc' or die $!;
while (<INC_FILE>){
  my $line=$_;
  if ($line =~ /^\s*interface\s+(\S+)/){
    $mass_name = $1;
  } else {
    if (defined($mass_name)){
      if ($line =~ /^\s*end\s+interface/){
	undef($mass_name);
	next;
      }
      if ($line =~ /^\s*end\s+\S+\s+/){
	my $wrap_name = $';
	chomp($wrap_name);
	&create_function($wrap_name,$mass_name,\@args,\@adds,\@tmpl);
	@args = ();
	@adds = ();
      } else {
	unless ($line =~ /^\s*end/){
	  if ($line =~ /^\s*!ADD\s+/){
	    $adds[++$#adds] = $';}
	  else{
	    $args[++$#args] = $line;
	  }
	}
      }
    }
  }
}
close INC_FILE;
close FD_OUT;

sub create_function($$$$$){
  my ($mw_name,$mass_name,$arglist,$addlist,$tmpl) = @_;
  my @template = @$tmpl;
  open FD_OUT, '>', $mw_name.'.f90' or die $!;
  my $func_declare = $$arglist[0];
  my $call_args = $func_declare; $call_args =~ m/\(.*\)/;
  $call_args = $&;
  my $call_name = $`; $call_name =~ m/\S+\s+${mw_name}/;
  $call_name = $&;
  my $args_declare = join('',@$arglist[1..$#$arglist+1]);
  my $adds = join('',@$addlist);
  my $mass_call = 'call '.$mass_name.$call_args;
  if ($call_name =~ m/function/){
    $mass_call = $mw_name.' = '.$mass_name.$call_args;
  }
  my $mass_inc = ($args_declare =~ /\(/) ? "include 'massvp7.include'" : "";
  my @search = ('#WRAP_NAME','#ARGS','#ADDS','#MASS_CALL','#WRAP_SHORT','#MASSV_INCLUDE');
  my @replace = ($func_declare,$args_declare,$adds,$mass_call,$call_name,$mass_inc);
  foreach (0..$#template){
    my $line = $_;
    foreach (0..$#search){
      $template[$line] =~ s/$search[$_]/$replace[$_]/g;
    }
  }
  print FD_OUT "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
  print FD_OUT @template;
  close(FD_OUT);
}
