local LD = require("design.LevelDesignLibrary")
require("level.timer")
local thisObj, thisLevel, enabled, onCrystalFullyLitEvents, onCrystalFullyUnlitEvents, socketed, fullyLitCallbacks, fullyUnlitCallbacks, subFX, nestedFX, fullyLitMesh
local crystalActive = false
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  obj:AddMarker("SonTarget")
  local parentObj = obj.Parent
  if obj:FindLuaTableAttribute("CrystalFullyLit") ~= nil then
    onCrystalFullyLitEvents = LD.ExtractCallbacksForEvent(level, obj, obj:FindLuaTableAttribute("CrystalFullyLit"))
  end
  if obj:FindLuaTableAttribute("CrystalFullyUnlit") ~= nil then
    onCrystalFullyUnlitEvents = LD.ExtractCallbacksForEvent(level, obj, obj:FindLuaTableAttribute("CrystalFullyUnlit"))
  end
  enabled = obj:GetLuaTableAttribute("Enabled")
  fullyLitMesh = obj:FindSingleGOByName("FullyLitMesh")
  print("fully lit and new mesh is...", fullyLitMesh)
  subFX = obj:FindSingleGOByName("bifrost_crystal_temporal_active")
  subFX:Hide()
  print("SUB FX IS.....", subFX)
  nestedFX = subFX:FindSingleGOByName("bifrost_temporal_active")
  SoundInit()
  game.SubObject.Sleep(obj)
end
function OnFirstStart(level, obj)
  SetCrystalObjectStates(0)
end
function OnHitByArrow(level, go, arrow_owner, arrow_go, arrow_tweak)
  if arrow_go:GetName() == "bifrost_projectile" then
    ActivatePulse()
    PlayFailedEffectAlt()
  end
end
function ActivatePulse()
  local objPos = thisObj:GetWorldPosition()
  local pulseFX = game.FX.Spawn("bifrost_crystal_temporal_pulse", thisLevel, {AutoDelete = true})
  pulseFX:SetWorldPosition(objPos)
  local concussionParams = {
    Tweak = "CNC_Light_Crystal_Pulse_Large",
    WorldLocation = objPos,
    GameObject = thisObj,
    EnemyId = game.AI.FindSon():GetID()
  }
  game.Combat.PlayConcussion(concussionParams)
  PlayLightPulseSound()
end
function OnHitByWeapon(level, obj, weapon, attacker)
  if attacker == game.Player.FindPlayer() then
    game.Audio.IncrementBanterFact("HitBifrost", 1, 10)
    game.Audio.PlayBanterNonCritical("ca_carry_crystal_weapon_hit")
  end
end
function OnFullyLit(functionToCall)
  if fullyLitCallbacks == nil then
    fullyLitCallbacks = {}
  end
  table.insert(fullyLitCallbacks, functionToCall)
end
function FireFullyLitCallbacks()
  if fullyLitCallbacks ~= nil then
    for i = 1, #fullyLitCallbacks do
      fullyLitCallbacks[i]()
    end
  end
end
function OnFullyUnlit(functionToCall)
  if fullyUnlitCallbacks == nil then
    fullyUnlitCallbacks = {}
  end
  table.insert(fullyUnlitCallbacks, functionToCall)
end
function FireFullyUnlitCallbacks()
  if fullyUnlitCallbacks ~= nil then
    for i = 1, #fullyUnlitCallbacks do
      fullyUnlitCallbacks[i]()
    end
  end
end
function SetCrystalObjectStates(data)
  if data == 0 then
    print("Temporal Crystal State 0")
    fullyLitMesh:Hide()
    fullyLitMesh:PauseAnimation()
    crystalActive = false
    FireFullyUnlitCallbacks()
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, onCrystalFullyUnlitEvents, "CrystalFullyUnlitEvents")
    SetSoundBifrostInactive()
  elseif data == 1 then
    print("Temporal Crystal State 1")
    fullyLitMesh:Hide()
    subFX:Hide()
    fullyLitMesh:PauseAnimation()
    SetSoundBifrostInactive()
  elseif data == 2 then
    print("Temporal Crystal State 2")
    fullyLitMesh:Show()
    fullyLitMesh:PlayAnimationToEnd()
    nestedFX:JumpAnimationToFrame(0)
    nestedFX:PlayAnimationToFrame(20)
    nestedFX:OnAnimationDone(thisObj, "CrystalFXPeaked", {Force = true})
    nestedFX:Show()
    crystalActive = true
    FireFullyLitCallbacks()
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, onCrystalFullyLitEvents, "CrystalFullyLitEvents")
    SetSoundBifrostActive()
  elseif data == 3 then
    print("Temporal Crystal State 3")
    nestedFX:JumpAnimationToFrame(0)
    nestedFX:PlayAnimationToFrame(20)
    nestedFX:Show()
  else
    fullyLitMesh:Hide()
    fullyLitMesh:PauseAnimation()
    SetSoundBifrostInactive()
  end
end
function PlayFailedEffectAlt()
  local failFX = game.FX.Spawn("bifrost_temporal_fail", thisLevel, {
    GameObject = thisObj,
    Scale = 2.5,
    Joint = "fxJoint",
    AutoDelete = true
  })
end
function SetActive(active)
  crystalActive = active
end
function Enable()
  enabled = true
end
function Disable()
  enabled = false
end
function HideObjectCollision()
  thisObj:HideCollision()
end
function ShowObjectCollision()
  thisObj:ShowCollision()
end
function CrystalFXPeaked()
  nestedFX:ClearAllAnimationCallbacks()
  nestedFX:PlayAnimationToFrame(50)
end
function OnSaveCheckpoint(level, obj)
  print("Crystal  - Saving")
  return {
    crystalActive = crystalActive,
    socketed = socketed,
    enabled = enabled
  }
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  enabled = savedInfo.enabled
  crystalActive = savedInfo.crystalActive
  socketed = savedInfo.socketed
  print("Crystal - Restore Checkpoint", crystalActive, socketed)
  if crystalActive then
    SetCrystalObjectStates(2)
  elseif not crystalActive and socketed then
    SetCrystalObjectStates(1)
  else
    SetCrystalObjectStates(0)
  end
end
local soundEmitter, soundEmitterName
local SNDBifrostActiveLP = "SND_MAG_Temporal_Light_Crystal_Active_LP"
local SNDBifrostInactiveLP = "SND_MAG_Temporal_Light_Crystal_Inactive_LP"
local SNDBifrostPulse = "SND_MAG_Temporal_Light_Torches_Active_Hit_Sparks"
function SoundInit()
  soundEmitterName = thisObj:FindLuaTableAttribute("soundEmitterName")
  if soundEmitterName ~= nil and soundEmitterName ~= "" then
    soundEmitter = thisObj:FindSingleSoundEmitterByName(soundEmitterName)
  else
    soundEmitter = thisObj.SoundEmitters[1]
  end
end
function SetSoundBifrostActive()
  LD.StopRestartableSoundLoop(soundEmitter, SNDBifrostInactiveLP)
  LD.PlayRestartableSoundLoop(soundEmitter, SNDBifrostActiveLP)
end
function SetSoundBifrostInactive()
  LD.StopRestartableSoundLoop(soundEmitter, SNDBifrostActiveLP)
  LD.PlayRestartableSoundLoop(soundEmitter, SNDBifrostInactiveLP)
end
function PlayLightPulseSound()
  LD.PlaySound(soundEmitter, SNDBifrostPulse)
end
