local mod_name = minetest.get_current_modname()
local mod_path = minetest.get_modpath(mod_name)


aom_fonts.registered_fonts = {}
local reg = aom_fonts.registered_fonts

aom_fonts.default_characterset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.,;:?!-_~#\"\'&()[]{}<>\\/$%@+=*"

function aom_fonts.tile_texture(tex, from_x, from_y, to_x, to_y)
    local r = "[combine:"..to_x.."x"..to_y..":"
    local cx = math.ceil(to_x / from_x)
    local cy = math.ceil(to_y / from_y)

    for x = 0, cx do
        for y = 0, cy do
            r = r .. (from_x * x) .. "," .. (from_y * y) .. "=" .. tex .. ":"
        end
    end
    return r
end

function aom_fonts.register_font(name, def)
    def.file_for_char = {}
    local len = string.len(def.characterset)
    for i = 1, len do
        local char = string.sub(def.characterset, i, i)
        def.file_for_char[char] = ""
        if def.get_character_filename then
            def.file_for_char[char] = def.get_character_filename
        else
            local n = string.format("%0"..(def.zero_padding or 2).."d", i-1)
            def.file_for_char[char] = def.texture_prefix..n..".png"
        end
    end

    reg[name] = def
end

function aom_fonts.get_texture_string(text, font, def)
    local s = def.size or vector.new(16,16,0)
    local r = "[combine:"..(s.x).."x"..(s.y)..":"--<x2>,<y2>=<file2>:..."
    -- local 
    local len = string.len(text)
    local fontdef = reg[font]
    if not fontdef then return "null.png" end

    local fwidth = fontdef.char_size.x
    local fheight = fontdef.char_size.y
    if def.padding then
        fwidth = fwidth + def.padding.x
        fheight = fheight + def.padding.y
    end

    local linewidth = math.floor(s.x / fwidth)

    local ox = 0
    local oy = 0
    if def.offset then
        ox = def.offset.x
        oy = def.offset.y
    end

    if fontdef.case == "uppercase" then
        text = string.upper(text)
    elseif fontdef.case == "lowercase" then
        text = string.lower(text)
    end

    local offset = 0
    local tex_list = {r}
    for i = 1, len do
    repeat
        local char = string.sub(text, i, i)
        if char == "\n" then
            offset = offset + linewidth - (i-1+offset) % linewidth - 1
            break
        end
        if char == " " then break end
        local f = fontdef.file_for_char[char] or "null.png"
        local x = (i-1+offset) % linewidth
        if x == 0 and char == " " and string.sub(text, i-1, i-1) ~= "\n" then
            offset = offset - 1
            break
        end
        local y = math.floor((i-1+offset) / linewidth)
        table.insert(tex_list, table.concat({(x*fwidth + ox), ",", (y*fheight + oy), "=", f, (i < len and ":" or "")}))
    until true
    end

    return table.concat(tex_list)
end

aom_fonts.register_font("F5x8", {
    characterset = aom_fonts.default_characterset,
    case = "both", -- uppercase, lowercase, both
    texture_prefix = "F5x8_",
    char_size = vector.new(5,8,0),
    zero_padding = 2,
    get_character_filename = nil, -- optional function to calc filename `get_character_filename(char)`
})
aom_fonts.register_font("F3x5", {
    characterset = aom_fonts.default_characterset,
    case = "both", -- uppercase, lowercase, both
    texture_prefix = "F3x5_",
    char_size = vector.new(3,5,0),
    zero_padding = 2,
    get_character_filename = nil, -- optional function to calc filename `get_character_filename(char)`
})
aom_fonts.register_font("F_VK_4x5", {
    characterset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,?!",
    case = "uppercase",
    texture_prefix = "F_VK_4x5_",
    char_size = vector.new(4,5,0),
    zero_padding = 2,
    get_character_filename = nil,
})

minetest.register_node("aom_fonts:owo_node", {
    description = "Uwo it's winking at you",
    groups = {
        unobtainable = 1, not_in_creative_inventory = 1, oddly_breakable_by_hand = 1 },
    tiles = { aom_fonts.tile_texture("aom_stone_cobble.png", 16, 16, 32, 32) .. "^" ..
        aom_fonts.get_texture_string("\n OwO\n NoDe", "F5x8", {
            size = vector.new(32,32,0),
            padding = vector.new(1,1,0),
            offset = vector.new(1,1,0)
        }) .. ""
    },
})
