LD = require("design.LevelDesignLibrary")
timer = require("level.timer")
uiCalls = require("ui.uicalls")
local collisionCheck = require("camera.collisioncheck")
local TUT = require("game.GlobalTutorials")
local isInView = false
local isInOuterView = false
local currentCamera, cameraLookAtObject
local timeBeforeBreathReset = 12
local breathIsHeld = false
local lowRumbleParams, highRumbleParams, player, son, banterCooldownTime, banterTimer
local buttonSuccessTime = 2
local buttonPressTime = 0
local breathTimer, gestureTimer, sonGestureTimer
local timeBeforeSonGesutreAllowed = 10
local timeBeforeGestureAllowed = 10
local successInProgress = false
local aimTutorialDelay = 13
local aimTutorialDisplayed = false
local shootTutorialDelay = 8
local shootTutorialDisplayed = false
local gestureIsAllowed = true
local sonGestureIsAllowed = true
deerInteract = nil
miniGameActive = false
deerJoint = nil
deerTarget = nil
deerTargetForward = nil
e3ModeIsOn = true
e3DialogueStarted = nil
successDialoguePlaying = nil
brandNewBool = true
distanceToLockOn = nil
deerWiseValue = nil
offset = nil
deerOffset = nil
aimIsValidActive = nil
function OnScriptLoaded(level, obj)
  highRumbleParams = {EffectName = "FFB_LARGE", Duration = 0.02}
  lowRumbleParams = {EffectName = "FFB_SMALL", Duration = 1}
  player = game.Player.FindPlayer()
  son = game.AI.FindSon()
  breathTimer = StartLevelTimer(timeBeforeBreathReset, BreathTimedOut)
  breathTimer:Stop()
  gestureTimer = StartLevelTimer(timeBeforeGestureAllowed, GestureTimerReset)
  gestureTimer:Stop()
  sonGestureTimer = StartLevelTimer(timeBeforeSonGesutreAllowed, SonGestureTimerReset)
  sonGestureTimer:Stop()
end
function OnUpdate(level, obj)
  if miniGameActive then
    if deerInteract ~= nil then
      deerTarget = deerInteract:GetWorldPosition()
      deerTargetForward = deerInteract:GetWorldForward()
      local percentDeerForward = 0
      local deerAnimFrame = deerInteract:GetCreature().AnimFrame
      if 38 < deerAnimFrame and deerAnimFrame < 133 then
        percentDeerForward = 1 - (133 - deerAnimFrame) / 95
      elseif 133 <= deerAnimFrame and deerAnimFrame <= 175 then
        percentDeerForward = 1
      elseif 175 < deerAnimFrame and deerAnimFrame < 269 then
        percentDeerForward = (269 - deerAnimFrame) / 94
      end
      local offset = engine.Vector.New(0, 1.5, 0) + deerTargetForward * (0.15 + 0.15 * percentDeerForward)
      local deerOffset = deerTarget + offset
      isInOuterView = collisionCheck.isTargetInFrustumUnobstructed(deerOffset, 0.3, 0.1, 0.55, true)
      isInView = collisionCheck.isTargetInFrustumUnobstructed(deerOffset, 0.3, 0.1, 0.88, true)
      if isInView == true and successInProgress == false then
        TargetIsInView()
        isInOuterView = false
      elseif isInOuterView == true and successInProgress == false then
        TargetIsInOuterView()
      end
    end
    if son:IsPlayingMove("MOV_DeerInteractHitAim") then
      if e3ModeIsOn ~= true then
        if sonGestureIsAllowed == true then
          SonPlayGesture()
          sonGestureIsAllowed = false
        end
      elseif e3DialogueStarted ~= true then
        UITurnOn()
        LD.CallFunctionAfterDelay(E3StartDialogue, 1.5)
        LD.CallFunctionAfterDelay(StartDeerGesture, 0.5)
        e3DialogueStarted = true
      end
    end
    if e3DialogueStarted == true then
      SetWWiseValue()
    end
    if e3ModeIsOn ~= true and player:IsPlayingMove("MOV_DeerInteractBreathEnter") then
      game.Camera.SubmitCameraByName("PLYR_DeerAim_Test_BreathHeld")
      if gestureIsAllowed == true then
        PlayGesture()
      end
    end
    if player:IsPlayingMove("MOV_DeerInteractBreathLoop") then
      if isInView ~= true then
        game.Camera.SubmitCameraByName("PLYR_DeerAim_Test_BreathHeld")
        PlayerIsHoldingBreath()
      else
        PlayerIsHoldingBreath()
      end
    end
    local breathJustTimedOut = false
    if player.Pad.L2Down == false and breathIsHeld == true then
      BreathTimedOut()
      breathJustTimedOut = true
    end
    if breathIsHeld == true then
      if isInView == true and successInProgress ~= true then
        uiCalls.UI_Event_Minigame_Hold_Breath_Valid_Target()
        ShowShootTutorialMessage()
        game.Camera.SubmitCameraByName("PLYR_DeerAim_Test_Focus")
        buttonPressTime = math.min(buttonPressTime + player:GetUnitTime(), buttonSuccessTime + 0.01)
        if buttonPressTime >= buttonSuccessTime then
          AimIsValid(true)
          game.Audio.PlayBanterNonCritical("AimCenterBreathHeld")
        end
      else
        uiCalls.UI_Event_Minigame_Hold_Breath_Invalid_Target()
        if 0 < buttonPressTime then
          buttonPressTime = buttonPressTime - player:GetUnitTime()
          if buttonPressTime < 0 then
            buttonPressTime = 0
          end
        end
        if buttonPressTime == 0 then
          game.Audio.PlayBanterNonCritical("NoAimBreathHeld")
        end
      end
    elseif not breathJustTimedOut and not player:HasMarker("SonRecoveringBreath") then
      if isInView then
        game.Audio.PlayBanterNonCritical("AimCenterNoBreathe")
      else
        game.Audio.PlayBanterNonCritical("NoAimNoBreathe")
      end
    end
  end
