class_name OverworldSingleton extends Node

signal mapChanged(map:PackedScene, playerDestinationNodeName:String)

var newMapPath:String
var hasFadedOut:bool = false
var playerDestinationNodeName:String
var newMapLoaded:bool = false

func isMapChanging() -> bool:
  return newMapPath != ""

func _enter_tree() -> void:
  pass

func _exit_tree() -> void:
  TRANSITION.fadeOutEnd.disconnect(onFadeOutEnd)
  TRANSITION.fadeInEnd.disconnect(onFadeInEnd)

func _process(_delta:float) -> void:
  if(!isMapChanging()):
    return

  var status = ResourceLoader.load_threaded_get_status(newMapPath)
  if status == ResourceLoader.THREAD_LOAD_FAILED:
    push_error("Failed to load map: " + newMapPath)
    newMapPath = ""
    
  elif status == ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
    push_error("Failed to load map: " + newMapPath)
    newMapPath = ""

  elif status == ResourceLoader.THREAD_LOAD_IN_PROGRESS:
    print("Map loading in progress for: " + newMapPath)

  elif status == ResourceLoader.THREAD_LOAD_LOADED:
    newMapLoaded = true
    newMapReady()



func mapChange(map:String, playerDestinationNodeName:String) -> void:
  # Begin Loading new map
  newMapPath = map
  playerDestinationNodeName = playerDestinationNodeName
  ResourceLoader.load_threaded_request(newMapPath)

  # Begin fadeout
  hasFadedOut = false
  TRANSITION.fade(TransitionSingleton.FadeType.FADE_OUT)
  TRANSITION.fadeOutEnd.connect(onFadeOutEnd)

func onFadeOutEnd() -> void:
  # Fade out has occurred, are we still waiting for the map to load?
  TRANSITION.fadeOutEnd.disconnect(onFadeOutEnd)
  hasFadedOut = true

  # Make sure we aren't still waiting for the map to load.
  if !newMapLoaded:
    return
  newMapReady()

func newMapReady():
  if !hasFadedOut:
    return

  # Instantiate the new map
  var mapResource = ResourceLoader.load_threaded_get(newMapPath)
  if mapResource == null:
    push_error("Failed to load map resource: " + newMapPath)
    return
  
  # Stop tracking new map name
  newMapPath = ""

  # Emit event
  mapChanged.emit(mapResource, playerDestinationNodeName)

  # Begin Fade In
  TRANSITION.fade(TransitionSingleton.FadeType.FADE_IN)
  TRANSITION.fadeInEnd.connect(onFadeInEnd)

func onFadeInEnd() -> void:
  TRANSITION.fadeInEnd.disconnect(onFadeInEnd)
