#!/usr/bin/perl
#
# webdata.cgi for outputting O3 graphs of CMDL's Dobson data
#
# this file lives at /cmdl/www/ozwv/cgi-bin on vortex.cmdl.noaa.gov
#
# by:  Mark Clark, January - May 2001
#      June 2001 - added graph-only output
#      July 2001 - switched layout to new web format - EJH
#      November 2001 - added Marcapomacocha and adapted program to partial year data
#      Dec 10, 2001 - changed stations to a 2-column format
#      Dec 11, 2001 - got ready for the new year (in perpetuity(?))
#   -> Jan 03, 2002 - check!
#      Jan 22, 2002 - added dobson_o3_plasmagraph.gif for Hack's plasma page
#      Feb  1, 2002 - defined default color for single-station graphs to 1 (black)
#      Oct 24, 2002 - added links to the stations
#      Mar 14, 2003 - allowed all stations to be on webdata.cgi page

use CGI::Pretty qw( :all );
use CGI::Carp qw( fatalsToBrowser );

use PGPLOT;
$ENV{PGPLOT_FONT} = '/usr/lib/pgplot/grfont.dat';
$ENV{PGPLOT_BACKGROUND} = 'white';
$ENV{PGPLOT_FOREGROUND} = 'black';

$title = 'Near Real-Time Total Ozone Data Graphing';

# get time of the starting of the page
$now  = localtime;
@time = localtime(time);
$now_year = $time[5] + 1900;

# start html;
print header;  

if (param) {   # check incoming parameters
  # the one parameter/no value case
  if (param('keywords')) { 
    ${param('keywords')} = 1 ; 
    #print param('keywords'), " => ", ${param('keywords')}, '<br>';
  }
  else {
    foreach $name (param) { 
      if    (param($name) eq '')  { 
        $$name = 1 ;  #print '1 ';
      }
      else { 
        $$name = param($name) ;  #print 'non-null';
      }      
      #print "param $name ", param($name), " => $$name<br>";
    }
  }
  
  if (defined $connect) { 
    if ($connect) { $disconnect = 0 } 
    else          { $disconnect = 1 } 
  }
  
  if (defined $pic) {
    unless ($type)       { $type       = 'current' }
    unless (defined $disconnect) { $disconnect = 0 }
    unless ($average)    { $average    = 1 }
    unless ($envelope)   { $envelope   = 1 }
  }

  if (defined $plasma) {
    $type       = 'last';
    $disconnect = 0;
    $average    = 1;
    $envelope   = 1;
  }
  
  unless ($type)               { $type       = 'current' }
  #unless (defined $average)    { $average    = 1 }
  #unless (defined $envelope)   { $envelope   = 1 }
  unless (defined $disconnect) { $disconnect = 0 }
}
else { # no parameters 
  #set default values for parameters
  $type       = 'current';
  $average    = 1;
  $envelope   = 1;
  $disconnect = 0;
}

@stats = qw/ams bdr bis bna brw car fbk hnx ldr mlo mpo ohp pth smo tal wai/;

# check program name to see if we should run in test mode.  :^)
if ( $0 =~ /webdata/ ) { $web  = 1 }
else                   { $test = 1 }

# check IP of caller and deal with it...
$rem = remote_addr;
if ($rem =~ /^137\.229\./) { $fbk = 1 }

# generate a list of stations from the CGI parameters
$default_stat = 1;
foreach $stat (@stats) {
  if (param($stat) && defined $stat) { $$stat = 1 }
  if ($$stat) {
    push @stations, $stat;
    $default_stat = 0;
  }
}
if ($default_stat) { $bdr = 1 }

unless (@stations) { # set parameters for graphs
  if ($fbk) { @stations = qw(fbk) }
  else      { @stations = qw(bdr) }
}

