<?php
/* Copyright (c) 2002 Raymond van Beek <ray@devolder.nl>.
Licensed under the GPL, see the file COPYING.

Parts of this code are derived from the phpweather.inc code
by Martin Geisler <gimpster@gimpster.com>

Also see

  http://www.sourceforge.net/projects/phpweather

for updates and further instructions on how to use PHP Weather.
*/
// =======================================================================
// This section contains user configurable items: The user can configure
// the image filenames to be generated by the script.

// Specify the absolute path to the directory that contains the weather
// icon files.

$abs_image_path = 'pw_icons/';

// An array to convert the weather group codes to an index of the
// $images and $n_images array.

$phenomena_array = array (
  '#'  => 'None',
  'TS' => 'Thun',
  'RA' => 'Rain',
  'DZ' => 'Rain',
  'SN' => 'Snow',
  'SG' => 'Snow',
  'GR' => 'Hail',
  'GS' => 'Hail',
  'PE' => 'Hail',
  'IC' => 'Hail',
  'BR' => 'Fog',
  'FG' => 'Fog'
);

// An array to convert the cloud coverage codes to an index of the
// $images and $n_images array.

$coverage = array (
  'CLR' => '0',
  'SKC' => '0',
  'FEW' => '1',
  'SCT' => '2',
  'BKN' => '3',
  'OVC' => '4',
  'VV'  => '4'
);

// Clear all images

if (isset($images)) {
  unset($images);
}
if (isset($n_images)) {
  unset($n_images);
}

$sky_nodata_image = 'sky_nodata.gif';

// Define a lot of images for daylight weather-group/cloud condition.
// It's a 2-dimensional array, indexed by the:
// - Precipitation (first index)
// - Cloud coverage (second index).

$images = array (
  'None'  => array ('0' => '0cloud.gif',
                    '1' => '1cloud_norain.gif',
                    '2' => '2cloud_norain.gif',
                    '3' => '3cloud_norain.gif',
                    '4' => '4cloud_norain.gif'),
  '-Rain' => array ('0' => '0cloud.gif',
                    '1' => '1cloud_lightrain.gif',
                    '2' => '2cloud_lightrain.gif',
                    '3' => '3cloud_lightrain.gif',
                    '4' => '4cloud_lightrain.gif'),
  'Rain'  => array ('0' => '0cloud.gif',
                    '1' => '1cloud_modrain.gif',
                    '2' => '2cloud_modrain.gif',
                    '3' => '3cloud_modrain.gif',
                    '4' => '4cloud_modrain.gif'),
  '+Rain' => array ('0' => '0cloud.gif',
                    '1' => '1cloud_heavyrain.gif',
                    '2' => '2cloud_heavyrain.gif',
                    '3' => '3cloud_heavyrain.gif',
                    '4' => '4cloud_heavyrain.gif'),
  '-Snow' => array ('0' => '0cloud.gif',
                    '1' => '2cloud_snow.gif',
                    '2' => '2cloud_snow.gif',
                    '3' => '3cloud_snow.gif',
                    '4' => '4cloud_lightsnow.gif'),
  '+Snow' => array ('0' => '0cloud.gif',
                    '1' => '2cloud_snow.gif',
                    '2' => '2cloud_snow.gif',
                    '3' => '3cloud_snow.gif',
                    '4' => '4cloud_heavysnow.gif'),
  '-Hail' => array ('0' => '0cloud.gif',
                    '1' => '2cloud_hail.gif',
                    '2' => '2cloud_hail.gif',
                    '3' => '3cloud_hail.gif',
                    '4' => '4cloud_lighthail.gif'),
  '+Hail' => array ('0' => '0cloud.gif',
                    '1' => '2cloud_hail.gif',
                    '2' => '2cloud_hail.gif',
                    '3' => '3cloud_hail.gif',
                    '4' => '4cloud_heavyhail.gif'),
  'Thun'  => array ('0' => '0cloud.gif',
                    '1' => '2cloud_thunders.gif',
                    '2' => '2cloud_thunders.gif',
                    '3' => '3cloud_thunders.gif',
                    '4' => '4cloud_thunders.gif'),
  'Fog'   => array ('0' => '0cloud_fog.gif',
                    '1' => '1cloud_fog.gif',
                    '2' => '2cloud_fog.gif',
                    '3' => '3cloud_fog.gif',
                    '4' => '4cloud_fog.gif')
  );

