HudElement = class("HudElement")
function HudElement:onNew()	
	self.x = 0
	self.y = 0
	self.bounds = Bounds:new(0,0,0,0)	
end

function HudElement:render(x,y,scale,angle,a,r,g,b)
	self.bounds:render(x,y,scale,a,r,g,b, scale*2)	
end

function HudElement:expand_bounds()	
end

function HudElement:set_position(x,y)
	self.x = x
	self.y = y
end

function HudElement:reset_bounds()
	self.bounds:set(0,0,0,0)	
end

function HudElement:find_interactive(x,y)
	local rx,ry = x-self.x, y-self.y
	if self.bounds:isInside(rx,ry) then
		return self
	end
end

function HudElement:get_hud_info()
	return nil
end

function HudElement:get_pressed_action()
	return nil
end

function HudElement:set_game(game)
	self.game = game	
end


function HudElement:set_hovered(v)
	self.hovered = v	
end

function HudElement:set_pressed(v)
	self.pressed = v	
end

function HudElement:sort()
	--
end

function HudElement:get_dimensions()
	return self.bounds:get_width(), self.bounds:get_height()
end







local LAYOUTS = {
	bottom_horisontal_centered = {
		x_order = 1,
		x_align = -0.5,
		y_order = 0,
		y_align = 0,
		w_start = 0.6,
		h_start = 1,
		w_offset = 0.5,
		h_offset = -0.5,
		margin = 0,		
	},
	bottom_right_horisontal_left = {
		x_order = -1,
		x_align = 0,
		y_order = 0,
		y_align = 0,
		w_start = 1,
		h_start = 1,
		w_offset = -0.5,
		h_offset = -0.5,
		margin = 0,		
	},
	right_top_down = {
		x_order = 0,
		x_align = 0,
		y_order = 1,
		y_align = 0,
		w_start = 1,
		h_start = 0,
		w_offset = -0.5,
		h_offset = 0.5,
		margin = 0,		
	},
	bottom_horisontal_side = {
		x_order = 1,
		x_align = -0.5,
		y_order = 0,
		y_align = 0,
		w_start = 0.4,
		h_start = 1,
		w_offset = 0,
		h_offset = -0.5,
		margin = 0,		
	},
	bottom_left_horisontal_down = {
		x_order = 0,
		x_align = 0,
		y_order = 1,
		y_align = 0,
		w_start = 0,
		h_start = 0,
		w_offset = 0.5,
		h_offset = 0.5,		
		margin = 0,		
	},
	bottom_horisontal_left = {
		x_order = 1,
		x_align = 0,
		y_order = 0,
		y_align = 0,
		w_start = 0,
		h_start = 1,
		w_offset = 0.5,
		h_offset = -0.5,		
		margin = 0,		
	},
	
	mid_centered = {
		x_order = 1,
		x_align = -0.5,
		y_order = 0,
		y_align = 0,
		w_start = 0.5,
		h_start = 0.35,
		w_offset = 0,
		h_offset = -0.5,
		margin = 0,		
	},
}


HudLayout = inherited("HudLayout", HudElement)
function HudLayout:new(layout_type)
	local elem = instance(self)	
	elem.layout_type = layout_type
	assert(LAYOUTS[layout_type])
	elem.children = {}
	return elem
end

function HudLayout:add_child(child)
	table.insert(self.children, child)
end

function HudLayout:render(x,y,scale,angle,a,r,g,b)
	--self.bounds:render(x,y,scale,a,0,0,b, scale*4)
	for index, child in pairs(self.children) do
		child:render(x+child.x*scale, y + child.y*scale, scale, angle, a, r, g, b)
	end
end

function HudLayout:reset_bounds()
	local child = self.children[1]
	self.bounds:set(child.x,child.y,child.x,child.y)	
end

function HudLayout:layout_inside(x,y,w,h)	
	for index, child in pairs(self.children) do
		child:reset_bounds()
	end
	for index, child in pairs(self.children) do
		child:expand_bounds()
	end
	
	self:layout_children(x,y,w,h)
	self:reset_bounds()	
	self:expand_bounds()
end


function HudLayout:set_game(game)
	self.game = game
	for index, child in pairs(self.children) do
		child:set_game(game)
	end	
end


function HudLayout:expand_bounds()
	for index, child in pairs(self.children) do
		self.bounds:expandFromOffset(child.bounds, child.x, child.y)
	end
end

function HudLayout:find_interactive(x,y)
	local rx,ry = x-self.x, y-self.y

	if self.bounds:isInside(rx,ry) then
		for index, child in pairs(self.children) do		
			local found = child:find_interactive(rx,ry)
			if found then
				return found
			end
		end
	end
end


function HudLayout:update(dt)
	for index, child in pairs(self.children) do
		child:update(dt)
	end
end


function HudLayout:layout_children(x,y,w,h)
	local def = LAYOUTS[self.layout_type]
	local list = self.children
	local num = #list
	local num_w = math.max(1,num*(def.x_order ~= 0 and 1 or 0))
	local num_h = math.max(1,num*(def.y_order ~= 0 and 1 or 0))

	local total_width = 0
	local total_height = 0
	local total_size = 0
	local w_margin = def.margin
	local h_margin = def.margin
	for index, element in ipairs(list) do
		local element_width, element_height = element:get_dimensions()

		local order_sensitive_width = element_width*math.abs(def.x_order)
		local order_sensitive_height = element_height*math.abs(def.y_order)

		total_size = total_size + order_sensitive_width
		total_size = total_size + order_sensitive_height

		total_width = math.max(total_width + order_sensitive_width, element_width)
		total_height = math.max(total_height + order_sensitive_height, element_height)
	end

	local x = x + w*def.w_start
	local y = y + h*def.h_start

	total_width = 0
	total_height = 0
	
	total_size = total_size + math.max(0,(num-1))*math.max(w_margin, h_margin)
	
	x = x + total_size * def.x_align
	y = y + total_size * def.y_align

	local sx, sy = x, y

	local last_wrap = 0
	local row_h = 0
	local row_w = 0
	for index, element in ipairs(list) do
		local element_width, element_height = element:get_dimensions()
		local bw = element_width
		local bh = element_height
		local bx,by = x + bw*def.w_offset, y + bh*def.h_offset
		element:set_position(bx,by)
		x = x + (bw + w_margin)*def.x_order
		y = y + (bh + h_margin)*def.y_order
	end
