--[[
	Responsible for displaying a single piece of artwork on the canvas.
]]

local SurfaceSpot = Roact.Component:extend("SurfaceSpot")

SurfaceSpot.defaultProps = {
	padding = UDim.new(0, 16),
}

function SurfaceSpot:init()
	self.scale, self.updateScale = Roact.createBinding(1)
	self.scaleMotor = Otter.createSingleMotor(self.scale:getValue())
	self.scaleMotor:onStep(self.updateScale)

	self.transparency, self.updateTransparency = Roact.createBinding(0)
	self.transparencyMotor = Otter.createSingleMotor(self.transparency:getValue())
	self.transparencyMotor:onStep(self.updateTransparency)
end

function SurfaceSpot:render()
	local image = self.props.image or self.image

	return Roact.createElement("Frame", {
		BackgroundTransparency = 1,
		Size = UDim2.fromScale(1, 1),
		[Roact.Ref] = self.props.innerRef,
	}, {
		-- Add extra padding if needed
		Padding = Roact.createElement("UIPadding", {
			PaddingTop = self.props.padding,
			PaddingBottom = self.props.padding,
			PaddingLeft = self.props.padding,
			PaddingRight = self.props.padding,
		}),
		Art = image and Roact.createElement("ImageLabel", {
			BackgroundTransparency = 1,
			ImageTransparency = self.transparency,
			Size = UDim2.fromScale(1, 1),
			AnchorPoint = Vector2.new(0.5, 0.5),
			Position = UDim2.fromScale(0.5, 0.5),
			Image = image,
			ScaleType = Enum.ScaleType.Fit,
		}, {
			UIScale = Roact.createElement("UIScale", {
				Scale = self.scale,
			}),
			UIAspectRatio = Roact.createElement("UIAspectRatioConstraint", {
				DominantAxis = Enum.DominantAxis.Height,
				AspectType = Enum.AspectType.FitWithinMaxSize,
			}),
		}),
	})
end

function SurfaceSpot:willUpdate(nextProps)
	if nextProps.image == self.props.image then
		return
	end

	-- Stores the image temporarily before render is called so that ImageLabel does not unmount after image props
	-- change, and before animation completes.
	if not nextProps.image then
		self.image = self.props.image
	else
		self.image = nil
	end
end

function SurfaceSpot:didUpdate(prevProps)
	if prevProps.image ~= self.props.image then
		task.spawn(function()
			if self.props.image then
				-- Scale image when it appears
				self.transparencyMotor:setGoal(Otter.instant(0))
				self.scaleMotor:setGoal(Otter.spring(1.2))
				task.wait(1)
				self.scaleMotor:setGoal(Otter.spring(1))
				task.wait(1)
			else
				-- Fade image out when it disappears
				self.transparencyMotor:setGoal(Otter.spring(1))
				task.wait(1)
				self.image = nil
			end
		end)
	end
end

return Roact.forwardRef(function(props, ref)
	return Roact.createElement(SurfaceSpot, Cryo.Dictionary.join(props, { innerRef = ref }))
end)
