local debug = false
local component = require("component")
local computer = require("computer")
local event = require("event")
local gpu = component.gpu
local os = require("os")
local unicode = require("unicode")

function resetGPU(w, h)
	gpu.setResolution(w, h)
	gpu.setBackground(0, false)
	gpu.setForeground(16777215, false)
	gpu.fill(1, 1, w, h, " ")
end

active = 50
function onKeyDown(name, addr, char, key, player)
	active = 0
	return false
end
if debug then
	event.listen("key_down", onKeyDown)
end

resetGPU(160, 50)
local ticks = 0

function getLine(data, n)
	local p = (n)*2+1
	if (p+1 > #data) or (p <= 0) then
		return nil
	else
		local d = string.byte(data, p) | (string.byte(data, p + 1) << 8)
		local s = ""
		for i=1,16 do
			if (d & 1) == 0 then
				s = s .. "███"
			else
				s = s .. "   "
			end
			d = d >> 1
		end
		return s .. "██"
	end
end

function getColor(ticks, mul)
	local ctr = ((ticks & 31) / 32) * 6
	local x = math.floor(mul * (ctr % 1))
	local y = mul
	local z = math.floor(mul * (1 - (ctr % 1)))
	if ctr >= 5 then
		return (y << 16) | z
    end
	if ctr >= 4 then
		return (x << 16) | y
    end
	if ctr >= 3 then
		return (z << 8) | y
    end
	if ctr >= 2 then
		return (y << 8) | x
    end
	if ctr >= 1 then
		return (z << 16) | (y << 8)
    end
	return (y << 16) | (x << 8)
end

function getColorL(ticks, mul)
	local bp = math.floor((ticks >> 4) / 7)
	if bp >= #data then
		return 0xFF
	end
	if (ticks % 16) >= 11 then
		local x = mul
		local datapos = ticks >> 4
		local bitpos = datapos % 7
		local bytepos = math.floor(datapos / 7)
		local v = string.byte(data, bytepos + 1, bytepos + 1) >> bitpos
		if (v & 1) == 0 then
			x = x >> 2
		end
		return (x << 16) | (x << 8) | x
	end
	return getColorR(ticks, mul)
end

local lastSleep = computer.uptime()
function sleep(time)
	local target = lastSleep + time
	while computer.uptime() < target do
		os.sleep(0.05)
	end
	lastSleep = target
end

local obarx = 80
local bary, baryh, baryd, barw, delta
local xd = 0
local ci = 1

function updateColors()
	local col = 8
	ci = ci - 1
	if ci < 0 then ci = 14 end
	for i=ci,ci do
		local ii = i % 15
		-- gpu.setPaletteColor(ii, 0x1F1F1F * col)
		col = col - 1
	end
end

gpu.setPaletteColor(15, 0x000000)
updateColors()

local file = io.open("kscroll.dat")
local data = file:read("*all")
local mul = 0xFF
io.close(file)

while active > 0 do
	bary = 1
	barh = 50
	baryd = 1
	barx = math.sin(ticks / 20) * math.cos(ticks / 40) * math.sin(ticks / 26.5)
	barx = barx * 80 + 80
	barw = 1
	delta = (barx - obarx)
	obarx = barx
	if delta < 0 then
		xd = 1
	elseif delta >= 0 then
		xd = -1
	end
	if math.abs(delta) > 1 then
		if delta < 0 then
			delta = delta + 1
			barw = barw - delta
		else
			delta = delta - 1
			barx = barx - delta
			barw = barw + delta
		end
	end
	barx = barx - 1
	barw = barw + 2
	xd = xd * math.max(1, barw / 3)
	obarx = obarx + xd
	gpu.setBackground(15, true)
	gpu.fill(1, bary, 160, baryd, " ")
	if xd < 0 then
		gpu.fill(160 + xd, bary, 160, barh, " ")      
	elseif xd > 0 then
		gpu.fill(1, bary, xd, barh, " ")      
	end
    -- gpu.setBackground((ci - 1) % 15, true)
	gpu.copy(1, bary, 160, barh - baryd, xd, baryd)
	local line = getLine(data, ticks)
	if line == nil then
		if ticks > 0 then
			if mul >= 2.5 then
				mul = mul - 2.5
			else
				active = active - 1
			end
		end
		line = "██████████████████████████████████████████████████"
	end
	gpu.setForeground(getColor(ticks, math.floor(mul + 0.5)), false)
	for i=0,barw-1 do
		gpu.set(barx - 2 + i, 1, line, true)
	end
	if ticks % 3 == 1 then
		sleep(0.05)
	end
	ticks = ticks + 1
end
resetGPU(80, 25)