if ((!$pic && !$plasma) && ($test || $web || $fbk)) { # normal start
#  print start_html(-title=> $title,
#                   -author=>'Mark Clark',
#                   -base=>'true',
#                   -bgcolor=>'#FFFFFF', 
#                   -meta=>{'keywords'=>'ozone Dobson Spectrophotometer graphing data near real-time
#                                        Amundsen-Scott South Pole Station
#                                        Boulder Colorado
#                                        Barrow Poker Flats Fairbanks University Alaska
#                                        Marcapomacocha Huancayo PERU
#                                        NIWA Lauder NEW ZEALAND
 #                                       Mauna Loa Observatory Hawaii
 #                                       Observatoire Haute Provence FRANCE
#                                        Perth Western AUSTRALIA
#                                        Pago Pago American Samoa
#                                        Tallahassee Florida
#                                        NASA Wallops Island Flight Facility 
#                                        National Weather Service
#                                        Bismarck North Dakota
#                                        Caribou Maine
#                                        Hanford Fresno California
#                                        Nashville Tennessee',
#                          'description'=>'The NOAA/CMDL/OZWV - near Real-Time Total Ozone Graphing page.'},
#                   -head=>[ Link({-rel=>'shortcut icon', -href=>'../dobson/gifs/o3_icon.ico'}),
#			                Link({-rel=>'icon', -href=>'../dobson/gifs/o3_icon.png', -type=>'image/png'})
#			              ]);

open (FILE, "header.html");
@header = (<FILE>);
close (FILE);
print @header;
} 

@mon = qw(- Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);

# high and low values for graphing - subject to change later
$high = 500.;
$low  = 100.;

# number of days per normal month
$nd[1]=$nd[3]=$nd[5]=$nd[7]=$nd[8]=$nd[10]=$nd[12]=31;
$nd[4]=$nd[6]=$nd[9]=$nd[11]=30;
# $nd[2] is determined elsewhere - deals with the Leap averageaverage problem.

# months in the year
@mos = qw(- January February March April May June July August September
            October November December);

# number of cumulative days per month in a normal year
$td[1] =  31; $td[2]  =  59; $td[3]  =  90; $td[4]  = 120;
$td[5] = 151; $td[6]  = 181; $td[7]  = 212; $td[8]  = 243;
$td[9] = 273; $td[10] = 304; $td[11] = 334; $td[12] = 365;

%yrs = ( ams => [1963, $now_year], bdr => [1966, $now_year], bis => [1962, $now_year],
         bna => [1962, $now_year], brw => [1973, $now_year], car => [1962, $now_year],
         fbk => [1984, $now_year], hnx => [1983, $now_year], mpo => [1964, $now_year],
         ldr => [1987, $now_year], mlo => [1963, $now_year], ohp => [1983, $now_year],
         pth => [1984, $now_year], smo => [1975, $now_year], tal => [1964, $now_year], 
         wai => [1967, $now_year],                      );

# setup the list of names available from the web
#if ($test) { # for 'testdata.cgi' access
  %names = ( ams => 'South Pole Station, ANTARCTICA', 
             bdr => 'Boulder, Colorado',              
             bis => 'Bismarck, North Dakota',
             bna => 'Nashville, Tennessee',           
             brw => 'Barrow, Alaska',
             car => 'Caribou, Maine',                 
             fbk => 'Fairbanks, Alaska',
             hnx => 'Hanford, California',            
             ldr => 'Lauder, NEW ZEALAND',            
             mlo => 'Mauna Loa Observatory, Hawaii',
             mpo => 'Marcapomacocha, PERU',
             ohp => 'Observatoire de Haute Provence, FRANCE', 
             pth => 'Perth, Western Australia, AUSTRALIA',
             smo => 'Cape Matatula, American Samoa',      
             tal => 'Tallahassee, Florida',
             wai => 'Wallops Island, Virginia', );
#}
#else { # for 'webdata.cgi' access
#  %names = ( bdr => 'Boulder, Colorado', ); 
#}

# determine the earliest and latest dates available  
foreach $k (keys %names) {
  # determine most recent data year
  if ($yrs{$k}[1] >= $rec_year) {
    $rec_year = $yrs{$k}[1];
  }
  # determine earliest data year
  if ($early_year) {
    if ($yrs{$k}[0] <= $early_year) {
      $early_year = $yrs{$k}[0]
    }
  } else {
    $early_year = $yrs{$k}[0]
  }
}

# build the rows of data for each station
#if ($test) { # testdata.cgi
  $Th = "th(' &nbsp; '), th('Station'), th('Earliest Data'), 
         th(' &nbsp; '), 
         th(' &nbsp; '), th('Station'), th('Earliest Data')",
#} 
#else {       # webdata.cgi
#  $Th = "th('Station'), th('Start Year'), th('End Year'),"
#}

