-- adds a BezierPoint to the Bezier
-- a BezierPoint can either be a Vector3 or a BasePart
-- a Vector3 BezierPoint is static, while a BasePart BezierPoint changes if the BasePart's position changes

function Bezier:AddBezierPoint(p: Vector3 | BasePart, index: number?)
	
	-- check if given value is a Vector3 or BasePart
	if p and (typeof(p) == "Instance" and p:IsA("BasePart")) or typeof(p) == "Vector3" then
		local newPoint: BezierPoint = {
			Type = typeof(p) == "Vector3" and "StaicPoint" or "BasePartPoint";
			Point = p;
		}
		
		-- if point is a BasePartPoint, then watch for removal and changes
		if newPoint.Type == "BasePartPoint" then
			local connection, connection2
			
			-- changed connection
			connection = (p:: BasePart).Changed:Connect(function(prop)
				if prop == "Position" then
					self:UpdateLength()
				end
			end)
			
			-- deleted connection
			connection2 = (p:: BasePart).AncestryChanged:Connect(function(_, parent)
				if parent == nil then
					local index = table.find(self.Points, newPoint)
					if index then
						table.remove(self.Points, index)
					end
					connection:Disconnect()
					connection:Disconnect()
				end
			end)
			
			-- check if there is a connection table for the basepart
			if not self._connections[p] then
				self._connections[p] = {}
			end
			
			-- add connections to connection table
			table.insert(self._connections[p], connection)
			table.insert(self._connections[p], connection2)
		end
		
		-- add to list of points
		if index and type(index) == "number" then
			
			-- found index, add at index
			table.insert(self.Points, index, newPoint)
		elseif not index then
			
			-- did not find index, add to end of table
			table.insert(self.Points, newPoint)
		elseif type(index) ~= "number" then
			
			-- incorrect type
			error("Bezier:AddBezierPoint() only accepts an integer as the second argument!")
		end
		
		-- update bezier
		self:UpdateLength()
	else
		error("Bezier:AddBezierPoint() only accepts a Vector3 or BasePart as the first argument!")
	end
end

