local LD = require("design.LevelDesignLibrary")
local timers = require("level.timer")
local uiCalls = require("ui.uicalls")
local TUT = require("game.GlobalTutorials")
local player, thisObj, thisLevel, burnedOut, ignited, breakableComponent, tutorialDone, tutorialActive, onFullyLitEnterEvents, onBurnedOutEvents
local damageTakenAmount = 0
local damageOnHit
local burnThresholdStageOne = 2
local burnThresholdStageTwo = 10
local burnThresholdIgnite = 20
local fxStage01, fxStage01_B, fxStage01_C, fxStage02, fxStage02_B, fxStage02_C, fxIgnite, rumbleParams, shakeParams, shadowProxy
local hitByWeaponCount = 0
local isLargeType
function OnScriptLoaded(level, obj)
  player = game.Player.FindPlayer()
  thisObj = obj
  thisLevel = level
  breakableComponent = thisObj:GetBreakable()
  SoundInit()
  PlaySoundIdleLoop()
  if thisObj.Parent ~= nil then
    shadowProxy = thisObj.Parent:FindSingleGOByName("shadow_proxy")
  end
  game.SubObject.Sleep(thisObj)
  isLargeType = obj:FindLuaTableAttribute("isLargeType")
  rumbleParams = {
    EffectName = "FSE_shake_temp_Generic_Large",
    Duration = 0.4
  }
end
function OnStart(level, obj)
  if burnedOut then
    HideShadowProxy()
  end
end
function OnUseWorld(level, obj)
end
function OnHitByWeapon(level, obj, weapon, weaponOwnerCreature)
  if not ignited then
    if weapon:GetName() == "axe00" then
      game.Audio.IncrementBanterFact("HitGatedObject", 1, 10)
      game.Audio.PlayBanterNonCritical("ca_bramble_noblades")
    end
    if weapon:GetName() == "explosive00" then
      hitByWeaponCount = hitByWeaponCount + 1
      if hitByWeaponCount == 1 then
        TriggerBurnStage(1)
        PlayShakeAnim(1)
        CompleteBurnTutorial()
      else
        IgniteObject()
        ignited = true
        TriggerBurstFX(1.5)
        PlayShakeAnim(1)
      end
    end
  end
end
function OnBreakableDamaged(level, obj, attackerCreature, hitFlags, damage)
  if obj:HasHitFlag("HIT_BLADES", hitFlags) then
    damageOnHit = damage
    damageTakenAmount = damageTakenAmount + damageOnHit
    DamageCheck()
    CompleteBurnTutorial()
  elseif obj:HasHitFlag("HIT_SPECIAL", hitFlags) then
    local weapon = player:GetCurrentWeapon()
    if weapon ~= nil and weapon == "Blades" then
      damageOnHit = damage
      damageTakenAmount = damageTakenAmount + damageOnHit
      DamageCheck()
      CompleteBurnTutorial()
    end
  end
end
function OnBreakableBroken(level, obj)
  OnBurnedOut()
end
function DamageCheck()
  if damageTakenAmount >= burnThresholdStageOne and damageTakenAmount < burnThresholdStageTwo then
    TriggerBurnStage(1)
  elseif damageTakenAmount >= burnThresholdStageTwo and damageTakenAmount < burnThresholdIgnite then
    TriggerBurnStage(2)
  elseif damageTakenAmount >= burnThresholdIgnite then
    TriggerBurnStage(3)
  end
end
function TriggerBurnStage(stage)
  if stage == 1 then
    TriggerStage01FX()
    TriggerHitReact()
    Stage1Sounds()
  elseif stage == 2 then
    TriggerStage02FX()
    TriggerHitReact()
    Stage2Sounds()
  elseif stage == 3 then
    IgniteObject()
    Stage3Sounds()
  end
end
function IgniteObject()
  if thisObj == nil then
    return
  end
  if not ignited then
    ignited = true
    BreakObject()
    HideShadowProxy()
    TriggerIgniteFX()
    OnFullyLitEnter()
    game.Audio.PlayBanterNonCritical("ca_brambleburned_withson")
    StopSoundIdleLoop()
  end
end
function HideShadowProxy()
  if shadowProxy ~= nil then
    shadowProxy:HideBehaviors()
    shadowProxy:Hide()
  end
