local huxdemp = require("huxdemp")

local M = {}

-- This is set on the first call to main().
local use_color = nil

local ebcdic_chars = {
    "0",  "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·",
    "·",  "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·",
    "·",  "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·",
    "?",  "?", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "?", "·",
    " ",  "?", "?", "?", "?", "?", "?", "?", "?", "?", "¢", ".", "<", "(", "+", "|",
    "&",  "?", "?", "?", "?", "?", "?", "?", "?", "?", "!", "$", "*", ")", ";", "¬",
    "—",  "/", "?", "?", "?", "?", "?", "?", "?", "?", "¦", ",", "%", "_", ">", "?",
    "?",  "?", "?", "?", "?", "?", "?", "?", "?", "?", ":", "#", "@", "'", "=", "\"",
    "?",  "a", "b", "c", "d", "e", "f", "g", "h", "i", "?", "?", "?", "?", "?", "±",
    "?",  "j", "k", "l", "m", "n", "o", "p", "q", "r", "?", "?", "?", "?", "?", "?",
    "?",  "~", "s", "t", "u", "v", "w", "x", "y", "z", "?", "?", "?", "?", "?", "?",
    "^",  "?", "?", "?", "?", "?", "?", "?", "?", "?", "[", "]", "?", "?", "?", "?",
    "{",  "A", "B", "C", "D", "E", "F", "G", "H", "I", "?", "?", "?", "?", "?", "?",
    "}",  "J", "K", "L", "M", "N", "O", "P", "Q", "R", "?", "?", "?", "?", "?", "?",
    "\\", "?", "S", "T", "U", "V", "W", "X", "Y", "Z", "?", "?", "?", "?", "?", "?",
    "0",  "1", "2", "3", "4", "5", "6", "7", "8", "9", "?", "?", "?", "?", "?", "·",
}

local ebcdic_colors = {
      0,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
     32,  32,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,  32,   1,
     32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  65,  65,  65,  65,  65,  65,
     65,  32,  32,  32,  32,  32,  32,  32,  32,  32,  65,  65,  65,  65,  65,  65,
     65,  65,  32,  32,  32,  32,  32,  32,  32,  32,  65,  65,  65,  65,  65,  32,
     32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  65,  65,  65,  65,  65,  65,
     32,  65,  65,  65,  65,  65,  65,  65,  65,  65,  32,  32,  32,  32,  32,  65,
     32,  65,  65,  65,  65,  65,  65,  65,  65,  65,  32,  32,  32,  32,  32,  32,
     32,  65,  65,  65,  65,  65,  65,  65,  65,  65,  32,  32,  32,  32,  32,  32,
     65,  32,  32,  32,  32,  32,  32,  32,  32,  32,  65,  65,  32,  32,  32,  32,
     65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  32,  32,  32,  32,  32,  32,
     65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  32,  32,  32,  32,  32,  32,
     65,  32,  65,  65,  65,  65,  65,  65,  65,  65,  32,  32,  32,  32,  32,  32,
     65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  32,  32,  32,  32,  32,   1,
}

assert(#ebcdic_chars == 256)

function M.main(buffer, offset, out)
    use_color = use_color or huxdemp.colors_enabled()

    local border = "|"
    if use_color then border = "│" end

    out:write(border)

    for i = 1, #buffer do
        if use_color then
            local color = huxdemp.color_for(ebcdic_colors[buffer[i] + 1])
            out:write("\x1b[38;5;" .. color .. "m")
        end

        out:write(ebcdic_chars[buffer[i] + 1])

        if use_color then
            out:write("\x1b[m")
        end
    end

    out:write(border)
    out:write((" "):rep(huxdemp.linewidth() - #buffer))
end

return M
