---------------------------------------------------------------------------
-- @author Julien Danjou <julien@danjou.info>
-- @copyright 2008 Julien Danjou
-- @release @AWESOME_VERSION@
---------------------------------------------------------------------------

-- Grab environment we need
local math = math
local ipairs = ipairs
local otable = otable
local capi =
{
    wibox = wibox,
    widget = widget,
    button = button,
    client = client,
}
local beautiful = require("awful.beautiful")
local hooks = require("awful.hooks")
local util = require("awful.util")
local widget = require("awful.widget")

--- Titlebar module for awful
module("awful.titlebar")

-- Privata data
local data = otable()

--- Create a standard titlebar.
-- @param c The client.
-- @param args Arguments.
-- fg: the foreground color.
-- bg: the background color.
-- fg_focus: the foreground color for focused window.
-- fg_focus: the background color for focused window.
-- width: the titlebar width
function add(c, args)
    if not c or c.type ~= "normal" then return end
    if not args then args = {} end
    local theme = beautiful.get()
    -- Store colors
    data[c] = {}
    data[c].fg = args.fg or theme.titlebar_fg_normal or theme.fg_normal
    data[c].bg = args.bg or theme.titlebar_bg_normal or theme.bg_normal
    data[c].fg_focus = args.fg_focus or theme.titlebar_fg_focus or theme.fg_focus
    data[c].bg_focus = args.bg_focus or theme.titlebar_bg_focus or theme.bg_focus
    data[c].width = args.width

    local tb = capi.wibox(args)

    local title = capi.widget({ type = "textbox", name = "title", align = "flex" })
    title.text = " " .. util.escape(c.name) .. " "
    local bts =
    {
        capi.button({ }, 1, function (t) t.client:mouse_move() end),
        capi.button({ args.modkey }, 3, function (t) t.client:mouse_resize() end)
    }
    title:buttons(bts)

    local appicon = capi.widget({ type = "imagebox", name = "appicon", align = "left" })
    appicon.image = c.icon

    if theme.titlebar_close_button == "true" then
        local closef = widget.button({ name = "closef", align = "right",
                                       image = theme.titlebar_close_button_focus
                                               or theme.titlebar_close_button_img_focus
                                               or "@AWESOME_ICON_PATH@/titlebar/closer.png" })
        local close = widget.button({ name = "close", align = "right",
                                      image = theme.titlebar_close_button_normal
                                              or theme.titlebar_close_button_img_normal
                                              or "@AWESOME_ICON_PATH@/titlebar/close.png" })

        -- Bind kill button
        local b = capi.button({ }, 1, nil, function (t) t.client:kill() end)
        local bts = closef:buttons()
        bts[#bts + 1] = b
        closef:buttons(bts)

        bts = close:buttons()
        bts[#bts + 1] = b
        close:buttons(bts)

        tb.widgets = { appicon, title, closef, close }
    else
        tbx.widgets = { appicon, title }
    end

    c.titlebar = tb

    update(c)
    update(c, "geometry")
end

--- Update a titlebar. This should be called in some hooks.
-- @param c The client to update.
-- @param prop The property name which has changed.
function update(c, prop)
    if c.titlebar and data[c] then
        local widgets = c.titlebar.widgets
        local title, close, closef
        for k, v in ipairs(widgets) do
            if v.name == "title" then title = v
            elseif v.name == "close" then close = v
            elseif v.name == "closef" then closef = v
            elseif v.name == "appicon" then appicon = v end
            if title and close and closef and appicon then break end
        end
        if prop == "name" then
            if title then
                title.text = " " .. util.escape(c.name) .. " "
            end
        elseif prop == "icon" then
            if appicon then
                appicon.image = c.icon
            end
        elseif prop == "geometry" then
            if data[c].width then
                if c.titlebar.position == "top"
                    or c.titlebar.position == "bottom" then
                    local w = math.min(data[c].width, c:geometry().width + 2 * c.border_width)
                    c.titlebar:geometry({ width = w })
                else
                    local w = math.min(data[c].width, c:geometry().height + 2 * c.border_width)
                    c.titlebar:geometry({ height = w })
                end
            end
        end
        if capi.client.focus == c then
            c.titlebar.fg = data[c].fg_focus
            c.titlebar.bg = data[c].bg_focus
            if closef then closef.visible = true end
            if close then close.visible = false end
        else
            c.titlebar.fg = data[c].fg
            c.titlebar.bg = data[c].bg
            if closef then closef.visible = false end
            if close then close.visible = true end
        end
    end
end

--- Remove a titlebar from a client.
-- @param c The client.
function remove(c)
    c.titlebar = nil
    data[c] = nil
end

-- Register standards hooks
hooks.focus.register(update)
hooks.unfocus.register(update)
hooks.property.register(update)
hooks.unmanage.register(remove)

-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80