local LD = require("design.LevelDesignLibrary")
local timer = require("level.timer")
local thisLevel, thisObj, player, parentObject
local pickedUpByPlayer = false
local handle, frontInteractZone, heroPuppeteer, synchJointFacing, synchJointLocation, rumbleParams, shakeParams, controllerVibration, explosionFX, grenadeIdleFX, preDetonationFX, selfDestructWarningTimer, selfDestructTimer, disableInteractTimer, interactZoneTimer, onHitCallbacks
local destroyAboutToBeCalled = false
local selfDestructCooldown = 15
local selfDestructWarningCooldown = 9
local grenadeSoundEmitter
function OnScriptLoaded(level, obj)
  player = game.Player:FindPlayer()
  thisLevel = level
  thisObj = obj
  thisObj:AddMarker("CombatThrowable")
  handle = thisObj:GetJointIndex("handle1")
  onHitCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, thisObj:FindLuaTableAttribute("onHitGameObject"))
  selfDestructWarningTimer = StartLevelTimer(selfDestructWarningCooldown, SelfDestructWarning)
  selfDestructWarningTimer:Restart()
  selfDestructTimer = StartLevelTimer(selfDestructCooldown, SelfDestruct)
  selfDestructTimer:Restart()
  disableInteractTimer = StartLevelTimer(selfDestructCooldown - 0.75, DisableInteract)
  disableInteractTimer:Restart()
  frontInteractZone = LD.CreateInteractZone_Throwable_360(thisObj, "handle1")
  frontInteractZone:SetTags("CombatThrowable")
  frontInteractZone:SetOnScreenPercentWeight(0)
  local throwableIconTable = {
    normal = "WORLD_INTERACT_THROWABLE",
    unavailable = "WORLD_INTERACT_UNAVAILABLE",
    locked = "WORLD_INTERACT_LOCKED",
    hint = "WORLD_INTERACT_HINT_THROWABLE"
  }
  frontInteractZone:SetPromptIconSet(throwableIconTable)
  frontInteractZone:SetHintXZRange(20)
  grenadeIdleFX = game.FX.Spawn("Golem_HeatGrenade_FX", thisLevel, {
    GameObject = thisObj,
    Joint = "handle1",
    AutoDelete = true
  })
  rumbleParams = {EffectName = "FFB_MEDIUM", Duration = 0.1}
  shakeParams = {
    EffectName = "FSE_shake_temp_Generic_Large",
    Duration = 0.1
  }
  SoundInit()
  SoundPlaySpawn()
  SoundPlayLoop()
end
function LuaHook_SetParent(level, obj, parentObj)
  if parentObj ~= nil then
    parentObject = parentObj
  end
end
function LuaHookOnThrowRelease()
  game.Interact.EnableTags("CombatThrowable")
end
function PlayHitFXAndDestroy(level, obj)
  game.Interact.EnableTags("CombatThrowable")
  if thisObj ~= nil then
    local handlePos = thisObj:GetWorldJointPosition(handle)
    local player = game.Player.FindPlayer()
    if parentObject ~= nil then
      local concussionParamsPlayer = {
        Tweak = "CNC_GOLEM_GRENADE_PAYLOAD_PLAYER",
        WorldLocation = handlePos,
        Creature = parentObject,
        EnemyId = parentObject:GetID()
      }
      game.Combat.PlayConcussion(concussionParamsPlayer)
    end
    local concussionParamsAI = {
      Tweak = "CNC_GOLEM_GRENADE_PAYLOAD_AI",
      WorldLocation = handlePos,
      Creature = player,
      EnemyId = player:GetID()
    }
    game.Combat.PlayConcussion(concussionParamsAI)
    if pickedUpByPlayer then
      local concussionParamsGolem = {
        Tweak = "CNC_GOLEM_GRENADE_PAYLOAD_GOLEM",
        WorldLocation = handlePos,
        Creature = player,
        EnemyId = player:GetID()
      }
      game.Combat.PlayConcussion(concussionParamsGolem)
    end
    explosionFX = game.FX.Spawn("Golem_HeatGrenadeDetonate_FX", thisLevel, {AutoDelete = true})
    explosionFX:SetWorldPosition(handlePos)
    game.FX.SubmitEffect(rumbleParams)
    game.FX.SubmitEffect(shakeParams)
    SoundStopLoop()
  end
  game.Interact.EnableTags("CombatThrowable")
  DestroyThrowable()
end
function OnUseWorld(level, go)
  if frontInteractZone:PlayerCanInteract() then
    player:RequestInteract(thisObj)
  end
end
function LuaHookDrop()
  interactZoneTimer = timer.StartLevelTimer(1, InteractEnable)
  game.Interact.EnableTags("CombatThrowable")
end
function LuaHookSetThrowable()
  SetThrowable(thisObj)
  game.Interact.DisableTags("CombatThrowable")
