local LD = require("design.LevelDesignLibrary")
local timers = require("level.timer")
local monitors = require("level.MonitorLibrary")
local mpicon = require("ui.mpicon")
local thisObj, thisLevel, player, sonRangeMonitor, frontInteractZone
local interactComplete = false
local tripTychBanterBranch
local interactActive = false
local mainBlockStarted, enabled, son, startsEnabled, triptychCompletedTimer
local triptychCompleted = false
local banterConvoPlayed
local interactWasAborted = false
local config
local banterFirstStart = "triptych_first_start"
local banterSubsequentStart = "triptych_sub_start"
local banterBreakout = "triptych_breakout"
local banterInteractBlock, journalUpdateID
local breakOutDistance = 20
local triptychFX
local started = false
local journal
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  triptychCompletedTimer = StartLevelTimer(30, ConvoDone)
  triptychCompletedTimer:Stop()
  player = game.Player.FindPlayer()
  son = game.AI.FindSon()
  triptychFX = obj:FindSingleGOByName("Tryptich_Light_Burst")
  frontInteractZone = LD.CreateInteractZone_Standard_180(obj, "promptJoint")
  LD.OverrideInteractZoneTags(frontInteractZone, "NotWhileSonInteracting", true)
  if frontInteractZone.SetRequiresCriticalBanterComplete then
    frontInteractZone:SetRequiresCriticalBanterComplete(true)
  end
  startsEnabled = obj:GetLuaTableAttribute("startsEnabled")
  banterInteractBlock = obj:GetLuaTableAttribute("banterInteractBlock")
  journalUpdateID = obj:GetLuaTableAttribute("journalUpdateID")
  config = obj:FindLuaTableAttribute("config")
  if startsEnabled then
    enabled = true
  else
    enabled = false
  end
  if config == "bergelmir" then
    thisObj:SetCharacterConfig("bergelmir")
  elseif config == "solargram" then
    thisObj:SetCharacterConfig("solargramAndManagarm")
  elseif config == "surtr" then
    thisObj:SetCharacterConfig("surtr")
  elseif config == "groa" then
    thisObj:SetCharacterConfig("groa")
  elseif config == "thamur" then
    thisObj:SetCharacterConfig("thamur")
    breakOutDistance = 6
  elseif config == "jormungandr" then
    thisObj:SetCharacterConfig("jormungandr")
  elseif config == "thrym" then
    thisObj:SetCharacterConfig("thrym")
  elseif config == "tyr" then
    thisObj:SetCharacterConfig("tyr")
    thisObj:StartAnimation({
      Animation = "envTriptychOpenIdle"
    })
  elseif config == "ymir" then
    thisObj:SetCharacterConfig("ymir")
  elseif config == "hrungnir" then
    thisObj:SetCharacterConfig("brawler")
  elseif config == "skadi" then
    thisObj:SetCharacterConfig("skadi")
  elseif config == "starkadr" then
    thisObj:SetCharacterConfig("starkadr")
  end
  journal = obj:FindSingleGOByName("sonJournal00")
  game.SubObject.Sleep(obj)
end
function OnStart(level, obj)
  if enabled and not triptychCompleted then
    if config == "thamur" and game.Wallets.GetResourceValue("HERO", "Tryptich_Thamur") > -1 then
      DisableTriptych()
      thisObj:StartAnimation({
        Animation = "envTriptychOpenIdle"
      })
    else
      EnableTriptych()
    end
  elseif triptychCompleted then
    DisableTriptych()
    thisObj:StartAnimation({
      Animation = "envTriptychOpenIdle"
    })
  else
    DisableTriptych()
  end
  SoundInit()
  if journal ~= nil then
    journal:Hide()
  end
  QuestFixUp()
end
function OnUseWorld(level, obj)
  if frontInteractZone:PlayerCanInteract() and son ~= nil and son:IsAvailableForSync() == true and not son:IsInteracting() then
    son:RequestInteract(obj, frontInteractZone)
    player:RequestInteract(obj, frontInteractZone)
  end
end
function OnInteractStart(level, obj, creature)
  if not started then
    sonRangeMonitor = monitors.CreateDistanceMonitor(player, obj)
    sonRangeMonitor:OnFartherThan(breakOutDistance, StartAbort)
    StartPlayerInteract()
    started = true
  end
end
function OnInteractAbort(level, obj, creature)
end
function OnInteractFinish(level, obj, creature)
end
function OnInteractDone(level, obj, creature)
  print("got interact done msg", creature:GetName())
  if creature:GetName() == "son00" then
    game.Interact.EnableTags("NotWhileLoreReadActive")
  end
end
function QuestFixUp()
  if triptychCompleted == true and journalUpdateID ~= nil and not game.Wallets.HasResource("HERO", journalUpdateID) then
    triptychCompleted = false
    thisObj:JumpAnimationToFrame(0, {
      Animation = "envTriptychOpen"
    })
    thisObj:PauseAnimation()
    EnableTriptych()
  end
end
function SpawnJournal()
  if journal ~= nil then
    journal:Show()
    journal:Unparent()
  end
end
function ResetJournal()
  if journal ~= nil then
    journal:Hide()
    thisObj:AddChild(journal)
  end
end
function StartPlayerInteract()
  thisObj:HideNavObstacle()
  LD.PlaySingleSynchMove_KratosObject(thisObj, "synchJoint", "Triptych Open", "BRA_TriptychEnter", "envTriptychOpen", frontInteractZone, true)
  frontInteractZone:Disable()
  triptychCompleted = true
  if son.OwnedPOI and son.OwnedPOI.Type == "ContextAction" then
    son.OwnedPOI:SendEvent("CA_Interrupt")
  end
  LD.ExtractAndExecuteCallbacksForEvent(thisLevel, thisObj, thisObj:FindLuaTableAttribute("Event_OnTriptychStarted"), "Triptych Started")
  print(thisObj, "GOT START FROM GENERIC SUB OBJECT.....")
