local LD = require("design.LevelDesignLibrary")
local EC = require("design.Encounter")
local checkpoint = require("level.checkpoint")
local TUT = require("game.GlobalTutorials")
local timer = require("level.timer")
local uiCalls = require("ui.uicalls")
local CCOS = require("camera.camera_oneshot")
local thisLevel, player, son, pad
local camShakeLarge = {
  EffectName = "FSE_shake_temp_Generic_Large",
  Duration = 1
}
local ForceFeedbackRumble = {
  EffectName = "FFB_HEAVY_ATTACK",
  Duration = 1
}
local isBridgeLowered = false
local isReadyToCross = false
local sonBoost, wheelCrank, EV_Bridge
local isBridgePinned = false
local varSonByTheRope = false
local varKratosOnCrank = false
local varKratosSawCrank = false
local btrMadeItPlayed = false
local btrGoodIdeaPlayed = false
local btrEarlyAxeCallPlayed = false
local varSonCurrentFloor, varKratosCurrentFloor, bCasketBroken, Area_1_Encounter_1, camOneShotFollowSon
function OnScriptLoaded(level)
  thisLevel = level
  player = game.Player.FindPlayer()
  son = game.AI.FindSon()
  pad = player.Pad
  sonBoost = GameObjects.SonBoost.Child
  wheelCrank = GameObjects.BridgeWheelCrank.Child
  EV_Bridge = GameObjects.BridgeZone
end
function OnFirstStart(level, obj)
  bCasketBroken = false
end
function OnStart(level)
  SoundOnStart()
  Stop_SonChainDrop_Tutorial()
  StopBoostTutorial()
  GameObjects.NavObstacleA:HideNavObstacle()
  GameObjects.NavObstacleB:HideNavObstacle()
  GameObjects.Btr_LowerBridge:HideEntityVolume()
  GameObjects.Gear_IceSkirt:PlayAnimToEnd(-30)
  GameObjects.BtrZone_OthersOnTheRoad:HideEntityVolume()
  if game.Level.GetVariable("CompletedCineNumber") >= 110 then
    DisableCameraRecenter_LookToDestinationAfterMantle()
  end
end
function OnStartGameFromThisLevel(level)
  LD.SetEntityVariable("FOR_BaldurBossDone", true)
  LD.SetEntityVariable("CompletedCineNumber", 100)
  LD.SetEntityVariable("CAL_LightingState", 5)
end
function OnUpdate(level)
  if camOneShotFollowSon ~= nil then
    camOneShotFollowSon:Update()
  end
end
function OnSaveCheckpoint(level)
  local savedInfo = {
    levelstate = checkpoint.Save(),
    bCasketBroken = bCasketBroken
  }
  return savedInfo
end
function OnRestoreCheckpoint(level, savedInfo)
  checkpoint.Restore(savedInfo.levelstate)
  bCasketBroken = savedInfo.bCasketBroken
end
function PinPlatform()
  isBridgePinned = true
  LockBridge()
  GameObjects.Gear_IceSkirt:PlayAnimToEnd(3)
  if isReadyToCross and isBridgeLowered then
    SonSequence_EnableRope()
  end
  if isBridgeLowered and btrGoodIdeaPlayed == false then
    btrGoodIdeaPlayed = true
    game.Audio.PlayBanterNonCritical("536_ForestBridgePuzzle_FreezeGear")
  end
end
function UnPinPlatform()
  isBridgePinned = false
  UnlockBridge()
  GameObjects.Gear_IceSkirt:PlayAnimToEnd(-3)
end
function EnterBridgeZone()
  if isBridgeLowered then
    LockBridge()
  end
end
function LockBridge()
  wheelCrank.LuaObjectScript.Lock()
end
function UnlockBridge()
  if not isBridgePinned and not player:IsInsideEntityZone(EV_Bridge) and not son:IsInsideEntityZone(EV_Bridge) then
    wheelCrank.LuaObjectScript.Unlock()
  end
end
function ShakeRumble()
  game.FX.SubmitEffect(camShakeLarge)
  game.FX.SubmitEffect(ForceFeedbackRumble)
end
function ShowBoostTutorial()
  TUT.BoostSon_Tutorial()
end
function HideBoostTutorial()
  TUT.HideTutorial()
end
function StopBoostTutorial()
  GameObjects.BoostTutorialZone:HideEntityVolume()
end
function Show_SonChainDrop_Tutorial()
  TUT.SonChainDropTutorial()
end
function Hide_SonChainDrop_Tutorial()
  TUT.HideTutorial()
end
function Stop_SonChainDrop_Tutorial()
  GameObjects.ChainDropTutorialZone:HideEntityVolume()
