-- register what camera scripts we are using
do
	local PlayerScripts = PlayersService.LocalPlayer:WaitForChild("PlayerScripts")
	local canRegisterCameras = pcall(function() PlayerScripts:RegisterTouchCameraMovementMode(Enum.TouchCameraMovementMode.Default) end)

	if canRegisterCameras then
		PlayerScripts:RegisterTouchCameraMovementMode(Enum.TouchCameraMovementMode.Follow)
		PlayerScripts:RegisterTouchCameraMovementMode(Enum.TouchCameraMovementMode.Classic)

		PlayerScripts:RegisterComputerCameraMovementMode(Enum.ComputerCameraMovementMode.Default)
		PlayerScripts:RegisterComputerCameraMovementMode(Enum.ComputerCameraMovementMode.Follow)
		PlayerScripts:RegisterComputerCameraMovementMode(Enum.ComputerCameraMovementMode.Classic)
	end
end

local CameraTypeEnumMap = 
{
	[Enum.CameraType.Attach] = AttachCamera;
	[Enum.CameraType.Fixed] = FixedCamera;
	[Enum.CameraType.Scriptable] = ScriptableCamera;
	[Enum.CameraType.Track] = TrackCamera;
	[Enum.CameraType.Watch] = WatchCamera;
	[Enum.CameraType.Follow] = FollowCamera;
}

if isOrbitalCameraEnabled then
	CameraTypeEnumMap[Enum.CameraType.Orbital] = OrbitalCamera;
end

local EnabledCamera = nil
local EnabledOcclusion = nil

local cameraSubjectChangedConn = nil
local cameraTypeChangedConn = nil
local renderSteppedConn = nil

local lastInputType = nil
local hasLastInput = false

local function IsTouch()
	return UserInputService.TouchEnabled
end

local function shouldUsePlayerScriptsCamera()
	local player = PlayersService.LocalPlayer
	local currentCamera = workspace.CurrentCamera
	if AllCamerasInLua then
		return true
	else
		if player then
			if currentCamera == nil or (currentCamera.CameraType == Enum.CameraType.Custom)
						or (isOrbitalCameraEnabled and currentCamera.CameraType == Enum.CameraType.Orbital) then
				return true
			end
		end
	end
	return false
end

local function isClickToMoveOn()
	local usePlayerScripts = shouldUsePlayerScriptsCamera()
	local player = PlayersService.LocalPlayer
	if usePlayerScripts and player then
		if (hasLastInput and lastInputType == Enum.UserInputType.Touch) or IsTouch() then -- Touch
			if player.DevTouchMovementMode == Enum.DevTouchMovementMode.ClickToMove or
					(player.DevTouchMovementMode == Enum.DevTouchMovementMode.UserChoice and GameSettings.TouchMovementMode == Enum.TouchMovementMode.ClickToMove) then
				return true
			end
		else -- Computer
			if player.DevComputerMovementMode == Enum.DevComputerMovementMode.ClickToMove or
					(player.DevComputerMovementMode == Enum.DevComputerMovementMode.UserChoice and GameSettings.ComputerMovementMode == Enum.ComputerMovementMode.ClickToMove) then
				return true
			end
		end
	end
	return false
end

local function getCurrentCameraMode()
	local usePlayerScripts = shouldUsePlayerScriptsCamera()
	local player = PlayersService.LocalPlayer
	if usePlayerScripts and player then
		if (hasLastInput and lastInputType == Enum.UserInputType.Touch) or IsTouch() then -- Touch (iPad, etc...)
			if not FFlagUserNoCameraClickToMove and isClickToMoveOn() then
				return Enum.DevTouchMovementMode.ClickToMove.Name
			elseif player.DevTouchCameraMode == Enum.DevTouchCameraMovementMode.UserChoice then
				local touchMovementMode = GameSettings.TouchCameraMovementMode
				if touchMovementMode == Enum.TouchCameraMovementMode.Default then
					return Enum.TouchCameraMovementMode.Follow.Name
				end
				return touchMovementMode.Name
			else
				return player.DevTouchCameraMode.Name
			end
		else -- Computer
			if not FFlagUserNoCameraClickToMove and isClickToMoveOn() then
				return Enum.DevComputerMovementMode.ClickToMove.Name
			elseif player.DevComputerCameraMode == Enum.DevComputerCameraMovementMode.UserChoice then
				local computerMovementMode = GameSettings.ComputerCameraMovementMode
				if computerMovementMode == Enum.ComputerCameraMovementMode.Default then
					return Enum.ComputerCameraMovementMode.Classic.Name
				end
				return computerMovementMode.Name
			else
				return player.DevComputerCameraMode.Name
			end
		end
	end
end

local function getCameraOcclusionMode()
	local usePlayerScripts = shouldUsePlayerScriptsCamera()
	local player = PlayersService.LocalPlayer
	if usePlayerScripts and player then
		return player.DevCameraOcclusionMode
	end
end