' Bar Graph — draws ASCII horizontal and vertical bar charts
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL data(100) AS LONG
    LOCAL labels(100) AS STRING
    LOCAL n AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL maxVal AS LONG
    LOCAL barLen AS LONG
    LOCAL maxBarLen AS LONG
    LOCAL lineStr AS STRING
    LOCAL elemStr AS STRING
    LOCAL totalVal AS LONG
    LOCAL barLenA AS LONG
    LOCAL barLenTotal AS LONG
    LOCAL labelStr AS STRING
    LOCAL tempStr AS STRING
    n = 12
    maxBarLen = 40
    PRINT "============================================"
    PRINT "          ASCII BAR CHART"
    PRINT "============================================"
    PRINT ""
    FOR i = 0 TO n - 1
        data(i) = ((i * 17 + 5) MOD 30) + 3
    NEXT i
    maxVal = data(0)
    FOR i = 1 TO n - 1
        IF data(i) > maxVal THEN
            maxVal = data(i)
        END IF
    NEXT i
    IF maxVal < 1 THEN
        maxVal = 1
    END IF
    PRINT "Horizontal bar chart:"
    PRINT ""
    FOR i = 0 TO n - 1
        barLen = data(i) * maxBarLen / maxVal
        lineStr = " Item " + STR$(i)
        DO WHILE LEN(lineStr) < 10
            lineStr = lineStr + " "
        LOOP
        lineStr = lineStr + "|"
        FOR j = 1 TO barLen
            lineStr = lineStr + "#"
        NEXT j
        lineStr = lineStr + " " + STR$(data(i))
        PRINT lineStr
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "     VERTICAL BAR CHART"
    PRINT "============================================"
    PRINT ""
    n = 20
    FOR i = 0 TO n - 1
        data(i) = ((i * 11 + 3) MOD 20) + 2
    NEXT i
    maxVal = data(0)
    FOR i = 1 TO n - 1
        IF data(i) > maxVal THEN
            maxVal = data(i)
        END IF
    NEXT i
    IF maxVal < 1 THEN
        maxVal = 1
    END IF
    maxBarLen = 14
    PRINT "Vertical bar chart:"
    PRINT ""
    FOR j = maxBarLen TO 1 STEP -1
        lineStr = ""
        FOR i = 0 TO n - 1
            barLen = data(i) * maxBarLen / maxVal
            IF barLen >= j THEN
                lineStr = lineStr + "## "
            ELSE
                lineStr = lineStr + "   "
            END IF
        NEXT i
        PRINT lineStr
    NEXT j
    lineStr = ""
    FOR i = 0 TO n - 1
        elemStr = STR$(data(i))
        DO WHILE LEN(elemStr) < 3
            elemStr = " " + elemStr
        LOOP
        lineStr = lineStr + elemStr + " "
    NEXT i
    PRINT lineStr
    PRINT ""
    PRINT "============================================"
    PRINT "     GROUPED BAR CHART"
    PRINT "============================================"
    PRINT ""
    LOCAL groupA(20) AS LONG
    LOCAL groupB(20) AS LONG
    n = 8
    FOR i = 0 TO n - 1
        groupA(i) = ((i * 7 + 3) MOD 15) + 5
        groupB(i) = ((i * 11 + 5) MOD 12) + 3
    NEXT i
    maxVal = groupA(0)
    FOR i = 1 TO n - 1
        IF groupA(i) > maxVal THEN
            maxVal = groupA(i)
        END IF
        IF groupB(i) > maxVal THEN
            maxVal = groupB(i)
        END IF
    NEXT i
    IF maxVal < 1 THEN
        maxVal = 1
    END IF
    maxBarLen = 10
    PRINT "Grouped bars (A=# B=@):"
    PRINT ""
    FOR j = maxBarLen TO 1 STEP -1
        lineStr = ""
        FOR i = 0 TO n - 1
            barLen = groupA(i) * maxBarLen / maxVal
            IF barLen >= j THEN
                lineStr = lineStr + "#"
            ELSE
                lineStr = lineStr + " "
            END IF
            barLen = groupB(i) * maxBarLen / maxVal
            IF barLen >= j THEN
                lineStr = lineStr + "@ "
            ELSE
                lineStr = lineStr + "  "
            END IF
        NEXT i
        PRINT " " + lineStr
    NEXT j
    lineStr = ""
    FOR i = 0 TO n - 1
        elemStr = STR$(groupA(i))
        DO WHILE LEN(elemStr) < 2
            elemStr = " " + elemStr
        LOOP
        lineStr = lineStr + elemStr + " "
    NEXT i
    PRINT " A:" + lineStr
    lineStr = ""
    FOR i = 0 TO n - 1
        elemStr = STR$(groupB(i))
        DO WHILE LEN(elemStr) < 2
            elemStr = " " + elemStr
        LOOP
        lineStr = lineStr + elemStr + " "
    NEXT i
    PRINT " B:" + lineStr
    PRINT ""
    PRINT "============================================"
    PRINT "     STACKED BAR CHART"
    PRINT "============================================"
    PRINT ""
    n = 6
    FOR i = 0 TO n - 1
        groupA(i) = ((i * 5 + 2) MOD 10) + 2
        groupB(i) = ((i * 7 + 3) MOD 8) + 1
    NEXT i
    maxVal = groupA(0) + groupB(0)
    FOR i = 1 TO n - 1
        IF groupA(i) + groupB(i) > maxVal THEN
            maxVal = groupA(i) + groupB(i)
        END IF
    NEXT i
    IF maxVal < 1 THEN
        maxVal = 1
    END IF
    maxBarLen = 15
    PRINT "Stacked bars (A=below B=above):"
    PRINT ""
    FOR j = maxBarLen TO 1 STEP -1
        lineStr = ""
        FOR i = 0 TO n - 1
            totalVal = groupA(i) + groupB(i)
            barLenA = groupA(i) * maxBarLen / maxVal
            barLenTotal = totalVal * maxBarLen / maxVal
            IF barLenTotal >= j THEN
                IF j <= barLenA THEN
                    lineStr = lineStr + "# "
                ELSE
                    lineStr = lineStr + "@ "
                END IF
            ELSE
                lineStr = lineStr + "  "
            END IF
        NEXT i
        PRINT " " + lineStr
    NEXT j
    lineStr = ""
    FOR i = 0 TO n - 1
        elemStr = STR$(groupA(i) + groupB(i))
        DO WHILE LEN(elemStr) < 2
            elemStr = " " + elemStr
        LOOP
        lineStr = lineStr + elemStr + " "
    NEXT i
    PRINT " T:" + lineStr
    PRINT ""
    PRINT "============================================"
    PRINT "     PERCENTAGE BAR CHART"
    PRINT "============================================"
    PRINT ""
    n = 10
    FOR i = 0 TO n - 1
        data(i) = ((i * 13 + 7) MOD 20) + 5
    NEXT i
    maxVal = data(0)
    FOR i = 1 TO n - 1
        IF data(i) > maxVal THEN
            maxVal = data(i)
        END IF
    NEXT i
    IF maxVal < 1 THEN
        maxVal = 1
    END IF
    PRINT "Percentage bars (100% = " + STR$(maxBarLen) + " chars):"
    PRINT ""
    FOR i = 0 TO n - 1
        barLen = data(i) * maxBarLen / maxVal
        lineStr = " " + STR$(data(i))
        DO WHILE LEN(lineStr) < 5
            lineStr = " " + lineStr
        LOOP
        lineStr = lineStr + " ["
        FOR j = 1 TO barLen
            lineStr = lineStr + "="
        NEXT j
        FOR j = barLen + 1 TO maxBarLen
            lineStr = lineStr + "."
        NEXT j
        lineStr = lineStr + "] "
        elemStr = STR$(data(i) * 100 / maxVal)
        DO WHILE LEN(elemStr) < 3
            elemStr = " " + elemStr
        LOOP
        lineStr = lineStr + elemStr + "%"
        PRINT lineStr
    NEXT i
    PRINT ""
    PRINT "Bar chart demonstration complete"
    FUNCTION = 0
END FUNCTION