// Define a lot of images for nigh time weather-group/cloud condition.
// It has the same structure as the daylight array $images
// It's a 2-dimensional array, indexed by the:
// - Precipitation (first index)
// - Cloud coverage (second index).

$n_images = array (
  'None'   => array ('0' => 'n_0cloud.gif',
                     '1' => 'n_1cloud_norain.gif',
                     '2' => 'n_2cloud_norain.gif',
                     '3' => 'n_3cloud_norain.gif',
                     '4' => '4cloud_norain.gif'),
  '-Rain'  => array ('0' => 'n_0cloud.gif',
                     '1' => 'n_1cloud_lightrain.gif',
                     '2' => 'n_2cloud_lightrain.gif',
                     '3' => 'n_3cloud_lightrain.gif',
                     '4' => '4cloud_lightrain.gif'),
  'Rain'   => array ('0' => 'n_0cloud.gif',
                     '1' => 'n_1cloud_modrain.gif',
                     '2' => 'n_2cloud_modrain.gif',
                     '3' => 'n_3cloud_modrain.gif',
                     '4' => '4cloud_modrain.gif'),
  '+Rain'  => array ('0' => 'n_0cloud.gif',
                     '1' => 'n_1cloud_heavyrain.gif',
                     '2' => 'n_2cloud_heavyrain.gif',
                     '3' => 'n_3cloud_heavyrain.gif',
                     '4' => '4cloud_heavyrain.gif'),
  '-Snow'  => array ('0' => 'n_0cloud.gif',
                     '1' => 'n_2cloud_snow.gif',
                     '2' => 'n_2cloud_snow.gif',
                     '3' => 'n_3cloud_snow.gif',
                     '4' => '4cloud_lightsnow.gif'),
  '+Snow'  => array ('0' => 'n_0cloud.gif',
                     '1' => 'n_2cloud_snow.gif',
                     '2' => 'n_2cloud_snow.gif',
                     '3' => 'n_3cloud_snow.gif',
                     '4' => '4cloud_heavysnow.gif'),
  '-Hail'  => array ('0' => 'n_0cloud.gif',
                     '1' => 'n_2cloud_hail.gif',
                     '2' => 'n_2cloud_hail.gif',
                     '3' => 'n_3cloud_hail.gif',
                     '4' => '4cloud_lighthail.gif'),
  '+Hail'  => array ('0' => 'n_0cloud.gif',
                     '1' => 'n_2cloud_hail.gif',
                     '2' => 'n_2cloud_hail.gif',
                     '3' => 'n_3cloud_hail.gif',
                     '4' => '4cloud_heavyhail.gif'),
  'Thun'   => array ('0' => 'n_0cloud.gif',
                     '1' => 'n_2cloud_thunders.gif',
                     '2' => 'n_2cloud_thunders.gif',
                     '3' => 'n_3cloud_thunders.gif',
                     '4' => '4cloud_thunders.gif'),
  'Fog'    => array ('0' => 'n_0cloud_fog.gif',
                     '1' => 'n_1cloud_fog.gif',
                     '2' => 'n_2cloud_fog.gif',
                     '3' => 'n_3cloud_fog.gif',
                     '4' => '4cloud_fog.gif')
);

// Define image filenames for:
// - 16 wind directions,
// - 'no wind direction data'
// - variable wind direction (VRB)
// - calm wind (00000KT), or 'nodir'

$wind_dir_images = array (
  0 => 'nnn.gif',
  1 => 'nne.gif',
  2 => 'ne.gif',
  3 => 'nee.gif',
  4 => 'eee.gif',
  5 => 'see.gif',
  6 => 'se.gif',
  7 => 'sse.gif',
  8 => 'sss.gif',
  9 => 'ssw.gif',
 10 => 'sw.gif',
 11 => 'sww.gif',
 12 => 'www.gif',
 13 => 'nww.gif',
 14 => 'nw.gif',
 15 => 'nnw.gif',
 16 => 'nnn.gif');

$wind_nodata_image = 'wind_nodata.gif';
$wind_vrb_image = 'vrb.gif';
$wind_nodir_image = 'nodir.gif';

