Загрузка данных


-- Auto-detect output: Advanced Monitor or Computer Screen
local monitor = peripheral.find("monitor")
local target_term = monitor or term

-- Find Storage System
local storage = peripheral.find("functionalstorage:storage_controller") or 
                peripheral.find("sophisticatedstorage:storage_controller") or 
                peripheral.find("inventory")

if not storage then
    error("Error: Storage Controller not found!")
end

-- Configuration
local UPDATE_INTERVAL = 1.0
local WINDOW_SIZE = 10
local active_tab = "Main" -- Active tab state: "Main" or "Resources"

-- Databases
local last_counts = {}
local history = {}

-- Screen Size Dimensions
local width, height = target_term.getSize()

-- Color handling helper for standard vs advanced computers
local function setColors(text_col, bg_col)
    if target_term.isColor() then
        target_term.setTextColor(text_col)
        target_term.setBackgroundColor(bg_col)
    end
end

-- Fetch item counts from the inventory system
local function getInventoryCounts()
    local counts = {}
    local items = storage.list()
    for _, item in pairs(items) do
        if item and item.name then
            counts[item.name] = (counts[item.name] or 0) + item.count
        end
    end
    return counts
end

-- Render top navigation bar
local function drawUI()
    setColors(colors.white, colors.gray)
    target_term.clear()
    
    -- Draw top bar background
    setColors(colors.white, colors.black)
    for y = 1, 2 do
        target_term.setCursorPos(1, y)
        target_term.write(string.rep(" ", width))
    end
    
    -- Render Main Tab Button
    if active_tab == "Main" then
        setColors(colors.yellow, colors.lightGray)
    else
        setColors(colors.white, colors.black)
    end
    target_term.setCursorPos(2, 1)
    target_term.write(" [ Home ] ")
    
    -- Render Resources Tab Button
    if active_tab == "Resources" then
        setColors(colors.yellow, colors.lightGray)
    else
        setColors(colors.white, colors.black)
    end
    target_term.setCursorPos(14, 1)
    target_term.write(" [ Resources ] ")
    
    setColors(colors.white, colors.gray)
end

-- Render Resources Page Content
local function drawResourcesPage(current_counts)
    setColors(colors.white, colors.gray)
    
    -- Table Header
    target_term.setCursorPos(2, 4)
    target_term.write(string.format("%-16s | %-8s | %-8s", "Resource", "Total", "Gain/s"))
    target_term.setCursorPos(2, 5)
    target_term.write(string.rep("-", width - 2))
    
    local line = 6
    for name, hist in pairs(history) do
        local total_diff = 0
        for _, entry in ipairs(hist) do
            total_diff = total_diff + entry.diff
        end
        
        local avg_gain = total_diff / WINDOW_SIZE
        local current_total = current_counts[name] or 0
        local short_name = name:match(":(.+)$") or name
        
        -- Display items currently in system or items with a change rate
        if current_total > 0 or math.abs(avg_gain) > 0.01 then
            target_term.setCursorPos(2, line)
            
            local trunc_name = short_name:sub(1, 16)
            
            if avg_gain > 0 then
                setColors(colors.green, colors.gray)
                target_term.write(string.format("%-16s | %-8d | +%.2f", trunc_name, current_total, avg_gain))
            elseif avg_gain < 0 then
                setColors(colors.red, colors.gray)
                target_term.write(string.format("%-16s | %-8d | %.2f", trunc_name, current_total, avg_gain))
            else
                setColors(colors.white, colors.gray)
                target_term.write(string.format("%-16s | %-8d |  0.00", trunc_name, current_total))
            end
            
            line = line + 1
            if line > height - 1 then break end
        end
    end
end

-- Render Home Page Content
local function drawMainPage()
    setColors(colors.white, colors.gray)
    target_term.setCursorPos(2, 4)
    target_term.write("Welcome to Storage Monitor OS!")
    target_term.setCursorPos(2, 6)
    target_term.write("Click on [ Resources ] tab above")
    target_term.setCursorPos(2, 7)
    target_term.write("to view live item tracking stats.")
end

-- Handle Touch and Click Events
local function handleClicks()
    while true do
        local event, side, x, y = os.pullEvent()
        
        if event == "mouse_click" or event == "monitor_touch" then
            -- Check if click is inside the top menu bounds
            if y == 1 or y == 2 then
                if x >= 2 and x <= 11 then
                    active_tab = "Main"
                elseif x >= 14 and x <= 28 then
                    active_tab = "Resources"
                end
                
                -- Force instant UI refresh on interaction
                drawUI()
                if active_tab == "Main" then drawMainPage() else drawResourcesPage(last_counts) end
            end
        end
    end
end

-- Main Data Tracking Loop
local function dataLoop()
    last_counts = getInventoryCounts()
    
    while true do
        local current_counts = getInventoryCounts()
        local current_time = os.epoch("utc") / 1000
        
        local all_items = {}
        for name in pairs(last_counts) do all_items[name] = true end
        for name in pairs(current_counts) do all_items[name] = true end
        
        for name in pairs(all_items) do
            local old_val = last_counts[name] or 0
            local new_val = current_counts[name] or 0
            local diff = new_val - old_val
            
            if not history[name] then history[name] = {} end
            table.insert(history[name], { time = current_time, diff = diff })
            
            while #history[name] > 0 and (current_time - history[name].time) > WINDOW_SIZE do
                table.remove(history[name], 1)
            end
        end
        
        -- Refresh display layout
        drawUI()
        if active_tab == "Main" then
            drawMainPage()
        elseif active_tab == "Resources" then
            drawResourcesPage(current_counts)
        end
        
        last_counts = current_counts
        os.sleep(UPDATE_INTERVAL)
    end
end

-- Start parallel processes (Data tracking + Event listener)
parallel.waitForAny(dataLoop, handleClicks)