local LD = require("design.LevelDesignLibrary")
local timers = require("level.timer")
local thisObj, thisLevel, player, interactZone, heroPuppeteer, synchJointIndex, kratosAxe, kratosAxeJointIndex, centerFreezeBreakableComponent, breakableIceObj, frostMesh, centerMesh, tendonFreezeFX
local struggleInProgress = false
local baseFrostMaterial, centerStalkBlend
local animState = 0
local lowerHiveTendril, upperHiveTendril, enabled, parentFXGroup, childTendonFreezeFX, outerCageOne_IsBroken, outerCageTwo_IsBroken, outerCageBreakTwo, skipCombatTag, exitIs180, interactAutoEnableAllowed, interactionComplete, interactionOnStart, interactionOnFinish, interactionOnAbort
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  player = game.Player.FindPlayer()
  interactZone = game.InteractZone.New(obj, "promptJoint")
  interactZone:SetHintAngle(180)
  interactZone:SetAngle(145)
  interactZone:SetYRange(2)
  interactZone:SetXZRange(4)
  interactZone:SetTags("NotInRageMode")
  Disable()
  breakableIceObj = thisObj:FindSingleGOByName("CenterFreezePillar")
  centerFreezeBreakableComponent = breakableIceObj.Child:GetBreakable()
  breakableIceObj:Hide()
  skipCombatTag = obj:FindLuaTableAttribute("skipCombatTag")
  if skipCombatTag then
    interactZone:SetTags("HiveCombatOverride")
  else
    interactZone:SetTags("NotInCombat")
  end
  enabled = obj:GetLuaTableAttribute("startEnabled")
  exitIs180 = obj:GetLuaTableAttribute("exitIs180")
  frostMesh = thisObj:FindSingleGOByName("FrostMesh")
  centerMesh = thisObj:FindSingleGOByName("CenterMesh")
  lowerHiveTendril = thisObj:FindSingleGOByName("lowerHiveTendril00")
  upperHiveTendril = thisObj:FindSingleGOByName("upperHiveTendril00")
  outerCageBreakTwo = thisObj:FindSingleGOByName("OuterCageBreakTwo")
  synchJointIndex = thisObj:GetJointIndex("synchJoint")
  print("sync index", synchJointIndex)
  parentFXGroup = obj:FindSingleGOByName("hive_tendon_freeze")
  parentFXGroup:Hide()
  childTendonFreezeFX = parentFXGroup:FindSingleGOByName("hive_tendon_freeze_rt")
  SoundInit()
end
function OnFirstStart(level, obj)
  timers.StartLevelTimer(0.1, DelayedHide)
end
function OnStart(level, obj)
  if not outerCageTwo_IsBroken then
    outerCageBreakTwo:Hide()
  elseif outerCageTwo_IsBroken and not interactionComplete then
    PlayTendonRetractAnim()
    Enable()
  end
  if not outerCageTwo_IsBroken then
    PlayTendonIdleAnim()
  end
  if not interactionComplete and frostMesh ~= nil then
    timers.StartLevelTimer(0.1, DelayedHide)
  end
  if interactionComplete then
    StopIdleLoopSound()
    lowerHiveTendril:Hide()
    upperHiveTendril:Hide()
  end
end
function OnUpdate(level, obj)
  if struggleInProgress then
    UpdateIce()
  end
end
function OnUseWorld(level, obj)
  if interactZone:PlayerCanInteract() then
    player:RequestInteract(thisObj)
  end
end
function DelayedHide()
  HideFrostMesh()
  breakableIceObj:Hide()
end
function PerformInteraction()
  LD.PlaySingleSynchMove_KratosObject(thisObj, "synchJoint", "Axe Freeze TNF", "BRA_TNF_TendonFreezeEnter", "", interactZone, false, "Axe")
end
function EnableInteract()
  enabled = true
  if outerCageTwo_IsBroken then
    Enable()
  end
