-- Ctor

function ActiveCastStatic.new(caster: Caster, origin: Vector3, direction: Vector3, velocity: Vector3 | number, castDataPacket: FastCastBehavior): ActiveCast
	if typeof(velocity) == "number" then
		velocity = direction.Unit * velocity
	end	
	
	-- Basic setup
	local cast = {
		Caster = caster,
		
		-- Data that keeps track of what's going on as well as edits we might make during runtime.
		StateInfo = {
			UpdateConnection = nil,
			Paused = false,
			TotalRuntime = 0,
			DistanceCovered = 0,
			IsActivelySimulatingPierce = false,
			Trajectories = {
				{
					StartTime = 0,
					EndTime = -1,
					Origin = origin,
					InitialVelocity = velocity,
					Acceleration = castDataPacket.Acceleration
				}
			}
		},
		
		-- Information pertaining to actual raycasting.
		RayInfo = {
			Parameters = castDataPacket.RaycastParams,
			WorldRoot = workspace,
			MaxDistance = castDataPacket.MaxDistance or 1000,
			CosmeticBulletObject = castDataPacket.CosmeticBulletTemplate,
			CanPierceCallback = castDataPacket.CanPierceFunction
		},
		
		UserData = {}
	}
	
	
	if cast.RayInfo.Parameters ~= nil then
		cast.RayInfo.Parameters = CloneCastParams(cast.RayInfo.Parameters)
	end
	
	if cast.RayInfo.CosmeticBulletObject ~= nil then
		cast.RayInfo.CosmeticBulletObject = cast.RayInfo.CosmeticBulletObject:Clone()
		cast.RayInfo.CosmeticBulletObject.CFrame = CFrame.new(origin, origin + direction)
		cast.RayInfo.CosmeticBulletObject.Parent = castDataPacket.CosmeticBulletContainer
	end
	
	if castDataPacket.AutoIgnoreContainer == true and castDataPacket.CosmeticBulletContainer ~= nil then
		local ignoreList = cast.RayInfo.Parameters.FilterDescendantsInstances
		if table.find(ignoreList, castDataPacket.CosmeticBulletContainer) == nil then
			table.insert(ignoreList, castDataPacket.CosmeticBulletContainer)
			cast.RayInfo.Parameters.FilterDescendantsInstances = ignoreList
		end
	end
	
	local event
	if RunService:IsClient() then
		event = RunService.RenderStepped
	else
		event = RunService.Heartbeat
	end
	event:wait()
	cast.StateInfo.UpdateConnection = event:Connect(function (delta)
		if cast.StateInfo.Paused then return end
		SimulateCast(cast, delta)
	end)
	
	return setmetatable(cast, ActiveCastStatic)
end

function ActiveCastStatic.SetStaticFastCastReference(ref)
	FastCast = ref
end
