-- print boxes on the screen using cp437 encoding on DOS/Windows platform,
-- or using UTF-8 encoding on Linux platform (assuming that your console/
-- terminal is configured to use this encoding). 
-- Update: December/27/2021

include graphics.e

include cp437.e
include utf8.e


object
    box_up_left,
    box_up_right,
    box_dn_left,
    box_dn_right,
    box_horizontal,
    box_vertical,
    box_fill_char

sequence
    u8

if platform() = DOS32 or platform() = WIN32 then -- cp437
    box_up_left    = 218
    box_up_right   = 191
    box_dn_left    = 192
    box_dn_right   = 217
    box_horizontal = 196
    box_vertical   = 179
    box_fill_char  = 219
else -- platform() = LINUX
    u8 = group_utf8(unicode_to_utf8(CP437)) -- mapping cp437 to UTF-8
    box_up_left    = u8[218]
    box_up_right   = u8[191]
    box_dn_left    = u8[192]
    box_dn_right   = u8[217]
    box_horizontal = u8[196]
    box_vertical   = u8[179]
    box_fill_char  = u8[219]
end if


constant
    VC = video_config(),
    MAX_ROWS = VC[VC_LINES],
    MAX_COLS = VC[VC_COLUMNS]


procedure print_box(integer up, integer left, integer down, integer right)
    integer width, height
    sequence hline, space

    -- adjust down and right to terminal size
    if down > MAX_ROWS then
	down = MAX_ROWS
    end if
    if right > MAX_COLS then
	right = MAX_COLS
    end if

    width = right - left - 2
    height = down - up - 2

    if width < 0 or height < 0 then
	return        -- out of range, can't print this box...
    end if

    space = {}
    hline = {}
    for i = 1 to width do
	space &= box_fill_char
	hline &= box_horizontal
    end for

    -- print box on screen
    position(up, left)
    puts(1, box_up_left & hline & box_up_right)
    position(down, left)
    puts(1, box_dn_left & hline & box_dn_right)

    for row = up + 1 to down - 1 do
	position(row, left)
	puts(1, box_vertical & space & box_vertical)
    end for
end procedure


constant ESC = 27

procedure hide_cursor()
    if platform() = LINUX then
	if system_exec("tput civis", 2) then              -- compatible (terminfo)
	    if system_exec("setterm -cursor off", 2) then -- compatible
		puts(1, ESC & "[?25l" & ESC & "[?1c")     -- fast, less compatible
	    end if
	end if
    else
	cursor(NO_CURSOR)
    end if
end procedure


procedure show_cursor()
    if platform() = LINUX then
	if system_exec("tput cnorm", 2) then             -- compatible (terminfo)
	    if system_exec("setterm -cursor on", 2) then -- compatible
		puts(1, ESC & "[?25h" & ESC & "[?0c")    -- fast, less compatible
	    end if
	end if
    else
	cursor(THICK_UNDERLINE_CURSOR)
    end if
end procedure


-- run demo

integer color, up, left, down, right
sequence slowdown

-- print background box
hide_cursor()
bk_color(BLACK)
text_color(WHITE)
print_box(1, 1, MAX_ROWS, MAX_COLS)

-- print many boxes on the screen until user press any key
while get_key() = -1 do
    color = rand(8) - 1
    bk_color(color)
    text_color(color + 8)

    up = rand(MAX_ROWS - 2)
    left = rand(MAX_COLS - 2)
    down = rand(MAX_ROWS)
    right = rand(MAX_COLS)

    print_box(up, left, down, right)

    slowdown = sprintf("%.1f", time())
    while equal(slowdown, sprintf("%.1f", time())) do
    end while
end while


-- restore screen attributes
bk_color(BLACK)
text_color(WHITE)
puts(1, '\n')
position(1, 1)
show_cursor()