end
function PushOffCol_On()
  GameObjects.IC_Bridge_PushOff:ShowCollision()
end
function PushOffCol_Off()
  GameObjects.IC_Bridge_PushOff:HideCollision()
end
function CasketBroken()
  bCasketBroken = true
  GameObjects.CA_Casket.LuaObjectScript.Disable()
end
function SonSequence_BridgeLowered()
  IdleKratos()
  LD.CallFunctionAfterDelay(function()
    if varKratosOnCrank then
      isBridgeLowered = true
      if isReadyToCross and isBridgeLowered and varKratosOnCrank then
        SonSequence_EnableRope()
      else
        UnidleKratos()
      end
    else
      UnidleKratos()
    end
  end, 0.75)
end
function SonSequence_BridgeUp()
  isBridgeLowered = false
end
function SunSequence_Start()
  wheelCrank.LuaObjectScript.Enable()
  GameObjects.CA_BuddyBoost.LuaObjectScript.Enable()
  GameObjects.PuzzleTriggerZone:HideEntityVolume()
end
function SonHintsAtBoost()
  LD.CallFunctionAfterDelay(function()
    sonBoost.LuaObjectScript.Enable()
    GameObjects.BoostTutorialZone:ShowEntityVolume()
    if player:IsInsideEntityZone(GameObjects.BoostTutorialZone) == true then
      ShowBoostTutorial()
    end
  end, 4)
end
function SonSequence_SonBoosted()
  game.Audio.PlayBanter("536_ForestBridgePuzzle_Boost")
  SonAvailable_No()
  GameObjects.sonSequenceLTW.LuaObjectScript.Enable()
  GameObjects.CA_BuddyBoost.LuaObjectScript.Disable()
  GameObjects.LTW_Zone_start:HideEntityVolume()
  LTW_BeforePuzzle_Off()
  GameObjects.LTW_Zone_stop1:HideEntityVolume()
  StopBoostTutorial()
  local for350 = game.FindLevel("For350_ExitTunnel")
  if for350 ~= nil then
    for350:CallScript("DisableClimb")
  end
  if isBridgeLowered then
    pad:DisableGameButton(tweaks.ePad.kPadTriangle)
  end
end
function SonSequence_WaitForBridge()
  isReadyToCross = true
  if isBridgeLowered then
    pad:DisableGameButton(tweaks.ePad.kPadTriangle)
    SonSequence_EnableRope()
  else
    GameObjects.sonSequenceLTW.LuaObjectScript.Disable()
    GameObjects.CA_WaitForBridge.LuaObjectScript.Enable()
  end
  GameObjects.BridgeWaitZone:HideEntityVolume()
  if varKratosSawCrank == false then
    GameObjects.Btr_LowerBridge:ShowEntityVolume()
  end
end
function SonSequence_EnableRope()
  if varSonByTheRope == false then
    GameObjects.RopeDrop_1.LuaObjectScript.EnableSonInteract()
    local sonInteractZone = GameObjects.RopeDrop_1:FindSingleGOByName("releaseRopeInteract").LuaObjectScript.GetInteractZone()
    sonInteractZone:Disable()
    GameObjects.CA_WaitForBridge.LuaObjectScript.Interrupt()
    GameObjects.CA_WaitForBridge.LuaObjectScript.Disable()
    GameObjects.sonSequenceLTW.LuaObjectScript.Enable()
    Show_SonChainDrop_Tutorial()
    if varKratosOnCrank then
      CameraFollowSon()
      game.Audio.PlayBanter("536_ForestBridgePuzzle_LowerBridge_Hunt2")
      IdleKratos()
    end
    timer.StartLevelTimer(5, UnidleKratos)
    timer.StartLevelTimer(5.5, EnableRope_1_Interact)
  end
end
function EnableRope_1_Interact()
  local sonInteractZone = GameObjects.RopeDrop_1:FindSingleGOByName("releaseRopeInteract").LuaObjectScript.GetInteractZone()
  sonInteractZone:Enable()
end
function IdleKratos()
  pad:DisableGameButton(tweaks.ePad.kPadCircle)
  pad:DisableGameButton(tweaks.ePad.kPadSquare)
  pad:DisableGameButton(tweaks.ePad.kPadTriangle)
  pad:DisableGameButton(tweaks.ePad.kPadL1)
  pad:DisableGameButton(tweaks.ePad.kPadL2)
  pad:DisableGameButton(tweaks.ePad.kPadL3)
  pad:DisableGameButton(tweaks.ePad.kPadR1)
  pad:DisableGameButton(tweaks.ePad.kPadR2)
  pad:DisableGameButton(tweaks.ePad.kPadR3)
  pad:DisableGameButton(tweaks.ePad.kPadLeftStickX)
  pad:DisableGameButton(tweaks.ePad.kPadLeftStickY)
