--[[-- Core Module - Gui
    @module Gui
    @alias Prototype
]]

--- Toolbar.
-- Gui structure for the toolbar (top left)
-- @section toolbar

--[[
>>>> Example format
    -- this is the same as any other button define, this just automatically draws it
    -- you can use add_button if you already defined the button
    local toolbar_button =
    Toolbar.new_button('print-click')
    :on_click(function(player,_element)
        player.print('You clicked a button!')
    end)

>>>> Functions
    Toolbar.new_button(name) --- Adds a new button to the toolbar
    Toolbar.add_button(button) --- Adds an existing buttton to the toolbar
    Toolbar.update(player) --- Updates the player's toolbar with an new buttons or expected change in auth return
]]
local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core
local Buttons = require 'expcore.gui.elements.buttons' --- @dep expcore.gui.elements.buttons
local Roles = require 'expcore.roles' --- @dep expcore.roles
local Event = require 'utils.event' --- @dep utils.event
local Game = require 'utils.game' --- @dep utils.game
local mod_gui = require 'mod-gui' --- @dep mod-gui

local Toolbar = {
    permission_names = {},
    buttons = {}
}

function Toolbar.allowed(player,define_name)
    local permission_name = Toolbar.permission_names[define_name] or define_name
    return Roles.player_allowed(player,permission_name)
end

function Toolbar.permission_alias(define_name,permission_name)
    Toolbar.permission_names[define_name] = permission_name
end

--- Adds a new button to the toolbar
-- @tparam[opt] string name when given allows an alias to the button for the permission system
-- @treturn table the button define
function Toolbar.new_button(name)
    local button =
    Buttons.new_button()
    :set_post_authenticator(Toolbar.allowed)
    :set_style(mod_gui.button_style,function(style)
        Gui.set_padding_style(style,-2,-2,-2,-2)
    end)
    Toolbar.add_button(button)
    Toolbar.permission_alias(button.name,name)
    return button
end

--- Adds an existing buttton to the toolbar
-- @tparam table button the button define for the button to be added
function Toolbar.add_button(button)
    table.insert(Toolbar.buttons,button)
    Gui.allow_player_to_toggle_top_element_visibility(button.name)
    Gui.on_player_show_top(button.name,function(event)
        if not button.post_authenticator(event.player,button.name) then
            event.element.visible = false
        end
    end)
    if not button.post_authenticator then
        button:set_post_authenticator(function() return true end)
    end
end

--- Updates the player's toolbar with an new buttons or expected change in auth return
-- @tparam LuaPlayer player the player to update the toolbar for
function Toolbar.update(player)
    local top = Gui.get_top_element_flow(player)
    if not top then return end
    local visible = top[Gui.top_toggle_button_name].caption == '<'
    for _,button in pairs(Toolbar.buttons) do
        local element
        if top[button.name] then element = top[button.name]
        else element = button:draw_to(top) end
        if button.post_authenticator(player,button.name) then
            element.visible = visible
            element.enabled = true
        else
            element.visible = false
            element.enabled = false
        end
    end
end

--- When there is a new player they will have the toolbar update
Event.add(defines.events.on_player_created,function(event)
    local player = Game.get_player_by_index(event.player_index)
    Toolbar.update(player)
end)

--- When a player gets a new role they will have the toolbar updated
Event.add(Roles.events.on_role_assigned,function(event)
    local player = Game.get_player_by_index(event.player_index)
    Toolbar.update(player)
end)

--- When a player loses a role they will have the toolbar updated
Event.add(Roles.events.on_role_unassigned,function(event)
    local player = Game.get_player_by_index(event.player_index)
    Toolbar.update(player)
end)

return Toolbar