require("util")
require("tilevid")

function _gui_init()
local ns = "GUI"
-----------------------------------------------------------------------------------
local Container = ns_class(ns,"Container")

function Container:init(view)
    self.items = {}
    self.view = view
    self.focus = nil
    self._focus = nil
    self.button = nil
end

function Container:draw()
    cuz.view_set(self.view.x,self.view.y,self.view.w,self.view.h)
    for n,obj in ipairs(self.items) do
        obj:draw(self)
    end
end

function Container:loop(t)
    self:_focus_set(self.focus)
    for n,obj in ipairs(self.items) do
        if obj.loop then obj:loop(t) end
    end
end


function Container:add(obj,rect)
    obj.rect = rect
    self.items[#self.items+1] = obj
end

function Container:_focus_set(obj)
    if self._focus then self._focus.focus = false end
    self.focus = obj
    self._focus = obj
    if self.focus then self.focus.focus = true end
end

function Container:event(e)
    -- ignore buttons from previous states
    if e.type == 'down' then
        self.button = e.button
    end
    if e.type == 'up' or e.type == 'down' or e.type == 'motion' then
        if self.button ~= e.button then
            return
        end
    end

    for n,obj in ipairs(self.items) do
    	local ok = true
        if e.type == 'up' or e.type == 'down' or e.type == 'motion' then
			-- if e.type == 'up' or e.type == 'down' then ok = false end
            ok = false
            if obj.rect:collidepoint(e) then
                self:_focus_set(obj)
				ok = true
            else
                if self.focus == obj then
                    self:_focus_set(nil)
                end
            end
        end
        if obj.focus and ok then
            if obj:method("event") then obj:event(e) end
            if e.type == 'up' then
                self:_focus_set(nil)
            end
        end
    end
end

local Font = ns_class(ns,"Font")

function Font:init(name,points,padding)
    self.name = name
    self.padding = padding or {0,0,0,0}
    self.points = points
end

function Font:draw(text,x,y)
    local padding = self.padding

    local _w,_h = self:size(text)

    for _,txt in pairs(str_split(text,"\n")) do
        local ww,hh = cuz.font_size(self.name,self.points,txt)
        hh = hh + padding[1] + padding[3]
        ww = ww + padding[2] + padding[4]
        local _x = x + (_w - ww) / 2
        cuz.font_draw(self.name,self.points,txt,_x+padding[4],y+padding[1])
        y = y + hh
    end
end

function Font:size(text)
    local padding = self.padding
    local w = 0
    local h = 0
    for _,txt in pairs(str_split(text,"\n")) do
        local ww,hh = cuz.font_size(self.name,self.points,txt)
        hh = hh + padding[1] + padding[3]
        ww = ww + padding[2] + padding[4]
        w = math.max(w,ww)
        h = h + hh
    end
    return w,h
end

local Label = ns_class(ns,"Label")

function Label:init(font,text,align,valign)
    self.font = font
    self.text = text
    self.align = align or 0
    self.valign = valign or 0
end

function Label:draw()
    local ww = self.rect.w
    ww = 0
    local w,h = self.font:size(self.text)
    local x = self.rect.x + (self.align+1) * (self.rect.w-w)/2
    local y = self.rect.y + (self.valign+1) * (self.rect.h-h)/2
    self.font:draw(self.text,x,y)
end

local Image = ns_class(ns,"Image")

function Image:init(image,size)
    self.image = image
    self.size = size
end

function Image:draw()
    local x = self.rect.x + (self.rect.w-self.size.w)/2
    local y = self.rect.y + (self.rect.h-self.size.h)/2
    cuz.image_draw(self.image,x,y,self.size.w,self.size.h)
end

local Background = ns_class(ns,"Background")

function Background:init(image,color,focus_color,blink)
    self.image = image
    self.color = color
    self.focus_color = focus_color
    self.t = 0
    self.blink = blink or false
end
function Background:draw()
    local color = self.color
    if self.focus then color = self.focus_color end
    if self.blink == true and math.floor(self.t*3)%2 == 0 then
        color = self.focus_color
    end

    if color == nil then color = 0xffffff end
--     cuz.image_draw(self.image,self.rect.x,self.rect.y,self.rect.w,self.rect.h,0,0,0,color,1.0,0,0)
    cuz.rect_draw(color,self.rect.x,self.rect.y,self.rect.w,self.rect.h)
end
function Background:loop(t)
    self.t = self.t + t
end

local Button = ns_class(ns,"Button")

function Button:init(widget,click,background)
    self.widget = widget
    self.click = click
    self.background = background
    self.padding = -2
    self.disabled = false
end

function Button:loop(t)
    local rate = 0.5
    local dest = 0
    if self.focus and not self.disabled then dest = -1 end
    if self.padding < dest then self.padding = self.padding + rate end
    if self.padding > dest then self.padding = self.padding - rate end
    if self.widget.loop ~= nil then self.widget:loop(t) end
    if self.background.loop ~= nil then self.background:loop(t) end
    --self.padding = self.padding * rate + dest * (1.0-rate)

    -- self.padding = 0
end

function Button:draw()

    local border = 1 -- 2
    local padding = self.padding
    local r = Rect(self.rect.x-padding,self.rect.y-padding,self.rect.w+padding*2,self.rect.h+padding*2)
    local shadow = 10
    cuz.image_draw('shadow',r.x+shadow,r.y+shadow,r.w,r.h)
    cuz.rect_draw(self.background.focus_color,r.x-border,r.y-border,r.w+border*2,r.h+border*2)


    if self.background then
        self.background.focus = self.focus
        self.background.rect = r
        self.background:draw()
    end
    self.widget.focus = self.focus
    self.widget.rect = self.rect
    self.widget:draw()
end

function Button:event(e)
    if self.disabled then return end
    if e.type == 'up' then
        -- cuz.sample_play("sfx-button")
        self.click()
    end
    if e.type == 'keydown' and (e.name == 'Fire' or e.name == 'Space' or e.name == 'Return') then self.click() end
end


local Icon = ns_class(ns,"Icon")

function Icon:init(image,size,onclick)
    self.image = image
    self.size = size
    self.click = onclick
    self.t = 0
end

function Icon:loop(t)
    self.t = self.t + t
end

function Icon:draw()
    -- if math.floor((self.t*2)%2) == 0 then return end

    local x = self.rect.x + (self.rect.w-self.size.w)/2
    local y = self.rect.y + (self.rect.h-self.size.h)/2
    cuz.image_draw(self.image,x,y,self.size.w,self.size.h)
end

function Icon:event(e)
    if e.type == 'up' then
        -- cuz.sample_play("sfx-button")
        self.click()
    end
    if e.type == 'keydown' and (e.name == 'Fire' or e.name == 'Space' or e.name == 'Return') then self.click() end
end

-----------------------------------------------------------------------------------
local Div = ns_class(ns,"Div")

function Div:init()
end
function Div:draw()
    local z = 0 ; local color = 0xdddddd
    cuz.rect_draw(color,self.rect.x+z,self.rect.y+z,self.rect.w-z*2,self.rect.h-z*2)
    local z = 1 ; local color = 0xffffff
    cuz.rect_draw(color,self.rect.x+z,self.rect.y+z,self.rect.w-z*2,self.rect.h-z*2)
end


-----------------------------------------------------------------------------------
end ; _gui_init()