local class = require("core.class")
local statemachine = require("ai.statemachine")
local locomotion = require("creature.locomotion")
local thunk = require("core.thunk")
local poilib = require("behavior.poi")
local unaware = require("awareness.unaware")
local CoreBrain = class.Class("CoreBrain")
local Brain = statemachine.StateMachine.New("CoreSimpleBrain")
local state_machine_list = {Brain}
local STATE_NonHostile = Brain:State("NonHostile")
local STATE_Unaware = Brain:State("Unaware", unaware.Unaware)
local STATE_UsePOI = poilib.NewPOIState(Brain, "UsePOI")
poilib.AllowPOIFromStates(STATE_NonHostile, STATE_Unaware)
function CoreBrain:init()
end
function CoreBrain:OnAIPostSpawn(ai, global, constants, optionalTable)
end
function CoreBrain:OnAICreateLuaState(ai, global, constants)
  constants.isSimple = true
  locomotion.Install()
  locomotion.CreateDrivers(ai)
  global.navData = {}
  global.navData.navSpeedWalk = 1
  global.navData.navSpeedJog = 4
  self:SetPoiStates(ai)
  if StartConfig ~= nil then
    global.aggroState = StartConfig.AggroState
  else
    global.aggroState = "NonHostile"
  end
  ai:SetNavBank(global.navBank)
  if ai:GetBlackboard() == nil then
    ai:SetBlackboardSize(16)
  end
  self:StartUpdate(ai, global, constants)
end
function CoreBrain:Update(ai, global, constants)
  if engine.IsDebug() then
    local debugTable = statemachine.GetDebugTable(state_machine_list, ai)
    if debugTable then
      self:DrawDebugTable(debugTable, global)
    end
  end
  statemachine.UpdateAll(state_machine_list, ai, global, constants)
end
function CoreBrain:SetPoiStates(ai)
  local poiStateName = string.format("%s.POIStates", ai:GetName())
  if package.preload[poiStateName] == nil then
    return
  end
  local setupPOI = require(poiStateName).SetupPOIStates
  assert(type(setupPOI) == "function", "Invalid POIStates, make sure it follows the standard setup. See Henry if you need help.")
  setupPOI(STATE_UsePOI)
end
function CoreBrain:StartUpdate(ai, global, constants)
  statemachine.StartAll(ai, state_machine_list, ai, global, constants)
end
local Brain_Core = CoreBrain.New()
local OnAIUpdate = function(ai)
  CoreBrain:Update(ai, _G.global, _G.constants)
end
local OnAIPostSpawn = function(ai)
  CoreBrain:OnAIPostSpawn(ai, _G.global, _G.constants)
end
local OnAICreateLuaState = function(ai)
  CoreBrain:OnAICreateLuaState(ai, _G.global, _G.constants)
end
thunk.Install("OnAIUpdate", OnAIUpdate)
thunk.Install("OnAIPostSpawn", OnAIPostSpawn)
thunk.Install("OnAICreateLuaState", OnAICreateLuaState)
function Brain:OnBrainInit(ai, global, constants)
  print("init brain")
end
function Brain:SelectNextState(ai, global, constants)
  if poilib.IsPOIActive() then
    return STATE_UsePOI
  end
  if global.aggroState == "Unaware" then
    return STATE_Unaware
  end
  return STATE_NonHostile
end
function STATE_NonHostile:Enter(ai, global, constants)
end
function STATE_UsePOI:OnUpdateAwareness(ai, global, constants)
  local update_this
  if global.aggroState == "NonHostile" then
    update_this = STATE_NonHostile
  end
  if update_this then
    update_this:Update(ai, global, constants)
  end
end
function OnDeath(ai)
end
function CoreBrain:DrawDebugTable(debugTable, global)
  if debugTable then
    table.insert(debugTable, {
      "Current POI:",
      global.currentPOI
    })
    engine.DrawDebugTable(debugTable)
  end
end
return Brain_Core
