local LD = require("design.LevelDesignLibrary")
local thisObj, thisLevel, leftRuneRead, rightRuneRead, leftFire, rightFire, leftRune, rightRune, startInteractionCallbacks, endInteractionCallbacks, failLanguageCheckCallbacks, partialFailLanguageCheckCallbacks, noSoftSave, state
local states = {
  ENABLED = 1,
  DISABLED = 2,
  INTERACTED = 3
}
local attributes
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  attributes = obj:GetLuaTableAttributes({
    "DoNotSoftSave",
    "StartInteractionCallbacks",
    "EndInteractionCallbacks",
    "FailLanguageCheckCallbacks",
    "PartialFailLanguageCheckCallbacks",
    "LeftRune_FXObject",
    "RightRune_FXObject",
    "StartEnabled",
    "RealmTower"
  })
  noSoftSave = attributes.DoNotSoftSave
  startInteractionCallbacks = attributes.StartInteractionCallbacks
  if startInteractionCallbacks then
    startInteractionCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, startInteractionCallbacks)
  end
  endInteractionCallbacks = attributes.EndInteractionCallbacks
  if endInteractionCallbacks then
    endInteractionCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, endInteractionCallbacks)
  end
  failLanguageCheckCallbacks = attributes.FailLanguageCheckCallbacks
  if failLanguageCheckCallbacks then
    failLanguageCheckCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, failLanguageCheckCallbacks)
  end
  partialFailLanguageCheckCallbacks = attributes.PartialFailLanguageCheckCallbacks
  if partialFailLanguageCheckCallbacks then
    partialFailLanguageCheckCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, partialFailLanguageCheckCallbacks)
  end
  leftFire = thisObj:FindSingleGOByName("LeftBrazier"):FindSingleGOByName("brazierfire3")
  leftRuneRead = thisObj:FindSingleGOByName("LeftSonReadRune").Child:FindSingleGOByName("GenericSonInteract").Child
  leftRune = thisLevel:GetGameObject(attributes.LeftRune_FXObject).Child
  rightFire = thisObj:FindSingleGOByName("RightBrazier"):FindSingleGOByName("brazierfire3")
  rightRuneRead = thisObj:FindSingleGOByName("RightSonReadRune").Child:FindSingleGOByName("GenericSonInteract").Child
  rightRune = thisLevel:GetGameObject(attributes.RightRune_FXObject).Child
  game.SubObject.Sleep(obj)
  game.SubObject.SetForgetOnCheckpoint(obj)
  if state ~= states.INTERACTED then
    UnlightFires()
  end
  local startEnabled = attributes.StartEnabled
  if startEnabled then
    state = states.ENABLED
  else
    state = states.DISABLED
  end
  attributes.DoNotSoftSave = nil
  attributes.StartInteractionCallbacks = nil
  attributes.EndInteractionCallbacks = nil
  attributes.FailLanguageCheckCallbacks = nil
  attributes.PartialFailLanguageCheckCallbacks = nil
  attributes.LeftRune_FXObject = nil
  attributes.RightRune_FXObject = nil
  SoundInit()
end
function OnSaveCheckpoint(level, obj)
  return {state = state}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  state = savedInfo.state
end
function SoftSave(level, obj)
  if noSoftSave ~= true then
    print("soft save occurred")
    game.SubObject.SoftSave(thisObj)
  end
end
function OnStart(level, obj)
  if state == states.INTERACTED then
    Disable()
    LightFires()
    HideRunes()
    return
  elseif state == states.ENABLED then
    Enable()
    PauseRunes()
  else
    Disable()
    PauseRunes()
  end
end
function Enable()
  if state ~= states.INTERACTED then
    state = states.ENABLED
  end
  leftRuneRead.LuaObjectScript.Enable()
  rightRuneRead.LuaObjectScript.Enable()
end
function Disable()
  if state ~= states.INTERACTED then
    state = states.DISABLED
  end
  leftRuneRead.LuaObjectScript.Disable()
  rightRuneRead.LuaObjectScript.Disable()
end
function LightFires()
  leftFire:Show()
  rightFire:Show()
  PlaySoundOnBraziersLit()
