#!/usr/bin/perl
#
# TGCM configure script.
#
use Getopt::Long;
use IO::File;
use File::Copy;
use File::Basename;
use Cwd;
#
$cwd = cwd();
($progname = $0) =~ s!(.*)/!!;
#
# Set option defaults (local):
#
my $wrkdir      = $cwd;   # user's root working dir (default is cwd)
my $copysrc     = 0;      # default is not to copy source
my $hres        = 5.0;    # default horizontal resolution
my $vres        = 0.5;    # default vertical resolution
my $debug       = 0;      # default is no debug run
my $nomake      = 0;      # default is to make a Makefile
my $mpi         = '';     # default parallel vs serial is system dependent (T/F)
my $mss         = '';     # availablity of NCAR mass store (default is TRUE)
my $help        = 0;      # default is no help
my $debug       = 0;      # default is no debug
   $lib_netcdf  = '';     # default netcdf lib location is system dependent
   $inc_netcdf  = '';     # default netcdf inc location is system dependent
#
# Parse arguments:
#
&GetOptions(
   "model=s"        => \$model,
   "wrkdir=s"       => \$wrkdir,
   "usr_srcdirs:s"  => \$usr_srcdirs,
   "execdir:s"      => \$execdir,
   "tgcmroot:s"     => \$tgcmroot,
   "tgcmdata:s"     => \$tgcmdata,
   "utildir:s"      => \$utildir,
   "copysrc!"       => \$copysrc,
   "hres=f"         => \$hres,
   "vres=f"         => \$vres,
   "debug:i"        => \$debug,
   "nomake"         => \$nomake,
   "mpi:s"          => \$mpi,
   "mss:s"          => \$mss,
   "lib_netcdf:s"   => \$lib_netcdf,
   "inc_netcdf:s"   => \$inc_netcdf,
   "h|help"         => \$help,
) or usage();
#
# Provide usage statement for help:
if ($help) { usage(); } # provide usage if help was requested
#
# Check for unparsed arguments:
if (@ARGV) {
    print "ERROR: unrecognized arguments: @ARGV\n";
    usage();
}
#
# Default tgcmroot at hao and scd:
#
$tgcmroot_default_hao = "/home/tgcm";
$tgcmroot_default_scd = "/fis/hao/tgcm";
#
#
# Validate args:
&validate_options();
#
# Report options to stdout:
#
$date = `date`; chop($date);
print << "EOF";

$progname executing in $cwd at $date:
  model       = $model
  wrkdir      = $wrkdir
  usr_srcdirs = $usr_srcdirs
  execdir     = $execdir
  tgcmroot    = $tgcmroot
  tgcmdata    = $tgcmdata
  utildir     = $utildir
  copysrc     = $copysrc
  hres        = $hres
  vres        = $vres
  mpi         = $mpi
  mss         = $mss
  lib_netcdf  = $lib_netcdf
  inc_netcdf  = $inc_netcdf
  debug       = $debug

EOF
#
# Model source directory:
#
$model_srcdir = "$tgcmroot/$model/src";
if (! -d $model_srcdir) { 
  print ">>> WARNING $progname: could not find source directory $model_srcdir\n"; }