end
function UnidleKratos()
  pad:ClearAllDisabledGameButtons()
end
function HideNavObstaclesOnBridge()
  timer.StartLevelTimer(3, function()
    GameObjects.NavObstacleA:HideNavObstacle()
    GameObjects.NavObstacleB:HideNavObstacle()
    GameObjects.CA_ShootFromAbove.LuaObjectScript.Disable()
  end)
end
function ShowNavObstaclesOnBridge()
  GameObjects.NavObstacleA:ShowNavObstacle()
  GameObjects.NavObstacleB:ShowNavObstacle()
end
function SonEnterFloor_1()
  varSonCurrentFloor = 1
  CheckSonAvailability()
end
function SonEnterFloor_2()
  varSonCurrentFloor = 2
  CheckSonAvailability()
end
function KratosEnterFloor_1()
  varKratosCurrentFloor = 1
  CheckSonAvailability()
end
function KratosEnterFloor_2()
  varKratosCurrentFloor = 2
  CheckSonAvailability()
end
function CheckSonAvailability()
  if varKratosCurrentFloor == varSonCurrentFloor then
    SonAvailable_Yes()
  else
    SonAvailable_No()
  end
end
function SonAvailable_No()
  local availabilityState = {
    AvailableForSync = false,
    AvailableForBanter = true,
    AvailableInLevel = true,
    AvailableForCombat = true
  }
  game.AI.FindSon():SetNewAvailabilityRequest("LevelDesignScript", availabilityState)
end
function SonAvailable_Yes()
  game.AI.FindSon():RemoveAvailabilityRequest("LevelDesignScript")
end
function DisableCameraRecenter_LookToDestinationAfterMantle()
  local camZoneRecenterDestination = thisLevel:GetGameObject("CamZone_Recenter_Destination")
  assert(camZoneRecenterDestination, "For900: Can't find camZoneRecenterDestination")
  camZoneRecenterDestination:HideCameraVolume()
  local camZoneRecenterDestination_LevelOut = thisLevel:GetGameObject("CamZone_Recenter_Destination_LevelOut")
  assert(camZoneRecenterDestination_LevelOut, "For900: Can't find camZoneRecenterDestination_LevelOut")
  camZoneRecenterDestination_LevelOut:HideCameraVolume()
end
function KratosOnCrank()
  GameObjects.BridgeZone:HideEntityVolume()
  GameObjects.Btr_LowerBridge:HideEntityVolume()
  varKratosOnCrank = true
  varKratosSawCrank = true
end
function KratosOffCrank()
  GameObjects.BridgeZone:ShowEntityVolume()
  varKratosOnCrank = false
end
function CameraFollowSon()
  camOneShotFollowSon = CCOS.OneShotCamera.New("PLYR_Nar_FollowSon_010", 5)
  camOneShotFollowSon:SetCallback(DestroyCamera)
  camOneShotFollowSon:Start()
end
function DestroyCamera()
  camOneShotFollowSon = nil
end
function SonSequence_SonNextToRope()
  varSonByTheRope = true
  isReadyToCross = false
  if btrMadeItPlayed == false then
    btrMadeItPlayed = true
    game.Audio.PlayBanter("536_ForestBridgePuzzle_MadeIt", nil, nil, false)
  end
end
function SonSequence_SonAwayFromRope()
  varSonByTheRope = false
end
function SonSequence_KratosClimbing()
  if isBridgeLowered == false and btrEarlyAxeCallPlayed == false then
    btrEarlyAxeCallPlayed = true
    game.Audio.PlayBanterNonCritical("536_ForestBridgePuzzle_EarlyAxeCall", nil, nil, false)
  end
  if varSonByTheRope and isBridgeLowered and isBridgePinned then
    GameObjects.CA_WaitForClimb.LuaObjectScript.Interrupt()
    GameObjects.CA_WaitForClimb.LuaObjectScript.Disable()
    GameObjects.LTW_PostPuzzle.LuaObjectScript.Enable()
    if bCasketBroken == false then
      GameObjects.CA_Casket.LuaObjectScript.Enable()
      LD.CallFunctionAfterDelay(function()
        game.Audio.PlayBanter("160_CaskSpotted")
      end, 6)
      LD.CallFunctionAfterDelay(function()
        GameObjects.CA_Casket.LuaObjectScript.Disable()
        GameObjects.CA_CrackClimbReady.LuaObjectScript.Enable()
      end, 27)
      LD.CallFunctionAfterDelay(function()
        GameObjects.BtrZone_OthersOnTheRoad:ShowEntityVolume()
      end, 28)
    else
      GameObjects.BtrZone_OthersOnTheRoad:ShowEntityVolume()
      GameObjects.CA_CrackClimbReady.LuaObjectScript.Enable()
    end
  end