end
function UnlightFires()
  leftFire:Hide()
  rightFire:Hide()
  StopSoundOnBraziersUnlit()
end
function PauseRunes()
  leftRune:JumpAnimToFrame(0)
  rightRune:JumpAnimToFrame(0)
  leftRune:PauseAnim()
  rightRune:PauseAnim()
end
function PlayRunes()
  leftRune:PlayAnimToEnd()
  rightRune:PlayAnimToEnd()
  PlaySoundOnRunesActivation()
end
function HideRunes()
  leftRune:Hide()
  rightRune:Hide()
end
function EnableAfterDelay()
  leftRuneRead.LuaObjectScript.Disable()
  rightRuneRead.LuaObjectScript.Disable()
  leftRuneRead.Parent.Parent.LuaObjectScript.EnableAfterDelay()
  rightRuneRead.Parent.Parent.LuaObjectScript.EnableAfterDelay()
end
function OnBrazierReadingStarted()
  if startInteractionCallbacks then
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, startInteractionCallbacks)
  end
end
function OnBrazierReadingFinished()
  print("Test Stage 3")
  local _, progress = game.QuestManager.GetQuestProgressAndGoal("Quest_Labor_LightBrazier")
  local firstTime = progress < 1
  Disable()
  LightFires()
  PlaySoundOnBrazierIgnition()
  if endInteractionCallbacks then
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, endInteractionCallbacks)
  end
  local questState = game.QuestManager.GetQuestState("Quest_Labor_LightBrazier_Parent")
  if questState == "Inactive" then
    game.QuestManager.StartQuest("Quest_Labor_LightBrazier_Parent")
  end
  game.QuestManager.IncrementQuestProgress("Quest_Labor_LightBrazier", 1)
  state = states.INTERACTED
  SoftSave()
  if firstTime then
    game.Audio.PlayBanter("Brazier_Light_First_Lit", FirstTImeFollowupOne)
  else
    SubsequentBraziersLit()
  end
end
function FirstTImeFollowupOne()
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  if 330 <= cineNumber then
    game.Audio.PlayBanter("Brazier_Light_Subsequent_Mimir")
  else
    game.Audio.PlayBanter("Brazier_Light_First_Kratos", FirstTImeFollowupTwo)
  end
end
function FirstTImeFollowupTwo()
  game.Audio.PlayBanter("Brazier_Light_First_Kratos")
end
function OnBrazierReadingInterrupted()
  if state == states.ENABLED then
    Enable()
  else
    Disable()
  end
end
function OnFail()
  if failLanguageCheckCallbacks then
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, failLanguageCheckCallbacks)
  end
  EnableAfterDelay()
end
function OnPartialFail()
  if partialFailLanguageCheckCallbacks then
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, partialFailLanguageCheckCallbacks)
  end
  EnableAfterDelay()
end
function RealmSpecificBanter()
  PlayRunes()
  local realm = tostring(attributes.RealmTower)
  if realm == "Asgard" then
    game.Audio.PlayBanter("Brazier_Realm_Asgard", OnBrazierReadingFinished)
  elseif realm == "Svartalfheim" then
    game.Audio.PlayBanter("Brazier_Realm_Svartalfheim", OnBrazierReadingFinished)
  elseif realm == "Alfheim" then
    game.Audio.PlayBanter("Brazier_Realm_Alfheim", OnBrazierReadingFinished)
  elseif realm == "Muspelheim" then
    game.Audio.PlayBanter("Brazier_Realm_Muspelheim", OnBrazierReadingFinished)
  elseif realm == "Vanaheim" then
    game.Audio.PlayBanter("Brazier_Realm_Vanaheim", OnBrazierReadingFinished)
  elseif realm == "Helheim" then
    game.Audio.PlayBanter("Brazier_Realm_Helheim", OnBrazierReadingFinished)
  elseif realm == "Jotunheim" then
    game.Audio.PlayBanter("Brazier_Realm_Jotunheim", OnBrazierReadingFinished)
  elseif realm == "Niflheim" then
    game.Audio.PlayBanter("Brazier_Realm_Niflheim", OnBrazierReadingFinished)
  end