#
#print "Using model source directory model_srcdir   = $model_srcdir\n";
#
# Model class:
$model_class = "tgcm";
SWITCH: {
  if ($model =~ /^tiegcm/)  { $model_class = "tiegcm"  ; last SWITCH; }
  if ($model =~ /^timegcm/) { $model_class = "timegcm" ; last SWITCH; }
  if ($model =~ /^mtgcm/)   { $model_class = "mtgcm"   ; last SWITCH; }
  if ($model =~ /^titan/)   { $model_class = "titan"   ; last SWITCH; }
  if ($model =~ /^glbmean/) { $model_class = "glbmean" ; last SWITCH; }
}
#
# Build list of source directories and write list to file $execdir/$fp_filename:
#
$fp_filename = "Filepath";
@srcdirs = write_filepath($usr_srcdirs, $model_srcdir, "$execdir/$fp_filename");
#
# Copy source code if requested:
#
if ($copysrc) { &copy_model_src(@srcdirs, $execdir); }
#
# Make defs.h according to given model and resolution:
# (a copy may or may not already exist)
#
&write_defs_h("$execdir/defs.h",$hres,$vres,$model);
#
# Write macros to Makefile:
#
if ($nomake) {
  print "$progname: Not making Makefile because -nomake option was set.\n";
} else {
  &write_makefile("$utildir/Makefile", "$execdir/Makefile", $debug);
}
#
# Successful exit:
#
$date = `date`; print "\n$0 done at $date\n";
exit;
#
#-------------------------------------------------------------------------
sub usage {
  die <<EOF;

SYNOPSIS
  $0 [options]
OPTIONS
  -model	Name of requested model (usually begins with "tiegcm" or "timegcm").
  -wrkdir	Top directory for job (default is current directory)
  -usr_srcdirs	Optional list directories containing user-provided source code
                (Comma-separated list with no imbedded whitespace).
  -execdir	Build/Execution directory (default \$wrkdir/\$model-\$os)
  -tgcmroot  	TGCM root distribution (default \$TGCMROOT).
  -tgcmdata  	TGCM root distribution of model data (default \$TGCMDATA). 
  -utildir   	Directory containing tgcm_config and other utility scripts.
                (default based on tgcmroot)
  -copysrc      If copysrc=1, copy source code to build dir (default is 0)
  -hres         Horizontal resolution (float, either 5.0 or 2.5 degrees)
  -vres         Vertical resolution (float, either 0.5 or 0.25 delta log pressure)
  -debug	If > 0, configure Makefile for a debug run (fpe trapping, etc).
  -mpi          TRUE, FALSE, or DEFAULT (default is system and model dependent)
  -mss          TRUE, FALSE, or DEFAULT (default is system and model dependent)
  -help		Print usage message and quit.

EOF
}
#-----------------------------------------------------------------------
sub validate_options {
#
# Validate (possible modify) user options (globals, not local).
  print "\n";
#
# -model option is required:
#
  if (! defined $model or $model eq "") {
    print "\n>>> $progname: Please provide the name of the desired model using the -model option.\n";
    usage();
  } 
#
# Working directory: default is cwd, otherwise make it if necessary:
#
  if (! defined $wrkdir or $wrkdir eq "") {
    $wrkdir = abspath(".");
#   print "$progname: Using wrkdir = $wrkdir\n";
  } else {
    $wrkdir = abspath($wrkdir);
    if (! -d $wrkdir) {
      mkdir($wrkdir, 0777) || \
        die "\n>>> $progname: Could not make wrkdir directory $wrkdir\n\n";
      print "Made new wrkdir directory $wrkdir\n";
    } else { 
#     print "Using already existing wrkdir $wrkdir\n"; 
    }
  }
#
# User source directories (optional, but must exist if provided):
#
  if (defined $usr_srcdirs) {
    if ($usr_srcdirs eq '') { 
      undef $srcdir; 
    } else {
      my @dirs = split(',', $usr_srcdirs);
      my @paths;
      while (my $dir = shift @dirs) {
        if (-d $dir) { 
          push(@paths, abspath($dir)); 
        } else {
          die "\n>>> $progname: Cannot find user source directory $dir\n";
        }
      }
      $usr_srcdirs = join(',', @paths);
#     print "$progname: usr_srcdirs = $usr_srcdirs\n";
    }
  }
#
# Build/Execution directory (default is $wrkdir/$model-$os):
# (If Linux and machine is lightning, set OS to linux-mpi)
# 6/05: Makefile file now does this.
#
  $OS = `uname -s`; chop $OS; 
  $hardware = `uname -i`; chop $hardware;
  $nbit     = 32;
  if ($hardware =~ 64) { $nbit = 64; } # 64-bit linux
  $nodename = `uname -n`; chop $nodename;
  ($os = $OS) =~ tr/A-Z/a-z/;
  print "tgcm_config: OS=$OS os=$os nbit=$nbit\n";
#
  if (! defined $execdir or $execdir eq "") {
    $execdir = "$wrkdir/$model-$os"; # default
    print "$progname: Set execdir = $execdir\n";
  }
  $execdir = abspath($execdir);
  if (! -d $execdir) {
    mkdir($execdir, 0777) || \
      die "\n>>> $progname: Could not make execdir directory $execdir\n\n";
  }
#
# Determine tgcm root directory $tgcmroot, in the following search order:
#   1) Config option -tgcmroot
#   2) Environment variable $TGCMROOT
#   3) The default HAO directory, if it exists ($tgcmroot_default_hao)
#   4) The default SCD directory, if it exists ($tgcmroot_default_scd)
# If this search fails, quit with an error message explaining tgcmroot.
#
  if (! defined $tgcmroot or $tgcmroot eq "") {
    if (defined $ENV{TGCMROOT}) { 
      $tgcmroot = $ENV{TGCMROOT}; 
      print "$progname: Set tgcmroot from TGCMROOT env var: $tgcmroot\n";
    } elsif (-d $tgcmroot_default_hao) {
      $tgcmroot = $tgcmroot_default_hao;
      print "$progname: Set tgcmroot to default HAO tgcmroot: $tgcmroot\n";
    } elsif (-d $tgcmroot_default_scd) {
      $tgcmroot = $tgcmroot_default_scd;
      print "$progname: Set tgcmroot to default SCD tgcmroot: $tgcmroot\n";
    } else {
      die <<EOF;

>>> $progname: tgcmroot option not set, and TGCMROOT env var not set.

  To set tgcmroot, please do one of the following:
    1. Use the -tgcmroot option to tgcm_config.
    2. Set the tgcmroot shell variable in your job script that called tgcm_config.
    3. Set the environment variable TGCMROOT in your ~/.cshrc file
       (or from the command line if it is not set in your ~/.cshrc file)

  If configuring the model at HAO you can set tgcmroot to "$tgcmroot_default_hao".
  If configuring the model at SCD you can set tgcmroot to "$tgcmroot_default_scd".

  If you downloaded or otherwise obtained a tar file, set the tgcmroot 
    shell variable in your job script to the directory in which you 
    extracted the tar file.

  The tgcmroot directory should contain a subdirectory with the name of
  the requested model. The model subdirectory in turn should contain the 
  subdirectories src/ and scripts/.

EOF
    }
  }
  $tgcmroot = abspath($tgcmroot);
  if (! -d $tgcmroot) {
    die "\n>>> Cannot find tgcmroot directory $tgcmroot\n\n"; } 
#
# tgcm data directory (non-fatal if not defined or does not exist)
# If option not set and env var TGCMDATA is not set, use $execdir.
#
  if (! defined $tgcmdata or $tgcmdata eq "") {
    if (defined $ENV{TGCMDATA}) { 
      $tgcmdata = $ENV{TGCMDATA}; 
      print "$progname: Set tgcmdata from TGCMDATA env var: $tgcmdata\n";
    } else {
      print "$progname: Set tgcmdata directory to execdir $execdir\n";
      $tgcmdata = $execdir;
    }
  }
  $tgcmdata = abspath($tgcmdata);
  if (! -d $tgcmdata) {
    print "\n>>> WARNING: Cannot find tgcmdata directory $tgcmdata\n\n"; } 
#
# If utildir was provided, it must exist. If not provided, will default
# to scripts directory based on $tgcmroot (see above, after validation).
#
  if (defined $utildir) {
    if (! -d $utildir) {
      die "\n>>> $progname: utility directory $utildir does not exist.\n\n";
    }
  }
#
# Horizontal and Vertical resolution requests:
  if ($hres != 5.0 &&  $hres != 2.5) {
    print "\n>>> Bad hres = $hres (hres must be either 5.0 or 2.5 degrees)\n\n";
    usage();
  }
  if ($vres != 0.5 &&  $vres != 0.25) {
    print "\n>>> Bad vres = $vres (vres must be either 0.5 or 0.25)\n\n";
    usage();
  }
#
# Option mpi can be TRUE, FALSE, or DEFAULT.
  SWITCH: {
    if (not $mpi)     { $mpi = "DEFAULT"; last SWITCH; }
    if ($mpi =~ /^T/) { $mpi = "TRUE"   ; last SWITCH; }
    if ($mpi =~ /^F/) { $mpi = "FALSE"  ; last SWITCH; }
    if ($mpi =~ /^D/) { $mpi = "DEFAULT"; last SWITCH; }
    $nothing = 1;
    print "\n>>> Bad mpi = $mpi (can be null, TRUE, FALSE, or DEFAULT)\n\n";
    print "If mpi == TRUE,  MPI libraries will be linked for parallel run.\n";
    print "If mpi == FALSE, MPI libraries will NOT be linked (serial run).\n";
    print "If mpi == DEFAULT (or is not provided), then mpi is set as follows:\n";
    print "   1) mpi = TRUE\n";
    print "   2) if system is non-lightning Linux, then mpi = FALSE\n";
    print "   3) if model is glbmean, then mpi = FALSE\n";
    usage();
  } # switch
  $mpiflag = $mpi;
#
# Option mss can be TRUE, FALSE, or DEFAULT.
  SWITCH: {
    if (not $mss)     { $mss = "TRUE"   ; last SWITCH; }
    if ($mss =~ /^T/) { $mss = "TRUE"   ; last SWITCH; }
    if ($mss =~ /^F/) { $mss = "FALSE"  ; last SWITCH; }
    $nothing = 1;
    print "\n>>> Bad mss = $mss (can be null, TRUE or FALSE)\n\n";
    print "If mss == TRUE,  NCAR Mass Store is available.\n";
    print "If mss == FALSE, NCAR Mass Store is NOT available.\n";
    print "Default mss == TRUE\n";
    usage();
  } # switch
  $mssflag = $mss;
} # end sub validate_options
#-----------------------------------------------------------------------
sub abspath {
#
# Convert a pathname into an absolute pathname, expanding any . or .. characters.
# Assumes pathnames refer to a local filesystem.
# Assumes the directory separator is "/".
#
  my ($path) = @_;
  my $cwd = getcwd();  # current working directory
  my $abspath;         # resulting absolute pathname
#
# Strip off any leading or trailing whitespace.  
# (This pattern won't match if there's embedded whitespace.
#
  $path =~ s!^\s*(\S*)\s*$!$1!;
#
# Convert relative to absolute path.
#
  if ($path =~ m!^\.$!) {          # path is "."
      return $cwd;
  } elsif ($path =~ m!^\./!) {     # path starts with "./"
      $path =~ s!^\.!$cwd!;
  } elsif ($path =~ m!^\.\.$!) {   # path is ".."
      $path = "$cwd/..";
  } elsif ($path =~ m!^\.\./!) {   # path starts with "../"
      $path = "$cwd/$path";
  } elsif ($path =~ m!^[^/]!) {    # path starts with non-slash character
      $path = "$cwd/$path";
  }
  my ($dir, @dirs2);
#
# The -1 prevents split from stripping trailing nulls
# This enables correct processing of the input "/".
#
  my @dirs = split "/", $path, -1;   

  my $i;
  # Remove any "" that are not leading.
  for ($i=0; $i<=$#dirs; ++$i) {
      if ($i == 0 or $dirs[$i] ne "") {
          push @dirs2, $dirs[$i];
      }  
  }
  @dirs = ();

  # Remove any "."
  foreach $dir (@dirs2) {
      unless ($dir eq ".") {
          push @dirs, $dir;
      }  
  }
  @dirs2 = ();

  # Remove the "subdir/.." parts.
  foreach $dir (@dirs) {
    if ( $dir !~ /^\.\.$/ ) {
        push @dirs2, $dir;
    } else {
        pop @dirs2;   # remove previous dir when current dir is ..
    }
  }  
  if ($#dirs2 == 0 and $dirs2[0] eq "") { return "/"; }
  $abspath = join '/', @dirs2;
  return( $abspath );
}
#-----------------------------------------------------------------------
sub fullpath {
#
# Get full path to relative $path by cd'ing to $path and doing a pwd.
# (this will fail if $path does not exist)
#
  my ($path) = @_;
  my $mycwd = cwd();
  my ($basename, $dirname, $suffix) = fileparse($path);
  if (! -d $dirname) { die "\n>>> fullpath: Directory $dirname does not exist\n"; }
  chdir($dirname) || die "\n>>> fullpath: Cannot cd to $dirname\n";
  $fulldir = cwd(); 
  chdir($mycwd);
  $fullpath = $fulldir . '/' . $basename;
  $fullpath =~ s/\.$//;     # remove trailing "."
  $fullpath =~ s/\/$//;     # remove trailing "/"
  $fullpath =~ s/^\/\//\//; # replace two leading slashes with one
  return $fullpath;
}
#-----------------------------------------------------------------------
sub copy_model_src {
#
# Copy source code to build directory:
#
  my (@dirlist) = @_;
  my $blddir = pop(@dirlist);
#
# Note source is copied from reversed dirlist. This is so model code
# is copied first, and is then overwritten with any user code.
#
  foreach $dir (reverse @dirlist) {
    my @files = (glob("$dir/*.[Fc]"), glob("$dir/*.F90"));
    if (($nfiles = $#files) >= 0) { 
      $nfiles = $nfiles + 1;
      foreach $file (@files) {
        my $stat = copy($file,$blddir);
        if ($stat != 1) { 
          print ">>> WARNING: Error copying source file $file to $dir\n"; }
      }
      print "Copied $nfiles source files from $dir\n";
    } else {
      print ">>> WARNING: No source files found in directory $dir\n";
    }
  }
}
#-------------------------------------------------------------------------
sub write_defs_h {
#
# Write new $file (defs.h) for given model and resolution:
#
  my ($file, $hres, $vres, $model) = @_;
#
# --------------------------- Grids for timegcm ---------------------
#
if ($model =~ /^timegcm/) {
#
# Standard resolution for timegcm:
  $nlat=36; $glat1="-87.5" ; $dlat="5.0";
  $nlon=72; $glon1="-180.0"; $dlon="5.0"; 
#
# Double horizontal res for timegcm:
  if ($hres == 2.5) {
    $nlat=72 ; $glat1="-88.75"; $dlat="2.5";
    $nlon=144; $glon1="-180.0"; $dlon="2.5"; 
  }
#
# Top interface boundary is zp +7.0 for timegcm:
  $zitop="7.0";
  $zibot="-17.0";
#
# Number of levels
  $nlev = ($zitop - $zibot) / $vres;
#
# Midpoints are 0.5*dz above interfaces:
  $zmbot = $zibot + (0.5 * $vres);
  $zmtop = $zitop + (0.5 * $vres);
#
# --------------------------- Grids for tiegcm ---------------------
#
} elsif ($model =~ /^tiegcm/) {
#
# Standard horizontal resolution for tiegcm:
  $nlat=36; $glat1="-87.5" ; $dlat="5.0";
  $nlon=72; $glon1="-180.0"; $dlon="5.0"; 
#
# Double horizontal res for tiegcm:
  if ($hres == 2.5) {
    $nlat=72 ; $glat1="-88.75"; $dlat="2.5";
    $nlon=144; $glon1="-180.0"; $dlon="2.5"; 
  }
#
# Top interface boundary is zp +7.0 for tiegcm:
  $zitop="7.0";
  $zibot="-7.0";
#
# Number of levels 
  $nlev = ($zitop - $zibot) / $vres;
#
# Midpoints are 0.5*dz above interfaces:
  $zmbot = $zibot + (0.5 * $vres);
  $zmtop = $zitop + (0.5 * $vres);
#
# -------------------------------------------------------------------
# 
# Global Mean model -- defs.h not needed:
} elsif ($model =~ /^glbmean/) {
  print "Header file $file is not needed for model $model.\n";
  return;
#
# Unrecognized model:
} else {
  print ">>> Model name $model not recognized -- NOT making header file $file\n";
  return;
}
#
# If file exists, check to see if it is already set for the desired resolution:
#
  if (-e $file) {
    my $fh = new IO::File;
    $fh->open("<$file") || die ">>> can't open header file: $file\n";
    while (<$fh>) { 
      if (/NLAT\s+\((\S+)\)/) { $nlat_rd = $1 };
      if (/NLON\s+\((\S+)\)/) { $nlon_rd = $1 };
      if (/NLEV\s+\((\S+)\)/) { $nlev_rd = $1 };
      if (/ZIBOT\s+\((\S+)\)/) { $zibot_rd = $1 };
    }
    $fh->close;
    if ($nlat_rd == $nlat &&
        $nlon_rd == $nlon &&
        $nlev_rd == $nlev &&
        $zibot_rd == $zibot) {
      print "NOT writing new defs.h for $model because it is already set for\n";
      print "  the desired resolution of hres=$hres  vres=$vres (nlat=$nlat nlon=$nlon nlev=$nlev)\n";
      print "  and zibot = $zibot\n";
      return;
    }
  }
#
# Write new file:
#
  print "Making header file $file for model $model at hres=$hres vres=$vres\n";
  print "  nlat=$nlat  nlon=$nlon  nlev=$nlev\n";
  print "  zibot=$zibot  zitop=$zitop  zmbot=$zmbot  zmtop=$zmtop\n";
  my $fh = new IO::File;
  $fh->open(">$file") || die ">>> can't open header file: $file\n";
  $date = `date`; chop($date);
  print $fh <<"EOF";
!
! Grid parameter definitions for $model (see params.F).
! Horizontal resolution = $hres  Vertical resolution = $vres
!
! hres = $hres
#define NLAT  ($nlat)
#define GLAT1 ($glat1)
#define DLAT  ($dlat)
!
! hres = $hres
#define NLON  ($nlon)
#define GLON1 ($glon1)
#define DLON  ($dlon)
!
! vres = $vres
! Define interface and midpoint levels
#define ZIBOT ($zibot)
#define ZITOP ($zitop)
#define ZMBOT ($zmbot)
#define ZMTOP ($zmtop)
#define NLEV ($nlev)
EOF
  $fh->close;
}  # end sub write_defs_h
#-----------------------------------------------------------------------
sub write_filepath {
  my ($usr_srcdirs, $model_srcdir, $fileout) = @_;
  my $fh = new IO::File;
  $fh->open(">$fileout") or die "$progname: Can't open filepath file: $fileout\n";
  print "Writing source directory list to file $fileout.\n";
#
# User source directories (they are currently a comma-separated list
# without white space):
#
  @dirs = ();
  if ($usr_srcdirs =~ /\S+/) {
    @dirs = split(',',$usr_srcdirs);
    foreach $dir (@dirs) {
      print $fh "$dir\n";
      print "  User source directory: $dir\n";
    }
  }
#
# Add model directory:
#
  print $fh "$model_srcdir\n";
  print "  Model source directory: $model_srcdir\n";
  push(@dirs,$model_srcdir);
#
  $fh->close;
  return @dirs;
}
#-----------------------------------------------------------------------
sub write_makefile {
#
# Write macros to Makefile:
#
  $OS = `uname -s`; chop $OS; ($os = $OS) =~ tr/A-Z/a-z/;
  $nodename = `uname -n`; chop $nodename;
  if ($nodename =~ /^ln/) { $nodename = 'lightning' }
  $date = `date`; chop($date);
#
  my ($file_in, $file_out, $debugarg) = @_;
  my $fh_in = new IO::File;
  my $fh_out = new IO::File;
  $fh_out->open(">$file_out") or die ">>> Can't open file: $file_out\n";
#
# Default MPI is true. MPI is set false below if serial linux is 
# suspected, or the model is glbmean. User can override by setting
# mpi option either T or F.
#
  if ($mpi eq "DEFAULT") { $mpiflag = "TRUE"; }
  if ($os eq "linux") { 
    if ($nodename ne "lightning") {
      if ($mpi eq "DEFAULT") { $mpiflag = "FALSE"; }
    }
  }
  if ($model =~ /^glbmean/) {
    if ($mpi eq "DEFAULT") { 
      $mpiflag = "FALSE"; 
      print "Note tgcm_config: model $model is serial -- setting mpi FALSE.\n";
    }
  }
  print "write_makefile: os=$os mpi=$mpi mpiflag=$mpiflag\n";
#
# Location of netcdf lib:
#
  if ($lib_netcdf ne '') {
    if (! -d $lib_netcdf) { 
      print "\n>>> WARNING: Could not find lib_netcdf $lib_netcdf\n"; }
  }
  if ($lib_netcdf eq '') {
    SWITCH: {
      if ($os eq "aix") { 
        $lib_netcdf = "/usr/local/lib";
        last SWITCH;
      }
      if ($os eq "irix64") { 
        $lib_netcdf = "/usr/local/lib32/r4i4";
        last SWITCH;
      }
      if ($os eq "linux") { 
        if ($nodename eq "lightning") {         # SCD linux cluster "lightning"
          $lib_netcdf = "/usr/local/lib";
        } elsif ($nodename eq 'gale') {         # CISL Linux machine "gale"
          $lib_netcdf = "/fs/local/lib";     
        } else {                               # Generic linux (probably HAO)
          $lib_netcdf = "/opt/local/lib";
          if ($nbit eq 64) { $lib_netcdf = "/opt/local/netcdf/linux86-64/lib"; }
        }
        last SWITCH;
      }
    $nothing = 1;
    } # end switch
  } # end lib_netcdf == ''
#
# Location of netcdf include file:
#
  if ($inc_netcdf ne '') {
    if (! -d $inc_netcdf) { 
      print "\n>>> WARNING: Could not find inc_netcdf $inc_netcdf\n"; }
  }
  if ($inc_netcdf eq '') {
    SWITCH: {
      if ($os eq "aix") { 
        $inc_netcdf = "/usr/local/include";
        last SWITCH;
      }
      if ($os eq "irix64") { 
        $inc_netcdf = "/usr/local/include";
        last SWITCH;
      }
      if ($os eq "linux") { 
        if ($nodename eq "lightning") {         # SCD linux cluster "lightning"
          $inc_netcdf = "/usr/local/include";
        } elsif ($nodename eq 'gale') {         # CISL Linux machine "gale"
          $inc_netcdf = "/fs/local/include";
        } else {                               # Generic linux (probably HAO)
          $inc_netcdf = "/opt/local/include";
          if ($nbit eq 64) { $inc_netcdf = "/opt/local/netcdf/linux86-64/include"; }
        }
        last SWITCH;
      }
    $nothing = 1;
    } # end switch
  } # end inc_netcdf == ''
#
# print "write_makefile: OS=$OS lib_netcdf=$lib_netcdf inc_netcdf=$inc_netcdf\n";
#
  $mkdebug = "FALSE";
  if ($debugarg) {
    $mkdebug = "TRUE";
#   print "Writing Makefile for debug run..\n";
  }
#
# Write macros to top of output Makefile:
#
  print $fh_out <<"EOF";
#
# Macros for model $model, written by $progname at $date
#
UNAMES     := $OS
UNAMEN     := $nodename
EXECNAME   := $model
MODEL_CLASS:= $model_class
EXECDIR    := $execdir
UTILDIR    := $utildir
LIB_NETCDF := $lib_netcdf
INC_NETCDF := $inc_netcdf
DEBUG      := $mkdebug
MPI        := $mpiflag
MSS        := $mssflag
NBIT       := $nbit
EOF
#
# Copy template and close files:
#
  $fh_in->open("<$file_in") or die "Can't open file: $file_in\n";
  while (<$fh_in>) { print $fh_out $_; }
  $fh_out->close;
  $fh_in->close;
  print "\nWrote Makefile $file_out:\n";
  print << "EOF";
    UNAMES     := $OS
    UNAMEN     := $nodename
    EXECNAME   := $model
    MODEL_CLASS:= $model_class
    EXECDIR    := $execdir
    LIB_NETCDF := $lib_netcdf
    INC_NETCDF := $inc_netcdf
    DEBUG      := $mkdebug
    MPI        := $mpiflag
    MSS        := $mssflag
    NBIT       := $nbit
EOF
}
