--MasterControl needs access to ControlState in order to be able to fully enable and disable control
MasterControl.ControlState = ControlState

local DynamicThumbstickModule = require(script.MasterControl:WaitForChild('DynamicThumbstick'))
local ThumbstickModule = require(script.MasterControl:WaitForChild('Thumbstick'))
local ThumbpadModule = require(script.MasterControl:WaitForChild('Thumbpad'))
local DPadModule = require(script.MasterControl:WaitForChild('DPad'))
local DefaultModule = ControlModules.Thumbstick
local TouchJumpModule = require(script.MasterControl:WaitForChild('TouchJump'))
MasterControl.TouchJumpModule = TouchJumpModule

local keyboardModule = require(script.MasterControl:WaitForChild('KeyboardMovement'))
ControlModules.Gamepad = require(script.MasterControl:WaitForChild('Gamepad'))

function getTouchModule()
	local module = nil
	if not IsUserChoice then
		if DynamicThumbstickAvailable and DevMovementMode == Enum.DevTouchMovementMode.DynamicThumbstick then
			module = DynamicThumbstickModule
			isJumpEnabled = false
		elseif DevMovementMode == Enum.DevTouchMovementMode.Thumbstick then
			module = ThumbstickModule
			isJumpEnabled = true
		elseif DevMovementMode == Enum.DevTouchMovementMode.Thumbpad then
			module = ThumbpadModule
			isJumpEnabled = true
		elseif DevMovementMode == Enum.DevTouchMovementMode.DPad then
			module = DPadModule
			isJumpEnabled = false
		elseif DevMovementMode == Enum.DevTouchMovementMode.ClickToMove then
			-- Managed by CameraScript
			module = nil
		elseif DevMovementMode == Enum.DevTouchMovementMode.Scriptable then
			module = nil
		end
	else
		if DynamicThumbstickAvailable and UserMovementMode == Enum.TouchMovementMode.DynamicThumbstick then
			module = DynamicThumbstickModule
			isJumpEnabled = false
		elseif UserMovementMode == Enum.TouchMovementMode.Default or UserMovementMode == Enum.TouchMovementMode.Thumbstick then
			module = ThumbstickModule
			isJumpEnabled = true
		elseif UserMovementMode == Enum.TouchMovementMode.Thumbpad then
			module = ThumbpadModule
			isJumpEnabled = true
		elseif UserMovementMode == Enum.TouchMovementMode.DPad then
			module = DPadModule
			isJumpEnabled = false
		elseif UserMovementMode == Enum.TouchMovementMode.ClickToMove then
			-- Managed by CameraScript
			module = nil
		end
	end
	
	return module
end

function setJumpModule(isEnabled)
	if not isEnabled then
		TouchJumpModule:Disable()
	elseif ControlState.Current == ControlModules.Touch then
		TouchJumpModule:Enable()
	end
end

function setClickToMove()
	if DevMovementMode == Enum.DevTouchMovementMode.ClickToMove or DevMovementMode == Enum.DevComputerMovementMode.ClickToMove or
		UserMovementMode == Enum.ComputerMovementMode.ClickToMove or UserMovementMode == Enum.TouchMovementMode.ClickToMove then
		--
		if lastInputType == Enum.UserInputType.Touch then
			ClickToMoveTouchControls = ControlState.Current
		end
	elseif ClickToMoveTouchControls then
		ClickToMoveTouchControls:Disable()
		ClickToMoveTouchControls = nil
	end
end

ControlModules.Touch = {}
ControlModules.Touch.Current = nil
ControlModules.Touch.LocalPlayerChangedCon = nil
ControlModules.Touch.GameSettingsChangedCon = nil

function ControlModules.Touch:RefreshControlStyle()
	if ControlModules.Touch.Current then
		ControlModules.Touch.Current:Disable()
	end
	setJumpModule(false)
	TouchJumpModule:Disable()
	ControlModules.Touch:Enable()
end
function ControlModules.Touch:DisconnectEvents()
	if ControlModules.Touch.LocalPlayerChangedCon then
		ControlModules.Touch.LocalPlayerChangedCon:disconnect()
		ControlModules.Touch.LocalPlayerChangedCon = nil
	end
	if ControlModules.Touch.GameSettingsChangedCon then
		ControlModules.Touch.GameSettingsChangedCon:disconnect()
		ControlModules.Touch.GameSettingsChangedCon = nil
	end
