
-- NEXUS CONTROL SYSTEM
-- ComputerCraft / CC:Tweaked
-- Minecraft 1.20.1 Forge

local mon = peripheral.find("monitor")
if not mon then
    print("ERROR: Monitor not found!")
    return
end

mon.setTextScale(0.5)
mon.setBackgroundColor(colors.black)
mon.setCursorBlink(false)

local W, H = mon.getSize()
local GREEN = colors.green
local LIME = colors.lime
local WHITE = colors.white
local RED = colors.red
local GRAY = colors.gray
local CYAN = colors.cyan
local BLACK = colors.black

local PAGE_TIME_MIN = 25
local PAGE_TIME_MAX = 35
local FRAME_DELAY = 0.15

local messages = {
    "All systems operational",
    "Scanning peripheral network...",
    "Security protocol active",
    "Data stream synchronized",
    "Checking system integrity",
    "Energy core interface ready",
    "Network signal detected",
    "Diagnostics completed",
    "Monitoring active",
    "Background process running",
    "Awaiting new instructions",
    "System stability nominal"
}

local pages = {
    "SYSTEM DIAGNOSTICS",
    "NETWORK SCAN",
    "SECURITY SCAN"
}

local chars = "0123456789ABCDEF#$%&*"

local function randChar()
    local i = math.random(1, #chars)
    return chars:sub(i, i)
end

local function center(y, s, color)
    s = tostring(s)
    local x = math.max(1, math.floor((W - #s) / 2) + 1)
    mon.setCursorPos(x, y)
    mon.setTextColor(color or GREEN)
    mon.write(s:sub(1, W - x + 1))
end

local function text(x, y, s, color)
    if y < 1 or y > H or x > W then return end
    x = math.max(1, x)
    mon.setCursorPos(x, y)
    mon.setTextColor(color or GREEN)
    mon.write(tostring(s):sub(1, W - x + 1))
end

local function clear()
    mon.setBackgroundColor(BLACK)
    mon.setTextColor(GREEN)
    mon.clear()
end

local function bar(x, y, width, pct)
    local n = math.floor(width * pct / 100)
    for i = 0, width - 1 do
        text(x + i, y, i < n and "#" or "-", 
            i < n and LIME or GRAY)
    end
end

-- Fixed-offset world clocks.
-- UTC offsets are manually configurable.
local function clockLine()
    local epoch = os.epoch("utc") / 1000

    local clocks = {
        {name = "UKRAINE", offset = 2},
        {name = "USA-NY", offset = -5},
        {name = "USA-LA", offset = -8},
        {name = "NEW ZEALAND", offset = 12}
    }

    local parts = {}

    for _, c in ipairs(clocks) do
        local t = os.date("!*t", epoch + c.offset * 3600)
        parts[#parts + 1] = string.format(
            "%s %02d:%02d:%02d",
            c.name, t.hour, t.min, t.sec
        )
    end

    return table.concat(parts, " | ")
end

local function header(name)
    clear()
    text(2, 1, "NEXUS // CONTROL SYSTEM", LIME)
    text(math.max(2, W - #name - 1), 1, name, CYAN)

    if H >= 3 then
        for x = 1, W do
            text(x, 2, "-", GREEN)
        end
    end
end

local function footer(message)
    if H < 5 then return end

    text(2, H - 2, "SYSTEM MESSAGE:", CYAN)
    text(2, H - 1, message, LIME)

    local clocks = clockLine()
    text(2, H, clocks, WHITE)
end

-- Smooth transition: progressively clear the screen.
local function fadeOut()
    for y = 1, H do
        mon.setCursorPos(1, y)
        mon.setBackgroundColor(BLACK)
        mon.setTextColor(BLACK)
        mon.write(string.rep(" ", W))
        sleep(0.025)
    end
end

-- Random audio-wave-style visualization.
-- Visual only: no actual sound is played.
local function drawWave(frame)
    if H < 8 then return end

    local yMid = math.floor((H - 4) / 2)
    local available = math.max(1, H - 6)

    for x = 2, W - 1 do
        local a = math.sin(x * 0.35 + frame * 0.3)
        local b = math.sin(x * 0.16 - frame * 0.2)
        local noise = (math.random() - 0.5) * 0.7

        local amplitude = (a + b + noise) * available / 5
        local y = math.floor(yMid + amplitude)

        local color = math.abs(amplitude) > available / 4
            and LIME or GREEN

        text(x, y, "*", color)
    end

    text(2, 3, "SIGNAL WAVEFORM", CYAN)
end

-- 1. SYSTEM DIAGNOSTICS
local function diagnostics(frame)
    header("DIAGNOSTICS")

    local names = peripheral.getNames()
    local total = #names

    text(2, 4, "HARDWARE DIAGNOSTICS", CYAN)
    text(2, 6, "COMPUTER STATUS", WHITE)
    text(2, 7, "ONLINE", LIME)

    text(2, 9, "PERIPHERALS DETECTED:", GREEN)
    text(2, 10, tostring(total), WHITE)

    local maxRows = math.max(0, H - 15)

    for i = 1, math.min(total, maxRows) do
        text(2, 11 + i, "> " .. names[i], GREEN)
    end

    local free = math.floor(
        100 * (1 - os.getComputerID() % 10 / 20)
    )

    text(2, H - 4, "SYSTEM LOAD (SIMULATED)", CYAN)
    bar(2, H - 3, math.max(1, W - 4), free)

    footer(messages[math.random(#messages)])
end

-- 2. NETWORK SCAN
local function networkScan(frame)
    header("NETWORK SCAN")

    local cx = math.floor(W / 2)
    local cy = math.floor(H / 2)

    for i = 1, math.max(8, math.floor(W / 2)) do
        local angle = i * 2 * math.pi /
            math.max(8, math.floor(W / 2)) + frame * 0.08

        local x = math.floor(cx + math.cos(angle) * W * 0.3)
        local y = math.floor(cy + math.sin(angle) * H * 0.25)

        text(x, y, "+", LIME)

        if i % 3 == 0 then
            text(math.floor((x + cx) / 2),
               math.floor((y + cy) / 2), ".", GREEN)
        end
    end

   text(cx, cy, "[N]", WHITE)
    text(2, 4, "SIGNAL ROUTING ACTIVE", CYAN)

    footer(messages[math.random(#messages)])
end

-- 3. REACTOR CONTROL
-- Decorative values only until connected to real Mekanism data.
--local function reactorControl(frame)
--    header("REACTOR CONTROL")

--    local temp = 50 + math.floor(
--        (math.sin(frame * 0.12) + 1) * 25
--    )
--    local energy = 40 + math.floor(
--        (math.sin(frame * 0.08 + 2) + 1) * 30
--    )

--    text(2, 4, "CORE STATUS: SIMULATION", CYAN)
--    text(2, 6, "TEMPERATURE", WHITE)
--    text(2, 7, temp .. "%", temp > 80 and RED or LIME)
--    bar(2, 8, math.max(1, W - 4), temp)

--    text(2, 10, "ENERGY OUTPUT", WHITE)
--    text(2, 11, energy .. "%", LIME)
--    bar(2, 12, math.max(1, W - 4), energy)

---    local pulse = frame % 4
--    center(math.max(14, math.floor(H / 2)),
--        pulse == 0 and "[ CORE ]" or
--        pulse == 1 and "< CORE >" or
--        pulse == 2 and "{ CORE }" or
--        "* CORE *", LIME)

--    footer("SIMULATION - NOT REAL REACTOR DATA")
--end

-- 5. SECURITY SCAN
local function securityScan(frame)
    header("SECURITY SCAN")

    text(2, 4, "ACCESS CONTROL", CYAN)
    text(2, 6, "SCANNING SYSTEM...", WHITE)

    local width = math.max(1, W - 4)
    local pct = (frame * 7) % 101

    bar(2, 8, width, pct)
    text(2, 9, "SCAN: " .. pct .. "%", LIME)

    for y = 11, H - 5 do
        local line = ""
        for x = 1, math.min(W - 3, 24) do
            line = line .. randChar()
        end

        text(2, y, line, math.random(1, 5) == 1
            and WHITE or GREEN)
    end

    footer(messages[math.random(#messages)])
end

-- Random page selection without repeating the previous page.
local previous = nil
local frame = 0

local function choosePage()
    local choices = {}

    for i = 1, #pages do
        if i ~= previous then
            choices[#choices + 1] = i
        end
    end

    local selected = choices[math.random(#choices)]
    previous = selected

    return selected
end

-- MAIN LOOP
while true do
    local selected = choosePage()
    local duration = math.random(PAGE_TIME_MIN, PAGE_TIME_MAX)
    local started = os.clock()

    fadeOut()

    while os.clock() - started < duration do
        frame = frame + 1

        if selected == 1 then
            diagnostics(frame)
        elseif selected == 2 then
            networkScan(frame)
        elseif selected == 4 then
            securityScan(frame)
        end

        drawWave(frame)
        sleep(FRAME_DELAY)
    end
end
