function PlayerSpots.assignSpot(T,F,H)T:_removeUnusedSpots(F)local C=#T.placedSpots<T.quota local b=not H:isFull()local A=T:_hasArtOnCanvas(H)if b and C then return T:_assignRandomSpot(H)elseif b and not C then T:_removeOldestArt()return T:_assignRandomSpot(H)elseif not b and A then T:_removeOldestArtFromCanvas(H)return T:_assignRandomSpot(H)elseif b and(not C and not A)then T:_removeOldestArtFromOtherCanvas(H)return T:_assignRandomSpot(H)elseif not b and not A then return false,constants.Errors.SpotNotAvailable end end
--[[
	Assigns a new spot on a canvas for the current player.

	Complex logic for multiple cases, but we broke these down into a table form in Confluence.
	Refer to the tech spec for more information!

	https://confluence.rbx.com/display/SOCIAL/Surface+Art+Tech+Spec#SurfaceArtTechSpec-spot-assigning-logic

	Parameters:
	- canvas (Canvas): current Canvas object that player wants to apply an art on
]]
function PlayerSpots:assignSpot(player, canvas)
	-- Removes previous spot that has no art placed. This happens if player gets a spot but cancels before placing an art
	self:_removeUnusedSpots(player)

	local playerHasQuota = #self.placedSpots < self.quota
	local canvasHasSpot = not canvas:isFull()
	local playerHasArtOnSurface = self:_hasArtOnCanvas(canvas)

	if canvasHasSpot and playerHasQuota then
		return self:_assignRandomSpot(canvas)
	elseif canvasHasSpot and not playerHasQuota then
		self:_removeOldestArt()

		return self:_assignRandomSpot(canvas)
	elseif not canvasHasSpot and playerHasArtOnSurface then
		self:_removeOldestArtFromCanvas(canvas)

		return self:_assignRandomSpot(canvas)
	elseif canvasHasSpot and not playerHasQuota and not playerHasArtOnSurface then
		self:_removeOldestArtFromOtherCanvas(canvas)

		return self:_assignRandomSpot(canvas)
	elseif not canvasHasSpot and not playerHasArtOnSurface then
		return false, constants.Errors.SpotNotAvailable
	end
end
