local LD = require("design.LevelDesignLibrary")
local timer = require("level.timer")
local uiCalls = require("ui.uicalls")
local TUT = require("game.GlobalTutorials")
local drivenObject, childObject, drivenObjectIdle01Anim, drivenObjectIdle02Anim, drivenObject01HitAnim, drivenObjectStage01To02Anim, drivenObject02HitAnim, drivenObjectExitAnim, thisLevel, player
local enabled = true
local hitStage = 0
local hitMax = 4
local heroPuppeteer, frontInteractZone
local firstInteractStarted = false
local fxState01, fxState02, fxSpawn01SpawnPos
local exitInProgress = false
local exitIs180
local objectDestroyed = false
stage1Callbacks = nil
stage2Callbacks = nil
stage3Callbacks = nil
finalStageCallbacks = nil
initCallBacks = nil
function OnScriptLoaded(level, obj)
  drivenObject = obj
  thisLevel = level
  player = game.Player.FindPlayer()
  drivenObjectIdle01Anim = drivenObject:GetLuaTableAttribute("drivenObjectIdle01Anim")
  drivenObjectIdle02Anim = drivenObject:GetLuaTableAttribute("drivenObjectIdle02Anim")
  drivenObject01HitAnim = drivenObject:GetLuaTableAttribute("drivenObject01HitAnim")
  drivenObjectStage01To02Anim = drivenObject:GetLuaTableAttribute("drivenObjectStage01To02Anim")
  drivenObject02HitAnim = drivenObject:GetLuaTableAttribute("drivenObject02HitAnim")
  drivenObjectExitAnim = drivenObject:GetLuaTableAttribute("drivenObjectExitAnim")
  if obj:FindLuaTableAttribute("childObject") ~= nil then
    local childObjectName = drivenObject:FindLuaTableAttribute("childObject")
    childObject = drivenObject:FindSingleGOByName(childObjectName)
  end
  if obj:FindLuaTableAttribute("fxState01") ~= nil then
    local fxState01Name = drivenObject:FindLuaTableAttribute("fxState01")
    fxState01 = drivenObject:FindSingleGOByName(fxState01Name)
  end
  if obj:GetLuaTableAttribute("exitIs180") ~= nil and obj:GetLuaTableAttribute("exitIs180") ~= "" then
    exitIs180 = obj:GetLuaTableAttribute("exitIs180")
  end
  if obj:FindLuaTableAttribute("fxState02") ~= nil then
    local fxState02Name = drivenObject:FindLuaTableAttribute("fxState02")
    fxState02 = drivenObject:FindSingleGOByName(fxState02Name)
  end
  print("Driven Object name is....", drivenObject)
  frontInteractZone = LD.CreateInteractZone_Standard_180(drivenObject, "promptJoint")
  frontInteractZone:SetHintXZRange(5)
  frontInteractZone:SetDebugOffset(0, 0, 2)
  InitializeObject()
  SoundInit()
  game.SubObject.Sleep(obj)
end
function OnStart(level, obj)
  if enabled then
    EnableInteract()
  else
    DisableInteract()
  end
end
function OnUseWorld(level, obj)
  if frontInteractZone:PlayerCanInteract() then
    player:RequestInteract(drivenObject, frontInteractZone)
  end
end
function OnInteractStart(level, obj)
  local SyncToInteract = function()
    LD.PlaySingleSynchMove_KratosObject(drivenObject, "synchJointAlt", "Generic Axe Chop", "BRA_AxeChop_GenericEnter", "", frontInteractZone, false, "Axe")
    if not firstInteractStarted then
      firstInteractStarted = true
      Play01IdleAnim()
    end
  end
  if player:GetCurrentWeapon() == "Blades" then
    local sheathePup = game.Puppeteer.NewForce(obj, "Sheathe Blades before Axe-Chop", player)
    sheathePup:WeaponEquip({
      weaponMode = "Bare",
      use_completion_percentage = true,
      completion_percentage = 1
    })
    sheathePup:OnComplete(function()
      if sheathePup ~= nil then
        sheathePup:Clear()
        sheathePup = nil
      end
      SyncToInteract()
    end)
  else
    SyncToInteract()
  end
end
function LuaHook_ObjectArrivalDone()
  DisableInteract()
  TUT.AxeSwingTutorial()
end
function EnableCinematicTrigger()
  if heroPuppeteer ~= nil then
    heroPuppeteer:Clear()
    heroPuppeteer:DetachPuppet()
    heroPuppeteer = nil
  end
end
function LH_OnLightHit(level, obj, creature)
  print("got light hit msg")
  IncrementHitStage()