$http = 'http://thunder.cmdl.noaa.gov/gmd/ozwv/dobson/'; # prefix for URLs
@snames = sort keys %names;
$l = @snames;  # get a count of the names in %names
$mid = int $l/2;
for $i (0 .. $mid-1) {
  $a = $snames[$i];
  $b = $snames[$i+$mid];
  if ($$a) { $on  = 1 } else { $on  = 0 }
  if ($$b) { $son = 1 } else { $son = 0 }

  # links to station pages
  ($h1, $h2) = split ',', $names{$snames[$i]};
  $ha = a({-href=>"$http$a.html"}, $h1) . ", $h2";
  ($h3, $h4) = split ',', $names{$snames[$i+$mid]};
  $hb = a({-href=>"$http$b.html"}, $h3) . ", $h4";
 
  # the excessive use of quote here allows me to add and comment out lines for testing 
  $Tr .= " Tr ( {-valign=>TOP}, " .
              " td ( checkbox( -name  => '$snames[$i]', 
                              -on    => '$on', 
                              -value => 1, 
                              -label => '')), " .
              " td ( {-align=>LEFT},'$ha'), " .
              " td ( {-align=>CENTER}, $yrs{$snames[$i]}[0] ), " .
              " td (' &nbsp; '), " .
              " td ( checkbox( -name  => '$snames[$i+$mid]', 
                              -on    => '$son', 
                              -value => 1, 
                              -label => '')), " .
              " td ( {-align=>LEFT}, '$hb'), " .
              " td ( {-align=>CENTER}, $yrs{$snames[$i+$mid]}[0] ), " .
             " ),";
}
unless ($l%2 == 0) {
  $a = $snames[$l-1];
  if ($$a) { $on  = 1 } else { $on  = 0 }
  $Tr .= " Tr ( {-valign=>TOP},
               td ( checkbox( -name  => '$snames[$l-1]', 
                              -on    => '$on', 
                              -value => 1, 
                              -label => '$names{$snames[$l-1]}')),
               td ( {-align=>CENTER}, $yrs{$snames[$l-1]}[0] ),
               td ( {-align=>CENTER}, $yrs{$snames[$l-1]}[1] ),
             )";
}

# build the columns for the 'type' table
%radio_label = ('all'     => 'All - a graph of all available data',
                'current' => 'Current - this year\'s data',
                'some'    => 'Some - a subset of the available data',
                'last'    => 'Last year - previous full year of data',
                );
@radio = radio_group(-name=>'type',
                     -values=>['current', 'last', 'all', 'some',],
                     -default=>'current',
                     -labels=>\%radio_label,
                     -linebreak=>1,
                     );

# generate the graphs
%colors = ( ams => 1, # black
            bdr => 2, # red
            smo => 3, # green
            bis => 4, # blue
            bna => 5, # light blue-green
            brw => 6, # fuscia
            car => 7, # yellow
            fbk => 8, # reddish brown
            hnx => 9, # light green
            ldr =>10, # 
            mlo =>11, # 
            mpo =>12, # 
            ohp =>13, # 
            pth =>14, # 
            tal =>15, # gray
            wai =>16  # gray
          );

# setup for graphing the average values and std devs for a single station
if (@stations == 1) {
  $ave_file = $stations[0]."dailyaverage.csv";
  if (-e "./data/$ave_file") {  # check to see if Bob has given me the .csv file...  :^)
    open IN, "./data/$ave_file" or die "couldn't open $ave_file - $! <p>\n";
    while (<IN>) {
      ($do, $oz, $dv) = split ',';
      if ($do =~ /\d/) { 
        $mid{$do} = $oz;
        $env{$do} = $dv;
      }
    }
    close IN;
  }
} 

if    ( $type eq 'all' ) {
  $all = 1;
  $start = $early_year;
  $end = $rec_year;
}
elsif ( $type eq 'current' ) {
  $current = 1;
  $start = 1900 + (localtime)[5];
  $end = $start + 1;
}
elsif ( $type eq 'last' ) {
  $last = 1;
  $start = 1900 - 1 + (localtime)[5];
  $end = $start + 1;
}
elsif ( $type eq 'some' ) {
  $some = 1;
  $start = param('start');
  $end = param('end');
  
  # fix the endpoints of the graph 
  if ( $start == $end ) {$end++}
  if ( $start > $end )  { ($start, $end) = ($end, $start) }
}

