// 📈 Real-time Data Chart Demo - TimerBox + WebCanvasBox + RandomBox  
// Dynamic chart visualization with multiple chart types and data streaming

print("📈 === Real-time Data Chart Demo Starting ===")

// Initialize components
local canvas, timer, random
canvas = new WebCanvasBox("demo-canvas", 800, 500)
timer = new TimerBox()
random = new RandomBox()

// Chart configuration
local chartConfig
chartConfig = {
    type: "line",  // line, bar, area, scatter
    title: "Nyash Performance Metrics",
    width: 700,
    height: 350,
    marginLeft: 80,
    marginTop: 50,
    marginRight: 50,
    marginBottom: 80,
    maxDataPoints: 50,
    updateInterval: 100,  // milliseconds
    colors: ["#3498db", "#e74c3c", "#2ecc71", "#f39c12", "#9b59b6"]
}

// Data series
local dataSeries
dataSeries = [
    {name: "Memory Usage", data: [], color: "#3498db", unit: "MB"},
    {name: "CPU Usage", data: [], color: "#e74c3c", unit: "%"},
    {name: "Network I/O", data: [], color: "#2ecc71", unit: "KB/s"},
    {name: "Disk Usage", data: [], color: "#f39c12", unit: "GB"}
]

// Chart drawing functions
local drawAxes
drawAxes = function() {
    local plotX, plotY, plotWidth, plotHeight
    plotX = chartConfig.marginLeft
    plotY = chartConfig.marginTop
    plotWidth = chartConfig.width - chartConfig.marginLeft - chartConfig.marginRight
    plotHeight = chartConfig.height - chartConfig.marginTop - chartConfig.marginBottom
    
    // Draw axes
    canvas.setStrokeStyle("#34495e")
    canvas.setLineWidth(2)
    
    // Y axis
    canvas.drawLine(plotX, plotY, plotX, plotY + plotHeight, "#34495e", 2)
    
    // X axis
    canvas.drawLine(plotX, plotY + plotHeight, plotX + plotWidth, plotY + plotHeight, "#34495e", 2)
    
    // Grid lines
    canvas.setStrokeStyle("#ecf0f1")
    canvas.setLineWidth(1)
    
    local i, x, y
    // Vertical grid lines
    i = 1
    loop(i < 10) {
        x = plotX + (plotWidth / 10) * i
        canvas.drawLine(x, plotY, x, plotY + plotHeight, "#ecf0f1", 1)
        i = i + 1
    }
    
    // Horizontal grid lines
    i = 1
    loop(i < 8) {
        y = plotY + (plotHeight / 8) * i
        canvas.drawLine(plotX, y, plotX + plotWidth, y, "#ecf0f1", 1)
        i = i + 1
    }
}

local drawLabels
drawLabels = function() {
    local plotX, plotY, plotWidth, plotHeight
    plotX = chartConfig.marginLeft
    plotY = chartConfig.marginTop
    plotWidth = chartConfig.width - chartConfig.marginLeft - chartConfig.marginRight
    plotHeight = chartConfig.height - chartConfig.marginTop - chartConfig.marginBottom
    
    // Y axis labels
    canvas.setFillStyle("#2c3e50")
    local i, value, y
    i = 0
    loop(i <= 8) {
        value = 100 - (i * 12.5)  // 0-100 scale
        y = plotY + (plotHeight / 8) * i
        canvas.fillText(value.toString(), plotX - 30, y + 5, "12px Arial", "#2c3e50")
        i = i + 1
    }
    
    // X axis labels (time)
    i = 0
    loop(i <= 10) {
        local timeLabel, x
        timeLabel = "-" + (10 - i) + "s"
        x = plotX + (plotWidth / 10) * i
        canvas.fillText(timeLabel, x - 10, plotY + plotHeight + 20, "12px Arial", "#2c3e50")
        i = i + 1
    }
    
    // Axis titles
    canvas.fillText("Time", plotX + plotWidth / 2 - 20, plotY + plotHeight + 50, "14px Arial", "#2c3e50")
    
    // Y axis title (rotated)
    canvas.fillText("Value", 20, plotY + plotHeight / 2, "14px Arial", "#2c3e50")
}

