parse (Irc::Utils::Metar)

    # File rbot/utils.rb, line 328
          def parse
            @decoded = Hash.new
            puts @input
            @input.split(" ").each {|part|
              if (part == 'METAR')
                # Type of Report: METAR
                @decoded['type'] = 'METAR'
              elsif (part == 'SPECI')
                # Type of Report: SPECI
                @decoded['type'] = 'SPECI'
              elsif (part == 'AUTO')
                # Report Modifier: AUTO
                @decoded['report_mod'] = 'AUTO'
              elsif (part == 'NIL')
                @nodata = true
              elsif (part =~ /^\S{4}$/ && ! (@decoded.has_key?('station')))
                # Station Identifier
                @decoded['station'] = part
              elsif (part =~ /([0-9]{2})([0-9]{2})([0-9]{2})Z/)
                # ignore this bit, it's useless without month/year. some of these
                # things are hideously out of date.
                # now = Time.new
                # time = Time.gm(now.year, now.month, $1, $2, $3, 0)
                # Date and Time of Report
                # @decoded['time'] = time
              elsif (part == 'COR')
                # Report Modifier: COR
                @decoded['report_mod'] = 'COR'
              elsif (part =~ /([0-9]{3}|VRB)([0-9]{2,3}).*(KT|MPS|KMH)/)
                # Wind Group
                windunit = $3
                # now do ereg to get the actual values
                part =~ /([0-9]{3}|VRB)([0-9]{2,3})((G[0-9]{2,3})?#{windunit})/
                if ($1 == 'VRB')
                  @decoded['wind_deg'] = 'variable directions'
                  @decoded['wind_dir_text'] = 'variable directions'
                  @decoded['wind_dir_text_short'] = 'VAR'
                else
                  @decoded['wind_deg'] = $1
                  @decoded['wind_dir_text'] = @wind_dir_texts[($1.to_i/22.5).round]
                  @decoded['wind_dir_text_short'] = @wind_dir_texts_short[($1.to_i/22.5).round]
                end
                store_speed($2, windunit,
                            'wind_meters_per_second',
                            'wind_knots',
                            'wind_miles_per_hour')

                if ($4 != nil)
                  # We have a report with information about the gust.
                  # First we have the gust measured in knots
                  store_speed($4,windunit,
                              'wind_gust_meters_per_second',
                              'wind_gust_knots',
                              'wind_gust_miles_per_hour')
                end
              elsif (part =~ /([0-9]{3})V([0-9]{3})/)
                #  Variable wind-direction
                @decoded['wind_var_beg'] = $1
                @decoded['wind_var_end'] = $2
              elsif (part == "9999")
                # A strange value. When you look at other pages you see it
                # interpreted like this (where I use > to signify 'Greater
                # than'):
                @decoded['visibility_miles'] = '>7';
                @decoded['visibility_km']    = '>11.3';
              elsif (part =~ /^([0-9]{4})$/)
                # Visibility in meters (4 digits only)
                # The visibility measured in kilometers, rounded to one decimal place.
                @decoded['visibility_km'] = sprintf("%.1f", $1.to_i / 1000)
                # The visibility measured in miles, rounded to one decimal place.
                @decoded['visibility_miles'] = sprintf("%.1f", $1.to_i / 1000 / 1.609344)
              elsif (part =~ /^[0-9]$/)
                # Temp Visibility Group, single digit followed by space
                @decoded['temp_visibility_miles'] = part
              elsif (@decoded['temp_visibility_miles'] && (@decoded['temp_visibility_miles']+' '+part) =~ /^M?(([0-9]?)[ ]?([0-9])(\/?)([0-9]*))SM$/)
                # Visibility Group
                if ($4 == '/')
                  vis_miles = $2.to_i + $3.to_i/$5.to_i
                else
                  vis_miles = $1.to_i;
                end
                if (@decoded['temp_visibility_miles'][0] == 'M')
                  # The visibility measured in miles, prefixed with < to indicate 'Less than'
                  @decoded['visibility_miles'] = '<' + sprintf("%.1f", vis_miles)
                  # The visibility measured in kilometers. The value is rounded
                  # to one decimal place, prefixed with < to indicate 'Less than' */
                  @decoded['visibility_km']    = '<' . sprintf("%.1f", vis_miles * 1.609344)
                else
                  # The visibility measured in mile.s */
                  @decoded['visibility_miles'] = sprintf("%.1f", vis_miles)
                  # The visibility measured in kilometers, rounded to one decimal place.
                  @decoded['visibility_km']    = sprintf("%.1f", vis_miles * 1.609344)
                end
              elsif (part =~ /^(-|\+|VC|MI)?(TS|SH|FZ|BL|DR|BC|PR|RA|DZ|SN|SG|GR|GS|PE|IC|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS)+$/)
                # Current weather-group
                @decoded['weather'] = '' unless @decoded.has_key?('weather')
                if (part[0].chr == '-')
                  # A light phenomenon
                  @decoded['weather'] += @strings['light']
                  part = part[1,part.length]
                elsif (part[0].chr == '+')
                  # A heavy phenomenon
                  @decoded['weather'] += @strings['heavy']
                  part = part[1,part.length]
                elsif (part[0,2] == 'VC')
                  # Proximity Qualifier
                  @decoded['weather'] += @strings['nearby']
                  part = part[2,part.length]
                elsif (part[0,2] == 'MI')
                  @decoded['weather'] += @strings['mild']
                  part = part[2,part.length]
                else
                  # no intensity code => moderate phenomenon
                  @decoded['weather'] += @strings['moderate']
                end

                while (part && bite = part[0,2]) do
                  # Now we take the first two letters and determine what they
                  # mean. We append this to the variable so that we gradually
                  # build up a phrase.

                  @decoded['weather'] += @weather_array[bite]
                  # Here we chop off the two first letters, so that we can take
                  # a new bite at top of the while-loop.
                  part = part[2,-1]
                end
              elsif (part =~ /(SKC|CLR)/)
                # Cloud-layer-group.
                # There can be up to three of these groups, so we store them as
                # cloud_layer1, cloud_layer2 and cloud_layer3.

                @cloud_layers += 1;
                # Again we have to translate the code-characters to a
                # meaningful string.
                @decoded['cloud_layer'+ (@cloud_layers.to_s) +'_condition']  = @cloud_condition_array[$1]
                @decoded['cloud_layer'+ (@cloud_layers.to_s) +'_coverage'] = @cloud_coverage[$1]
              elsif (part =~ /^(VV|FEW|SCT|BKN|OVC)([0-9]{3})(CB|TCU)?$/)
                # We have found (another) a cloud-layer-group. There can be up
                # to three of these groups, so we store them as cloud_layer1,
                # cloud_layer2 and cloud_layer3.
                @cloud_layers += 1;
                # Again we have to translate the code-characters to a meaningful string.
                if ($3 == 'CB')
                  # cumulonimbus (CB) clouds were observed. */
                  @decoded['cloud_layer'+ (@cloud_layers.to_s) +'_condition'] =
                              @cloud_condition_array[$1] + @strings['clouds_cb']
                elsif ($3 == 'TCU')
                  # towering cumulus (TCU) clouds were observed.
                  @decoded['cloud_layer'+ (@cloud_layers.to_s) +'_condition'] =
                              @cloud_condition_array[$1] + @strings['clouds_tcu']
                else
                  @decoded['cloud_layer'+ (@cloud_layers.to_s) +'_condition'] =
                              @cloud_condition_array[$1] + @strings['clouds']
                end
                @decoded['cloud_layer'+ (@cloud_layers.to_s) +'_coverage'] = @cloud_coverage[$1]
                @decoded['cloud_layer'+ (@cloud_layers.to_s) +'_altitude_ft'] = $2.to_i * 100
                @decoded['cloud_layer'+ (@cloud_layers.to_s) +'_altitude_m']  = ($2.to_f * 30.48).round
              elsif (part =~ /^T([0-9]{4})$/)
                store_temp($1,'temp_c','temp_f')
              elsif (part =~ /^T?(M?[0-9]{2})\/(M?[0-9\/]{1,2})?$/)
                # Temperature/Dew Point Group
                # The temperature and dew-point measured in Celsius.
                @decoded['temp_c'] = sprintf("%.1f", $1.tr('M', '-'))
                if $2 == "//" || !$2
                  @decoded['dew_c'] = 0
                else
                  @decoded['dew_c'] = sprintf("%.1f", $2.tr('M', '-'))
                end
                # The temperature and dew-point measured in Fahrenheit, rounded to
                # the nearest degree.
                @decoded['temp_f'] = (@decoded['temp_c'].to_f * (9/5) + 32).round
                @decoded['dew_f']  = (@decoded['dew_c'].to_f * (9/5) + 32).round
              elsif(part =~ /A([0-9]{4})/)
                # Altimeter
                # The pressure measured in inHg
                @decoded['altimeter_inhg'] = sprintf("%.2f", $1.to_i/100)
                # The pressure measured in mmHg, hPa and atm
                @decoded['altimeter_mmhg'] = sprintf("%.1f", $1.to_f * 0.254)
                @decoded['altimeter_hpa']  = sprintf("%.1f", $1.to_f * 0.33863881578947)
                @decoded['altimeter_atm']  = sprintf("%.3f", $1.to_f * 3.3421052631579e-4)
              elsif(part =~ /Q([0-9]{4})/)
                # Altimeter
                # This is strange, the specification doesnt say anything about
                # the Qxxxx-form, but it's in the METARs.
                # The pressure measured in hPa
                @decoded['altimeter_hpa']  = sprintf("%.1f", $1.to_f)
                # The pressure measured in mmHg, inHg and atm
                @decoded['altimeter_mmhg'] = sprintf("%.1f", $1.to_f * 0.7500616827)
                @decoded['altimeter_inhg'] = sprintf("%.2f", $1.to_f * 0.0295299875)
                @decoded['altimeter_atm']  = sprintf("%.3f", $1.to_f * 9.869232667e-4)
              elsif (part =~ /^T([0-9]{4})([0-9]{4})/)
                # Temperature/Dew Point Group, coded to tenth of degree.
                # The temperature and dew-point measured in Celsius.
                store_temp($1,'temp_c','temp_f')
                store_temp($2,'dew_c','dew_f')
              elsif (part =~ /^1([0-9]{4}$)/)
                # 6 hour maximum temperature Celsius, coded to tenth of degree
                store_temp($1,'temp_max6h_c','temp_max6h_f')
              elsif (part =~ /^2([0-9]{4}$)/)
                # 6 hour minimum temperature Celsius, coded to tenth of degree
                store_temp($1,'temp_min6h_c','temp_min6h_f')
              elsif (part =~ /^4([0-9]{4})([0-9]{4})$/)
                # 24 hour maximum and minimum temperature Celsius, coded to
                # tenth of degree
                store_temp($1,'temp_max24h_c','temp_max24h_f')
                store_temp($2,'temp_min24h_c','temp_min24h_f')
              elsif (part =~ /^P([0-9]{4})/)
                # Precipitation during last hour in hundredths of an inch
                # (store as inches)
                @decoded['precip_in'] = sprintf("%.2f", $1.to_f/100)
                @decoded['precip_mm'] = sprintf("%.2f", $1.to_f * 0.254)
              elsif (part =~ /^6([0-9]{4})/)
                # Precipitation during last 3 or 6 hours in hundredths of an
                # inch  (store as inches)
                @decoded['precip_6h_in'] = sprintf("%.2f", $1.to_f/100)
                @decoded['precip_6h_mm'] = sprintf("%.2f", $1.to_f * 0.254)
              elsif (part =~ /^7([0-9]{4})/)
                # Precipitation during last 24 hours in hundredths of an inch
                # (store as inches)
                @decoded['precip_24h_in'] = sprintf("%.2f", $1.to_f/100)
                @decoded['precip_24h_mm'] = sprintf("%.2f", $1.to_f * 0.254)
              elsif(part =~ /^4\/([0-9]{3})/)
                # Snow depth in inches
                @decoded['snow_in'] = sprintf("%.2f", $1);
                @decoded['snow_mm'] = sprintf("%.2f", $1.to_f * 25.4)
              else
                # If we couldn't match the group, we assume that it was a
                # remark.
                @decoded['remarks'] = '' unless @decoded.has_key?("remarks")
                @decoded['remarks'] += ' ' + part;
              end
            }

            # Relative humidity
            @decoded['rel_humidity'] = sprintf("%.1f",100 *
              (
               610.710701 +
               44.4293573 * @decoded['dew_c'].to_f +
               1.41696846 * ((@decoded['dew_c'].to_f ** 2)) +
               0.0274759545 * ((@decoded['dew_c'].to_f ** 3)) +
               2.61145937E-4 * ((@decoded['dew_c'].to_f ** 4)) +
               2.85993708E-6 * ((@decoded['dew_c'].to_f ** 5))
               ) / (
               610.710701 +
               44.4293573 * @decoded['temp_c'].to_f +
               1.41696846 * ((@decoded['temp_c'].to_f ** 2)) +
               0.0274759545 * ((@decoded['temp_c'].to_f ** 3)) +
               2.61145937E-4 * ((@decoded['temp_c'].to_f ** 4)) +
               2.85993708E-6 * ((@decoded['temp_c'].to_f ** 5))
               )) if @decoded.has_key?('dew_c')
          end