local player = require'cplayer'

local kappa = 4 / 3 * (math.sqrt(2) - 1)

local function button_path(cr, x1, y1, w, h, cut)
	local rx, ry = 5, 5
	rx = math.min(math.abs(rx), math.abs(w/2))
	ry = math.min(math.abs(ry), math.abs(h/2))
	if rx == 0 and ry == 0 then
		rect_to_lines(write, x1, y1, w, h)
		return
	end
	local x2, y2 = x1 + w, y1 + h
	if x1 > x2 then x2, x1 = x1, x2 end
	if y1 > y2 then y2, y1 = y1, y2 end
	local lx = rx * kappa
	local ly = ry * kappa
	local cx, cy = x2-rx, y1+ry
	if cut == 'right' or cut == 'both' then
		cr:move_to(x2, y1)
		cr:line_to(x2, y2)
		cr:line_to(cut == 'right' and x1+rx or x1, y2)
	else
		cr:move_to(cx, y1)
		cr:curve_to(cx+lx, cy-ry, cx+rx, cy-ly, cx+rx, cy) --q1
		cr:line_to(x2, y2-ry)
		cx, cy = x2-rx, y2-ry
		cr:curve_to(cx+rx, cy+ly, cx+lx, cy+ry, cx, cy+ry) --q4
		cr:line_to(cut and x1 or x1+rx, y2)
	end
	if cut == 'left' or cut == 'both' then
		cr:line_to(x1, y1)
	else
		cx, cy = x1+rx, y2-ry
		cr:curve_to(cx-lx, cy+ry, cx-rx, cy+ly, cx-rx, cy) --q3
		cr:line_to(x1, y1+ry)
		cx, cy = x1+rx, y1+ry
		cr:curve_to(cx-rx, cy-ly, cx-lx, cy-ry, cx, cy-ry) --q2
		cr:line_to(cx, y1)
	end
	cr:close_path()
end

function player:button(t)
	local id = assert(t.id, 'id missing')
	local x, y, w, h = self:getbox(t)
	local text = t.text or id
	local cut = t.cut
	local selected = t.selected
	local enabled = t.enabled == nil and true or t.enabled
	local font = t.font

	local down = self.lbutton
	local pressed = self.lpressed
	local hot = enabled and self:hotbox(x, y, w, h)

	if hot and (not self.active or self.active == id)  then
		self.cursor = 'hand'
	end

	local clicked = false
	if not self.active and hot and pressed then
		self.active = id
	elseif self.active == id then
		if hot then
			clicked = not down
			selected = clicked
		end
		if not down then
			self.active = nil
		end
	end

	local color_state = (selected or self.active == id and hot and down) and 'selected'
								or ((not self.active or self.active == id) and hot and 'hot')
								or enabled and (t.default and 'default' or 'normal')
								or 'disabled'
	local bg_color = color_state..'_bg'
	local fg_color = color_state..'_fg'

	--drawing
	local old_theme = self:save_theme(t.theme)
	button_path(self.cr, x + 0.5, y + 0.5, w - 1, h - 1, cut)
	self:fillstroke(bg_color, 'normal_border', 1)
	self:textbox(x, y, w, h, text, font, fg_color, 'center', 'center')
	self.theme = old_theme

	return (t.immediate and self.active == id and hot and down) or clicked
end

function player:togglebutton(t)
	if self:button(t) then
		return not t.selected
	else
		return t.selected
	end
end

function player:mbutton(t)
	local id = assert(t.id, 'id missing')
	local x, y, w, h = self:getbox(t)
	local values, texts, selected, enabled = t.values, t.texts, t.selected, t.enabled
	local multisel = type(selected) == 'table' and (t.multiselect == true or t.multiselect == nil)

	local bw = math.floor(w / #values)
	local left_w = w
	for i,v in ipairs(values) do
		local bw = i < #values and bw or left_w
		local cut = #values > 1 and (i==#values and 'left' or i==1 and 'right' or 'both')
		local t = {
			id = id..'_'..i,
			x = x, y = y, w = bw, h = h,
			text = texts and (texts[v] or texts[i]) or tostring(v),
			cut = cut,
			enabled = enabled and enabled[v],
			default = t.default == v,
		}
		self.layout:push()
		if multisel then
			t.selected = selected[v]
			selected[v] = self:togglebutton(t)
		else
			t.selected = selected == v
			if self:button(t) then
				selected = v
			end
		end
		self.layout:pop()
		x = x + bw - 1
		left_w = left_w - (bw - 1)
	end
	return selected
end

if not ... then require'cplayer.widgets_demo' end