local drawLineChart
drawLineChart = function() {
    local plotX, plotY, plotWidth, plotHeight
    plotX = chartConfig.marginLeft
    plotY = chartConfig.marginTop
    plotWidth = chartConfig.width - chartConfig.marginLeft - chartConfig.marginRight
    plotHeight = chartConfig.height - chartConfig.marginTop - chartConfig.marginBottom
    
    local i, series
    i = 0
    loop(i < dataSeries.length()) {
        series = dataSeries[i]
        
        if (series.data.length() > 1) {
            canvas.setStrokeStyle(series.color)
            canvas.setLineWidth(3)
            canvas.beginPath()
            
            local j, x, y, value
            j = 0
            loop(j < series.data.length()) {
                value = series.data[j]
                x = plotX + (j / (chartConfig.maxDataPoints - 1)) * plotWidth
                y = plotY + plotHeight - (value / 100) * plotHeight
                
                if (j == 0) {
                    canvas.moveTo(x, y)
                } else {
                    canvas.lineTo(x, y)
                }
                j = j + 1
            }
            
            canvas.stroke(series.color, 3)
            
            // Draw data points
            j = 0
            loop(j < series.data.length()) {
                value = series.data[j]
                x = plotX + (j / (chartConfig.maxDataPoints - 1)) * plotWidth
                y = plotY + plotHeight - (value / 100) * plotHeight
                
                canvas.setFillStyle(series.color)
                canvas.fillCircle(x, y, 4)
                
                j = j + 1
            }
        }
        
        i = i + 1
    }
}

local drawBarChart
drawBarChart = function() {
    local plotX, plotY, plotWidth, plotHeight
    plotX = chartConfig.marginLeft
    plotY = chartConfig.marginTop
    plotWidth = chartConfig.width - chartConfig.marginLeft - chartConfig.marginRight
    plotHeight = chartConfig.height - chartConfig.marginTop - chartConfig.marginBottom
    
    if (dataSeries[0].data.length() > 0) {
        local barWidth, spacing, i, series, value, x, y, height
        barWidth = (plotWidth / chartConfig.maxDataPoints) * 0.8
        spacing = (plotWidth / chartConfig.maxDataPoints) * 0.2
        
        local dataIndex
        dataIndex = dataSeries[0].data.length() - 1
        
        i = 0
        loop(i < dataSeries.length()) {
            series = dataSeries[i]
            
            if (dataIndex < series.data.length()) {
                value = series.data[dataIndex]
                x = plotX + plotWidth - barWidth * (i + 1) - spacing * i
                height = (value / 100) * plotHeight
                y = plotY + plotHeight - height
                
                canvas.setFillStyle(series.color)
                canvas.fillRect(x, y, barWidth * 0.8, height)
                
                // Value label
                canvas.setFillStyle("#2c3e50")
                canvas.fillText(value.toString(), x + 5, y - 10, "10px Arial", "#2c3e50")
            }
            
            i = i + 1
        }
    }
}

local drawAreaChart
drawAreaChart = function() {
    local plotX, plotY, plotWidth, plotHeight
    plotX = chartConfig.marginLeft
    plotY = chartConfig.marginTop
    plotWidth = chartConfig.width - chartConfig.marginLeft - chartConfig.marginRight
    plotHeight = chartConfig.height - chartConfig.marginTop - chartConfig.marginBottom
    
    local i, series
    i = 0
    loop(i < dataSeries.length()) {
        series = dataSeries[i]
        
        if (series.data.length() > 1) {
            // Create area fill
            canvas.beginPath()
            
            local j, x, y, value
            j = 0
            loop(j < series.data.length()) {
                value = series.data[j]
                x = plotX + (j / (chartConfig.maxDataPoints - 1)) * plotWidth
                y = plotY + plotHeight - (value / 100) * plotHeight
                
                if (j == 0) {
                    canvas.moveTo(x, plotY + plotHeight)
                    canvas.lineTo(x, y)
                } else {
                    canvas.lineTo(x, y)
                }
                j = j + 1
            }
            
            // Close the area
            canvas.lineTo(plotX + plotWidth, plotY + plotHeight)
            canvas.lineTo(plotX, plotY + plotHeight)
            canvas.closePath()
            
            // Fill with semi-transparent color
            local fillColor
            fillColor = series.color.replace(")", ", 0.3)")
            if (series.color.startsWith("#")) {
                // Convert hex to rgba
                fillColor = series.color + "80"  // Add alpha
            }
            canvas.fill(fillColor)
            
            // Draw border line
            canvas.setStrokeStyle(series.color)
            canvas.setLineWidth(2)
            
            canvas.beginPath()
            j = 0
            loop(j < series.data.length()) {
                value = series.data[j]
                x = plotX + (j / (chartConfig.maxDataPoints - 1)) * plotWidth
                y = plotY + plotHeight - (value / 100) * plotHeight
                
                if (j == 0) {
                    canvas.moveTo(x, y)
                } else {
                    canvas.lineTo(x, y)
                }
                j = j + 1
            }
            canvas.stroke(series.color, 2)
        }
        
        i = i + 1
    }
}

