entity = {list = {}, ticks = 0, space = dspacehash.new(), layer = layer}
function entity.new (name,x,y,z)
	local self = {
		name = name or "entity",
		actor = actornode.new (name or "entity"),
		geoms = {}, geomlut = {}, transformedgeoms = {},
		l3ds = {},
		emitters = {},
		age = 0,
		actorlist = {},
		defaultspace = entity.space,
		jointlist = {}
	}
	
	self.actor:pos(x or 0, y or 0, z or 0)
	table.insert(entity.list,self)
	
	setmetatable(self,{__index = entity})
	
	return self
end

function entity.pos (self,...)
	return self.actor:pos(...)
end

function entity.think (self)
	return self._remove
end

function entity.makesubspace (self)
	self.subspace = dspacehash.new()
	self.defaultspace = self.subspace
	entity.space:add(self.subspace)
end

function entity.addjoint(self,joint)
	table.insert(self.jointlist,joint)
	return joint
end

function entity.pause(self,pause)
	if (self.animpause and pause or (not self.animpause and not pause))
		then return end
	if (not self.animpause) then
		self.animpause = {}
		for i,v in ipairs(self.l3ds) do
			if (v:isanimateable()) then
				self.animpause[i] = {
					v:seqState(0), v:seqState(1) 
				}
				v:seqState(0,2) v:seqState(1,2)
			end
		end
	else
		for i,v in ipairs(self.l3ds) do
			if (v:isanimateable()) then
				v:seqState(0,self.animpause[i][1])
				v:seqState(1,self.animpause[i][2])
			end
		end
		self.animpause = nil
	end
end

function entity.addl3d (self,l3d,x,y,z,boneanim)
	if (type(l3d)=="string") then
		mdl = model.load(l3d,boneanim and true or false,true,boneanim and  technique.arb_v():supported() and true or false)
		l3d = l3dmodel.new(self.name,self.layer,mdl,boneanim and true or false,false)
		l3d:rfLitSun(true)
		l3d:rfLitFX(true)
	end
	table.insert(self.l3ds,l3d)
	l3d:linkinterface(self.actor)
	if (x and y and z) then 
		l3d:uselocal(true)
		l3d:localpos(x,y,z)
	end
	return l3d
end

function entity.addemitter(self,psys,layer,position)
	local e = l3dpemitter.new(self.name,layer,psys)
	table.insert(self.emitters,e)
	e:linkinterface(self.actor)
	if (position) then 
		local x,y,z,rx,ry,rz = unpack(position)
		e:uselocal(true)
		e:localrotdeg(rx or 0,ry or 0,rz or 0)
		e:localpos(x or 0,y or 0, z or 0)
	end
	e:start(0)
	return e
end

function entity.addgeom (self,geom,surfid,transformgeom,x,y,z)
	self.defaultspace:add(geom)
	self.geomlut[luxinia.dataID(geom)] = self
	geom:surfaceid(surfid or 0)
	table.insert(self.geoms,geom)
	if (transformgeom) then
		geom:geom(transformgeom)
		transformgeom:pos(x or 0,y or 0,z or 0)
		table.insert(self.transformedgeoms,transformgeom)
	end
	
	if (not self.body) then return geom,transformgeom end
	geom:body(self.body)
	return geom,transformgeom
end

function entity.getnewactor (self)
	local ac = actornode.new(self.name)
	table.insert(self.actorlist,ac)
	return ac
end

function entity.hasgeom (self,geom)
	return self.geomlut[luxinia.dataID(geom)]
end

function entity.makebody (self)
	if (self.body) then return end
	self.body = dbody.new()
	self.body:pos(self.actor:pos())
	self.actor:link(self.body)
	for i,v in ipairs(self.geoms) do
		v:body(self.body)
	end
	return body
end

function entity.pauseall (p)
	for i,v in ipairs(entity.list) do
		v:pause(p)
	end
end

function entity.delete (self)
	self._delete = true
end

do 
	local function delete (self) 	 -- private delete function
		if (self.delete) then self:delete() end
		if (self._del) then return end
		self._del = true
		self.actor:delete()
		if (self.body) then self.body:delete() end
		for i,v in ipairs(self.geoms) do
			v:delete()
		end
		for i,v in ipairs(self.l3ds) do
			pcall(function() v:delete() end)
		end
		for i,v in ipairs(self.emitters) do
			v:delete()
		end
		for i,v in ipairs(self.transformedgeoms) do
			v:delete()
		end
		for i,v in ipairs(self.actorlist) do
			v:delete()
		end
		if (self.subspace) then
			self.subspace:delete()
		end
		for i,v in ipairs(self.jointlist) do
			v:delete()
		end
	end
	
	function entity.removeall ()
		for i,v in ipairs(entity.list) do
			delete(v)
		end
		entity.list = {}
		entity.space:delete()
		entity.space = dspacehash.new()
	end
	
	function entity.thinkall ()
		for i,v in ipairs(entity.list) do
			if (v._delete or v:think()) then
				delete(v)
				table.remove(entity.list,i);
				i = i-1;
			end
			v.age = v.age + 1
		end
		entity.ticks = entity.ticks + 1
	end
end	
