#!/usr/bin/ruby

require 'gdbm'

def dms2frac str
  return nil if str.nil?
  case str
  when nil then nil
  when /(\d+)-(\d+)-(\d+)([NEWS]?)/ then
    d, m, s, sign = $1, $2, $3, $4
    f = (s.to_i / 60.0 + m.to_i) / 60.0 + d.to_i
    f = -f if /^[WS]/ === sign
    format('%.4f', f)
  when /(\d+)-(\d+)([NEWS])/ then
    d, m, sign = $1, $2, $3
    f = m.to_i / 60.0 + d.to_i
    f = -f if /^[WS]/ === sign
    format('%.2f', f)
  else
    STDERR.puts "dms2frac: <#{str}> unreadable"
    nil
  end
end

dbfile = ARGV.shift
raise "usage: #$0 dbfile [input ...]" unless dbfile
GDBM.open(dbfile) {|db|
  for line in ARGF
    row = line.strip.split(/;/, 14)
    cccc = row[0]
    r = Hash[*db[cccc].to_s.split(/\t/).map{|s| s.split(/:/, 2)}.flatten]
    wmo = row[1] + row[2]
    r['wm1'] = wmo if /^\d{5}$/ === wmo
    name = row[3, 2]
    name.pop if name.last.empty?
    r['sn1'] = name.join(', ')
    r['cn1'] = row[5]
    r['ra1'] = row[6]
    lat = dms2frac(row[7])
    lon = dms2frac(row[8])
    if lat and lon
      r['la1'] = lat
      r['lo1'] = lon
    end
    r['ha1'] = row[11] unless row[11].to_s.empty?
    r['hp1'] = row[12] unless row[12].to_s.empty?
    raise line.inspect if /;/ === row[12]
    STDOUT.write "[#{cccc}]"
    db[cccc] = r.to_a.sort.map{|kv| kv.join(':')}.join("\t")
  end
  puts '.'
}