end
function SonSequence_RopeDone()
  GameObjects.sonSequenceLTW.LuaObjectScript.Disable()
  GameObjects.CA_WaitForClimb.LuaObjectScript.Enable()
  GameObjects.BridgeWaitZone:HideEntityVolume()
end
function SonSequence_RopeClimbed()
  GameObjects.ClimbedRopeZone:HideEntityVolume()
  GameObjects.PuzzleTriggerZone:HideEntityVolume()
  GameObjects.CA_BuddyBoost.LuaObjectScript.Disable()
end
function FreeKratos()
  local for000_sky = game.FindLevel("For000_Sky")
  if for000_sky ~= nil then
    for000_sky:CallScript("DisableNoPass")
  end
end
function LTW_BeforePuzzle_On()
  GameObjects.LTW_beforePuzzle.LuaObjectScript.Enable()
end
function LTW_BeforePuzzle_Off()
  GameObjects.LTW_beforePuzzle.LuaObjectScript.Disable()
end
function PlayerPastPuzzle()
  GameObjects.LTW_PostPuzzle.LuaObjectScript.Disable()
  GameObjects.CrackClimbStartZone:HideEntityVolume()
  GameObjects.LTW_Zone_start:HideEntityVolume()
end
function PlayerReturn2Puzzle()
  if isBridgeLowered == true then
    GameObjects.LTW_PostPuzzle.LuaObjectScript.Enable()
  end
end
function Area_1_Fight_1()
  Area_1_Encounter_1 = EC.NewEncounter(thisLevel, "[Area 1]EC:1 For900", {CheckpointOnComplete = false})
  Area_1_Encounter_1:AddWave({
    {
      spawners = "Draugr_N_SFG",
      spawnLocators = "A1_O_Loc_2",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 2.5
    },
    {
      spawners = "Draugr_N_SFG",
      spawnLocators = "A1_O_Loc_1",
      useSpawnLocatorsOnly = true,
      maxActive = 1,
      totalSpawns = 1,
      spawnCooldown = 0
    }
  })
  Area_1_Encounter_1:OnComplete(HideNavObstaclesOnBridge)
end
function ShowDebugTable()
  local debugTable = {}
  debugTable.X = 95
  debugTable.Y = 10
  debugTable.Title = "For900 Info"
  debugTable[#debugTable + 1] = {
    "isBridgeLowered ",
    isBridgeLowered
  }
  debugTable[#debugTable + 1] = {
    "isReadyToCross ",
    isReadyToCross
  }
  debugTable[#debugTable + 1] = {
    "varSonByTheRope ",
    varSonByTheRope
  }
  debugTable[#debugTable + 1] = {
    "isBridgePinned ",
    isBridgePinned
  }
  engine.DrawDebugTable(debugTable)
end
local drawBridgeOverrides = {
  OnReturnToStart = "SND_MECH_Wood_Bridge_Slam_Up_For900",
  OnForward = "SND_MECH_Wood_Bridge_LP_For900",
  OnBackward = "SND_MECH_Wood_Bridge_LP_For900",
  OnFastForward = "SND_MECH_Wood_Bridge_LP_For900",
  OnRewind = "SND_MECH_Wood_Bridge_LP_For900",
  OnEnd = "SND_MECH_Wood_Bridge_Slam_Down_For900"
}
local SNDDrawBridge
local bridgePaused = true
function SoundOnStart()
  GameObjects.BridgeWheelCrank.LuaObjectScript.DrivenObjectSoundSetup(drawBridgeOverrides)
  SNDDrawBridge = GameObjects.DrawBridge:FindSingleSoundEmitterByName("SNDDrawBridge")
end
function PlaySoundOnBridgeDown()
  if bridgePaused then
    LD.PlaySound(SNDDrawBridge, "SND_MECH_Wood_Bridge_Crank_Down_For900")
  end
  bridgePaused = false
end
function PlaySoundOnBridgeUp()
  if bridgePaused then
    LD.PlaySound(SNDDrawBridge, "SND_MECH_Wood_Bridge_Crank_Up_For900")
  end
  bridgePaused = false
end
function BridgePaused()
  bridgePaused = true
end
function BridgeAtBeginning()
  BridgePaused()
  GameObjects.BridgeWheelCrank.LuaObjectScript.StopRewindSound()
end