end
function ControlModules.Touch:Enable()
	DevMovementMode = LocalPlayer.DevTouchMovementMode
	IsUserChoice = DevMovementMode == Enum.DevTouchMovementMode.UserChoice
	if IsUserChoice then
		UserMovementMode = GameSettings.TouchMovementMode
	end
		
	local newModuleToEnable = getTouchModule()
	if newModuleToEnable then
		setClickToMove()
		setJumpModule(isJumpEnabled)
		
		newModuleToEnable:Enable()
		ControlModules.Touch.Current = newModuleToEnable
				
		if isJumpEnabled then TouchJumpModule:Enable() end
	end
	
	-- This being within the above if statement was causing issues with ClickToMove, which isn't a module within this script.
	ControlModules.Touch:DisconnectEvents()
	ControlModules.Touch.LocalPlayerChangedCon = LocalPlayer.Changed:connect(function(property)
		if property == 'DevTouchMovementMode' then
			ControlModules.Touch:RefreshControlStyle()
		end
	end)
	
	ControlModules.Touch.GameSettingsChangedCon = GameSettings.Changed:connect(function(property)
		if property == 'TouchMovementMode' then
			ControlModules.Touch:RefreshControlStyle()
		end
	end)
end
function ControlModules.Touch:Disable()
	ControlModules.Touch:DisconnectEvents()
	
	local newModuleToDisable = getTouchModule()
	
	if newModuleToDisable == ThumbstickModule or
		newModuleToDisable == DPadModule or
		newModuleToDisable == ThumbpadModule or
		newModuleToDisable == DynamicThumbstickModule then
			newModuleToDisable:Disable()
			setJumpModule(false)
			TouchJumpModule:Disable()
	end
end

local function getKeyboardModule()
	-- NOTE: Click to move still uses keyboard. Leaving cases in case this ever changes.
	local whichModule = nil
	if not IsUserChoice then
		if DevMovementMode == Enum.DevComputerMovementMode.KeyboardMouse then
			whichModule = keyboardModule
		elseif DevMovementMode == Enum.DevComputerMovementMode.ClickToMove then
			-- Managed by CameraScript
			whichModule = keyboardModule
		end 
	else
		if UserMovementMode == Enum.ComputerMovementMode.KeyboardMouse or UserMovementMode == Enum.ComputerMovementMode.Default then
			whichModule = keyboardModule
		elseif UserMovementMode == Enum.ComputerMovementMode.ClickToMove then
			-- Managed by CameraScript
			whichModule = keyboardModule
		end
	end

	return whichModule
end

ControlModules.Keyboard = {}
function ControlModules.Keyboard:RefreshControlStyle()
	ControlModules.Keyboard:Disable()
	ControlModules.Keyboard:Enable()
end
function ControlModules.Keyboard:Enable()
	DevMovementMode = LocalPlayer.DevComputerMovementMode
	IsUserChoice = DevMovementMode == Enum.DevComputerMovementMode.UserChoice
	if IsUserChoice then
		UserMovementMode = GameSettings.ComputerMovementMode
	end
		
	local newModuleToEnable = getKeyboardModule()
	if newModuleToEnable then
		newModuleToEnable:Enable()
	end
	
	ControlModules.Keyboard:DisconnectEvents()
	ControlModules.Keyboard.LocalPlayerChangedCon = LocalPlayer.Changed:connect(function(property)
		if property == 'DevComputerMovementMode' then
			ControlModules.Keyboard:RefreshControlStyle()
		end
	end)
	
	ControlModules.Keyboard.GameSettingsChangedCon = GameSettings.Changed:connect(function(property)
		if property == 'ComputerMovementMode' then
			ControlModules.Keyboard:RefreshControlStyle()
		end
	end)
end
function ControlModules.Keyboard:DisconnectEvents()
	if ControlModules.Keyboard.LocalPlayerChangedCon then
		ControlModules.Keyboard.LocalPlayerChangedCon:disconnect()
		ControlModules.Keyboard.LocalPlayerChangedCon = nil
	end
	if ControlModules.Keyboard.GameSettingsChangedCon then
		ControlModules.Keyboard.GameSettingsChangedCon:disconnect()
		ControlModules.Keyboard.GameSettingsChangedCon = nil
	end
end
function ControlModules.Keyboard:Disable()
	ControlModules.Keyboard:DisconnectEvents()
	local newModuleToDisable = getKeyboardModule()
	if newModuleToDisable then
		newModuleToDisable:Disable()
	end
end

if IsTouchDevice then
	BindableEvent_OnFailStateChanged = script.Parent:WaitForChild('OnClickToMoveFailStateChange')
end