end
function DisableInteract()
  enabled = false
end
function Enable()
  if enabled then
    interactZone:Enable()
  end
end
function Disable()
  interactZone:Disable()
end
function OnInteractStart(level, obj, creature)
  if thisObj:FindLuaTableAttribute("interactionOnStart") ~= nil then
    LD.ExtractAndExecuteCallbacksForEvent(thisLevel, thisObj, thisObj:GetLuaTableAttribute("interactionOnStart"), "Freeze Started")
  end
  PerformInteraction()
end
function OnInteractAbort(level, obj, creature)
  if thisObj:FindLuaTableAttribute("interactionOnAbort") ~= nil then
    LD.ExtractAndExecuteCallbacksForEvent(thisLevel, thisObj, thisObj:GetLuaTableAttribute("interactionOnAbort"), "Abort Started")
  end
  Enable()
end
function OnInteractFinish(level, obj, creature)
end
function OnInteractDone(level, obj, creature)
end
function UpdateIce()
  if player:IsPlayingMove("MOV_TNF_TendonFreezeStruggle") then
    local strugglePercent = player:GetActiveMovePercent()
    local mult = 5 ^ (2 or 0)
    local adjustedStrugglePercent = math.floor(strugglePercent * mult + 0.5) / mult
    local adjustedFrostPercent = adjustedStrugglePercent * 100
    frostMesh:JumpAnimToFrame(adjustedFrostPercent)
    if childTendonFreezeFX ~= nil then
      childTendonFreezeFX:SetWorldPosition(kratosAxe:GetWorldJointPosition(kratosAxeJointIndex))
      childTendonFreezeFX:JumpAnimationToFrame(adjustedFrostPercent)
    end
    if kratosAxe ~= nil then
      player:CallScript("LuaHook_SetFrostPercent", adjustedFrostPercent)
    end
  end
end
function LuaHook_StuggleStarted()
  if struggleInProgress == false then
    struggleInProgress = true
    frostMesh:Show()
    frostMesh:JumpAnimToFrame(0)
    frostMesh:PauseAnim()
    Disable()
  end
  if kratosAxe == nil and player ~= nil then
    for weaponInfo in player:IterateActiveWeapons() do
      local gameobj = weaponInfo.Weapon
      if gameobj:GetName() == "axe00" then
        kratosAxe = gameobj
      end
      print("GAME OBJ", kratosAxe)
    end
  end
  if kratosAxe ~= nil then
    kratosAxeJointIndex = kratosAxe:GetJointIndex("weaponEmbedJoint")
    childTendonFreezeFX:Show()
    childTendonFreezeFX:SetWorldPosition(kratosAxe:GetWorldJointPosition(kratosAxeJointIndex))
  end
  AudioEnterFreezeBreakStateB()
end
function PlayStruggleFXToEnd()
  if childTendonFreezeFX then
    childTendonFreezeFX:PlayAnimToEnd()
  end
end
function KillStruggleFX()
  if childTendonFreezeFX then
    childTendonFreezeFX:Hide()
  end
end
function StartEndBreakable()
  struggleInProgress = false
  interactionComplete = true
  enabled = false
  PlayTendonBreakAnim()
  PlayTendrilDeathSound()
  breakableIceObj:Show()
  frostMesh:Hide()
  centerMesh:Hide()
  if centerFreezeBreakableComponent.Broken == false then
    centerFreezeBreakableComponent:Break()
  end
end
function LuaHook_ShatterCenter()
  KillStruggleFX()
  StartEndBreakable()
end
function LuaHook_EndTriggered()
  print("GOT END TRIGTGER")
  LuaHookPlaySoundFreezeBreakStop()
  if not exitIs180 then
    ClearPuppeteer()
    if thisObj:FindLuaTableAttribute("interactionOnFinish") ~= nil then
      LD.ExtractAndExecuteCallbacksForEvent(thisLevel, thisObj, thisObj:GetLuaTableAttribute("interactionOnFinish"), "Freeze Ended")
    end
  end