// Legend drawing
local drawLegend
drawLegend = function() {
    local legendX, legendY, i, series
    legendX = chartConfig.width - chartConfig.marginRight - 150
    legendY = chartConfig.marginTop + 20
    
    // Legend background
    canvas.setFillStyle("#f8f9fa")
    canvas.fillRect(legendX - 10, legendY - 10, 160, dataSeries.length() * 25 + 20)
    canvas.setStrokeStyle("#dee2e6")
    canvas.strokeRect(legendX - 10, legendY - 10, 160, dataSeries.length() * 25 + 20)
    
    canvas.setFillStyle("#2c3e50")
    canvas.fillText("Legend", legendX, legendY, "14px Arial", "#2c3e50")
    
    i = 0
    loop(i < dataSeries.length()) {
        series = dataSeries[i]
        
        // Color box
        canvas.setFillStyle(series.color)
        canvas.fillRect(legendX, legendY + 15 + i * 25, 15, 15)
        
        // Series name and latest value
        canvas.setFillStyle("#2c3e50")
        local latestValue, valueText
        if (series.data.length() > 0) {
            latestValue = series.data[series.data.length() - 1]
            valueText = series.name + ": " + latestValue + series.unit
        } else {
            valueText = series.name + ": --"
        }
        canvas.fillText(valueText, legendX + 20, legendY + 27 + i * 25, "12px Arial", "#2c3e50")
        
        i = i + 1
    }
}

// Data generation
local generateDataPoint
generateDataPoint = function(seriesIndex) {
    local baseValue, variation, value
    
    if (seriesIndex == 0) {  // Memory Usage
        baseValue = 45
        variation = random.randInt(-5, 15)
    } else if (seriesIndex == 1) {  // CPU Usage
        baseValue = 35
        variation = random.randInt(-10, 25)
    } else if (seriesIndex == 2) {  // Network I/O
        baseValue = 25
        variation = random.randInt(-15, 30)
    } else {  // Disk Usage
        baseValue = 60
        variation = random.randInt(-3, 8)
    }
    
    value = baseValue + variation
    return Math.max(0, Math.min(100, value))
}

// Update data
local updateData
updateData = function() {
    local i, series, newValue
    i = 0
    loop(i < dataSeries.length()) {
        series = dataSeries[i]
        newValue = generateDataPoint(i)
        
        // Add new data point
        series.data.push(newValue)
        
        // Remove old data points if exceeding max
        if (series.data.length() > chartConfig.maxDataPoints) {
            series.data.removeFirst()
        }
        
        i = i + 1
    }
}

// Main chart drawing function
local drawChart
drawChart = function() {
    // Clear canvas
    canvas.setFillStyle("#ffffff")
    canvas.fillRect(0, 0, 800, 500)
    
    // Title
    canvas.setFillStyle("#2c3e50")
    canvas.fillText(chartConfig.title, 250, 30, "20px Arial", "#2c3e50")
    
    // Chart type indicator
    canvas.fillText("Chart Type: " + chartConfig.type.toUpperCase(), 50, 30, "16px Arial", "#34495e")
    
    // Draw chart elements
    drawAxes()
    drawLabels()
    
    if (chartConfig.type == "line") {
        drawLineChart()
    } else if (chartConfig.type == "bar") {
        drawBarChart()
    } else if (chartConfig.type == "area") {
        drawAreaChart()
    }
    
    drawLegend()
    
    // Status info
    canvas.setFillStyle("#6c757d")
    local statusText
    statusText = "Data Points: " + dataSeries[0].data.length() + "/" + chartConfig.maxDataPoints + " | Update Rate: " + chartConfig.updateInterval + "ms"
    canvas.fillText(statusText, 50, 480, "12px Arial", "#6c757d")
}

// Initialize with some sample data
local i
i = 0
loop(i < 10) {
    updateData()
    i = i + 1
}

// Draw initial chart
drawChart()

// Simulate real-time updates
local updateCount
updateCount = 0

local simulateUpdates
simulateUpdates = function() {
    local frameCount
    frameCount = 0
    
    loop(frameCount < 20) {
        updateData()
        drawChart()
        frameCount = frameCount + 1
        updateCount = updateCount + 1
    }
}

simulateUpdates()

print("📈 Real-time Data Chart Demo Ready!")
print("• Chart type: " + chartConfig.type)
print("• Data series: " + dataSeries.length())
print("• Max data points: " + chartConfig.maxDataPoints)
print("• Update interval: " + chartConfig.updateInterval + "ms")
print("• Total updates: " + updateCount)

// Demo different chart types
local chartTypes
chartTypes = ["line", "bar", "area"]
i = 0
loop(i < chartTypes.length()) {
    chartConfig.type = chartTypes[i]
    drawChart()
    print("✓ Rendered " + chartTypes[i] + " chart")
    i = i + 1
}

// Set back to line chart
chartConfig.type = "line"
drawChart()

print("🌟 Advanced chart features:")
print("• Multiple visualization types (line, bar, area)")
print("• Real-time data streaming with history")
print("• Professional grid system and axes")
print("• Interactive legend with current values")
print("• Responsive layout with proper margins")
print("• Data point management with rolling buffer")

print("🌐 Everything is Box - even data visualization!")
print("✅ Real-time Data Chart Demo Complete!")