local timer = require("level.timer")
local CCOS = require("camera.camera_oneshot")
local thisObj, thisLevel, kratosPuppeteer, sonPuppeteer, boatPuppeteer, camOneShot_SnakeBellyEnter
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  game.SubObject.Sleep(obj)
  game.SubObject.SetForgetOnCheckpoint(obj)
end
function Disengage()
  game.Player.FindPlayer():TriggerMoveEvent("LE_SnakeBellyEnter_Disengage")
  game.AI.FindSon():TriggerMoveEvent("LE_SnakeBellyEnter_Disengage")
  game.Boat.GetPlayerBoat():TriggerMoveEvent("LE_SnakeBellyEnter_Disengage")
  if kratosPuppeteer ~= nil then
    kratosPuppeteer:Clear()
    kratosPuppeteer = nil
  end
  if sonPuppeteer ~= nil then
    sonPuppeteer:Clear()
    sonPuppeteer = nil
  end
  if boatPuppeteer ~= nil then
    boatPuppeteer:Clear()
    boatPuppeteer = nil
  end
  thisLevel:CallScript("SwitchToSnakeBelly")
end
function EnterSnakeStart()
  kratosPuppeteer = game.Puppeteer.NewForce(thisObj, "POI_SnakesBellyEnter_Kra", game.Player.FindPlayer())
  sonPuppeteer = game.Puppeteer.NewForce(thisObj, "POI_SnakesBellyEnter_Son", game.AI.FindSon())
  boatPuppeteer = game.Puppeteer.NewForce(thisObj, "POI_SnakesBellyEnter_Boat", game.Boat.GetPlayerBoat())
  game.Compass.SetDesignerForcedHide(true)
  kratosPuppeteer:Clear()
  kratosPuppeteer:AcceptSync()
  timer.StartLevelTimer(1, PlayShake_MouthClosing)
  timer.StartLevelTimer(13, Disengage)
  local boat = game.Boat.GetPlayerBoat()
  if boat then
    game.Boat.EnableBoatControl(boat, false)
  end
  if game.AI.FindSon() ~= nil then
    sonPuppeteer:AcceptSync()
    boatPuppeteer:Sync("BRA_SnakeBellyEnter", false, {
      {
        Slave = sonPuppeteer,
        Branch = "BRA_SnakeBellyEnter"
      },
      {
        Slave = kratosPuppeteer,
        Branch = "BRA_SnakeBellyEnter"
      }
    })
  else
    boatPuppeteer:Sync("BRA_SnakeBellyEnter", false, {
      {
        Slave = kratosPuppeteer,
        Branch = "BRA_SnakeBellyEnter"
      }
    })
  end
  local cal200 = game.FindLevel("Cal200_Shore")
  if cal200 then
    cal200:CallScript("EnterSnakeMouth")
  else
    engine.Warning("Attempt to access cal200 when it was not loaded, this will break game progression")
  end
  kratosPuppeteer:OnComplete(function()
    kratosPuppeteer = nil
    local boat = game.Boat.GetPlayerBoat()
    if boat then
      game.Boat.EnableBoatControl(boat, false)
    end
  end)
  sonPuppeteer:OnComplete(function()
    sonPuppeteer = nil
  end)
end
function EnterSnakeSettleStart()
  kratosPuppeteer = game.Puppeteer.NewForce(thisObj, "POI_SnakesBellyEnter_Kra", game.Player.FindPlayer())
  sonPuppeteer = game.Puppeteer.NewForce(thisObj, "POI_SnakesBellyEnter_Son", game.AI.FindSon())
  boatPuppeteer = game.Puppeteer.NewForce(thisObj, "POI_SnakesBellyEnter_Boat", game.Boat.GetPlayerBoat())
  GameObjects.Cal800FXStart:PlayAnimToEnd()
  kratosPuppeteer:Clear()
  kratosPuppeteer:AcceptSync()
  if game.AI.FindSon() ~= nil then
    sonPuppeteer:AcceptSync()
    boatPuppeteer:Sync("BRA_SnakeBellySettle", false, {
      {
        Slave = sonPuppeteer,
        Branch = "BRA_SnakeBellySettle"
      },
      {
        Slave = kratosPuppeteer,
        Branch = "BRA_SnakeBellySettle"
      }
    })
  else
    boatPuppeteer:Sync("BRA_SnakeBellySettle", false, {
      {
        Slave = kratosPuppeteer,
        Branch = "BRA_SnakeBellySettle"
      }
    })
  end
  kratosPuppeteer:OnComplete(function()
    kratosPuppeteer = nil
    local boat = game.Boat.GetPlayerBoat()
    if boat then
      game.Audio.SetBanterFact("disableBoatLoreInWAD", true)
      game.Audio.SetBanterFact("selected_lore", -1)
      game.Boat.EnableBoatControl(boat, true)
    end
  end)
  sonPuppeteer:OnComplete(function()
    sonPuppeteer = nil
  end)
end
function DestroyOneShot_SnakeBellyEnter()
  camOneShot_SnakeBellyEnter = nil
end
function PlayCamOneShot_SnakeBellyEnter()
  game.SubObject.Wake(thisObj)
  camOneShot_SnakeBellyEnter = CCOS.OneShotCamera.New("ENV_Nar_GetInMyBelly", 8.8)
  camOneShot_SnakeBellyEnter:SetCallback(DestroyOneShot_SnakeBellyEnter)
  camOneShot_SnakeBellyEnter:Start()
end
function PlayShake(nameofeffect, duration, tweenin, tweenout)
  local effect = {
    EffectName = nameofeffect,
    Duration = duration,
    TweenInTime = tweenin,
    TweenOutTime = tweenout
  }
  game.FX.SubmitEffect(effect)
end
function PlayShake_MouthClosing()
  PlayShake("FSE_SWAY_WATERWAKE_BOUNCE", 10, 4, 0.8)
  game.Audio.StartCheckpointedMusic("SND_MX_CAL_snake_belly_enter")
end
function OnUpdate(level, obj)
  if camOneShot_SnakeBellyEnter ~= nil then
    camOneShot_SnakeBellyEnter:Update()
  end
end
