#!/usr/bin/env perl
=head1 NAME

readSkewtGrid.pl - get XML IDs (gXXXXXX), coordinates, and colors for drawn Skew-T grid 

=head1 DESCRIPTION

This script takes in a bounding box for a comma-separated rectangular domain 
(all decimal degrees) string (4 numbers) and based on those coordinates, 
writes out (STDOUT) the appropriate XML IDs (gXXXXXX where X is a digit) 
and the corresponding color in the Skew-T grid. There is one gridpoint 
per line. Other information given, in addition to the Skew-T ID and color,
is the upper-left corner coordinates of the Skew-T grid point.

=head1 USAGE

Here is an example of using this script from the command line:

  $ perl readSkewtGrid.pl coordinates=-64.17,-59.61,25.56,30.42
  Content-type: text/html

  30,-64,086632,FFFFFF
  30,-63.5,086633,FFFFFF
  30,-63,086634,FFFFFF
  30,-62.5,086635,FFFFFF
  30,-62,086636,FFFFFF
  30,-61.5,086637,FFFFFF
  ...

  As you can see, information for each gridpoint, within the
  bounds of the rectangular domain (passed-in at command-line),
  are written out to text/html. This script would usually 
  be called from client-side Javascript with an AJAX call, 
  and would return text output.

=head1 DEPENDENCIES

  Input: coordinates=LonMin,LonMax,LatMin,LatMax
  
  Static files config.properties and soundings.list; their paths are defined in
  SkewTable.pm.

=head1 AUTHOR

  Gerasimos Michalitsianos, 7 November 2019
  Reston Consulting Group (RCG, Inc.)
  gerasimos.michalitsianos@noaa.gov

=head1 HISTORY

  Oleg Roytburd (ERT, Inc.) - Made use of the soundings list file 
/data/web/mirror/www.ospo.noaa.gov/htdocs/data/soundings/nucaps/pskewt/soundings.list

  2023-05-01 Calculate ID instead of using stored latitudes and longitudes
             Read the colors from file .../skewt/snd_colors.bin

=cut

use warnings;
use strict;
use CGI;
use CGI qw(:standard);
use FindBin;
use lib "$FindBin::Bin";
use SkewtTable;

use constant DEBUG => $ENV{PERLDEBUG};

# - Executable Code ----------------------------------------------------------------
local $\ = "\n"; # Print newline by default
local $, = ',';  # The default field separator for print

my $coordinateStr = new CGI->param ("coordinates");

if (DEBUG) {
    die "Coordinate string should be comma-separated string of 4 numbers"
       unless ($coordinateStr =~
/^[-+]?([0-9]{1,3}|[0-9]{1,3}\.[0-9]*) *,[-+]?[0-9]{1,3}\.?[0-9]* *,[-+]?[0-9]{1,3}\.?[0-9]* *,[-+]?[0-9]{1,3}\.?[0-9]* *$/
       );
}
#
# Get the bounding box (input selected area)
my ($dLonMin, $dLonMax, $dLatMin, $dLatMax) = split ",", $coordinateStr;

die "Unable to read SkewT configuration file."
   unless ReadConfigFile ();

# Read the soundings list file
my $colors = ReadSoundingColors ();

# The grid steps
my $dLonStep = ($Config{lon_max} - $Config{lon_min}) / $Config{num_cols};
my $dLatStep = ($Config{lat_max} - $Config{lat_min}) / $Config{num_rows};

# Lower left corner of the bunding box (column and row)
my $nc0 = int (($dLonMin - $Config{lon_min}) / $dLonStep) + 1;
my $nr0 = int (($dLatMin - $Config{lat_min}) / $dLatStep) + 1;

print "Content-type: text/html\n"; # MIME header for the output

# Print data for soundings inside the box
my ($dLon, $dLat, $id, $i);
# Loop through the grid points in the latitude and longitude directions
for (my $nLat = $nr0; $nLat < $Config{num_rows}; $nLat++) {
   # The sounding latitude for the grid point.
   $dLat = $Config{lat_min} + $nLat * $dLatStep;
   last if ($dLat > $dLatMax);

   for (my $nLon = $nc0; $nLon < $Config{num_cols}; $nLon++) {
      # The sounding lngitude for the grid point.
      $dLon = $Config{lon_min} + $nLon * $dLonStep;
      last if ($dLon > $dLonMax);
      
      ($i, $id) = GetSoundingIdx ($nLat, $nLon);
      printf ("%.1f,%.1f,%s,%s\n", $dLat, $dLon, $id, $colors->[$i]);   

      if (DEBUG) {
         printf STDERR "lat = %.1f, lon = %.1f, nLat = %d, nLon = %d, ID = %s\n", $dLat, $dLon, $nLat, $nLon, $id
      }
   } # End for my $nLon
} # End for my $nLat

# End main::

=head2 GetSoundingIdx ($nr, $nc)

Obtain the grid index and the ID string for a sounding (image) based on its grid location

  $nr  - the row number (latitude index), zero-based

  $nc  - the column number (longitude index), zero-based
  
Note: the sounding numbering (IDs) starts from 1 in the _upper_ left corner

Returns: (zero-based grid index, sounding ID (string)).

=cut
sub GetSoundingIdx {
   my ($nr, $nc) = @_;
   my $idx = ($Config{num_rows} - 1 - $nr) * $Config{num_cols} + $nc;

   return ($idx, sprintf (IMG_ID_FMT, $idx + 1));
} # End GetSoundingIdx
