#!/usr/bin/perl -w

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

#  for SQM copies, add these dependencies as well to the list

#  Be sure do to a "make clean" before running this script!

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

$SQM{"qm2_dftb_scf"} = $SQM{"qm2_energy"} = $SQM{"qm2_scf"} =
$SQM{"qm2_read_nm_and_alloc"} = 1;

#  in order to get a mapping between module names and file names, we have
#  have to set up the following hash. 

$modulefile{"netcdf"} = "";  #special case, since this mod file is elsewhere

foreach $file ( <*.f> ){
	next if $file =~ /^_/;
	($fileroot) = $file =~ /(.+)\.f$/;
	$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 ( <*.f> ){

	next if $file =~ /^_/;

#	next if $file eq "qmmm_module.f";  #special case this module

	$deps = $depsSQM = "";

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

	#  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};
#				next if $modulefile{$usee} eq "qmmm_module";  # special case here

				$deps .= "\\\n                    " . $modulefile{$usee} .  ".o" ;
				if( defined $SQM{$modulefile{$usee}} ){
					$depsSQM .= "\\\n                    " .  $modulefile{$usee} .  ".SQM.o" ;
				} else {
					$depsSQM .= "\\\n                    " . $modulefile{$usee} .  ".o" ;
				}

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

	#  construct the compilation rules:

	if( $optimized{$fileroot} ){
		printf "\n$fileroot.o:   $fileroot.f\n";
		printf "\t\$(FPP) $fileroot.f > _$fileroot.f\n";
		printf "\t\$(FC) -c \$(FOPTFLAGS) -o \$@ _$fileroot.f\n\n";
	} else {
		printf "\n$fileroot.o:   $fileroot.f\n";
		printf "\t\$(FPP) $fileroot.f > _$fileroot.f\n";
		printf "\t\$(FC) -c \$(FFLAGS) -o \$@ _$fileroot.f\n\n";
	}
	if( defined $SQM{$fileroot} ){
		printf "$fileroot.SQM.o: $depsSQM\n" unless $depsSQM eq "";
		printf "\n$fileroot.SQM.o:   $fileroot.f\n";
		printf "\t\$(FPP) -DSQM $fileroot.f > _$fileroot.SQM.f\n";
		if( $optimized{$fileroot} ){
			printf "\t\$(FC) -c \$(FOPTFLAGS) -o \$@ _$fileroot.SQM.f\n\n";
		} else {
			printf "\t\$(FC) -c \$(FFLAGS) -o \$@ _$fileroot.SQM.f\n\n";
		}
	}
}
