local z={}z.__index=z function z.new(a,h)assert(a,"\077\105\115\115\105\110\103 \097\114\103\117\109\101\110\116 \035\049\058 \116\097\114\103\101\116\086\097\108\117\101")h=h or{}return setmetatable({_targetValue=a;_velocity=h.velocity or 1},z)end function z.step(h,z,a)local n=z.value local P=h._velocity local f=h._targetValue local M=a*P local B=M>=math.abs(f-n)n=n+M*(f>n and 1 or-1)if B then n=h._targetValue P=0 end return{complete=B;value=n;velocity=P}end return z
local Linear = {}
Linear.__index = Linear

function Linear.new(targetValue, options)
	assert(targetValue, "Missing argument #1: targetValue")

	options = options or {}

	return setmetatable({
		_targetValue = targetValue,
		_velocity = options.velocity or 1,
	}, Linear)
end

function Linear:step(state, dt)
	local position = state.value
	local velocity = self._velocity -- Linear motion ignores the state's velocity
	local goal = self._targetValue

	local dPos = dt * velocity

	local complete = dPos >= math.abs(goal - position)
	position = position + dPos * (goal > position and 1 or -1)
	if complete then
		position = self._targetValue
		velocity = 0
	end

	return {
		complete = complete,
		value = position,
		velocity = velocity,
	}
end

return Linear
