local profile = require("core.profile")
local bIsAiming = false
local AimModeHack = 0
local IsNotInsideWideCameraZone = function(worldposition)
  local pos = worldposition
  if game.World.IsInsideCameraZone(pos, "OutDoorWideNav*") then
    return false
  end
  if game.World.IsInsideCameraZone(pos, "IndoorWideNav*") then
    return false
  end
  if game.World.IsInsideCameraZone(pos, "BaseVeryWide*") then
    return false
  end
  return true
end
local aimModeTypeValue
local tbl_AimModeType = {
  CBT_Nav_Near = 1,
  AIM_Default_Hack_CBT_Nav_Far = 1,
  CBT_Dodge = 1,
  PLYR_Nav_Base_Idle = 2,
  AIM_Default_Hack_Nav_Base_Idle = 2,
  PLYR_Nav_Base_Jog = 3,
  AIM_Default_Hack_Nav_Base_Jog = 3,
  PLYR_Nav_Wide_22mm = 4,
  PLYR_Nav_Wide_22mm_Jog = 4,
  PLYR_Nav_Wide_21mm = 4,
  PLYR_Nav_Wide_21mm_Jog = 4,
  PLYR_Nav_Wide_18mm = 4,
  PLYR_Nav_Wide_18mm_Jog = 4,
  AIM_Default_Hack_Nav_Wides = 4,
  PLYR_Nav_Close_26mm_Jog = 5,
  AIM_Default_Hack_Nav_Nears = 5
}
local UpdateNavigationStateCamera = function(player, playerWorldPosition, son)
  local primary_camera = game.Camera.GetPrimary()
  if player:HasMarker("Aiming") or game.UI.GetUserShakeStrength() < 7 and player:HasMarker("Recall") and player.Pad.L2Down == true then
    if player.Pad.L2Down == false and player:HasMarker("Recall") then
      bIsAiming = false
      return
    end
    if bIsAiming == false then
      aimModeTypeValue = tbl_AimModeType[primary_camera.name]
      if aimModeTypeValue ~= nil then
        AimModeHack = aimModeTypeValue
      else
        AimModeHack = 0
      end
      bIsAiming = true
      if player:HasMarker("Recall") == false then
        game.Camera.ZoomSnap(0.2)
      end
    end
    if player:HasMarker("Cranking") then
      game.Camera.SubmitCameraByName("PLYR_Interactive_ChainPull_Aim_Set")
      game.Camera.SubmitCameraByName("PLYR_Crank_Wheel_Aim_PeaksCartCrank")
      game.Camera.SubmitCameraByName("PLYR_Crank_Wheel_Aim_R")
      game.Camera.SubmitCameraByName("PLYR_Crank_Wheel_Aim")
      game.Camera.SubmitCameraByName("PLYR_Crank_Chain_Aim")
    else
      if player:HasMarker("CSLimitedAim") then
        game.Camera.SubmitCameraByName("AIM_LimitedCS")
      end
      if player:HasMarker("FocusAiming") then
        game.Camera.SubmitCameraByName("AIM_Default_FocusCamera")
      end
      if AimModeHack == 1 then
        game.Camera.SubmitCameraByName("AIM_Default_Hack_CBT_Nav_Far")
      elseif AimModeHack == 2 then
        game.Camera.SubmitCameraByName("AIM_Default_Hack_Nav_Base_Idle")
      elseif AimModeHack == 3 then
        game.Camera.SubmitCameraByName("AIM_Default_Hack_Nav_Base_Jog")
      elseif AimModeHack == 4 then
        game.Camera.SubmitCameraByName("AIM_Default_Hack_Nav_Wides")
      elseif AimModeHack == 5 then
        game.Camera.SubmitCameraByName("AIM_Default_Hack_Nav_Nears")
      else
        game.Camera.SubmitCameraByName("AIM_Default")
        game.Camera.SubmitCameraByName("AIM_Default_Recall")
      end
    end
    return
  elseif bIsAiming == true then
    bIsAiming = false
    AimModeHack = 0
  end
  if player:HasMarker("Climbing") then
    game.Camera.SubmitCameraByName("PLYR_CrackClimb")
    local crackClimbInfo = player:GetCurrentTraversalPath()
    if crackClimbInfo.OnExitNode then
      game.Camera.SubmitCameraByName("PLYR_CrackClimb_Enter")
    end
    if player:HasMarker("Enter") then
      game.Camera.SubmitCameraByName("PLYR_CrackClimb_Enter")
      return
    end
    if player:HasMarker("Overhang") then
      game.Camera.SubmitCameraByName("PLYR_CrackClimb_Overhang")
      return
    end
    if player.Pad.CorrectedLeftStick:Length() > 0.01 and player:HasMarker("Idle") ~= true and player:HasMarker("HOD") ~= true then
      game.Camera.SubmitCameraByName("PLYR_CrackClimb_Moving")
    end
    return
  end
  if player:HasMarker("Jumping") then
    if player:HasMarker("Elevated") then
      game.Camera.SubmitCameraByName("PLYR_Nav_GapJump_Elevated")
      return
    else
      game.Camera.SubmitCameraByName("PLYR_Nav_GapJump")
      return
    end
  end
  if player:HasMarker("Sprinting") then
    if player:HasMarker("Frenzy") then
      game.Camera.SubmitCameraByName("PLYR_Sprint_Frenzy")
    elseif player:HasMarker("SprintStart") then
      game.Camera.SubmitCameraByName("CBT_Sprint_Start")
      game.Camera.SubmitCameraByName("CBT_Sprint")
    else
      game.Camera.SubmitCameraByName("CBT_Sprint")
    end
    return
  end
  if player:HasMarker("Evading") then
    if player.Pad.CorrectedLeftStick.y < 0.82 or player:HasMarker("Rolling") then
      game.Camera.SubmitCameraByName("CBT_Dodge")
    end
    return
  end
  if player:HasMarker("Launching") then
    game.Camera.SubmitCameraByName("CBT_Launcher")
    return
  end
  local isNearGapJump = false
  if player:IsInVehicle() == false and player.IsNearTraversalMove then
    isNearGapJump = player:IsNearTraversalMove("MOV_GapJump", 3.5, 0.5)
  end
  if isNearGapJump == true and IsNotInsideWideCameraZone(playerWorldPosition) == true then
    game.Camera.SubmitCameraByName("PLYR_Nav_GapJump_Hint")
  end
  if player:HasMarker("WallPress") then
    if game.World.IsInsideCameraZone(player.WorldPosition, "WallPressCloser*") then
      game.Camera.SubmitCameraByName("PLYR_CrackClimb_FrontPress_Closer")
    end
    game.Camera.SubmitCameraByName("PLYR_CrackClimb_FrontPress")
    return
  end
  if player:HasMarker("Crouching") then
    if son ~= nil and son:IsAvailableInLevel() then
      game.Camera.SubmitCameraByName("PLYR_Nav_Crouch_Idle")
      game.Camera.SubmitCameraByName("PLYR_Nav_Crouch_Moving")
    else
      game.Camera.SubmitCameraByName("PLYR_Nav_Crouch_NoSon")
    end
  end
  if player:HasMarker("Zipline") == true then
    if player:HasMarker("Exit") ~= true then
      game.Camera.SubmitCameraByName("PLYR_Zipline_Set")
    end
    if player:HasMarker("Loop") == true then
      game.Camera.SubmitCameraByName("PLYR_Zipline_MaxSpeed")
    end
  end
  if player:HasMarker("NarrativeCarry") and player:GetNavCurve() ~= nil then
    if player:HasMarker("Boar") then
      game.Camera.SubmitCameraByName("PLYR_NarrativeCarry_Boar_Set")
    elseif player:HasMarker("Son") then
      local playerCurveName = player:GetNavCurve():GetName()
      if playerCurveName == "SonCarryCurveObject" then
        game.Camera.SubmitCameraByName("PLYR_NarrativeCarry_SonSick_010")
      elseif playerCurveName == "sonSickCarry1Object" then
        game.Camera.SubmitCameraByName("PLYR_NarrativeCarry_SonSick_020")
      elseif playerCurveName == "sonSickCarry2Object" then
        game.Camera.SubmitCameraByName("PLYR_NarrativeCarry_SonSick_030")
      end
    elseif player:HasMarker("Log") then
      local playerCurveName = player:GetNavCurve():GetName()
      if playerCurveName == "LogCarry_CurveObj_010" then
        game.Camera.SubmitCameraByName("PLYR_NarrativeCarry_Log_010")
      elseif playerCurveName == "LogCarry_CurveObj" then
        game.Camera.SubmitCameraByName("PLYR_NarrativeCarry_Log_020")
      else
        game.Camera.SubmitCameraByName("PLYR_NarrativeCarry_Log_Testbed")
      end
    end
  end
  if player:HasMarker("CrystalCarry") then
    if player:HasMarker("Moving") then
      game.Camera.SubmitCameraByName("PLYR_Carry_Crystal")
    end
    game.Camera.SubmitCameraByName("PLYR_Carry_Crystal_Idle")
    return
  end
end
local BaseNavCamUpdate = function(player, playersPosition, level)
  if game.World.IsInsideCameraZone(playersPosition, "DefaultNav*") == true then
    return
  elseif game.World.IsInsideCameraZone(playersPosition, "OutDoorWideNav*") == true then
    game.Camera.SubmitCameraByName("PLYR_Nav_Wide_22mm_Set")
  elseif game.World.IsInsideCameraZone(playersPosition, "IndoorWideNav*") == true then
    game.Camera.SubmitCameraByName("PLYR_Nav_Wide_22mm_Set")
  elseif game.World.IsInsideCameraZone(playersPosition, "IndoorBaseNav*") == true then
    game.Camera.SubmitCameraByName("PLYR_Nav_Close_Set")
  elseif game.World.IsInsideCameraZone(playersPosition, "BaseVeryWide*") == true then
    game.Camera.SubmitCameraByName("PLYR_Nav_Wide_21mm_Set")
  end
end
return profile.WrapLibrary({UpdateNavigationStateCamera = UpdateNavigationStateCamera, BaseNavCamUpdate = BaseNavCamUpdate})
