local TS = require(
	game:GetService("ReplicatedStorage")
		:WaitForChild("RobloxTS")
		:WaitForChild("Include")
		:WaitForChild("RuntimeLib")
);
local _exports = {};
local MovementController = TS.import(script.Parent, "MovementController").MovementController;
local InputController = TS.import(script.Parent, "InputController").InputController;
local _0 = TS.import(script.Parent, "StateController");
local StateController, State = _0.StateController, _0.State;
local AnimationController = TS.import(script.Parent, "AnimationController").AnimationController;
local Players = require(TS.getModule("rbx-services", script.Parent)).Players;
local player = Players.LocalPlayer;
local playerScripts = player:WaitForChild("PlayerScripts");
_exports.State = TS.import(script.Parent, "StateController").State;
local CharacterController;
do
	CharacterController = {};
	CharacterController.__index = {
		getVelocity = function(self)
			return self.movementController.velocity;
		end;
		setVelocity = function(self, velocity)
			self.movementController.velocity = velocity;
		end;
		getMobile = function(self)
			return self.movementController.mobile;
		end;
		setMobile = function(self, mobile)
			self.movementController.mobile = mobile;
		end;
		bounce = function(self, height)
			self.movementController:bounce(height);
		end;
		move = function(self, position)
			self.movementController:move(position);
		end;
		isGrounded = function(self)
			return self.movementController:isGrounded();
		end;
		isMoving = function(self)
			return self.movementController:isMoving();
		end;
		humanoidStateChanged = function(self, event)
			return self.movementController:humanoidStateChanged(event);
		end;
		landed = function(self, event)
			return self.movementController:landed(event);
		end;
		getPrimaryPart = function(self)
			return self.movementController.primaryPart;
		end;
		getHumanoid = function(self)
			return self.movementController.humanoid;
		end;
		jumpInput = function(self, event)
			return self.inputController:jumpInput(event);
		end;
		moveInput = function(self, event)
			return self.inputController:moveInput(event);
		end;
		crouchInput = function(self, event)
			return self.inputController:crouchInput(event);
		end;
		addState = function(self, state)
			self.stateController:addState(state);
		end;
		addStates = function(self, states)
			self.stateController:addStates(states);
		end;
		setState = function(self, stateName)
			self.stateController:setState(stateName);
		end;
		getState = function(self)
			return self.stateController:getState();
		end;
		loadAnimation = function(self, animationId)
			return self.animationController:loadAnimation(animationId);
		end;
		getAnimatable = function(self)
			return self.animationController:getAnimatable();
		end;
		setAnimatable = function(self, animatable)
			self.animationController:setAnimatable(animatable);
		end;
	};
	CharacterController.new = function(...)
		return CharacterController.constructor(setmetatable({}, CharacterController), ...);
	end;
	CharacterController.constructor = function(self, character)
		if not character.PrimaryPart then
			error("No primaryPart found on the character.");
		end;
		spawn(function()
			if not game.IsLoaded then
				game.Loaded:Wait();
			end;
			if playerScripts:FindFirstChild("PlayerModule") and playerScripts:WaitForChild("PlayerModule"):FindFirstChild("ControlModule") then
				local controlModule = require(playerScripts:WaitForChild("PlayerModule"):WaitForChild("ControlModule"));
				controlModule.Disable(controlModule);
			end;
		end);
		player.Character = character;
		self.character = character;
		self.movementController = MovementController.new(self);
		self.inputController = InputController.new(self);
		self.stateController = StateController.new(self);
		self.animationController = AnimationController.new(self);
		return self;
	end;
end;
_exports.CharacterController = CharacterController;
return _exports;