end
function LH_OnLightHitEnter(level, obj, creature)
end
function LH_OnHeavyHit(level, obj, creature)
  print("got light hit msg")
  IncrementHitStage()
end
function LH_OnHeavyHitEnter(level, obj, creature)
end
function OnLightHit(level, obj, creature)
  print("got light rage hit msg")
  IncrementHitStage()
end
function OnLightEnter(level, obj, creature)
  print("got opening hit msg")
end
function OnExitHitEnter(level, obj, creature)
  print("got light rage hit msg")
end
function OnExitHit(level, obj, creature)
  print("got opening hit msg")
  TriggerFinalBreak()
  if player:PickupIsActive("AxeChopThresholdReachedAlt") then
    player:PickupRelinquish("AxeChopThresholdReachedAlt")
  end
  if player:PickupIsActive("AxeChopThresholdReached") then
    player:PickupRelinquish("AxeChopThresholdReached")
  end
end
function OnExitStart(level, obj, creature)
end
function InitializeObject()
  if drivenObject:FindLuaTableAttribute("initCallbacks") ~= nil then
    LD.ExtractAndExecuteCallbacksForEvent(thisLevel, drivenObject, drivenObject:FindLuaTableAttribute("initCallbacks"), "On init")
  end
  if childObject ~= nil then
    childObject.LuaObjectScript.Init()
  end
end
function IncrementHitStage()
  TUT.HideTutorial()
  if 3 <= hitStage and not exitInProgress then
    print("giving pickup")
    exitInProgress = true
    if exitIs180 then
      player:PickupAcquire("AxeChopThresholdReachedAlt")
    else
      player:PickupAcquire("AxeChopThresholdReached")
    end
  end
  if hitStage < hitMax then
    hitStage = hitStage + 1
    CheckBreakableStage()
    print("HIT STAGE IS...............", hitStage)
  end
end
function CheckBreakableStage()
  if hitStage >= hitMax then
    print("no")
    TriggerFxMinor()
  elseif hitStage == 1 then
    TriggerFirstBreak()
  elseif hitStage == 2 then
    TriggerSecondBreak()
  elseif hitStage == 3 then
    Trigger02HitReact()
  end
end
function Play01IdleAnim()
  if drivenObjectIdle01Anim ~= nil and drivenObjectIdle01Anim ~= "" then
    drivenObject:StartAnim(drivenObjectIdle01Anim)
  end
end
function Play01HitAnim()
  if drivenObject01HitAnim ~= nil and drivenObject01HitAnim ~= "" then
    drivenObject:StartAnim(drivenObject01HitAnim)
  end
end
function Play01to02Anim()
  if drivenObjectStage01To02Anim ~= nil and drivenObjectStage01To02Anim ~= "" then
    drivenObject:StartAnim(drivenObjectStage01To02Anim)
    drivenObject:OnAnimDone(drivenObject, "Play02IdleAnim")
  end
end
function Play02IdleAnim()
  if drivenObjectIdle02Anim ~= nil and drivenObjectIdle02Anim ~= "" then
    drivenObject:StartAnim(drivenObjectIdle02Anim)
  end
end
function Play02HitAnim()
  if drivenObject02HitAnim ~= nil and drivenObject02HitAnim ~= "" then
    drivenObject:StartAnim(drivenObject02HitAnim)
  end
end
function PlayExitAnim()
  if drivenObjectStage01To02Anim ~= nil then
    drivenObject:StartAnim(drivenObjectExitAnim)
    drivenObject:PlayAnimToEnd()
  end
end
function TriggerFxMinor()
  local fx = game.FX.Spawn(fxState01:GetName(), thisLevel, {AutoDelete = true})
  local spawnPos = drivenObject:GetWorldJointPosition(drivenObject:GetJointIndex("fxSpawnPoint"))
  fx:SetWorldPosition(spawnPos)
end
function TriggerFxMajor()
  if fxState02 == nil then
    local fx1 = game.FX.Spawn(fxState01:GetName(), thisLevel, {AutoDelete = true})
    local spawnPos = drivenObject:GetWorldJointPosition(drivenObject:GetJointIndex("fxSpawnPoint"))
    fx1:SetWorldPosition(spawnPos)
    local fx2 = game.FX.Spawn(fxState01:GetName(), thisLevel, {AutoDelete = true})
    local spawnPos2 = drivenObject:GetWorldJointPosition(drivenObject:GetJointIndex("fxSpawnPoint1"))
    fx2:SetWorldPosition(spawnPos2)
    local fx3 = game.FX.Spawn(fxState01:GetName(), thisLevel, {AutoDelete = true})
    local spawnPos3 = drivenObject:GetWorldJointPosition(drivenObject:GetJointIndex("fxSpawnPoint2"))
    fx3:SetWorldPosition(spawnPos3)
  else
    local fx02 = game.FX.Spawn(fxState02:GetName(), thisLevel, {AutoDelete = true})
    local spawnPosState02 = drivenObject:GetWorldJointPosition(drivenObject:GetJointIndex("fxSpawnPoint2"))
    fx02:SetWorldPosition(spawnPosState02)
  end