end
function LuaHook_AxePulledOut()
  KillStruggleFX()
end
function LuaHook_WinEntered()
  PlayStruggleFXToEnd()
end
function LuaHook_AltEndTriggered()
  if exitIs180 and thisObj:FindLuaTableAttribute("interactionOnFinish") ~= nil then
    LD.ExtractAndExecuteCallbacksForEvent(thisLevel, thisObj, thisObj:GetLuaTableAttribute("interactionOnFinish"), "Freeze Ended")
  end
end
function LuaHook_StartDecay()
  upperHiveTendril.Child:StartAnimation({
    Animation = "ChopSueyDecayMatFX"
  })
  upperHiveTendril.Child:StartAnimation({
    Animation = "LPHiveFleshyStaticMatDecayFX"
  })
  lowerHiveTendril.Child:StartAnimation({
    Animation = "ChopSueyDecayMatFX"
  })
  lowerHiveTendril.Child:StartAnimation({
    Animation = "LPHiveFleshyStaticMatDecayFX"
  })
  thisObj:HideCollision()
end
function LuaHook_Freeze_Failed()
  frostMesh:PlayAnimToEnd()
  frostMesh:SetAnimRate(-2)
  frostMesh:OnAnimationDone(thisObj, "HideFrostMesh", {Force = true})
  KillStruggleFX()
  struggleInProgress = false
  Enable()
end
function HideFrostMesh()
  frostMesh:ClearAllAnimCallbacks()
  frostMesh:JumpAnimToFrame(0)
  frostMesh:PauseAnim()
  frostMesh:Hide()
end
function ClearPuppeteer()
  if heroPuppeteer ~= nil then
    heroPuppeteer:Clear()
    heroPuppeteer:DetachPuppet()
    heroPuppeteer = nil
  end
end
function LuaHook_Exit180()
  player:TriggerMoveEvent("Exit180")
end
function FirstCageBroken()
  outerCageOne_IsBroken = true
  outerCageTwo_IsBroken = true
  LD.BreakObject(outerCageBreakTwo)
  timers.StartLevelTimer(0.5, BreakSecondCage)
end
function CageDamaged()
  PlayTendonHitReactAnim()
end
function SecondCageBroken()
  print("doing nothing now, keeping callback")
end
function BreakSecondCage()
  PlayTendonRetractAnim()
  Enable()
  PlayOuterCageBrokenSound()
end
function CenterBroken()
  print("main center part broken")
end
function PlayTendonHitReactAnim()
  lowerHiveTendril.Child:StartAnimation({
    Animation = "envHiveTendrilHit",
    Tween = 0.1
  })
  lowerHiveTendril.Child:JumpAnimationToFrame(0, {
    Animation = "envHiveTendrilHit"
  })
  lowerHiveTendril.Child:PlayAnimationToEnd({
    Animation = "envHiveTendrilHit"
  })
  upperHiveTendril.Child:StartAnimation({
    Animation = "envHiveTendrilHit",
    Tween = 0.1
  })
  upperHiveTendril.Child:JumpAnimationToFrame(0, {
    Animation = "envHiveTendrilHit"
  })
  upperHiveTendril.Child:PlayAnimationToEnd({
    Animation = "envHiveTendrilHit"
  })
end
function PlayTendonIdleAnim()
  lowerHiveTendril.Child:StartAnim("envHiveTendrilIdle")
  upperHiveTendril.Child:StartAnim("envHiveTendrilIdle")
  lowerHiveTendril.Child:PlayAnimCycle()
  upperHiveTendril.Child:PlayAnimCycle()
end
function PlayTendonRetractAnim()
  lowerHiveTendril.Child:StartAnim("envHiveTendrilKill")
  upperHiveTendril.Child:StartAnim("envHiveTendrilKill")
  upperHiveTendril.Child:OnAnimDone(thisObj, "PlayTendonRetractIdleAnim")
