local LD = require("design.LevelDesignLibrary")
local ND = require("design.NarrativeDesignLibrary")
local monitors = require("level.MonitorLibrary")
local checkpoint = require("level.checkpoint")
local actor = require("narrative.actor")
local TUT = require("game.GlobalTutorials")
local timers = require("level.timer")
local uiCalls = require("ui.uicalls")
local CCEC = require("camera.camera_cineentercamera")
local Player = game.Player.FindPlayer()
local thisObj, thisLevel, kratosActor, sonActor, sindriActor, toothObj, buttonMonitor
local shatterExplained = false
local shopState = 0
local L2buttonMonitor, cameraCineEnter_VibrateArrows, pad
local destroyedVibrateCrystal = false
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  game.SubObject.Sleep(obj)
  pad = Player.Pad
end
function OnStart(level, obj)
  if game.Level.GetVariable("CompletedCineNumber") < 295 then
    SetupActors()
    SetupProps()
    SetupSindriAndShop()
    L2buttonMonitor = monitors.CreateL2ButtonMonitor()
    L2buttonMonitor:OnButtonDown(L2Down)
    L2buttonMonitor:OnButtonUp(L2Up)
    L2buttonMonitor:Stop()
  else
    local sindriSpawnObject = thisLevel:GetGameObject("VendorSpawner")
    sindriSpawnObject.LuaObjectScript.SpawnEnemy()
  end
end
function OnUpdate(level, obj)
  if cameraCineEnter_VibrateArrows ~= nil then
    cameraCineEnter_VibrateArrows:Update()
  end
end
function OnSaveCheckpoint(level, obj)
  local savedInfo = {}
  savedInfo.shopState = shopState
  return savedInfo
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  if savedInfo ~= nil then
    shopState = savedInfo.shopState
  end
end
function ShopAfterSindriDragon()
  shopState = 1
  GameObjects.SmallShop.LuaObjectScript.EnableCinematicTrigger()
end
function ShopAfterDragonTooth()
  shopState = 2
  GameObjects.SmallShop.LuaObjectScript.EnableCinematicTrigger()
  game.World.StoreCheckpoint()
end
function ShopAfterVibrateArrow()
  shopState = 3
  GameObjects.SmallShop.LuaObjectScript.StartCounterRequest(sindriActor:GetCreature())
end
function ShopAfterTutorial()
  shopState = 4
  GameObjects.SmallShop.LuaObjectScript.DisableCinematicTrigger()
  LD.CallFunctionAfterDelay(QuestAfterTutorial, 3)
end
function QuestAfterTutorial()
  GameObjects.SmallShop:FindSingleGOByName("TalkInteract_SM").LuaObjectScript.AttemptToTriggerGreeting()
end
function FindOrSpawnSindri()
  return GameObjects.Cine_SindriDragon.LuaObjectScript.FindOrSpawnSindri()
end
function SetupActors()
  kratosActor = actor.Actor.New("KRATOS ACTOR: VIBRATE ARROWS", game.Player.FindPlayer)
  sonActor = actor.Actor.New("SON ACTOR: VIBRATE ARROWS", game.AI.FindSon)
  sindriActor = actor.Actor.New("SINDRI ACTOR: VIBRATE ARROWS", FindOrSpawnSindri)
end
function SetupProps()
  toothObj = thisObj:FindSingleGOByName("dragonToothTipProp").Child
  HideProps()
end
function HideProps()
  toothObj:Hide()
end
function ShowProps()
  toothObj:Show()