// Define image filenames for:
// - 'no data' condition,
// - 'temperature zero or below zero degrees Celcius
// - 'temperature above zero degrees Celcius
 
$temp_nodata_image = 'temp_nodata.gif';
$temp_low_image  = 'templow.gif';
$temp_high_image = 'temphigh.gif';
// ======================================================================

// The wind_speeds array can be used to convert wind speed values in [m/s]
// to [Bft] (beaufort).

$wind_speeds = array (
  'beaufort' => array (0,    1,    2,    3,    4,    5,    
                       6,    7,    8,    9,    10,   11,   12),
  'ms'       => array (0.3,  1.6,  3.4,  5.5,  8.0,  10.8,
                       13.9, 17.2, 20.8, 24.5, 28.5, 32.7, 999));
// ------------------------------------------------------------------------

// The get_sky_image() function takes the processed metar data and
// returns the sky image filename. The function combines the weather
// group and cloud group to a specific image. Example html code:
//
// <img src="< ?php
//   get_image($processed_metar)
// ? >" height="50" width="80" border="1">

function get_sky_image($processed_metar_data) {
  global $abs_image_path, $strings;
  global $itime;

  global $phenomena_array, $coverage, $images, $n_images;

  $metar = $processed_metar_data['metar'];

  $parts = explode(' ', $metar);
  $num_parts = count($parts);
  $night = 0;
  $maxcoverage = 0;

  for ($i = 0; $i < $num_parts; $i++) {
    $part = $parts[$i];
    
    if (ereg('RMK|TEMPO|BECMG', $part)) {
      /* The rest of the METAR is either a remark or temporary
         information. We skip the rest of the METAR. */
      break;
    } elseif (ereg('([0-9]{2})([0-9]{2})([0-9]{2})Z', $part, $regs)) {
      if (($regs[2] < 6) || ($regs[2] > 18)) {
      	$night = 1;
      }
    }
    elseif (ereg('^(-|\+|VC)?(TS|SH|FZ|BL|DR|MI|BC|PR|RA|DZ|SN|SG|GR|GS|PE|IC|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS)+$', $part)) {
      /*
       * Is this the current weather group?
       */ 

      // Get the intensity and get rid of it in the $part string
      $intensity = '';      
      if (ereg('^(-|\+|VC)(..)*$',$part)) {
        if ($part[0] == '-') {
          $intensity = '-';
          $part = substr($part,1);
        } elseif ($part[0] == '+') {
          $intensity = '+';
          $part = substr($part,1);
        } elseif ($part[0] . $part[1] == 'VC') {
          $intensity = '';
          $part = substr($part,2);
        }
      }

      
      // Now, take only the precipitation types that have icons.
      // Ignore the others In case more then one exist, take only the
      // first one (highest predominance).
      ereg('(TS|RA|DZ|SN|SG|GR|GS|PE|IC|BR|FG)(..)*$',$part,$match);
			if ($match[1] != '') {
				$phenomena = $match[1];
			} else {
        ereg('(..)(TS|RA|DZ|SN|SG|GR|GS|PE|IC|BR|FG)(..)*$',$part,$match);
	  		if ($match[2] != '') {
		  		$phenomena = $match[2];
			  }
			}
      // Not each precipitation type has a single icon with it.
      // Combine similar precipitation types to a phenomena group.
      // I.e. drizzle (DZ) and rain (RA) are both considered to be
      // rain (as far as the icons are concerned). Add intensity only
      // in case of rain and snow.
      if (ereg('^(Snow|Hail)$',$phenomena_array[$phenomena])) {
        if ($intensity == '') {
          $intensity = '-';
        }
      }
            
      if (ereg('^(Rain|Snow|Hail)$',$phenomena_array[$phenomena])) {
        $phenomena_group = $intensity . $phenomena_array[$phenomena];
      } else {
        $phenomena_group = $phenomena_array[$phenomena];
      }	

    }   
				
    // Now check the cloud coverage. There could be three cloud
    // layers, so check for all of them. Iconize the most covered
    // clouds, thus find the highest cloudcoverage layer, by
    // maximizing the $maxcoverage param
      
    elseif (ereg('(SKC|CLR)(...)', $part, $regs)) {
      $maxcoverage = max($maxcoverage,$coverage[$regs[1]]);
//      if ($maxcoverage < $coverage[$regs[1]]) {
//        $maxcoverage = $coverage[$regs[1]];
//      }
    }
    elseif (ereg('^(VV|FEW|SCT|BKN|OVC)([0-9]{3})(CB|TCU)?$', $part, $regs)) {
      $maxcoverage = max($maxcoverage,$coverage[$regs[1]]);
//      if ($maxcoverage < $coverage[$regs[1]]) {
//        $maxcoverage = $coverage[$regs[1]];
//      }
    }
  }
  // If looped through all groups and not found any weather group
  // (meaning no precipitation?), assume a '#' phenomena, resulting in
  // a 'None' phenomena group
  if ($phenomena == '') {
    $phenomena = '#';
    $phenomena_group = $phenomena_array[$phenomena];
  }
         
  // At this point, the $phenomena_group variable contains the one
  // index of the $images array, while the $maxcoverage variable
  // contains the other index of the $images array. The correct image
  // can be selected from the array.

  if (($night == 1) || ($itime == 'nite')) {
    echo $abs_image_path . $n_images[$phenomena_group][$maxcoverage];
  } else { 
    echo $abs_image_path . $images[$phenomena_group][$maxcoverage];
  }
  
}
// ------------------------------------------------------------------------

