local LD = require("design.LevelDesignLibrary")
local thisObj, son, zoneObj
local enabled = true
local contextEnter, contextExit, contextBanterEnabled, boatRequired, sonMarker
local inZone = false
local contextlist = {
  LeadTheWay = "LEAD_THE_WAY_BEHAVIOR_CONTEXT_CONFIG",
  WaitAndExplore = "WAIT_AND_EXPLORE_BEHAVIOR_CONTEXT_CONFIG",
  Sad = "SAD_BEHAVIOR_CONTEXT_CONFIG",
  Frustrated = "FRUSTRATED_BEHAVIOR_CONTEXT_CONFIG",
  Panic = "PANIC_BEHAVIOR_CONTEXT_CONFIG",
  LookAround = "NORMAL_LOOKAROUND_BEHAVIOR_CONTEXT_CONFIG",
  Cold = "COLD_BEHAVIOR_CONTEXT_CONFIG",
  NearPoison = "WAIT_AND_EXPLORE_BEHAVIOR_CONTEXT_CONFIG",
  Puzzled = "PUZZLED_BEHAVIOR_CONTEXT_CONFIG",
  Boat_LookAt_Left = "BOAT_CONTEXT_CONFIG_LEFT",
  Boat_LookAt_Right = "BOAT_CONTEXT_CONFIG_RIGHT",
  Boat_Sick = "BOAT_SICK_CONTEXT_CONFIG",
  Will_Not_Fight = "WILL_NOT_FIGHT_BEHAVIOR_CONTEXT_CONFIG",
  Sick = "SICK_BEHAVIOR_CONTEXT_CONFIG",
  Bored = "BORED_BEHAVIOR_CONTEXT_CONFIG",
  Normal = "NORMAL_BEHAVIOR_CONTEXT_CONFIG",
  Nervous = "NERVOUS_CONTEXT_CONFIG",
  Alert = "ALERT_BEHAVIOR_CONTEXT_CONFIG"
}
function OnScriptLoaded(level, obj)
  thisObj = obj
  son = game.AI.FindSon()
  contextEnter = thisObj:GetLuaTableAttribute("Context_OnEnter")
  contextExit = thisObj:GetLuaTableAttribute("Context_OnExit")
  contextBanterEnabled = thisObj:GetLuaTableAttribute("ContextBanterEnabled")
  enabled = thisObj:GetLuaTableAttribute("StartEnabled")
  boatRequired = thisObj:FindLuaTableAttribute("BoatRequired")
  zoneObj = obj.Parent.Parent
  game.SubObject.SetEntityZoneHandler(thisObj, zoneObj)
  sonMarker = game.LargeInteger.HashString(5)
  game.SubObject.Sleep(obj)
end
function OnStart(level, obj)
  if enabled then
    Enable()
  else
    Disable()
  end
end
function OnSaveCheckpoint(level, obj)
  return {enabled = enabled}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  enabled = savedInfo.enabled
end
function Enable()
  enabled = true
  zoneObj:ShowEntityVolume()
end
function Disable()
  enabled = false
  zoneObj:HideEntityVolume()
end
local SetContext = function(newContext)
  if CheckIsBoatRequired() then
    if newContext == "KeepCurrentContext" then
      return
    elseif newContext == "ClearContext" then
      son:CallScript("ClearBehaviorContext")
    elseif newContext == "Boat_LookAt_Auto" then
      son:CallScript("EnterBehaviorContext", contextlist[GetDirectionalBoatLookAt()])
    else
      son:CallScript("EnterBehaviorContext", contextlist[newContext])
    end
  end
end
function OnMarkerEnterZone(level, scriptObj, volumeGameObject, markerGameObject, markerId)
  if inZone == false and (sonMarker == markerId or sonMarker == game.LargeInteger.HashString(tostring(markerId))) then
    SetupContextBanter()
    SetContext(contextEnter)
    inZone = true
  end
end
function OnMarkerExitZone(level, scriptObj, volumeGameObject, markerGameObject, markerId)
  if inZone == true and (sonMarker == markerId or sonMarker == game.LargeInteger.HashString(tostring(markerId))) then
    SetContext(contextExit)
    LD.EnableContextBehaviorBanter()
    inZone = false
  end
end
function SetupContextBanter()
  if contextBanterEnabled then
    LD.EnableContextBehaviorBanter()
  else
    LD.DisableContextBehaviorBanter()
  end
end
function CheckIsBoatRequired()
  if boatRequired then
    return game.Boat.GetPlayerBoat() ~= nil
  else
    return true
  end
end
function GetDirectionalBoatLookAt()
  if boatRequired and game.Boat.GetPlayerBoat() ~= nil then
    local fromSonToEvent = thisObj:GetWorldPosition() - son:GetWorldPosition()
    local sonLeft = -game.Player.FindPlayer():GetWorldLeft()
    local leftToOffsetDot = sonLeft:Dot(fromSonToEvent:Normalized())
    local toLeftSide = 0 < leftToOffsetDot
    if toLeftSide then
      return "Boat_LookAt_Left"
    else
      return "Boat_LookAt_Right"
    end
  end
end