end
function BreakObject()
  if breakableComponent ~= nil and breakableComponent.Broken == false then
    breakableComponent:Break()
  end
end
function TriggerStage01FX()
  if fxStage01 == nil then
    if not isLargeType then
      fxStage01 = game.FX.Spawn("burnable_4x4_stage1", thisLevel, {
        GameObject = thisObj,
        Joint = "fxJoint",
        AutoDelete = true
      })
      thisObj:PlayAnimationToFrame(30, {
        Animation = "bramble_burn"
      })
      thisObj:PlayAnimToFrame(30)
    else
      fxStage01 = game.FX.Spawn("burnable_4x4_stage1", thisLevel, {
        GameObject = thisObj,
        Joint = "fxJoint",
        AutoDelete = true
      })
      fxStage01_B = game.FX.Spawn("burnable_4x4_stage1", thisLevel, {
        GameObject = thisObj,
        Joint = "fxJoint1",
        AutoDelete = true
      })
      fxStage01_C = game.FX.Spawn("burnable_4x4_stage1", thisLevel, {
        GameObject = thisObj,
        Joint = "fxJoint2",
        AutoDelete = true
      })
    end
  end
end
function TriggerStage02FX()
  if fxStage02 == nil then
    if fxStage01 ~= nil then
      fxStage01:Hide()
    end
    if fxStage01_B ~= nil then
      fxStage01_B:Hide()
    end
    if fxStage01_C ~= nil then
      fxStage01_C:Hide()
    end
    if not isLargeType then
      fxStage02 = game.FX.Spawn("burnable_4x4_stage2", thisLevel, {
        GameObject = thisObj,
        Joint = "fxJoint",
        AutoDelete = true
      })
      thisObj:PlayAnimationToFrame(60, {
        Animation = "bramble_burn"
      })
      thisObj:PlayAnimToFrame(60)
    else
      fxStage02 = game.FX.Spawn("burnable_4x4_stage2", thisLevel, {
        GameObject = thisObj,
        Joint = "fxJoint",
        AutoDelete = true
      })
      fxStage02_B = game.FX.Spawn("burnable_4x4_stage2", thisLevel, {
        GameObject = thisObj,
        Joint = "fxJoint1",
        AutoDelete = true
      })
      fxStage02_C = game.FX.Spawn("burnable_4x4_stage2", thisLevel, {
        GameObject = thisObj,
        Joint = "fxJoint2",
        AutoDelete = true
      })
    end
  end
end
function TriggerBurstFX(scale)
  local newScale = scale
  local burstFX = game.FX.Spawn("bramble_burst", thisLevel, {
    GameObject = thisObj,
    Scale = newScale,
    Joint = "fxJoint",
    AutoDelete = true
  })
end
function RampDown()
end
function TriggerIgniteFX()
  if fxIgnite == nil then
    if fxStage02 ~= nil then
      fxStage02:Hide()
    end
    if fxStage01 ~= nil then
      fxStage01:Hide()
    end
    if fxStage01_B ~= nil then
      fxStage01_B:Hide()
    end
    if fxStage01_C ~= nil then
      fxStage01_C:Hide()
    end
    if fxStage02_B ~= nil then
      fxStage02_B:Hide()
    end
    if fxStage02_C ~= nil then
      fxStage02_C:Hide()
    end
    if not isLargeType then
      fxIgnite = game.FX.Spawn("burnable4x4", thisLevel, {
        GameObject = thisObj,
        Follow = true,
        Joint = "fxJoint",
        AutoDelete = true
      })
      thisObj:JumpAnimationToFrame(60, {
        Animation = "bramble_burn"
      })
      thisObj:PlayAnimationToEnd({
        Animation = "bramble_burn"
      })
      thisObj:JumpAnimToFrame(60)
      thisObj:PlayAnimToFrame(100)
      game.FX.SubmitEffect(rumbleParams)
    else
      fxIgnite = game.FX.Spawn("burnable4x4", thisLevel, {
        GameObject = thisObj,
        Follow = true,
        Joint = "fxJoint",
        AutoDelete = true
      })
      local fxIgnite01 = game.FX.Spawn("burnable4x4", thisLevel, {
        GameObject = thisObj,
        Follow = true,
        Joint = "fxJoint1",
        AutoDelete = true
      })
      local fxIgnite02 = game.FX.Spawn("burnable4x4", thisLevel, {
        GameObject = thisObj,
        Follow = true,
        Joint = "fxJoint2",
        AutoDelete = true
      })
      thisObj:JumpAnimToFrame(60)
      thisObj:PlayAnimToFrame(100)
    end
  end
