gui = {}
gui.elements = {}

gui.element = {}
function gui.element.new (parent)
	local self = {bounds = {0,0,0,0,0},rotation = {0,0,0}}
	setmetatable(self,{__index = parent or gui.element })
	self.enabled = true
	table.insert(gui.elements,self)	
	return self
end

function gui.element.setbounds (self, x,y,z,w,h,d) 
	if (not x) then return self.bounds end
	self.bounds = {x,y,w,h,z,d}
	self:update()
end

function gui.element.rot (self,x,y,z)
	if (not x) then return unpack(self.rotation) end
	self.rotation = {x,y,z}
	self:update()
end

function gui.element.test (self, x,y)
	if (x<self.bounds[1] or y<self.bounds[2] or x>self.bounds[3]+self.bounds[1] or
		y> self.bounds[4]+self.bounds[2]) then return false end
	return true
end

function gui.element.click (self, x,y)
	if (self.enabled and self:visible() and self:test(x,y)) then 
		self:action()
		return true
	end
	return false
end

function gui.element.enable (self,on) 
	if (on == nil) then return self.enabled end
	self.enabled = on
	self:update()
end

function gui.element.delete (self) 
	if (gui.listthink) then
		self._remove = true
	else 
		self:ondelete()
		for i,v in ipairs(gui.elements) do 
			if (v == self) then
				table.remove(gui.elements,i)
				break
			end
		end
	end
end

-- empty interfaces
function gui.element.update (self) _print("overload this") end 
function gui.element.action (self) end 
function gui.element.visible (self,visible) end
function gui.element.think (self) end
function gui.element.ondelete(self) end



gui.button = {}
setmetatable(gui.button,{__index = gui.element})
function gui.button.new (imgtx, x,y,z,w,h,actionfn)
	local self = gui.element.new (gui.button)
	self.l2d = l2dimage.new("button",texture.load2d(imgtx,false))
	self.l2d:parent(l2dlist.getroot())
	self:setbounds(x,y,z,w,h)
	self.action = actionfn
	return self
end

function gui.button.update (self) 
	self.l2d:pos(self.bounds[1],self.bounds[2],self.bounds[5])
	self.l2d:scale(self.bounds[3],self.bounds[4],1)
end

function gui.button.visible (self,on)
	if (on == nil) then return not self.l2d:rfNodraw() end
	self.l2d:rfNodraw(not on)
end

function gui.button.ondelete (self)
	self.l2d:delete()
end

gui.l3dbutton = {}
setmetatable(gui.l3dbutton,{__index = gui.button})
function gui.l3dbutton.new (mdl, x,y,z,rx,ry,rz,w,h,scale,actionfn)
	local self = gui.element.new(gui.l3dbutton)
	self.l3d = l3dmodel.new("l3dbuttonmdl",l3dset.get(2):layer(0),mdl,false,false)
	self.l2d = l2dnode3d.new("l3dbutton",self.l3d)
	self.l2d:parent(l2dlist.getroot())
	self:setbounds(x,y,z,w,h,scale)
	self:rot(rx,ry,rz)
	self.action = actionfn
	return self
end

function gui.l3dbutton.update (self) 
	self.l2d:pos(self.bounds[1],self.bounds[2],self.bounds[5])
	self.l2d:scale(self.bounds[6],self.bounds[6],self.bounds[6])
	self.l2d:rot(unpack(self.rotation))
end

function gui.l3dbutton.ondelete (self)
--	self.l3d:delete()
	self.l2d:delete()
	self.deleted = true
end

function gui.l3dbutton.test (self, x,y)
	local w2,h2 = self.bounds[3]*0.5,self.bounds[4]*0.5
	if (x<self.bounds[1]-w2 or y<self.bounds[2]-h2 or 
		x>self.bounds[1]+w2 or y>self.bounds[2]+h2) then return false end
	return true
end

gui.textfield = {}
setmetatable(gui.textfield,{__index = gui.element})
function gui.textfield.new (text,maxlen,x,y,w,h,onEnter) 
	local self = gui.element.new(gui.textfield)
	self.l2d = l2dtext.new("",text or "");
	self.l2d:parent(l2dlist.getroot())
	self.l2d:pos(x or 0, y or 0,0)
	self.l2d:scale(0.8,0.8,0.8)
	self.l2d:spacing(10)
	self.maxlen = maxlen or 100
	gui.focus = self
	self.onEnter = onEnter
	return self
end

function gui.textfield.text(self,tx)
	if (tx) then
		self.l2d:text(tx)
	else
		return self.l2d:text()
	end
end

function gui.textfield.think(self)
	if (gui.focus ~= self or not self.enabled) then return end
	local texts = {self.l2d:text()}
	--local shift = false
	for i,v in ipairs(lastkeys) do
		if (v[2]) then
			--print(string.char(v[1]))
			--_print(v[1])
			if (v[1]==295 and table.getn(texts)>0) then 
				local str = string.sub(table.remove(texts),0,-2)
				if (string.len(str)>0) then 
					table.insert(texts,str)
				end
			elseif (v[1]==294) then
				if (self.onEnter) then
					self:onEnter()
				end
			elseif (v[1]>0 and v[1]<256) then
				table.insert(texts,string.char(v[1]))
				
			end
		end
	end
	texts = table.concat(texts)
	if (string.len(texts)>self.maxlen) then 
		texts = string.sub(texts,1,self.maxlen) 
	end
	self.l2d:text(texts)
end

function gui.click (x,y)
	for i,v in ipairs (gui.elements) do 
		if (v:click(x,y)) then return true end
	end
	return false
end

function gui.cleanup ()
	for i,v in ipairs (gui.elements) do 
		v:ondelete()
	end
	gui.elements = {}
end

function gguithink ()
	gui.listthink = true
	for i,v in ipairs (gui.elements) do 
		if (not v._remove) then
			v:think()
		end
	end
	for i,v in ipairs (gui.elements) do
		if (v._remove) then
			v:ondelete()
			i = i-1
		end
	end
	gui.listthink = false
end


Timer.set("gui",gguithink)