--[[
	Creates a new spring.
]]

function Spring.new(initial, td, ts)
	local d=td or 1
	local s=ts or 1
	local p0=initial or 0
	local v0=0*p0
	local p1=p0
	local v1=v0
	local t0=tick()

	local selfmeta={}
	local meta={}

	function selfmeta.getpv()
		return posvel(d,s,p0,v0,p1,v1,tick()-t0)
	end

	function selfmeta.setpv(p,v)
		local time=tick()
		local tp,tv=targposvel(p1,v1,time-t0)
		p0,v0=p,v
		p1,v1=tp,tv
		t0=time
	end

	function selfmeta.settargetpv(tp,tv)
		local time=tick()
		local p,v=posvel(d,s,p0,v0,p1,v1,time-t0)
		p0,v0=p,v
		p1,v1=tp,tv
		t0=time
	end

	function selfmeta:accelerate(a)
		local time=tick()
		local p,v=posvel(d,s,p0,v0,p1,v1,time-t0)
		local tp,tv=targposvel(p1,v1,time-t0)
		p0,v0=p,v+a
		p1,v1=tp,tv
		t0=time
	end

	function meta.__index(_self,index)
		local time=tick()
		if index=="p" or index=="position" then
			local p,_v=posvel(d,s,p0,v0,p1,v1,time-t0)
			return p
		elseif index=="v" or index=="velocity" then
			local _p,v=posvel(d,s,p0,v0,p1,v1,time-t0)
			return v
		elseif index=="tp" or index=="t" or index=="targetposition" then
			local tp,_tv=targposvel(p1,v1,time-t0)
			return tp
		elseif index=="tv" or index=="targetvelocity" then
			local _tp,tv=targposvel(p1,v1,time-t0)
			return tv
		elseif index=="d" or index=="damper" then
			return d
		elseif index=="s" or index=="speed" then
			return s
		else
			error("no value "..tostring(index).." exists")
		end
	end

	function meta.__newindex(_self,index,value)
		local time=tick()
		if index=="p" or index=="position" then
			local _p,v=posvel(d,s,p0,v0,p1,v1,time-t0)
			local tp,tv=targposvel(p1,v1,time-t0)
			p0,v0=value,v
			p1,v1=tp,tv
		elseif index=="v" or index=="velocity" then
			local p,_v=posvel(d,s,p0,v0,p1,v1,time-t0)
			local tp,tv=targposvel(p1,v1,time-t0)
			p0,v0=p,value
			p1,v1=tp,tv
		elseif index=="tp" or index=="t" or index=="targetposition" then
			local p,v=posvel(d,s,p0,v0,p1,v1,time-t0)
			local _tp,tv=targposvel(p1,v1,time-t0)
			p0,v0=p,v
			p1,v1=value,tv
		elseif index=="tv" or index=="targetvelocity" then
			local p,v=posvel(d,s,p0,v0,p1,v1,time-t0)
			local tp,_tv=targposvel(p1,v1,time-t0)
			p0,v0=p,v
			p1,v1=tp,value
		elseif index=="d" or index=="damper" then
			local p,v=posvel(d,s,p0,v0,p1,v1,time-t0)
			local tp,tv=targposvel(p1,v1,time-t0)
			p0,v0=p,v
			p1,v1=tp,tv
			d=value
		elseif index=="s" or index=="speed" then
			local p,v=posvel(d,s,p0,v0,p1,v1,time-t0)
			local tp,tv=targposvel(p1,v1,time-t0)
			p0,v0=p,v
			p1,v1=tp,tv
			s=value
		elseif index=="a" or index=="acceleration" then
			t0=tick()
			local p,v=posvel(d,s,p0,v0,p1,v1,time-t0)
			local tp,tv=targposvel(p1,v1,time-t0)
			p0,v0=p,v+value
			p1,v1=tp,tv
		else
			error("no value "..tostring(index).." exists")
		end
		t0=time
	end

	return setmetatable(selfmeta,meta)
end


return Spring