end
function StartMainBanterBlock()
  if not mainBlockStarted then
    mainBlockStarted = true
    game.Audio.PlayBanter(banterInteractBlock, ConvoDone)
    triptychCompletedTimer:Start()
  end
end
function LuaHook_StartSonSync()
  PlayBanterStart()
  SpawnJournal()
  SyncSonAndJournal()
end
function SyncSonAndJournal()
  local aiPuppeteer = game.Puppeteer.NewForce(thisObj, "LD Lib - Sync And Play Branch", son)
  local slaveTable = {}
  if journal ~= nil then
    slaveTable = {
      {
        Slave = journal,
        Anim = "envTriptychEnter"
      }
    }
  end
  aiPuppeteer:Sync("BRA_TriptychEnter", false, slaveTable, "synchJoint")
  game.Interact.DisableTags("NotWhileLoreReadActive")
  timers.StartLevelTimer(0.1, function()
    local sonSyncJointIndex = thisObj:GetJointIndex("sonSyncJoint")
    if son ~= nil and sonSyncJointIndex ~= nil then
      son:Warp(thisObj:GetWorldJointPosition(sonSyncJointIndex), thisObj:GetWorldJointForward(sonSyncJointIndex))
    end
  end)
  aiPuppeteer:OnComplete(function()
    ResetJournal()
    if aiPuppeteer ~= nil then
      aiPuppeteer:Clear()
      aiPuppeteer = nil
    end
  end)
end
function ConvoDone()
  triptychCompletedTimer:Stop()
  if interactWasAborted == false then
    banterConvoPlayed = true
    LD.ExtractAndExecuteCallbacksForEvent(thisLevel, thisObj, thisObj:GetLuaTableAttribute("Event_OnTriptychCompleted"), "Triptych Completed Normally")
    SonAbortedInteract()
    UpdateJournal()
  end
end
function LuaHook_TurnOffFX()
  if triptychFX ~= nil then
    triptychFX:Hide()
  end
end
function LuaHook_OpenTriptych()
  PlaySoundOnTriptychOpen()
end
function UpdateJournal()
  journalUpdateID = string.gsub(journalUpdateID, "%s+", "")
  LD.UpdateJournal(journalUpdateID, 0)
  if journalUpdateID == "Tryptich_Jormungandr" and game.Level.GetVariable("CompletedCineNumber") >= 340 then
    game.Wallets.AddResource("HERO", "Tryptich_Jormungandr_PostBoat", 1)
  end
  if journalUpdateID == "Tryptich_Thamur" then
    game.Wallets.AddResource("HERO", "Tryptich_Thamur_PostBoat", 1)
  end
  if journalUpdateID ~= "Tryptich_Tyr" then
    TrophyUpdate()
    IncrementQuest()
  end
  game.SubObject.SoftSave(thisObj)
end
function TrophyUpdate()
  game.Wallets.AddResource("HERO", "TryptichMarker", 1)
  if game.Wallets.GetResourceValue("HERO", "TryptichMarker") == 12 then
    AwardTrophy()
  end
end
function AwardTrophy()
  game.UnlockTrophy(33)
end
function StartAbort()
  interactWasAborted = true
  triptychCompletedTimer:Stop()
  LD.ExtractAndExecuteCallbacksForEvent(thisLevel, thisObj, thisObj:GetLuaTableAttribute("Event_OnTriptychAbort"), "Triptych Aborted")
  SonAbortedInteract()
end
function SonAbortedInteract()
  sonRangeMonitor:Stop()
  son:TriggerMoveEvent("abortInteract")
  if not son:HasMarker("exitingInteract") and not son:PickupIsAcquired("InteractAbort") then
    son:PickupAcquire("InteractAbort")
  end
  if not banterConvoPlayed then
    game.Audio.PlayBanter(banterBreakout)
    UpdateJournal()
  end
end
function Abort()
  if started and interactWasAborted == false then
    StartAbort()
  end
end
function EnableTriptych()
  if triptychCompleted == false then
    enabled = true
    frontInteractZone:Enable()
    if triptychFX ~= nil then
      triptychFX:Show()
    end
  end
end
function DisableTriptych()
  enabled = false
  frontInteractZone:Disable()
  if triptychFX ~= nil then
    triptychFX:Hide()
  end
end
function PlayBanterStart()
  if LD.GetEntityVariable("GLO_UsedFirstTriptych") == false then
    game.Audio.PlayBanter(banterFirstStart, StartMainBanterBlock)
    LD.SetEntityVariable("GLO_UsedFirstTriptych", true)
  else
    game.Audio.PlayBanter(banterSubsequentStart, StartMainBanterBlock)
  end
end
function IncrementQuest()
  local questState = game.QuestManager.GetQuestState("Quest_Triptychs_Parent")
  if questState == "Inactive" then
    game.QuestManager.StartQuest("Quest_Triptychs_Parent")
  end
  game.QuestManager.IncrementQuestProgress("Quest_Triptychs_Objective", 1)
end
local triptychEmitter
local triptychOnOpenSoundEvent = "SND_MECH_Triptych_Open"
function SoundInit()
  triptychEmitter = thisObj:FindSingleSoundEmitterByName("SNDTriptych")
end
function PlaySoundOnTriptychOpen()
  LD.PlaySound(triptychEmitter, triptychOnOpenSoundEvent)
end
function OnSaveCheckpoint(level, obj)
  return {enabled = enabled, triptychCompleted = triptychCompleted}
end
function OnRestoreCheckpoint(level, obj, tab)
  enabled = tab.enabled
  triptychCompleted = tab.triptychCompleted
end