end
function SetThrowable(obj)
  local throwableTemplate = {
    name = "Light",
    attachName = "ATT_Throwable",
    standardName = "Throwable",
    range = 15,
    maxThrowRange = 30,
    reticleOffset = 0.3,
    bounciness = 0.1,
    rotationSpeed = 0.1
  }
  thisObj = obj
  thisObj:ShowCollision()
  player = game.Player:FindPlayer()
  player:SetThrowable(thisObj, throwableTemplate, "reticle")
  frontInteractZone:Disable()
  pickedUpByPlayer = true
  if parentObject ~= nil then
    parentObject:CallScript("LuaHook_SetParamsFromGrenade")
  end
end
function OnInteractStart(level, obj, creature)
  player:MarkCurrentWeaponMode()
  if heroPuppeteer == nil then
    heroPuppeteer = game.Puppeteer.NewForce(thisObj, "Throwable Pickup", player)
  end
  heroPuppeteer:StartBranch("BRA_PickUpThrowable")
  heroPuppeteer:OnComplete(EndPickupThrowable)
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)
  print("got interact done msg")
end
function InteractEnable()
  game.Interact.EnableTags("CombatThrowable")
  if frontInteractZone == nil and thisObj == nil then
    return
  elseif destroyAboutToBeCalled == false then
    frontInteractZone:Enable()
  end
end
function DisableInteract()
  if frontInteractZone == nil and thisObj == nil then
    return
  else
    frontInteractZone:Disable()
  end
end
function EndPickupThrowable()
  if heroPuppeteer ~= nil then
    heroPuppeteer:Clear()
    heroPuppeteer:DetachPuppet()
    heroPuppeteer = nil
  end
end
function OnConcussionHit(level, go, attacker, hitflags, context)
end
function OnHitGameObject(level, gameObject, attacker, hitGameObject)
  if selfDestructWarningTimer ~= nil then
    selfDestructWarningTimer:Stop()
    selfDestructWarningTimer = nil
  end
  if selfDestructTimer ~= nil then
    selfDestructTimer:Stop()
    selfDestructTimer = nil
  end
  if disableInteractTimer ~= nil then
    disableInteractTimer:Stop()
    disableInteractTimer = nil
  end
  if interactZoneTimer ~= nil then
    interactZoneTimer:Stop()
    interactZoneTimer = nil
  end
  LD.ExecuteCallbacksForEvent(thisLevel, thisObj, onHitCallbacks, "combat throw hit something")
  PlayHitFXAndDestroy()
end
function SelfDestructWarning()
  if thisObj ~= nil then
    destroyAboutToBeCalled = true
    preDetonationFX = game.FX.Spawn("Golem_HeatGrenadePreDetonate_FX", thisLevel, {
      GameObject = thisObj,
      Joint = "handle1",
      AutoDelete = true
    })
  else
    print("myGO is nil")
  end
end
function SelfDestruct()
  if selfDestructWarningTimer ~= nil then
    selfDestructWarningTimer:Stop()
    selfDestructWarningTimer = nil
  end
  if selfDestructTimer ~= nil then
    selfDestructTimer:Stop()
    selfDestructTimer = nil
  end
  if disableInteractTimer ~= nil then
    disableInteractTimer:Stop()
    disableInteractTimer = nil
  end
  if interactZoneTimer ~= nil then
    interactZoneTimer:Stop()
    interactZoneTimer = nil
  end
  PlayHitFXAndDestroy()
end
function DestroyThrowable()
  if preDetonationFX ~= nil and preDetonationFX.Spawned then
    preDetonationFX:Remove()
  end
  if grenadeIdleFX ~= nil and grenadeIdleFX.Spawned then
    grenadeIdleFX:Remove()
  end
  thisObj:Destroy()
end
function SoundInit()
  grenadeSoundEmitter = thisObj:FindSingleSoundEmitterByName("SNDgolemGrenade")
end
function SoundPlaySpawn()
  if grenadeSoundEmitter ~= nil then
    LD.PlaySound(grenadeSoundEmitter, "SND_CHR_Golem_Shard_Spawn")
  end
end
function SoundPlayLoop()
  if grenadeSoundEmitter ~= nil then
    LD.PlaySound(grenadeSoundEmitter, "SND_CHR_Golem_Shard_LP")
  end
end
function SoundStopLoop()
  if grenadeSoundEmitter ~= nil then
    LD.StopSound(grenadeSoundEmitter, "SND_CHR_Golem_Shard_LP")
  end
end
function OnTeardown()
  if grenadeIdleFX ~= nil then
    grenadeIdleFX:Remove()
  end
  if preDetonationFX ~= nil then
    preDetonationFX:Remove()
  end
  if selfDestructWarningTimer ~= nil then
    selfDestructWarningTimer:Stop()
  end
  if selfDestructTimer ~= nil then
    selfDestructTimer:Stop()
  end
  if disableInteractTimer ~= nil then
    disableInteractTimer:Stop()
  end
  if interactZoneTimer ~= nil then
    interactZoneTimer:Stop()
  end
end