# get directory information
#$main_dir = '/ftp/dobson/';
$main_dir = '/data/webdata/ozwv/dobson/ozone/';
$data_dir = '/data/webdata/ozwv/cgi-bin/data/';
foreach $stat (@stations) {
  # initialize the data arrays
  @ozone = ();  
  $statdate = $stat.'date';
  $last_yr = $last_doy = 0;

  # get data from the SELECT files
  # main station data file
  @dfile = $main_dir.$stat.'/'.$stat.'_sel.txt';
print "$dfile[0]<br>";
  
  # set up for stations that have split data
  if ($stat eq 'fbk') { unshift @dfile, $main_dir.$stat.'/pok_sel.txt' }
  if ($stat eq 'hnx') { unshift @dfile, $main_dir.$stat.'/fat_sel.txt' }
  if ($stat eq 'mpo') { unshift @dfile, $main_dir.$stat.'/hua_sel.txt' }
  
  foreach $dfile (@dfile) { # usually only one file - exceptions: fbk, hnx, mpo (above)
    open IN, $dfile or die "couldn't open $dfile - $! \n";
    while (<IN>) {
      @line = split '';
#print "$_<br>";
#      $sss    = join '',  @line[ 0.. 2];  # station number
 
      $c      =           $line[ 3    ];  # line number
#print "c = $c<br>";
      
      # don't process the comment lines - You FOOL!
      if ($c == 5) { next } 

      $mm     = join '',  @line[ 4.. 5];  # month of the year
 
      $yy     = join '',  @line[ 6.. 7];  # year
#print "mm = $mm, yy = $yy<br>";
      if ($yy > 50) { $yy+= 1900 } else { $yy += 2000 }
      if ($some && ($yy < $start || $yy > $end)) { next }
      if ($current && ($yy < $rec_year)) { next }
     
      $ooo[1] = join '', @line[14..16]; # ozone in DU
      $ooo[2] = join '', @line[23..25]; $ooo[3] = join '', @line[32..34];
      $ooo[4] = join '', @line[41..43]; $ooo[5] = join '', @line[50..52];
      $ooo[6] = join '', @line[59..61]; $ooo[7] = join '', @line[68..70];
      $ooo[8] = join '', @line[77..79];
#      @hh[1]  = join '', @line[ 8.. 9]; # nothing or a '*' for questionable data
#      @hh[2]  = join '', @line[17..18]; @hh[3]  = join '', @line[26..27];  
#      @hh[4]  = join '', @line[35..36]; @hh[5]  = join '', @line[44..45];  
#      @hh[6]  = join '', @line[53..54]; @hh[7]  = join '', @line[62..63];  
#      @hh[8]  = join '', @line[71..72];  
#      @gg[1]  = join '', @line[10..11]; # nearest GMT hour
#      @gg[2]  = join '', @line[19..20]; @gg[3]  = join '', @line[28..29];  
#      @gg[4]  = join '', @line[37..38]; @gg[5]  = join '', @line[46..47];  
#      @gg[6]  = join '', @line[55..56]; @gg[7]  = join '', @line[64..65];  
#      @gg[8]  = join '', @line[73..74];  
#      @l[1]   =          @line[12    ]; # wavelengths used
#      @l[2]   =          @line[21    ]; @l[3]   =          @line[30    ];  
#      @l[4]   =          @line[39    ]; @l[5]   =          @line[48    ];  
#      @l[6]   =          @line[57    ]; @l[7]   =          @line[66    ];  
#      @l[8]   =          @line[75    ];  
#      @s[1]   =          @line[13    ]; # kind of observation
#      @s[2]   =          @line[22    ]; @s[3]   =          @line[31    ];  
#      @s[4]   =          @line[40    ]; @s[5]   =          @line[49    ];  
#      @s[6]   =          @line[58    ]; @s[7]   =          @line[67    ];  
#      @s[8]   =          @line[76    ];  

      if ( !($yy%400) )  { $nd[2] = 28; $ly = 0; $days = 365 }   # this block addresses the
      elsif ( !($yy%4) ) { $nd[2] = 29; $ly = 1; $days = 366 }   # Leap Year problem
      else               { $nd[2] = 28; $ly = 0; $days = 365 }      
    
      for $ct (1..8) {
        $dom = ($c-1)*8 + $ct;                  # day of month
#print "dom = $dom ";
        unless ($dom > 31) {
          $doy = $td[$mm-1] + $dom;             # day of year
          $dec_yr = $yy + $doy/$days;
          $o3 = $ooo[$ct];
#print "o3 = $o3 ";
        
          if ($o3 > 0) {
            # autoranging of graph Y-values
            if ($o3 > $high) { 
              until ($high > $o3) { $high += 20 }
            } 
            elsif ($o3 < $low) {
              until ($low < $o3)  { $low -= 20 } 
            }
             
            # generate the arrays to be graphed
            push @$stat, $o3;
            push @$statdate, $dec_yr;
          
            # set the most recent information...
            if ($mr{$stat} < $dec_yr) {
              $o_mr{$stat} = $o3;    #  last data point - to be circled
              $mrdate = "$mos[$mm] $dom, $yy";  # most recent date
              $mr{$stat} = $dec_yr;             # most recent date (decimal)
              $mro = $o3;                       # most recent ozone value
            } 
          }
          # set account for partial years overlapping preliminary data in .obs files
          $last_yr = $yy;
          $last_doy = $doy;
        }
      }
    }
    close IN;
  }
  

  # read in the recent data from .obs file(s)
  $file = "$data_dir$stat\.obs"; 
  open IN, $file or die "can't open $file - $!\n";
  while (<IN>) {
    unless (/^\W*$/) { # ignore blank lines!
      ($date, $doy, $obtype, $o3) = split;
      
      # autoranging of graph Y-values
      if ($o3 > $high) { 
        until ($high > $o3) { $high += 20 }
      } 
      elsif ($o3 < $low) {
        until ($low < $o3)  { $low -= 20 } 
      }
      
      if ($date =~ /-/) { ($mo, $day, $yy) = split '-', $date }
      else { ($mo, $day, $yy) = split '/', $date } 
     
      if ( !($yy%400) )  { $days = 365 }   # this block addresses the
      elsif ( !($yy%4) ) { $days = 366 }   # Leap Year problem
      else               { $days = 365 }   #  
 
      $tdoy = $yy + $doy/$days;

      # check for existing data from the SELECT files before adding .obs data
      if ($yy > $last_yr || ($yy == $last_yr && $doy > $last_doy) ) {
        push @$stat, $o3;
        push @$statdate, $tdoy;
        $disclaim = 1;
        
        # set up the most recent information...
        if ($mr{$stat} < $tdoy) {
          $mrdate = "$mos[$mo] $day, $yy";
          $mr{$stat} = $tdoy;  
          $o_mr{$stat} = $o3;
          $mro = $o3;
        } 
      }
     
      $prelim = $yy;
    }
  }
  close IN;
}    

