#!/usr/bin/perl -w

#  cycle through fortran files, determine which headers are included;
#      the "used" array eliminates duplicate enties

#  for SANDER programs, add these dependencies as well 
#      to the list

#  Be sure do to a "make clean" before running this script!
#      (probably not really needed, but better safe than sorry)

printf <<EOF;
#
#   Please do not edit the "depend" file directly, since it is created by the
#   "makedepend" script.  If changes are needed, edit "makedepend" itself.
#
EOF

$SANDER{"sa_driver"} = $SANDER{"pb_force"} = $SANDER{"np_force"} = 
	$SANDER{"pb_exmol"} = $SANDER{"pb_mpfrc"} = $SANDER{"pb_direct"} =
	$SANDER{"pb_list"} = $SANDER{"pb_read"} = $SANDER{"pb_write"} =
	$SANDER{"pb_init"} = $SANDER{"timer"} = $SANDER{"problem"} =
        $SANDER{"gen_dx_file"} = $SANDER{"membrane"} = 1;
$LIBPBSA{"sa_driver"} = $LIBPBSA{"pb_force"} = $LIBPBSA{"np_force"} = 
	$LIBPBSA{"pb_exmol"} = $LIBPBSA{"pb_fft"} = $LIBPBSA{"pb_direct"} =
	$LIBPBSA{"pb_list"} = $LIBPBSA{"pb_read"} = $LIBPBSA{"pb_write"} =
	$LIBPBSA{"pb_init"} = $LIBPBSA{"timer"} = $LIBPBSA{"problem"} =
        $LIBPBSA{"gen_dx_file"} = $LIBPBSA{"membrane"} = $LIBPBSA{"pbsaapi"} = 
        $LIBPBSA{"pb_fftsolv"} = $LIBPBSA{"fftw3"} = 1;

#  in order to get a mapping between module names and file names, we have
#  have to set up the following hash. 
#  (special cases, since source is elsewhere)
#  (check also below  (end of this file) for "compilation" rules)

foreach $file ( <*.F90> ){
	next if $file =~ /^_/;
	($fileroot) = $file =~ /(.+)\.F90$/;
	$optimized{$fileroot} = 0;
	open( F, "$file" ) || die "unable to open $file\n";
	while( <F> ){
		if( /^ *module /i ){
			($head,$modulename) = /( *[Mm][Oo][Dd][Uu][Ll][Ee]) +(\w*)/;
			$modulefile{$modulename} = $fileroot;
#			printf STDERR "modulefile:  $modulename  $fileroot\n";
		}
		if( /compile=optimized/ ){
			$optimized{$fileroot} = 1;
		}
	}
	close( F );
}

#  Now, cycle over all source files to create the compilation rules and 
#  dependencies.  Check for "compile=optimized" comments and do the right 
#  thing:

foreach $file ( <*.F90> ){

	next if $file =~ /^_/;

	$deps = $depsSANDER = $depsLIBPBSA = "";

	($fileroot) = $file =~ /(.+)\.F90$/;

	#  construct the header and module dependency rules:

	open( F, "$file" ) || die "unable to open $file\n";
	while( <F> ){

		if( /^ *use / ){
			($head,$usee) = /( *use) +(\w*)/;
#			printf STDERR "     usee: $usee; modulefile is $modulefile{$usee}\n";
            
			if( !defined $modulefile{$usee} ){
				printf STDERR "No file name associated with module $usee\n";
				exit(1);
			}
			if( !defined $used{ $fileroot,$modulefile{$usee} } ){

				#  remove any circular references:
				next if $fileroot eq $modulefile{$usee};
                                $deps .= "\\\n                    " . $modulefile{$usee} .      ".o" ;
                                if( defined $SANDER{$modulefile{$usee}} ){
                                        $depsSANDER .= "\\\n                    " . $modulefile    {$usee} .  ".SANDER.o" ;
                                } else {
                                        $depsSANDER .= "\\\n                    " . $modulefile    {$usee} .  ".o" ;
                                }

                                if( defined $LIBPBSA{$modulefile{$usee}} ){
                                        $depsLIBPBSA .= "\\\n                    " . $modulefile    {$usee} .  ".LIBPBSA.o" ;
                                } else {
                                        $depsLIBPBSA .= "\\\n                    " . $modulefile    {$usee} .  ".o" ;
                                }

				$used{ $fileroot,$modulefile{$usee} } = 1;
			}
		}
		if (/^# *include/) {
			($head,$included) = /(# *include) +"(.*)"/;
			if( !defined $used{ $fileroot,$included } ){
				$deps .= "\\\n                    " . $included ;
				$depsSANDER .= "\\\n                    " . $included ;
				$depsLIBPBSA .= "\\\n                    " . $included ;
				$used{ $fileroot,$included } = 1;
			}
		}
	}
	printf "$fileroot.o: $deps\n\n" unless $deps eq "";

	#  construct the compilation rules:
	if( defined $SANDER{$fileroot} ){
		printf "$fileroot.SANDER.o: $depsSANDER\n" unless $depsSANDER eq "";
	}
	if( defined $LIBPBSA{$fileroot} ){
		printf "$fileroot.LIBPBSA.o: $depsLIBPBSA\n" unless $depsLIBPBSA eq "";
	}

}

#  special "compilation" rules 