end
function SubsequentBraziersLit()
  local _, progress = game.QuestManager.GetQuestProgressAndGoal("Quest_Labor_LightBrazier")
  local cineNumber = game.Level.GetVariable("CompletedCineNumber")
  local explorationValks = game.Level.GetVariable("ValkyrieMuspSeen") and game.Level.GetVariable("ValkyrieNifSeen")
  if explorationValks == true then
    game.Audio.SetBanterFact("ExplorationValksSeen", true)
  else
    game.Audio.SetBanterFact("ExplorationValksSeen", false)
  end
  if 330 <= cineNumber and progress ~= 8 then
    if progress == 7 and cineNumber < 515 then
      game.Audio.PlayBanter("Brazier_Light_PreJotunheim", PreJotunheimBanter)
    else
      game.Audio.PlayBanter("Brazier_Light_Subsequent_Mimir")
    end
  elseif progress == 8 then
    FinalBrazierCheck()
  end
end
function PreJotunheimBanter()
  game.Audio.PlayBanter("Brazier_Light_Subsequent_Mimir")
end
function FinalBrazierCheck()
  local _, progress = game.QuestManager.GetQuestProgressAndGoal("Quest_Valkyrie_Sisters_Objective02")
  local queenState = game.QuestManager.GetQuestState("Quest_Valkyrie_Queen_Kill")
  if progress < 1 then
    game.Audio.PlayBanter("Brazier_Complete_None")
  elseif 0 < progress and progress < 8 then
    game.Audio.PlayBanter("Brazier_Complete_Some")
  end
  if queenState == "Complete" then
    game.Audio.PlayBanter("Brazier_Complete_All")
  end
end
function SetRequiresCriticalBanterComplete()
  rightRuneRead.LuaObjectScript.GetInteractZone():SetRequiresCriticalBanterComplete(true)
  leftRuneRead.LuaObjectScript.GetInteractZone():SetRequiresCriticalBanterComplete(true)
end
local brazierSoundEmitters = {}
local brazierFireSoundEvent = "SND_AMB_EMIT_Fire_Tyrs_Braziers_Cal100_LP"
local brazierIgnitionSoundEvent = "SND_AMB_EMIT_Fire_Tyrs_Braziers_Ignite_Cal100"
local runeSoundEmitters = {}
local runeBurnAwaySoundEvent = "SND_MAG_Rune_Read_Burn_Away_LP"
function SoundInit()
  table.insert(brazierSoundEmitters, thisObj:FindSingleGOByName("LeftBrazier"):FindSingleSoundEmitterByName("SNDRealmTowerBrazierFire"))
  table.insert(brazierSoundEmitters, thisObj:FindSingleGOByName("RightBrazier"):FindSingleSoundEmitterByName("SNDRealmTowerBrazierFire"))
  table.insert(runeSoundEmitters, thisObj:FindSingleGOByName("LeftBrazier"):FindSingleSoundEmitterByName("SNDRealmTowerBrazierRunes"))
  table.insert(runeSoundEmitters, thisObj:FindSingleGOByName("RightBrazier"):FindSingleSoundEmitterByName("SNDRealmTowerBrazierRunes"))
end
function PlaySoundOnBrazierIgnition()
  for _, brazierEmitter in ipairs(brazierSoundEmitters) do
    LD.PlaySound(brazierEmitter, brazierIgnitionSoundEvent)
  end
end
function PlaySoundOnBraziersLit()
  for _, brazierEmitter in ipairs(brazierSoundEmitters) do
    LD.PlayRestartableSoundLoop(brazierEmitter, brazierFireSoundEvent)
  end
end
function StopSoundOnBraziersUnlit()
  for _, brazierEmitter in ipairs(brazierSoundEmitters) do
    LD.StopRestartableSoundLoop(brazierEmitter, brazierFireSoundEvent)
  end
end
function PlaySoundOnRunesActivation()
  for _, runeEmitter in ipairs(runeSoundEmitters) do
    LD.PlaySoundOnFrame(runeEmitter, leftRune, runeBurnAwaySoundEvent, 35, "forward")
    LD.StopSoundOnFrame(runeEmitter, leftRune, runeBurnAwaySoundEvent, 178, "forward")
  end
end