# housekeeping - remove old plots
$wd = qx/pwd/;
$dir = '.';
$gifdir = '/data/webdata/ozwv/dobson/gifs';
chdir $gifdir or die "couldn't chdir $gifdir- $!<p>\n";
opendir DIR, $dir or die "couldn't opendir $dir - $!<p>\n";
foreach (readdir DIR) {
  $div = 0.05;    
  # $time = int (3600 * $div);     # 3600 * 0.05 = 3 hours
  if (/plot/ && -M $_ > $div) {  # should remove both .gif and .ps files  :^)
    qx/rm $_/;
  }
}

# get a 'unique' name for the file 
chdir '../../cgi-bin' or die "couldn't chdir $wd - $! <p>\n";
$file = '';
until ($file) {
  $file = "/data/webdata/ozwv/dobson/gifs/plot".(int rand 99999);
  if (-e $file) # check for existence of the file already
  { 
    $file = ''  # reset filename if it already exists
  } 
}

# Start PGPLOT
$outgif = $file.'.gif/GIF';
$outps  = $file.'.ps/CPS';

foreach $out ($outgif, $outps) {
  if ($plasma && ($out eq $outps)) { next } # don't generate PS for 'plasma' option
   if ( pgbeg(0, $out, 1, 1) == 1 ) {
#    # Generate the graph.
     pgsci(1);
     pgvstd;
     pgqch($char_ht);
     pgsch(0.75);
}
#    
#    if ($type eq 'all')     { 
#      $early_year = $rec_year - 1;
#      foreach $s (@stations) { 
#        if ($early_year > $yrs{$s}[0] ) { $early_year = $yrs{$s}[0]}
#      }
#      pgswin($early_year, $rec_year+1, $low, $high);     
#      pgbox( 'ABCNST',    # X options
#             0,           # Xtick
#             0,           # NXsub
#             'ABCNSTV',   # Yopt
#             0, 0);       # Ytick, NYsub
#      $title_type = ucfirst $type. " data for: ";
#    }
#    elsif ($type eq 'some') { 
#      $diff = $end - $start; 
#      pgswin($start, $end, $low, $high);
#      
#      # put months under the graph for a single year's worth of data 
#      if ($diff == 1) {
#        $xtick = 1; 
#        $nxsub = 12;
#        $mon = 0;
#        foreach (@mon) {
#          if ($mon) {
#            pgptxt($start+(($mon-0.5)/12), # X
#                     $low - 25,  # Y
#                     0,          # Angle
#                     0.5,        # Fjust
#                     $_);        # Text 
#          }
#          $mon++;
#        }
#      }
#      elsif ($diff < 10) { $xtick = 1; $nxsub = 4 }
#      elsif ($diff < 20) { $xtick = 2; $nxsub = 2 } 
#      else               { $xtick = 4; $nxsub = 4 }
#      pgbox( 'ABCNST',    # X options
#             $xtick,           # Xtick
#             $nxsub,      # NXsub
#             'ABCNSTV',   # Yopt
#             0, 0);       # Ytick, NYsub
#      $title_type = "Data from $start to $end for: ";
#    }
#    elsif ($type eq 'last') { 
#      pgswin($start, $start+1, $low, $high);     
#      pgbox( 'ABCNST',    # X options
#             1,           # Xtick
#             12,          # NXsub
#             'ABCNSTV',   # Yopt
#             0.0, 0.0);   # Ytick, NYsub
#      $mon = 0;
#      foreach (@mon) {
#        if ($mon) {
#          pgptxt($start+(($mon-0.5)/12), # X
#                 $low - 25,                 # Y
#                 0,                         # Angle
#                 0.5,                       # Fjust
#                 $_);                       # Text 
#        }
#        $mon++;
#      }
#      $title_type = "$start data for: ";
#    }
#    else {  # 'Current'
#      pgswin($rec_year, $rec_year+1, $low, $high);     
#      pgbox( 'ABCNST',    # X options
#             1,           # Xtick
#             12,          # NXsub
#             'ABCNSTV',   # Yopt
#             0.0, 0.0);   # Ytick, NYsub
#      $mon = 0;
#      foreach (@mon) {
#        if ($mon) {
#          pgptxt($rec_year+(($mon-0.5)/12), # X
#                 $low - 25,                 # Y
#                 0,                         # Angle
#                 0.5,                       # Fjust
#                 $_);                       # Text 
#        }
#        $mon++;
#      }
#      $title_type = "$rec_year data for: ";
#      $start = $rec_year;
#    }
#    
#    # Label the graph
#    pgsch($char_ht);  # set character height
#    pgmtxt('T',   # Top
#           2.2,   # Displacement from top of viewport 
#           # 0.0,  # Start at lefthand side of edge
#           0.5,   # Start at 1/2 way along edge
#           # 1.0,  # Start at righthand side of edge
#           0.5,   # Center from middle
#           $title_type);
#    pgmtxt('L',  # Left side
#           2.5,  # Displacement from top of viewport 
#           0.5,  # Start at 1/2 way along edge
#           0.5,  # Center from middle
#           'Ozone (DU)');
#           
#    pgsch($char_ht);
#  
#    # set up labels for station names
#    if (@stations == 1) { # single stations get long names
#      pgmtxt('T', 
#             0.8, 
#             0.5, 
#             0.5, 
#             $names{$stations[0]});
#    }
#    else {                # multiple stations get abbreviated and concatenated        
#      $commas = $len = 0;             
#      foreach (@stations) {
#        pgsci($colors{$_});
#        $b = uc $_;
#        $coord = 0.5 - (0.5 * ( ($#stations)/18));
#        pgmtxt('T', 0.8, $coord, 0.5, (' ' x $len) . $b);         
#        $len += (length $b) + 1;
#        if ($_ eq 'bdr') { $len++ }
#        unless ($commas == $#stations) {
#          $commas++;
#          pgsci(1);
#          pgmtxt('T', 0.8, $coord, 0.5, (' ' x $len) . ',');         
#          $len += 5;
#        }  
#      }
#    }    
#
#    # generate the envelope for Bob
#    if ( $#stations == 0 ) { # for single stations only
#      if ( $average || $envelope ) {
#        @ozone = @date = @top = @bot = @dev_date = ();
#        foreach $y ($start..$end) {
#          $days = 365; 
#          if ( !($y%400) )  { $days = 365 }   # this block addresses the
#          elsif ( !($y%4) ) { $days = 366 }   # Leap Year problem
#          
#          pgsci(15);
#          foreach $d (sort {$a <=> $b} keys %env) {
#            $ozone = $mid{$d};
#           
#            $dec_day = $y + $d/$days;
#            unless ($dec_day > ($y + 1)) {
#              if ($ozone > 0 && $days > 0) { 
#                push @ozone, $ozone;
#                push @date, $dec_day; 
#              }
#              elsif ($average) { 
#                pgline ($#ozone+1, \@date, \@ozone); 
#                @ozone = @date = ();
#              }
#                
#              $dev = $env{$d};
#              $top = $ozone + $dev;
#              $bot = $ozone - $dev;
#              if ($dev > 0  && $days > 0) { 
#                push @top, $top; 
#                push @bot, $bot;
#                push @dev_date, $dec_day; 
#              }
#              elsif ($envelope) {
#                pgline ($#top+1, \@dev_date, \@top);
#                pgline ($#bot+1, \@dev_date, \@bot);
#                @top = @bot = @dev_date = ();
#              }
#            }
#          }
#          if ($envelope) {   
#            pgline ($#top+1, \@dev_date, \@top);
#            pgline ($#bot+1, \@dev_date, \@bot);
#          }
#          if ($average) {
#            pgline ($#ozone+1, \@date, \@ozone); 
#          }
#        }
#      }
#    }
#    
#    # Output the date/ozone pairs
#    foreach $stat (@stations) {
#      $statdate = $stat."date";
#      
#      if (@stations > 1) { # use multiple colors for multiple stations
#        if ($colors{$stat}) { $color = $colors{$stat} }
#        else { $color++ }
#      }
#      else { $color = 1 }  # else use BLACK
#      pgsci($color);
#      
#      pgpt($#$stat+1, \@$statdate, \@$stat, 20);
#      
#      unless ($disconnect) {
#        pgline($#$stat+1, \@$statdate, \@$stat)
#      }
#
#      # output a larger circle for the last datum
#      @o_mr = $o_mr{$stat};
#      @mr = $mr{$stat};
#      pgsci(1);  # black circle around most recent point
#      pgpt(1, \@mr, \@o_mr, 23);
#    }
#
#    pgsch(0.5);
#    pgsci(1);
#    
#    # put in disclaimer as appropriate (when preliminary data is used)
#    if ($current || $all || $end > $prelim) {
#      pgsfs(2);         # 2 => outline style rectangle
#      
#      if ($all)     {  # horizontal fudge factor
#        $fuj1 = $rec_year - $early_year + 1;
#        $left = $early_year;
#      } 
#      elsif ($some) {
#        $fuj1 = $end - $start; 
#        $left = $start;
#      }
#      else          { 
#        $fuj1 = 1;
#        $left = $start;
#      }
#      $fuj2 = ($high-$low);                    # vertical fudge factor
#
#      if ($disclaim) {
#        $x1 = $left + $fuj1*(2/3);
#        $x2 = $left + $fuj1*(5/6);
#        $y1 = $low + $fuj2 * 381/400;   # 381 = 481 minus original $low (100)
#        $y2 = $low + $fuj2 * 392/400;   # 392 = 492 minus original $low
#      
#        pgrect($x1, $x2, $y1, $y2);
#        pgmtxt('T',  # Top
#               -2.5, # Displacement from top of viewport in units of char height
#               0.75, # Start at 3/4 way along edge
#               0.5,  # Center from middle
#              "$prelim Data is Preliminary");
#      }
#
#      if ($#stations == 0 && $mro) {  # output box with most recent data
#        unless ($stations[0] eq 'ams') {  # put the data box above the ozone trace
#          $disp = -4; $mult = 1;
#          $tb = 'B';
#          $y1 = $low + $fuj2 * 10/400;   # 10 = 110 minus original $low (100)
#          $y2 = $low + $fuj2 * 50/400;   # 50 = 150 minus original $low
#        }
#        else {                            # put the data box below the ozone trace
#          $disp = -2.5; $mult = -1;
#          $tb = 'T';
#          $y1 = $high - $fuj2 * 50/400;   # 10 = 110 minus original $low (100)
#          $y2 = $high - $fuj2 * 10/400;   # 50 = 150 minus original $low
#        }
#        $x1 = $left + $fuj1 * 0.15;
#        $x2 = $left + $fuj1 * 0.35;
#        pgrect($x1, $x2, $y1, $y2);
#
#        pgsch(0.75);
#        pgmtxt($tb,       # Bottom
#               $disp,     # Displacement from top of viewport in units of char height
#               0.25,      # Start at 1/4 way along edge
#               0.5,       # Center from middle
#               'Total Ozone for');
#        pgmtxt($tb,       # Bottom
#               $disp + $mult * 1,   # Displacement from top of viewport in units of char height
#               0.25,      # Start at 1/4 way along edge
#               0.5,       # Center from middle
#               "$mrdate");
#        pgmtxt($tb,       # Bottom
#               $disp + $mult * 2,   # Displacement from top of viewport in units of char height
#               0.25,      # Start at 1/4 way along edge
#               0.5,       # Center from middle
#               "$mro DU");
#      }
#    }         
#    
#    # Put in ownership tags
#    pgsch(0.5);
#    pgmtxt('B',  # Bottom
#           7.5,  # Displacement from top of viewport in units of char height
#           0.75, # Start at 3/4 way along edge
#           0.5,  # Center from middle
#           "(Generated courtesy of NOAA/CMDL - $now)");
#
#    # Stop PGPLOT
#    pgend;
#    
#    if ($out eq $outgif) {
#      # show image
#      unless ($pic || $plasma) { print center(p) }
#
#      print center (img( {-src=>"$file.gif", 
#                          -align=>'center',
#                          -border=>'1', 
#                          -alt=>'CMDL Dobson data'} ));
#      print qx "cp $file.gif ../dobson/gifs/dobson_o3_plasmagraph.gif"; 
#    }
#    else {
#      unless ($plasma) {
#        print br, 
#              center( 
#                h3(
#                   a( {-href=>"$file.ps"}, 'Download a postscript file of this image')
#                )
#              );
#      }
#      unless ($pic || $plasma) { 
#        if (@stations == 1) { 
#          print h4( blockquote("The dots are daily total column ozone
#                    amounts.  The most recent value is circled and the numerical amount is
#                    given in the box on the left.", p, "Total column ozone, the amount of ozone
#                    from the surface to the top of the atmosphere, is reported in
#                    Dobson units (DU). This unit is used for both surface based and
#                    satellite observations.") ) 
#        }
#        else {
#          print h4( blockquote("The dots are daily total column ozone amounts.  The most
#                    recent values are circled.", p, "Total column ozone, the amount of ozone
#                    from the surface to the top of the atmosphere, is reported in
#                    Dobson units (DU). This unit is used for both surface based and
#                    satellite observations.") ) 
#        }  
#      }
#    }  
#  }
#  else {
#    print "<p>an error has occurred - unable to PGBEG!<p>\n";
#  }
}

