class_name ModalBackdrop extends ColorRect

# Tracks which overlays are currently open. Each entry must be a direct sibling
# (child of the same parent). The backdrop repositions itself in the scene tree
# to sit immediately below whichever open overlay has the highest tree index,
# so only one backdrop is ever visible regardless of how many overlays are open.
var _openOverlays:Array[Control] = []

func _ready() -> void:
  visible = false

func register(overlay:Control) -> void:
  assert(overlay.get_parent() == get_parent(), "ModalBackdrop: overlay must be a sibling")
  assert(overlay.has_signal("opened") and overlay.has_signal("closed"),
    "ModalBackdrop: overlay must have opened/closed signals")
  overlay.connect("opened", func(): _onOpened(overlay))
  overlay.connect("closed", func(): _onClosed(overlay))

func _onOpened(overlay:Control) -> void:
  if overlay not in _openOverlays:
    _openOverlays.append(overlay)
  _reposition()

func _onClosed(overlay:Control) -> void:
  _openOverlays.erase(overlay)
  _reposition()

func _reposition() -> void:
  if _openOverlays.is_empty():
    visible = false
    return
  visible = true
  var top := _topOverlay()
  var topIdx := top.get_index()
  var myIdx := get_index()
  if myIdx == topIdx - 1:
    return
  if myIdx < topIdx:
    get_parent().move_child(self, topIdx - 1)
  else:
    get_parent().move_child(self, topIdx)

func _topOverlay() -> Control:
  var top:Control = _openOverlays[0]
  for overlay in _openOverlays:
    if overlay.get_index() > top.get_index():
      top = overlay
  return top