// The get_winddir_image() function takes the processed metar data and
// returns the appropriate wind direction image filename. There are 16
// wind direction icons defined to indicate the wind direction. Beside
// the 16 directions, there are icons for variable wind direction,
// calm wind and and an icon for the no data condition. Example html
// code:
//
// <img src="< ?php
//   get_winddir_image($processed_metar)
// ? >" height="40" width="40" border="1">

function get_winddir_image($processed_metar_data) {
  global $abs_image_path,
         $wind_nodir_image,$wind_dir_images,$wind_nodata_image,
         $wind_vrb_image,$strings;

  if (isset($processed_metar_data['wind_deg'])) {
    if ($processed_metar_data['wind_deg'] == $strings['wind_vrb_long']) {
      echo $abs_image_path . $wind_vrb_image;
    } elseif (($processed_metar_data['wind_deg'] == 0) && ($processed_metar_data['wind_knots'] == 0)) {
      echo $abs_image_path . $wind_nodir_image;
    } else {
      $array_index = round($processed_metar_data['wind_deg']/22.5);
      echo $abs_image_path . $wind_dir_images[$array_index];
    }
  } else {
    echo $abs_image_path . $wind_nodata_image;
  }
}
// ------------------------------------------------------------------------

// The get_temp_image() function takes the processed metar data and
// returns the appropriate temperature image filename. It uses the
// 'temp_c' value to decide weather a freezing thermometer icon or a
// non-freezing thermometer icon. When the 'temp_c' data is not
// available, a 'no data' icon filename is returned. Example html
// code:
//
// <img src="< ?php
//   get_temp_image($processed_metar)
// ? >" height="50" width="20" border="1">

function get_temp_image($processed_metar_data) {
  global $abs_image_path,
         $temp_high_image,$temp_low_image,$temp_nodata_image;
  
  if (isset($processed_metar_data['temp_c'])) {
    if ($processed_metar_data['temp_c'] > 0) {
      echo $abs_image_path . $temp_high_image;
    } else {
      echo $abs_image_path . $temp_low_image;
    }
  } else {
    echo $abs_image_path . $temp_nodata_image;
  }
}
// ------------------------------------------------------------------------

// The get_beaufort() function takes the 'wind_meters_per_second'
// value from the $decoded_metar array and converts it to beaufort
// values. This is done by iterating through a table with windspeeds
// in [m/s] and [bft] values.

function get_beaufort() {
  global $wind_speeds, $decoded_metar;
  $ms = $decoded_metar['wind_meters_per_second'];

  if ($ms != '') {
    $cnt = 0;
    while (($ms > $wind_speeds['ms'][$cnt]) && ($cnt <= 12)) {
      $cnt++;
    }
    return $cnt;
  } else {
    return 0;
  }
}
// ------------------------------------------------------------------------

// The set_time() function is purely added for overruling the metar
// time to night time. It is only intended to support displaying all
// weathergroup icons in the table.php script during daytime.

function set_time($ntime) {
  global $itime;
  $itime = $ntime;
}
// ------------------------------------------------------------------------


?>
