#!/usr/bin/perl -w

#------------------------------------------------------------------------------
#          Harvard University Atmospheric Chemistry Modeling Group            !
#------------------------------------------------------------------------------
#BOP
#
# !MODULE: gcUtInt
#
# !DESCRIPTION: This Perl script automatically creates code for the
#  sandbox code "ut_GEOSCHEM.F90".  Calls to MAPL_GetPointer for the 
#  Import state fields are generated for each element of the Internal state
#  in the GEOSCHEMchem_Registry.rc file.
#\\
#\\
# !USES:
#
  require 5.003;                        # Need this version of Perl or newer
  use English;                          # Use English language
  use Carp;                             # Get detailed error messages
  use strict;                           # Use "IMPLICIT NONE"-like syntax
#
# !PRIVATE MEMBER FUNCTIONS:
#  &readRcFile($)
#
# !PUBLIC MEMBER FUNCTIONS:
#  &main()
#
# !CALLING SEQUENCE:
#  gcUtInt GEOSCHEMchem_Registry.rc
#
# !REVISION HISTORY: 
#  10 Oct 2012 - R. Yantosca - Initial version, based on ncCodeWrite
#EOP
#------------------------------------------------------------------------------
#          Harvard University Atmospheric Chemistry Modeling Group            !
#------------------------------------------------------------------------------
#BOP
#
# !IROUTINE: readRcFile
#
# !DESCRIPTION: Routine readRcFile reads the resource file which describes
#  the variables, attributes, and dimensions of the netCDF file.
#\\
#\\
# !INTERFACE:
#
sub readRcFile($) {
#
# !INPUT PARAMETERS:
#
  # $fileName : Input file that describes the netCDF file
  my ( $fileName ) = @_;
#
# !CALLING SEQUENCE:
#  &readRcFile( RESOURCE-FILE-NAME );
#
# !REVISION HISTORY:
#  10 Oct 2012 - R. Yantosca - Initial version
#EOP
#------------------------------------------------------------------------------
#BOC
#
# !LOCAL VARIABLES:
#
  # Strings
  my $cmd      = "";
  my $outFile1 = "For_Fill_Import_State_1.h";
  my $outFile2 = "For_Fill_Import_State_2.h";
  my $outFile3 = "For_Fill_Import_State_3.h";

  # Loop indices
  my $i       = 0;
  my $iBeg    = 0;
  my $iEnd    = 0;

  # Arrays
  my @lines   = ();
  my @subStr  = ();

  #--------------------------------------------------------------------------
  # Read variable settings from the file
  #--------------------------------------------------------------------------
  open( I, "<$fileName" ) or die "Cannot open resource file $fileName!\n";
  chomp( @lines = <I> );
  close( I );

  # Open output files
  open( O1, ">$outFile1" ) or die "Cannot open output file $outFile1!\n";
  open( O2, ">$outFile2" ) or die "Cannot open output file $outFile2!\n";
  open( O3, ">$outFile3" ) or die "Cannot open output file $outFile3!\n";

  #--------------------------------------------------------------------------
  # Find the lines where the Internal State specifications begins and ends
  # Write Fortran commands to the output file
  #--------------------------------------------------------------------------
  for ( $i = 0; $i < scalar( @lines ); $i++ ) {
    if ( ( $lines[$i] =~ m/<ImportSpec/   ) ) { $iBeg = $i; }
    if ( ( $lines[$i] =~ m/<\/ImportSpec/ ) ) { $iEnd = $i; }
  } 
  
  #--------------------------------------------------------------------------
  # Write the calls to MAPL_GetPointer
  #--------------------------------------------------------------------------

  # Loop over all of the tracers & species in the internal state
  for ( $i = $iBeg+1; $i < $iEnd; $i++ ) {

    # Skip comment lines
    if ( !( substr( $lines[$i], 0, 1 ) eq '#' ) ) {

      # The tracer name is the first substring
      @subStr = split( ' ', $lines[$i] );

      $cmd = "    CALL MAPL_GetPointer( Import, $subStr[0], \'$subStr[0]\', __RC__ )";

      # Write line to output
      print O1 "$cmd\n";
    }
  }

  #--------------------------------------------------------------------------
  # Write the CASE statement entries
  #--------------------------------------------------------------------------

  # Loop over all of the tracers & species in the internal state
  for ( $i = $iBeg+1; $i < $iEnd; $i++ ) {

    # Skip comment lines
    if ( !( substr( $lines[$i], 0, 1 ) eq '#' ) ) {

      # The tracer name is the first substring
      @subStr = split( ' ', $lines[$i] );

      $cmd = "          CASE ( \'IMP_$subStr[0]\' )\n             READ( LUN, 10 ) IMP_$subStr[0]";
    
      # Write line to output
      print O2 "$cmd\n";
    }
  }

  #--------------------------------------------------------------------------
  # Write the assignment statements
  #--------------------------------------------------------------------------

  # Loop over all of the tracers & species in the internal state
  for ( $i = $iBeg+1; $i < $iEnd; $i++ ) {

    # Skip comment lines
    if ( !( substr( $lines[$i], 0, 1 ) eq '#' ) ) {

      # The tracer name is the first substring
      @subStr = split( ' ', $lines[$i] );

      # Check if is a 2D or 3D field
      if ( $lines[$i] =~ m/xyz/ ) {
	$cmd = "       $subStr[0](I,J,:) = IMP_$subStr[0](:)";
      } else {
        $cmd = "       $subStr[0](I,J) = IMP_$subStr[0]";
      }

      # Write line to output
      print O3 "$cmd\n";
    }
  }

  #----------------------------------------------
  # Cleanup and quit
  #----------------------------------------------

  # Close output files
  close( O1 );
  close( O2 );

  # Return
  return( 0 );
}
#EOC
#------------------------------------------------------------------------------
#          Harvard University Atmospheric Chemistry Modeling Group            !
#------------------------------------------------------------------------------
#BOP
#
# !IROUTINE: main
#
# !DESCRIPTION: Routine main is the driver routine for the ncCodeWrite script.
#\\
#\\
# !INTERFACE:
#
sub main() {
#
# !CALLING SEQUENCE:
#  &main();
#
# !REVISION HISTORY:
#  10 Oct 2012 - R. Yantosca - Initial version
#EOP
#------------------------------------------------------------------------------
#BOC

  # Error check arguments
  if ( scalar( @ARGV ) == 0 ) { 
    print "Usage: gcIncBef GEOSCHEMchem_Registry.rc\n"; 
    exit(1);
  }

  # Read the resource file and generate Fortran code
  &readRcFile( $ARGV[0] );

  # Return normally
  return( 0 );
}
#EOC

#------------------------------------------------------------------------------

# Start main program
main();

# Exit normally
exit(0);
