local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local timers = require("level.timer")
local actor = require("narrative.actor")
local checkpoint = require("level.checkpoint")
local uiCalls = require("ui.uicalls")
local thisObj, thisLevel, baldurActor, magniActor, modiActor, mimirActor
local playedBaldurVsMimir = false
local actorCreated = false
local voicesPlaying = false
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  game.SubObject.Sleep(thisObj)
end
function OnStart(level, obj)
  if game.Level.GetVariable("CompletedCineNumber") >= 310 then
    SpawnHeadlessMimir()
  end
end
function SpawnHeadlessMimir()
  mimirActor = actor.Actor.New("Mimir")
  SetMimirSpawnFunction()
  local seq = ND.CreateCineSequence(thisLevel, thisObj, "Always Spawn Mimir")
  seq:SpawnActorAndWait(mimirActor)
  seq:Do(function()
    local pos = thisObj:GetWorldJointPosition(thisObj:GetJointIndex("MimirBody_ZeroJoint"))
    local dir = thisObj:GetWorldJointForward(thisObj:GetJointIndex("MimirBody_ZeroJoint"))
    mimirActor:GetCreature():Warp(pos, dir)
  end)
  seq:WaitSeconds(1000)
  seq:StartSequence()
end
function OnSaveCheckpoint(level, obj)
  return {baldurVsMimir01Played = playedBaldurVsMimir}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  playedBaldurVsMimir = savedInfo.baldurVsMimir01Played
end
function CreateActors()
  if not actorCreated then
    actorCreated = true
    baldurActor = actor.Actor.New("Baldur")
    magniActor = actor.Actor.New("Magni")
    modiActor = actor.Actor.New("Modi")
    if mimirActor == nil then
      mimirActor = actor.Actor.New("Mimir")
      SetMimirSpawnFunction()
    end
    SetSpawnFunctions()
  end
end
function FindMimir()
  local objArray = game.World.FindGameObjectsByMarker("Mimir")
  for _, obj in ipairs(objArray) do
    if obj:GetCreature() ~= nil and obj:GetCreature():GetAI() ~= nil then
      return obj:GetCreature():GetAI()
    end
  end
  return nil
end
function SetSpawnFunctions()
  baldurActor:SetSpawnFunction(function()
    local cineWAD = game.FindLevel("Peak740_c310_MimirIntro")
    local baldur = ND.FindBaldur()
    if baldur == nil then
      return ND.SpawnAIAtJoint(cineWAD, "POI_BaldurVsMimir", "Baldur_Start", "CRT_Baldur00", "BRA_BaldurVsMimirIdle", "Baldur")
    end
    return baldur
  end)
  magniActor:SetSpawnFunction(function()
    local cineWAD = game.FindLevel("Peak740_c310_MimirIntro")
    local magni = ND.FindMagni()
    if magni == nil then
      return ND.SpawnAIAtJoint(cineWAD, "POI_BaldurVsMimir", "Magni_Start", "CRT_Magni00", "BRA_BaldurVsMimirIdle", "Magni")
    end
    return magni
  end)
  modiActor:SetSpawnFunction(function()
    local cineWAD = game.FindLevel("Peak740_c310_MimirIntro")
    local modi = ND.FindModi()
    if modi == nil then
      return ND.SpawnAIAtJoint(cineWAD, "POI_BaldurVsMimir", "Modi_Start", "CRT_Modi00", "BRA_BaldurVsMimirIdle", "Modi")
    end
    return modi
  end)
end
function SetMimirSpawnFunction()
  mimirActor:SetSpawnFunction(function()
    local mimir = FindMimir()
    if mimir == nil then
      local spawnBranch
      if game.Level.GetVariable("CompletedCineNumber") < 310 then
        spawnBranch = "BRA_IdleWithHead"
      else
        spawnBranch = "BRA_IdleWithoutHead"
      end
      mimir = ND.SpawnAIAtJoint(thisLevel, "Cine_MimirIntro", "Mimir_Start", "CRT_Mimir00", spawnBranch, "Mimir")
    end
    return mimir
  end)
end
function VoicesCarry_Play()
  if not voicesPlaying or FindMimir() == nil then
    voicesPlaying = true
    local seq = ND.CreateCineSequence(thisLevel, thisObj, "VoicesCarry")
    CreateActors()
    seq:SpawnActorAndWait(mimirActor)
    seq:WaitFrames(1)
    seq:Do(function()
      game.Audio.PlayBanter("445_VoicesCarry_1")
    end)
    seq:StartSequence()
  end
end
function BaldurVsMimir_Pre2_Play()
  local seq = ND.CreateCineSequence(thisLevel, thisObj, "BaldurVsMimir_Pre2")
  CreateActors()
  GameObjects.Btr_VoicesCarry:Hide()
  game.Compass.SetDesignerForcedHide(true)
  seq:SpawnActorAndWait(baldurActor)
  seq:Do(InterruptMimir)
  seq:Do(function()
    game.Audio.PlayBanter("BaldurVsMimir_Pre2", function()
      BuildBaldurVsMimirSeq()
    end)
  end)
  seq:StartSequence()
end
function InterruptMimir()
  if mimirActor:GetCreature() ~= nil then
    game.Audio.InterruptBanterOnCharacter("Mimir")
  end
end
function BuildBaldurVsMimirSeq()
  local seq = ND.CreateCineSequence(thisLevel, thisObj, "BaldurVsMimir")
  local actorTable = {
    {Actor = magniActor},
    {Actor = modiActor}
  }
  seq:SpawnActorAndWait(magniActor)
  seq:SpawnActorAndWait(modiActor)
  seq:SpawnActorAndWait(mimirActor)
  seq:Do(function()
    game.Audio.PlayBanter("BaldurVsMimir_01", function()
      playedBaldurVsMimir = true
    end)
  end)
  seq:ActorSync(baldurActor, {
    Slaves = actorTable,
    Branch = "BRA_BaldurVsMimirScene",
    ReferenceJoint = "BaldurVsMimir_SynchJoint"
  })
  seq:WaitForFunctionTrue(function()
    return playedBaldurVsMimir
  end)
  seq:StopPuppetingActor(baldurActor)
  seq:StopPuppetingActor(modiActor)
  seq:StopPuppetingActor(magniActor)
  seq:DespawnActor(baldurActor)
  seq:DespawnActor(modiActor)
  seq:DespawnActor(magniActor)
  seq:Do(UnlockBaldurBestiaryEntry)
  seq:StartSequence()
end
function isPOIDone()
  return playedBaldurVsMimir
end
function UnlockBaldurBestiaryEntry()
  local baldurBestiaryEntry = game.Wallets.GetResourceValue("HERO", "Bestiary_Unlock_Stranger")
  if 0 < baldurBestiaryEntry then
    game.Wallets.RemoveResource("HERO", "Bestiary_Unlock_Stranger", 1)
  end
  LD.UnlockBestiaryEntry("Bestiary_Unlock_Baldur")
end
