%%START_PERL%%
use File::Find;
use Cwd;
use Getopt::Long;
use File::Basename;
use File::stat;

my $CONFIG_FILE_NAME = 'Config.pm';
my $st_config;

# first we check if we are being run as part of a complete GeneX
# install, or only as an update to Genex.pm
if (-e "Bio/Genex/$CONFIG_FILE_NAME") {
  $st_config = stat("Genex/$CONFIG_FILE_NAME");

  # nice trick. we wrote the hash out as a perl module using Data:Dumper,
  # so to recreate it we just 'require' it ;-)
  eval {
    use lib '.';
    require Bio::Genex::Config;
  };
  die "$0: Couldn't load local Config.pm: $@\n"
    if $@;
} else {
  # this is part of a Genex.pm update
  eval {
    require Bio::Genex::Config;
  };
  if ($@) {
    die <<"EOE";

Could not load Bio::Genex::Config. This means you did not read the README.

EOE
  }
}

my %SUBST = %{$Bio::Genex::Config};

# now give some feedback to let the user know what values
# we've just passed in
my @keys = sort {length($b) <=> length($a)} keys %SUBST;

my $max = length($keys[0]);

print STDERR "Using the following configd values:\n";
foreach my $key (keys %SUBST) {
  printf STDERR "  %-$ {max}s => %s\n", $key ,$SUBST{$key};
}

my @ignore_dirs = ('blib');
my $rc = GetOptions(\%OPTIONS, 
		    'ignore_dirs=s@',
		   );

# ignore_dirs can be specified in two ways:
# --ignore_dirs=id_one --ignore_dirs=id_two ...
# or
# --ignore_dirs=id_one,id_two
# 
# so we use the following construct to handle both cases
push(@ignore_dirs,split(/,/,join(',',@{$OPTIONS{ignore_dirs}})));

# we turn @ignore_dirs from a list of names into a list of 
# regular expressions of the form: /^item$/
@ignore_dirs = map {qr/^$_$/} @ignore_dirs;

#
# Find all .in files and do  variable substitution
#
sub wanted {
  if (-d $_) {
    foreach my $dir_re(@ignore_dirs) {
      if ($_ =~ $dir_re) {
	# if we are to ignore this directory set $File::Find::prune
	$File::Find::prune = 1;
	return;
      }
    }
    # we don't substitue directories, so return
    return;
  }

  # only substitute '.in' files
  return unless /\.in$/;

  # we don't want to substitute the configure.pl.in 
  return if /^configure\.pl\.in$/;

  my ($outfile) = $File::Find::name =~ m/^(.*)\.in$/;
  
  # we only want to substitute if the infile has been modified 
  # since we last ran the substitution, or if the config file
  # has been modified
  if (-f $outfile) {
    my $st_out = stat($outfile);
    my $st_in = stat($File::Find::name);

    # First, if the config file is local, check if the config more
    # recent, otherwise check if infile is more recent
    if (!defined $st_config || $st_config->mtime > $st_out->mtime) {
      # has the infile been modified?
      return unless $st_in->mtime > $st_out->mtime;
    }
  }

  open(IN,$File::Find::name) or die "Couldn't open $File::Find::name for reading";
  open(OUT,">$outfile") or die "Couldn't open $outfile for writing";
  print STDERR "  Creating ", basename($outfile), " from $_ ";
  while (<IN>) {
    foreach my $pattern (keys %SUBST) {
      if ($_ =~ /\%\%$pattern\%\%/) { 
	print STDERR "."; 
	$_ =~  s/\%\%$pattern\%\%/$SUBST{$pattern}/g;
      }
    }
    print OUT;
  }
  print STDERR "\n";
  close(OUT);
  close(IN);

  # make the perl scripts executable
  if ($outfile =~ m/\.pl$/) {
    chmod(0775,$outfile);
  } else {
    chmod(0664,$outfile);
  }
}

print STDERR "Substituting parameters in perl scripts and modules\n";
find(\&wanted, cwd());

\%SUBST;
