local M = {}

local scenarioController = require("scenario/gravitationalRacing/scenarioController")
local hubworld = require("levels/smallgrid/scenarios/gravitationalRacing/hubworld")

local start, setup = false, false

--- Wraps the given hook in a function that will not call the hook on calling, should the player not be in a scenario
--- @param hook function The hook to wrap
--- @return function The wrapped hook
local scenarioHookWrapper = function(hook)
  return function(...)
    local isInScenario = scenario_scenarios and scenario_scenarios.getScenario()

    if not isInScenario then return end
    hook(...)
  end
end


local function onPreRender(dt)
  if setup then
    scenarioController.update(dt, start)
  end
end

local function begin()
  --[[
  Note: this function can be hooked and run from specific scenario script files
  to allow for earlier movement of celestials
  ]]--
  start = true
end

local function requestHubWorld(msg, params)
  --[[
  Responsible for transferring messages from UI to the hub world, and then
  sending back a message
  Parameters:
    msg    - the message to send
    params - the data to accompany the message
  Returns:
    <table> - a return message to the UI
  ]]--
  return hubworld.uiRequest(msg, params)
end

local function onRaceStart()
  begin()
  scenarioController.start()
end

local function onScenarioRestarted()
  scenarioController.onScenarioRestarted()
end

local function onScenarioChange(sc)
  if sc.state == "pre-running" then

    --Hub world only uses this for UI messages
    if not sc.sourceFile:find("hubworld") then
      scenarioController.onScenarioChange(sc)

      --Hide the floor(s)
      local ground = scenetree.findClassObjects('Groundplane')
      for _, name in ipairs(ground) do
        scenetree.findObject(name).hidden = true
      end

      -- And the compass
      local compass = scenetree.findObject("compassReference")
      if compass then compass:setField("hidden", 0, "1") end

      setup = true
    end
  end
end

M.onPreRender = scenarioHookWrapper(onPreRender)
M.begin = begin
M.requestHubWorld = requestHubWorld
M.onRaceStart = scenarioHookWrapper(onRaceStart)
M.onScenarioRestarted = scenarioHookWrapper(onScenarioRestarted)
M.onScenarioChange = scenarioHookWrapper(onScenarioChange)
return M
