# $Id: importNOS_Geogroups.rb 7139 2019-12-27 00:32:02Z flaterco $
# Functions for importNOS.rb:
# Working with geogroups

# Fix up level 6 geogroup names; make them presentable or nil them out.
# Those that do not appear in the hash are left unchanged.
L6rewrite = {
  "CONNECTICUT, Long Island Sound" => "Long Island Sound",
  "Delaware Bay, Western Shore" => "Delaware Bay",
  "Nassau Sound and Fort George River" => nil,
  "Hawaiin Islands" => nil,
  "British Columbia and Alaska" => nil,
  "Eastport to Swans Island" => nil,
  "MARYLAND, outer coast" => nil,
  "MASSACHUSETTS, outer coast" => nil,
  "MAINE and NEW HAMPSHIRE" => nil,
  "Long Island Sound, north side" => "Long Island Sound",
  "Delaware River-cont." => "Delaware River",
  "SOUTH CAROLINA, outer coast" => nil,
  "VIRGINIA, outer coast" => nil,
  "FLORIDA, St. Johns River" => "St. Johns River",
  "Tybee Creek and Wassaw Sound" => nil,
  "Southern California" => nil,
  "Outer Coast" => nil,
  "RHODE ISLAND, Outer Coast" => nil,
  "Chesapeake Bay, Eastern Shore" => "Chesapeake Bay",
  "FLORIDA, East Coast" => nil,
  "MAINE, outer coast" => nil,
  "Delaware Bay, Eastern Shore" => "Delaware Bay",
  "Long Island, Long Island Sound" => "Long Island",
  "DELAWARE, outer coast" => nil,
  "Chesapeake Bay, Western Shore-cont." => "Chesapeake Bay",
  "Florida Keys" => nil,
  "St. Catherines and Sapelo Sounds" => nil,
  "Cohasset Harbor to Davis Bank" => nil,
  "Chesapeake Bay, western shore" => "Chesapeake Bay",
  "Doboy and Altamaha Sounds" => nil,
  "MAINE, outer coast-cont." => nil,
  "Nantucket Sound, north side" => "Nantucket Sound",
  "SOUTH CAROLINA, outer coast-cont." => nil,
  "Dall Island, west coast" => "Dall Island",
  "Outer Coast, Port San Luis" => "Port San Luis",
  "The Kills and Newark Bay" => nil,
  "Lesser Antilles & Virgin Islands" => nil,
  "Meares Passage to Davidson Inlet" => nil,
  "Gulf Coast-cont." => nil,
  "Lower New York Bay, Raritan Bay, etc." => nil,
  "Chesapeake Bay, southern shore" => "Chesapeake Bay",
  "Yaquina Bay and River" => nil,
  "Outer Coast, San Francisco" => "San Francisco",
  "Possession Sound and Port Susan" => nil,
  "Baranof Island, west coast" => "Baranof Island",
  "Saratoga Passage and Skagit Bay" => nil,
  "Salisbury Sound and Peril Strait" => nil,
  "Rosario Strait, etc." => nil,
  "Chichagof Island, west coast" => "Chichagof Island",
  "Kenai Peninsula, outer coast" => "Kenai Peninsula",
  "Kodiak and Afognak Islands" => nil,
  "Kuskokwim Bay and River" => nil,
  "NORTH CAROLINA, outer coast" => nil
}

# Translate a geogroup ID to "blah, blah, de blah" naming convention.
# Returns an array because a given geogroup can have multiple parents and we
# have no clue which way to go.
# L4 is suppressed.  L6 is rewritten or suppressed per L6rewrite.
#
# As of 2017:
# Level 2 is only Elizabeth River.  Probably an error.
# There is nothing at levels 1 or 3.
# Level 4 is West Coast, East Coast, Gulf Coast, Pacific, Caribbean Islands.
# State names are level 5.
# Level 6 is a mixed bag; some need to be suppressed.
# Level 7 is the bottom and always good.
# And the only ones with multiple parents are Potomac River (DC/MD/VA) and
# Columbia River (WA/OR).
def longGeogroupName(gt, ggid)
  if gt.include?(ggid)
    g = gt[ggid]
    if g[:level] == 4
      []   # stahp
    else
      myname = g[:name]
      if g[:level] == 6 and L6rewrite.include?(myname)
	myname = L6rewrite[myname]
      end
      p = g[:parents].map{|pgid| longGeogroupName(gt, pgid)}.flatten
      if p.empty?
	(myname.nil? ? [] : [myname])
      else
	(myname.nil? ? p : p.map{|n| myname + ", " + n})
      end
    end
  else
    []
  end
end

# Ibid. starting with station ID instead of geogroup ID.
def stationLongGeogroupName(gt, sbgt, sid)
  if sbgt.include?(sid)
    longGeogroupName(gt, sbgt[sid]["parentGeoGroupId"].to_i)
  else
    []
  end
end

# Navigate upward and return the geogroups of a specified level as an array
# of names.  (lvl should be int)
# Does not modify l4 or l6.
# Does not suffix the parent levels.
# Duplicates resulting from diamond inheritance are removed.
def geoLevelName(gt, ggid, lvl)
  if gt.include?(ggid)
    g = gt[ggid]
    l = g[:level]
    if l > lvl
      g[:parents].map{|p| geoLevelName(gt, p, lvl)}.flatten.uniq
    elsif l == lvl
      [g[:name]]
    else
      []
    end
  else
    []
  end
end

# Ibid. starting with station ID instead of geogroup ID.
def stationGeoLevelName(gt, sbgt, sid, lvl)
  if sbgt.include?(sid)
    geoLevelName(gt, sbgt[sid]["parentGeoGroupId"].to_i, lvl)
  else
    []
  end
end
