local ns = artifact

local hud_pop_times = {}

function ns.push_chat_message(msg, sender, splash, duration)
    -- Special handling for the character names (and if sent by a player, colorize based on character).
    if sender == "Key" or artifact.players[sender] and artifact.players[sender].character == "key" then
        sender = minetest.colorize("#284", sender)
    elseif sender == "Vix" or artifact.players[sender] and artifact.players[sender].character == "vix" then
        sender = minetest.colorize("#f5dd66", sender)
    end
    for name, m in pairs(artifact.players) do
        local box = {}
        local w = minetest.get_player_window_information(name).size.x
        local y = (#m.chat *75)
        box.left = artifact.hud_add(m, {
            type = "image",
            name = ""..math.random(),
            pos = {x=0,y=0},
            offset={x=8,y=12 +y},
            align = {x=1,y=1},
            scale = {x=4,y=4},
            image = "artifact_chat_box_side.png"
        })
        box.middle = artifact.hud_add(m, {
            type = "image",
            name = ""..math.random(),
            pos = {x=0,y=0},
            offset={x=12,y=12 +y},
            align = {x=1,y=1},
            scale = {x=w -24,y=4},
            image = "artifact_chat_box_middle.png"
        })
        box.right = artifact.hud_add(m, {
            type = "image",
            name = ""..math.random(),
            pos = {x=1,y=0},
            offset={x=-8,y=12 +y},
            align = {x=-1,y=1},
            scale = {x=4,y=4},
            image = "artifact_chat_box_side.png"
        })
        if sender then msg = "["..sender.."] "..msg end
        local i = 0
        local str = ""
        for x in msg:gmatch("(%s*[^%s]+%s*)") do
            if (#str +#x) *8 < w -100 then
                str = str..x
            else
                box["text"..i] = artifact.hud_add(m, {
                    type = "text",
                    name = ""..math.random(),
                    pos = {x=0,y=0},
                    padding_y = 10 +(i *18),
                    offset={x=64,y=22 +(i *18) +y},
                    align = {x=1,y=1},
                    text = str
                })
                str = x
                i = i +1
            end
        end
        box["text"..i] = artifact.hud_add(m, {
            type = "text",
            name = ""..math.random(),
            pos = {x=0,y=0},
            padding_y = 10 +(i *18),
            offset={x=64,y=22 +(i *18) +y},
            align = {x=1,y=1},
            text = str
        })
--        if sender then
--            box.name = artifact.hud_add(m, {
--                type = "text",
--                pos = {x=0,y=0},
--                padding_y = 30,
--                offset={x=15,y=42 +y},
--                align = {x=1,y=1},
--                text = sender
--            })
--        end
        if splash then
            box.splash = artifact.hud_add(m, {
                type = "image",
                pos = {x=0,y=0},
                padding_y = 25,
                offset={x=32,y=37 +y},
                align = {x=0,y=0},
--                scale = {x=0.5,y=0.5},
                image = splash
            })
        end
        m.chat[#m.chat +1] = box
    end
    -- Ensure that messages auto-pop strictly in order, in case of different durations.
    -- If a message would cause a pop before its predecessor expires, its pop time is
    -- pushed forward to immediately follow that of the last visible message.
    table.insert(hud_pop_times, math.max(hud_pop_times[#hud_pop_times] or 0, (duration or 15) *1000000 +minetest.get_us_time()))
    -- Track pop jobs to get the number of active messages, since the actual HUD is stored in each player.
    if #hud_pop_times > 5 then
        ns.pop_chat_message()
    end
    -- Write the message to the chat log. (Note that `msg` is updated above to include the sender name, if present.)
    minetest.chat_send_all(msg)
end

function ns.pop_chat_message()
    table.remove(hud_pop_times, 1)
    for _, m in pairs(artifact.players) do
        for _, x in pairs(m.chat[1]) do
            x:remove(m)
        end
        table.remove(m.chat, 1)
        for i, x in ipairs(m.chat) do
            local y = (i -1) *75
            for _, el in pairs(x) do
                el:animate {
                    offset = {
                        value = {x=el.offset.x, y=12 +y +(el.padding_y or 0)},
                        duration = 0.3
                    }
                }
            end
        end
    end
end


minetest.register_on_chat_message(function(name, msg)
    ns.push_chat_message(msg, name)
    return true
end)

minetest.register_globalstep(function()
    local time = minetest.get_us_time()
    if time >= (hud_pop_times[1] or math.huge) then
        ns.pop_chat_message()
    end
end)

if artifact.debug then

    minetest.register_chatcommand("key", {
        func = function(name, args)
            ns.push_chat_message(args, "Key", "artifact_key_splash_low.png")
        end
    })
    
    minetest.register_chatcommand("vix", {
        func = function(name, args)
            ns.push_chat_message(args, "Vix", "artifact_vix_splash_low.png")
        end
    })

    minetest.register_chatcommand("color", {
        func = function(name, args)
            ns.push_chat_message(minetest.colorize(args, "This is a colored message"), "Server")
        end
    })
end