end
function SetupSindriAndShop()
  local seq = LD.CreateCineSequence(thisLevel, thisObj, "setup Sindri Shop")
  seq:SpawnActorAndWait(sindriActor)
  seq:Do(function()
    if shopState == 0 or shopState == 1 then
      GameObjects.SmallShop.LuaObjectScript.EnableCinematicTrigger()
      SindriDragonPostIdle()
    elseif shopState == 2 then
      GameObjects.SmallShop.LuaObjectScript.EnableCinematicTrigger()
      PreVibrateArrowsIdle()
      GameObjects.SmallShop.LuaObjectScript.EnableVendorInteract()
    elseif shopState == 3 then
      GameObjects.SmallShop.LuaObjectScript.EnableCinematicTriggerTalkInteract()
      GameObjects.SmallShop.LuaObjectScript.StartCounterRequest(sindriActor:GetCreature())
      TutoralSequence()
    else
      GameObjects.SmallShop.LuaObjectScript.StartCounterRequest(sindriActor:GetCreature())
    end
  end)
  seq:StartSequence()
end
function SetupCineSeq()
  if game.Level.GetVariable("CompletedCineNumber") < 295 then
    local cineSeq = LD.CreateCineSequence(thisLevel, thisObj, "Vibrate Arrows Sequence")
    local actorTable = {
      {Actor = sonActor},
      {Actor = sindriActor},
      {
        Obj = toothObj,
        Anim = "narPeakVibrateArrows000CineScene"
      }
    }
    cineSeq:SetPostSkipMusic("SND_MX_PEAK_start_master")
    cineSeq:MarkAbleToSkip()
    cineSeq:Do(IdleKratos)
    cineSeq:Do(function()
      game.World.DisablePlayerStateSoftSave()
    end)
    cineSeq:Do(ShowProps)
    cineSeq:RequestCineModeAndWait(kratosActor, thisObj)
    cineSeq:Do(StartCineEnter_VibrateArrows)
    cineSeq:Do(function()
      pad:EnableGameButton(tweaks.ePad.kPadCircle)
    end)
    cineSeq:ActorForceApproachAndWait(kratosActor, {
      Branch = "BRA_VibrateArrows",
      ReferenceJoint = "VibrateArrows_SynchJoint",
      speed = ND.KraWalkSpeed,
      stop = false,
      radius = ND.StopTurnRadius,
      weapon_state = "bare"
    })
    cineSeq:ActorSync(kratosActor, {
      Slaves = actorTable,
      Branch = "BRA_VibrateArrows",
      ReferenceJoint = "VibrateArrows_SynchJoint"
    })
    cineSeq:WaitForFunctionTrue(function()
      return game.AI.FindSon().AnimPercent >= 0.85
    end)
    cineSeq:Do(function()
      cineSeq:EndSkipIfActive()
    end)
    cineSeq:Do(function()
      TUT.VibrateArrow_Acquire()
      pad:DisableGameButton(tweaks.ePad.kPadCircle)
    end)
    cineSeq:WaitForAndCompleteCineMode(kratosActor, thisObj)
    cineSeq:StopPuppetingActor(kratosActor)
    cineSeq:Do(HideProps)
    cineSeq:SetCompletedCineNumber(295)
    cineSeq:Do(function()
      LD.GiveShockArrow()
      ShopAfterVibrateArrow()
    end)
    cineSeq:WaitForFunctionTrue(function()
      return game.AI.FindSon().AnimPercent >= 0.997
    end)
    cineSeq:Do(function()
      GameObjects.CA_Post_Up_Arrow_Upgrade_Tutorial.LuaObjectScript.Enable()
      game.AI.FindSon():RemoveAvailabilityRequest("LevelDesignScript")
      game.AI.FindSon():AddMarker("PostUpNoCollision")
    end)
    cineSeq:StopPuppetingActor(sonActor)
    cineSeq:StopPuppetingActor(sindriActor)
    cineSeq:Do(TutoralSequence)
    cineSeq:StartSequence()
  end
end
function TutoralSequence()
  local cineSeq = LD.CreateCineSequence(thisLevel, thisObj, "Vibrate Arrows Tutorial Sequence")
  cineSeq:Do(SCA_ToothPullWait_Disable)
  cineSeq:WaitSeconds(0.5)
  cineSeq:Do(VibrateArrow_Tutorial)
  cineSeq:WaitSeconds(0.25)
  cineSeq:Do(VibrateUpgrade_Banter)
  cineSeq:Do(function()
    game.Compass.SetDesignerForcedHide(false)
  end)
  cineSeq:StartSequence()