end
function PlayTendonRetractIdleAnim()
  upperHiveTendril.Child:ClearAllAnimCallbacks()
  lowerHiveTendril.Child:StartAnim("envHiveTendrilDead")
  upperHiveTendril.Child:StartAnim("envHiveTendrilDead")
end
function PlayTendonBreakAnim()
  lowerHiveTendril.Child:StartAnim("evnHiveTendrilBreak")
  upperHiveTendril.Child:StartAnim("evnHiveTendrilBreak")
  lowerHiveTendril:SetAnimRate(1)
  upperHiveTendril:SetAnimRate(1)
end
function EnableAlfOverride()
  game.Interact.DisableTags("HiveCombatOverride")
end
function DisableAlfOverride()
  game.Interact.EnableTags("HiveCombatOverride")
end
function OnSaveCheckpoint(level, obj)
  return {
    enabled = enabled,
    outerCageOne_IsBroken = outerCageOne_IsBroken,
    outerCageTwo_IsBroken = outerCageTwo_IsBroken,
    interactionComplete = interactionComplete
  }
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  outerCageOne_IsBroken = savedInfo.outerCageIsBroken
  outerCageTwo_IsBroken = savedInfo.outerCageTwo_IsBroken
  enabled = savedInfo.enabled
  interactionComplete = savedInfo.interactionComplete
  if outerCageTwo_IsBroken and not interactionComplete then
    Enable()
  elseif interactionComplete then
    upperHiveTendril:Hide()
    lowerHiveTendril:Hide()
    thisObj:Hide()
  end
end
local soundEmitter
function SoundInit()
  soundEmitter = thisObj:FindSingleSoundEmitterByName("SNDHiveTendon")
  PlayIdleLoopSound()
  print("Tendon Freeze Emitter - ", soundEmitter)
end
function PlayIdleLoopSound()
  LD.PlaySound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Break_Idle_LP")
end
function StopIdleLoopSound()
  LD.StopSound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Break_Idle_LP")
end
function AudioEnterFreezeBreakStateA()
  LD.PlaySound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Break_State_A")
end
function PlayTendrilDeathSound()
  LD.PlaySound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Death")
end
function AudioEnterFreezeBreakStateB()
  LD.PlaySound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Break_State_B")
end
function AudioEnterFreezeBreakStateC()
  LD.PlaySound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Break_State_C")
end
function PlayOuterCageBrokenSound()
  LD.PlaySound(soundEmitter, "SND_BRK_Hive_Tendon_Outer_Layer")
  print("Tendon Freeze - Cage Broken")
end
function LuaHookPlaySoundFreezeFail()
  LD.StopSound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Light_LP")
  LD.PlaySound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Fail")
  LD.StopSound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Break_LP")
  AudioEnterFreezeBreakStateA()
  PlayIdleLoopSound()
  print("Tendon Freeze - Failed")
end
function LuaHookPlaySoundFreezeEnter()
  LD.PlaySound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Start")
  StopIdleLoopSound()
  AudioEnterFreezeBreakStateA()
  LD.PlaySound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Break_LP")
  print("Tendon Freeze - Enter")
end
function LuaHookPlayFreezeSound()
  LD.PlaySound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Light_LP")
end
function LuaHookStopFreezeSound()
  LD.StopSound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Light_LP")
end
function LuaHookPlaySoundFreezeSuccess()
  LD.StopSound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Light_LP")
  LD.PlaySound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Win")
  print("Tendon Freeze - Success")
end
function LuaHookPlaySoundFreezeBreakStop()
  LD.PlaySound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Break_End")
  LD.StopSound(soundEmitter, "SND_TNF_Alf000_Hive_Tendon_Break_LP")
end
function LuaHookAudioEnterFreezeBreakStateC()
  AudioEnterFreezeBreakStateC()
end