end
function TriggerFirstBreak()
  print("first break triggered")
  Play01HitAnim()
  TriggerFxMinor()
  PlaySoundOnImpact()
  if drivenObject:FindLuaTableAttribute("stage1Callbacks") ~= nil then
    LD.ExtractAndExecuteCallbacksForEvent(thisLevel, drivenObject, drivenObject:FindLuaTableAttribute("stage1Callbacks"), "axe chop stage 1 reached")
  end
  if childObject ~= nil then
    childObject.LuaObjectScript.Stage1()
  end
end
function TriggerSecondBreak()
  Play01to02Anim()
  TriggerFxMinor()
  PlaySoundOnImpact()
  if drivenObject:FindLuaTableAttribute("stage2Callbacks") ~= nil then
    LD.ExtractAndExecuteCallbacksForEvent(thisLevel, drivenObject, drivenObject:FindLuaTableAttribute("stage2Callbacks"), "axe chop stage 2 reached")
  end
  if childObject ~= nil then
    childObject.LuaObjectScript.Stage2()
  end
end
function Trigger02HitReact()
  Play02HitAnim()
  TriggerFxMinor()
  PlaySoundOnImpact()
  if drivenObject:FindLuaTableAttribute("stage3Callbacks") ~= nil then
    LD.ExtractAndExecuteCallbacksForEvent(thisLevel, drivenObject, drivenObject:FindLuaTableAttribute("stage3Callbacks"), "axe chop stage 2 reached")
  end
  if childObject ~= nil then
    childObject.LuaObjectScript.Stage3()
  end
end
function TriggerFinalBreak()
  PlayExitAnim()
  TriggerFxMajor()
  PlaySoundOnFinal()
  objectDestroyed = true
  print("final break triggered")
  if drivenObject:FindLuaTableAttribute("finalStageCallbacks") ~= nil then
    LD.ExtractAndExecuteCallbacksForEvent(thisLevel, drivenObject, drivenObject:FindLuaTableAttribute("finalStageCallbacks"), "axe chop stage 2 reached")
  end
  if childObject ~= nil then
    childObject.LuaObjectScript.FinalStage()
  end
end
function EnableInteract()
  enabled = true
  frontInteractZone:Enable()
end
function DisableInteract()
  enabled = false
  frontInteractZone:Disable()
end
function OnInteractAbort(level, obj, creature)
  print("got interact Abort msg")
end
function OnInteractFinish(level, obj, creature)
  print("got interact finish msg")
end
function OnInteractDone(level, obj, creature)
  TUT.HideTutorial()
  if not objectDestroyed then
    EnableInteract()
  end
  print("got interact done msg")
end
function OnSaveCheckpoint(level, obj)
  return {
    hitStage = hitStage,
    enabled = frontInteractZone:IsEnabled()
  }
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  enabled = savedInfo.enabled
  hitStage = savedInfo.hitStage
end
local soundEmitter
local soundEvents = {
  OnImpact = "SND_BRK_Hive_Root_Axe_Chop_01",
  OnImpactFinal = "SND_BRK_Hive_Root_Axe_Chop_02"
}
function SoundInit()
  soundEmitter = drivenObject:FindSingleSoundEmitterByName("SNDHiveTendon")
end
function SoundSetup(sounds)
  if sounds ~= nil then
    if sounds.SoundEmitter ~= nil then
      soundEmitter = drivenObject:FindSingleSoundEmitterByName(sounds.SoundEmitter)
    end
    for key in pairs(soundEvents) do
      for newKey, newValue in pairs(sounds) do
        if newKey == key and newValue ~= nil and newValue ~= "" then
          soundEvents[key] = newValue
        end
      end
      LD.SoundDebug(tostring(key) .. ": " .. tostring(soundEvents[key]))
    end
  end
end
function PlaySoundOnImpact()
  LD.PlaySound(soundEmitter, soundEvents.OnImpact)
end
function PlaySoundOnFinal()
  LD.PlaySound(soundEmitter, soundEvents.OnImpactFinal)
end