end
function SCA_ToothPullWait_Disable()
  GameObjects.SCA_ToothPullWait.LuaObjectScript.Interrupt()
  GameObjects.SCA_ToothPullWait.LuaObjectScript.Disable()
end
function VibrateArrow_Tutorial()
  L2Up()
  L2buttonMonitor:Start()
end
function L2Down()
  uiCalls.SendSidebarDesignerMessage({
    Text = 18163,
    MessageVariant = uiCalls.msgParam.SIDEBAR_MEDIUM,
    AdvanceType = uiCalls.msgParam.INFINITE_TIMER
  })
end
function L2Up()
  uiCalls.SendSidebarDesignerMessage({
    Text = 18150,
    AdvanceType = uiCalls.msgParam.INFINITE_TIMER
  })
end
function IdleKratos()
  pad:ClearAllDisabledGameButtons()
  if not destroyedVibrateCrystal then
    pad:DisableGameButton(tweaks.ePad.kPadCircle)
    pad:DisableGameButton(tweaks.ePad.kPadTriangle)
    pad:DisableGameButton(tweaks.ePad.kPadDown)
    pad:DisableGameButton(tweaks.ePad.kPadRight)
    pad:DisableGameButton(tweaks.ePad.kPadL1)
    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
end
function DisableTutorialMessage()
  if L2buttonMonitor ~= nil then
    L2buttonMonitor:Stop()
  end
  uiCalls.UI_Event_TurnOffDesignerMessage()
  VibrateUpgrade_Interrupted_Banter()
  pad:ClearAllDisabledGameButtons()
  destroyedVibrateCrystal = true
  timers.StartLevelTimer(3, function()
    TUT.ArrowToggle_Tutorial()
  end)
end
function VibrateUpgrade_Banter()
  game.Audio.PlayBanter("410_VibrateUpgrade", function()
    shatterExplained = true
  end)
end
function VibrateUpgrade_Interrupted_Banter()
  if not shatterExplained then
    game.Audio.PlayBanter("410_VibrateUpgrade_Interrupted")
  end
end
function PreVibrateArrowsIdle()
  GameObjects.SmallShop.LuaObjectScript.PassInVendorNpc(sindriActor:GetCreature())
  local cineSeq = LD.CreateCineSequence(thisLevel, thisObj, "Vibrate Arrows Pre-Idle")
  cineSeq:ActorSync(sindriActor, {
    Branch = "BRA_VibrateArrowsPreIdle",
    ReferenceJoint = "VibrateArrows_SynchJoint"
  })
  cineSeq:StartSequence()
end
function SindriDragonPostIdle()
  local cineSeq = LD.CreateCineSequence(thisLevel, thisObj, "Sindri Dragon Post-Idle")
  cineSeq:ActorSync(sindriActor, {
    Branch = "BRA_PostSindriDragonIdles",
    ReferenceJoint = "SindriDragon_SynchJoint"
  })
  cineSeq:StartSequence()
end
function EnableSplineCamera()
  local camzone = thisLevel:GetGameObject("CamZone_VibrateArrowTutorial")
  camzone:ShowCameraVolume()
end
function StartCineEnter_VibrateArrows()
  game.SubObject.Wake(thisObj)
  EnableSplineCamera()
  cameraCineEnter_VibrateArrows = CCEC.CineEnterCamera.New("ENV_CineEnter_VibrateArrows", 8)
  cameraCineEnter_VibrateArrows:SetCallback(DestroyCineEnter_VibrateArrows)
  cameraCineEnter_VibrateArrows:Start()
end
function DestroyCineEnter_VibrateArrows()
  cameraCineEnter_VibrateArrows = nil
  game.SubObject.Sleep(thisObj)
end
function TutorialComplete()
  ShopAfterTutorial()
  local peak700 = game.FindLevel("peak700_SummitAscent")
  peak700:CallScript("Spline_700Hall_Enable")
  game.World.EnablePlayerStateSoftSave()
  game.World.StoreCheckpoint()
end