end
function TriggerHitReact()
  TriggerBurstFX(1)
  game.FX.SubmitEffect(rumbleParams)
  if damageOnHit ~= nil then
    if damageOnHit <= 5 then
      PlayShakeAnim(1.5)
    else
      PlayShakeAnim(0.75)
    end
  end
end
function PlayShakeAnim(speed)
  local speedToPlay
  if speed ~= nil then
    speedToPlay = speed
  else
    speedToPlay = 1
  end
  thisObj:JumpAnimationToFrame(0, {
    Animation = "bramble_shake"
  })
  thisObj:PlayAnimationToEnd({
    Animation = "bramble_shake",
    Rate = speedToPlay
  })
end
function OnFullyLitEnter()
  LD.ExtractAndExecuteCallbacksForEvent(thisLevel, thisObj, thisObj:GetLuaTableAttribute("Event_OnFullyLitEnter"), "Obj LIT Callback")
end
function OnBurnedOut()
  LD.ExtractAndExecuteCallbacksForEvent(thisLevel, thisObj, thisObj:GetLuaTableAttribute("Event_OnBurnedOut"), "Obj BURNED Callback")
end
function TriggerBurnTutorial()
  if not burnedOut and player ~= nil and player:PickupIsAcquired("Blades") and not game.Level.GetVariable("TUT_BurnableTutorialDone") then
    TUT.Burnables_Tutorial()
    tutorialActive = true
  end
end
function CloseBurnTutorial()
  if tutorialActive then
    uiCalls.UI_Event_TurnOffDesignerMessage()
    tutorialActive = false
  end
end
function CompleteBurnTutorial()
  if not tutorialDone then
    uiCalls.UI_Event_TurnOffDesignerMessage()
    game.Level.SetVariable("TUT_BurnableTutorialDone", true)
    tutorialDone = true
    tutorialActive = false
  end
end
function OnSaveCheckpoint(level)
  return {ignited = ignited, burnedOut = burnedOut}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  ignited = savedInfo.ignited
  burnedOut = savedInfo.burnedOut
end
local soundEmitter
local soundEvents = {
  isLooping = false,
  LoopIdle = "SND_BRK_Bramble_Idle_LP",
  OnBurn = "SND_BRK_Bramble_Hit_Burn",
  OnBurnIdle = "SND_BRK_Bramble_Burn_Glow_LP",
  OnBurnMusic = ""
}
local flammableType
function SoundInit()
  soundEmitter = thisObj:FindSingleSoundEmitterByName("SNDFlammableBramble")
  flammableType = thisObj:FindLuaTableAttribute("FlammableType")
  if flammableType ~= nil then
    local newSoundEvents = {}
    if flammableType == "bramble" then
      newSoundEvents = {
        OnBurn = "SND_BRK_Bramble_Hit_Burn",
        SoundEmitter = "SNDFlammableBramble"
      }
    end
    SoundSetup(newSoundEvents)
  end
end
function SoundSetup(sounds)
  if sounds ~= nil then
    if sounds.SoundEmitter ~= nil then
      soundEmitter = thisObj:FindSingleSoundEmitterByName(sounds.SoundEmitter)
    end
    for key, value 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(value))
    end
  end
end
function PlaySoundIdleLoop()
  LD.PlaySound(soundEmitter, soundEvents.LoopIdle)
end
function Stage1Sounds()
  LD.StopSound(soundEmitter, soundEvents.LoopIdle)
  LD.PlaySound(soundEmitter, soundEvents.OnBurnIdle)
  LD.PlaySound(soundEmitter, soundEvents.OnBurn)
end
function Stage2Sounds()
  LD.PlaySound(soundEmitter, soundEvents.OnBurn)
end
function Stage3Sounds()
  LD.PlaySound(soundEmitter, soundEvents.OnBurn)
end
function StopSoundIdleLoop()
  LD.StopSound(soundEmitter, soundEvents.OnBurnIdle)
  LD.PlaySound(soundEmitter, soundEvents.OnBurn)
  game.Audio.StartMusic(soundEvents.OnBurnMusic)
end
