-----------------------
--| Local Functions |--
-----------------------


local function LimbBehavior(castPoints)
	for limb, _ in pairs(TrackedLimbs) do
		castPoints[#castPoints + 1] = limb.Position
	end
end

local function MoveBehavior(castPoints)
	for i = 1, MOVE_CASTS do
		local position, velocity = Torso.Position, Torso.Velocity
		local horizontalSpeed = Vector3_new(velocity.X, 0, velocity.Z).Magnitude / 2
		local offsetVector = (i - 1) * Torso.CFrame.lookVector * horizontalSpeed
		castPoints[#castPoints + 1] = position + offsetVector
	end
end

local function CornerBehavior(castPoints)
	local cframe = Torso.CFrame
	local centerPoint = cframe.p
	local rotation = cframe - centerPoint
	local halfSize = Character:GetExtentsSize() / 2 --NOTE: Doesn't update w/ limb animations
	castPoints[#castPoints + 1] = centerPoint
	for i = 1, #CORNER_FACTORS do
		castPoints[#castPoints + 1] = centerPoint + (rotation * (halfSize * CORNER_FACTORS[i]))
	end
end

local function CircleBehavior(castPoints)
	local cframe = nil
	if Mode == MODE.CIRCLE1 then
		cframe = Torso.CFrame
	else
		local camCFrame = Camera.CoordinateFrame
		cframe = camCFrame - camCFrame.p + Torso.Position
	end
	castPoints[#castPoints + 1] = cframe.p
	for i = 0, CIRCLE_CASTS - 1 do
		local angle = (2 * math_pi / CIRCLE_CASTS) * i
		local offset = 3 * Vector3_new(math_cos(angle), math_sin(angle), 0)
		castPoints[#castPoints + 1] = cframe * offset
	end
end

local function LimbMoveBehavior(castPoints)
	LimbBehavior(castPoints)
	MoveBehavior(castPoints)
end

local function OnCharacterAdded(character)
	if childAddedConn then
		childAddedConn:disconnect()
		childAddedConn = nil
	end
	if childRemovedConn then
		childRemovedConn:disconnect()
		childRemovedConn = nil
	end

	Character = character
	
	TrackedLimbs = {}
	local function childAdded(child)
		if child:IsA('BasePart') and LIMB_TRACKING_SET[child.Name] then
			TrackedLimbs[child] = true
		end
	end
	
	local function childRemoved(child)
		TrackedLimbs[child] = nil
	end	
	
	childAddedConn = character.ChildAdded:connect(childAdded)
	childRemovedConn = character.ChildRemoved:connect(childRemoved)
	
	for _, child in pairs(Character:GetChildren()) do
		childAdded(child)
	end
end

local function OnWorkspaceChanged(property)
	if property == 'CurrentCamera' then
		local newCamera = workspace.CurrentCamera
		if newCamera then
			Camera = newCamera
		end
	end
end