end
function AimIsValid(data)
  if data == true then
    if not player:PickupIsAcquired("MiniGameAimValid") then
      player:PickupAcquire("MiniGameAimValid")
      print("Acquire Pickup MiniGameAimValid")
      aimIsValidActive = true
    end
  elseif data == false and aimIsValidActive then
    player:PickupRelinquish("MiniGameAimValid")
    print("Relinquish Pickup MiniGameAimValid")
    aimIsValidActive = false
  end
end
function SetWWiseValue()
  local DT
  if deerInteract ~= nil then
    DT = deerInteract:GetWorldPosition()
  else
    DT = deerTarget
  end
  if DT then
    local offset = engine.Vector.New(0, 1, 0)
    local deerOffset = DT + offset
    local thisCreaturePen = game.Camera.GetViewPenetration(deerOffset, 0.3, 0.1)
    local adjustedValue = thisCreaturePen * 100
    deerWiseValue = Clamp(0, adjustedValue, 100)
    game.Audio.SetWwiseRTPCValue(player, "WPN_Bow_Target_Lock", deerWiseValue)
  end
end
function Clamp(low, n, high)
  return math.min(math.max(n, low), high)
end
function UITurnOn()
  print("for bryce!")
  uiCalls.UI_Event_Minigame_Start()
end
function StartMiniGame(data)
  if data == true then
    miniGameActive = true
    if deerInteract == nil then
      deerInteract = LD.GetSingleAIByMarker("deer00")
    end
  else
    miniGameActive = false
    uiCalls.UI_Event_Minigame_End()
    uiCalls.UI_Event_TurnOffDesignerMessage()
  end
end
function StartDeerGesture()
  deerInteract:ForceMove("BRA_DeerHitLookUp")
end
function PlayGesture()
  gestureIsAllowed = false
  gestureTimer:Start()
end
function SonPlayGesture()
  local pressedL2Button = game.Player.FindPlayer().Pad.L2Down or false
  if miniGameActive and pressedL2Button == false then
    son:ForceMove("BRA_DeerHitInteractSonGesture01")
    print("I PLAYED THE SON GESTURE NEWWWWWWWWWWWWW!!")
    sonGestureIsAllowed = false
    if e3ModeIsOn ~= true then
      sonGestureTimer:Start()
    end
  end
end
function E3StartDialogue()
  e3DialogueStarted = true
  LD.CallFunctionAfterDelay(SonPlayGesture, 3)
end
function SonGestureTimerReset()
  sonGestureIsAllowed = true
  sonGestureTimer:Reset()
end
function GestureTimerReset()
  gestureIsAllowed = true
  gestureTimer:Reset()
end
function ShowAimTutorialMessage()
  if aimTutorialDisplayed ~= true then
    aimTutorialDisplayed = true
    TUT.DeerSteadyAim_Tutorial()
  end
end
function ShowShootTutorialMessage()
  if not shootTutorialDisplayed then
    TUT.FireArrow_Tutorial()
    shootTutorialDisplayed = true
  end
end
function PlayerIsHoldingBreath()
  if not breathIsHeld then
    breathIsHeld = true
    player:TriggerMoveEvent("triggerGestureSlow")
    uiCalls.UI_Event_Minigame_Hold_Breath_Start()
  else
    uiCalls.UI_Event_Minigame_Hold_Breath(buttonPressTime / buttonSuccessTime)
  end
  if e3ModeIsOn ~= true then
    breathTimer:Start()
  end
end
function BreathTimedOut()
  game.Camera.SubmitCameraByName("PLYR_DeerAim_Test")
  player:TriggerMoveEvent("breathTimeOut")
  buttonPressTime = 0
  breathIsHeld = false
  breathTimer:Reset()
  uiCalls.UI_Event_Minigame_Hold_Breath_End()
  aimTutorialDisplayed = false
  shootTutorialDisplayed = false
  ShowAimTutorialMessage()
  if not player:HasMarker("SonRecoveringBreath") then
    player:AddMarker("SonRecoveringBreath")
  end
  LD.CallFunctionAfterDelay(ClearRecoveringBreath, 2)
end
function ClearRecoveringBreath()
  if player:HasMarker("SonRecoveringBreath") then
    player:RemoveMarker("SonRecoveringBreath")
  end
end
function TriggerSuccess()
  AimIsValid(false)
  successInProgress = true
  print("PLAYING THE ACTUAL ENDING!!!!!!!!!!!!!!!!!!!!!!!!!!!")
  uiCalls.UI_Event_TurnOffDesignerMessage()
  player:TriggerMoveEvent("triggerDeerAimWin")
  deerInteract:TriggerMoveEvent("triggerDeerAimWin")
  StartMiniGame(false)
end
function TriggerEndDialogue()
  successDialoguePlaying = true
  print("PLAYING THE END DIALOGUE!!!!!!!!!!!!!!!!!!")
  LD.CallFunctionAfterDelay(TriggerSuccess, 1.5)
end
function TargetIsInOuterView()
  AimIsValid(false)
  if breathIsHeld then
    game.FX.SubmitEffect(lowRumbleParams)
  end
  ShowAimTutorialMessage()
end
function TargetIsInView()
  if breathIsHeld then
    game.FX.SubmitEffect(highRumbleParams)
  end
  ShowAimTutorialMessage()
end