# select stations for graphing...
unless ($pic || $plasma) {
  print center(
          blockquote(hr),
          h3('You may choose new parameters for another graph'),
          p, 
          start_form(), 
          table(
            Tr( {-align=>CENTER,-valign=>TOP},
              eval $Th),
            eval $Tr),
        ),
        # select type of graph you prefer
        blockquote(
          h3('What type of graph would you like?'),
          table (Tr ( td ($radio[0]) ),
                 Tr ( td ($radio[1]) ),
                 Tr ( td ($radio[2]) ),
                 Tr ( td ($radio[3]), 
                      td ( popup_menu ( -name=>'start', -values=>[$early_year...$rec_year]) ), 
                      td ( popup_menu ( -name=>'end',   -values=>[reverse $early_year+1..$rec_year+1]) ),
                     )
                ), 
          h3('Options:'),
          checkbox( -name  => 'disconnect', 
                    -on    => $disconnect,   # "s are very important here!
                    -value => 1, 
                    -label => 'Scatter Graph - disconnect the data points'), 
          p,
          blockquote(
            h4('Available for single station graphs:'),
            checkbox( -name  => 'average', 
                      -on    => '$average',   # "s are very important here!
                      -value => 1, 
                      -label => 'Average - Show the station\'s longterm average ozone amounts'), 
            br,
            checkbox( -name  => 'envelope', 
                      -on    => '$envelope',   # "s are very important here!
                      -value => 1, 
                      -label => 'Envelope - Show lines above and below the average that will contain most \'typical\' ozone amounts')
          ), 
        ),
        # end of form
        center(
          submit('New Graph'), 
          reset, 
          end_form, 
          blockquote(hr),
          'Data for particular stations are available by clicking on the station name/link in the table above.', 
          p, 
          'If you have questions or comments about this page, please contact:  ',
          a({-href => 'mailto:Gloria.Carbaugh@NOAA.gov'}, 'Gloria Carbaugh'),
          br, p
        );
}

	open (FILE, "footer.html") or print "cant open footer file";
	@header = (<FILE>);
	close (FILE);
	print @header;
# end of html
#print end_html;