end








--[[

88        88                      88 I8,        8        ,8I 88                      88
88        88                      88 `8b       d8b       d8' ""                      88
88        88                      88  "8,     ,8"8,     ,8"                          88
88aaaaaaaa88 88       88  ,adPPYb,88   Y8     8P Y8     8P   88 8b,dPPYba,   ,adPPYb,88  ,adPPYba,  8b      db      d8
88""""""""88 88       88 a8"    `Y88   `8b   d8' `8b   d8'   88 88P'   `"8a a8"    `Y88 a8"     "8a `8b    d88b    d8'
88        88 88       88 8b       88    `8a a8'   `8a a8'    88 88       88 8b       88 8b       d8  `8b  d8'`8b  d8'
88        88 "8a,   ,a88 "8a,   ,d88     `8a8'     `8a8'     88 88       88 "8a,   ,d88 "8a,   ,a8"   `8bd8'  `8bd8'
88        88  `"YbbdP'Y8  `"8bbdP"Y8      `8'       `8'      88 88       88  `"8bbdP"Y8  `"YbbdP"'      YP      YP


]]
HudWindow = inherited("HudWindow", HudLayout)
function HudWindow:new(layout_type, title)
	local elem = instance(self)	
	elem.layout_type = layout_type
	elem.title = title
	assert(LAYOUTS[layout_type])
	elem.children = {}
	return elem
end

function HudWindow:render(x,y,scale,angle,a,r,g,b)
	self.bounds:renderSurface(x,y,scale,a*0.75,0,0,0, scale*25)
	local font = "medium"	
	local rx,ry = x+self.bounds:getCenterX(),y+self.bounds.b + fonts.alignY(font,0)
	video.renderTextSprites(self.title, rx,ry, 1, font, a, r, g, b)
	for index, child in pairs(self.children) do
		child:render(x+child.x*scale, y + child.y*scale, scale, angle, a, r, g, b)
	end
end










HudSlot = inherited("HudSlot", HudElement)
function HudSlot:new(slot, size, item_scale, ent)
	local elem = instance(self)
	elem.slot = slot
	elem.size = size
	elem.item_scale = item_scale
	elem.ent = ent
	return elem
end

function HudSlot:expand_bounds()
	local hsize = self.size*0.5
	self.bounds:expand(-hsize, -hsize, hsize, hsize)
end

function HudSlot:update(dt)
	local slot = self.slot
	slot:update_hud(dt)
end


function HudSlot:get_pressed_action()
	local slot = self.slot
	return slot, slot:get_pressed_action()
end


function HudSlot:render(x,y,scale,angle,a,r,g,b)
	local slot = self.slot
	local ix,iy = x,y
	local cht = slot.changed_timer
	if cht then
		local exp = cht^4
		scale = scale - exp*0.5
		--iy = iy -math.max(0,cht-0.5)^2*150
		
		local ent = self.ent
		local cx,cy = self.game:camera_to_screen(ent.x, ent.y)
		local dx = math.abs(ix-cx)
		local dy = math.abs(iy-cy)
		ix = math.approach(ix, cx, dx*exp)
		iy = math.approach(iy-math.min(1,cht)^2*100*(1-cht), cy, dy*exp)
	end
	local line_size = 2
	if self.hovered then
		r,g,b = r*0.5,g,b*0.5
		line_size = 4
	end
	if self.pressed then
		r,g,b = r*0.33,g*0.33,b*0.33
		line_size = 6
	end
	
	--self.bounds:render(x,y,scale,a,r,g,b, scale*line_size)
	video.renderSpriteState(SPRITES.guiFrame, x, y, scale*4, 0, a, r, g, b)

	local attack_slot = slot.attack_slot
	if attack_slot then
		--local max = attack_slot.attack_charge_max
		--if max > 0 then
		--	local value = attack_slot.attack_charge/max
		--	local col = COLORS.pierce
		--	self.bounds:renderSurface(x,y,value*scale,a*0.25,col.r,col.g,col.b)
		--end
	end

	if self.pressed then
		y = y +2
	end

	local item = slot.item
	if item then		
		item:render(ix,iy,scale*self.item_scale,1,angle, a,r,g,b)
		local stack = item.stack
		if stack then
			local bounds = self.bounds
			local margin = 4
			video.renderTextSprites(stack, x+bounds.r-margin, y+bounds.b + fonts.alignY("medium", 2) - margin, 2, "medium", 255, 255, 255, 255)
		end
	end

	if attack_slot then		
		local delay = attack_slot.delay
		if delay > 0 then
			local start = attack_slot.delay_start
			if start > 0 then
				local val = delay/start
				local col = COLORS.rate
				self.bounds:renderSquishedSurface(x,y+self.bounds:get_height()*0.5*(1-val),scale,val,a*0.25,col.r,col.g,col.b)
			end
		end		
	end
end

function HudSlot:get_hud_info(compare)
	local slot = self.slot
	if slot.item then
		return slot:get_hud_info(compare)
	end
end
