' Callback Pattern — function dispatch via SELECT CASE
#COMPILE EXE
#DIM ALL

%DISP_DOUBLE = 1
%DISP_SQUARE = 2
%DISP_NEGATE = 3
%DISP_EVEN = 4
%DISP_POSITIVE = 5

FUNCTION Dispatch(n AS LONG, op AS LONG) AS LONG
    SELECT CASE op
        CASE %DISP_DOUBLE
            FUNCTION = n * 2
        CASE %DISP_SQUARE
            FUNCTION = n * n
        CASE %DISP_NEGATE
            FUNCTION = -n
        CASE %DISP_EVEN
            IF (n MOD 2) = 0 THEN FUNCTION = 1 ELSE FUNCTION = 0
        CASE %DISP_POSITIVE
            IF n > 0 THEN FUNCTION = 1 ELSE FUNCTION = 0
        CASE ELSE
            FUNCTION = n
    END SELECT
END FUNCTION

FUNCTION PBMAIN() AS LONG
    DIM nums(1 TO 8) AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL temp AS LONG
    LOCAL n AS LONG
    LOCAL sum AS LONG
    LOCAL product AS LONG
    LOCAL maxVal AS LONG
    LOCAL minVal AS LONG

    PRINT "=========================="
    PRINT " Callback / Pattern Demo"
    PRINT "=========================="
    PRINT

    n = 6
    nums(1) = 1
    nums(2) = 2
    nums(3) = 3
    nums(4) = 4
    nums(5) = 5
    nums(6) = 6

    PRINT "=== MAP PATTERN ==="
    PRINT "Original:"
    FOR i = 1 TO n
        PRINT STR$(nums(i))
    NEXT i
    PRINT

    PRINT "After doubling:"
    FOR i = 1 TO n
        nums(i) = Dispatch(nums(i), %DISP_DOUBLE)
        PRINT STR$(nums(i))
    NEXT i
    PRINT

    PRINT "After squaring:"
    FOR i = 1 TO n
        nums(i) = Dispatch(nums(i), %DISP_SQUARE)
        PRINT STR$(nums(i))
    NEXT i
    PRINT
    PRINT

    n = 8
    nums(1) = -3
    nums(2) = 5
    nums(3) = -1
    nums(4) = 8
    nums(5) = 0
    nums(6) = 2
    nums(7) = -7
    nums(8) = 4

    PRINT "=== FILTER PATTERN ==="
    PRINT "Array:"
    FOR i = 1 TO n
        PRINT STR$(nums(i))
    NEXT i
    PRINT

    sum = 0
    FOR i = 1 TO n
        IF Dispatch(nums(i), %DISP_EVEN) THEN sum = sum + nums(i)
    NEXT i
    PRINT "Sum of even numbers: " & STR$(sum)

    sum = 0
    FOR i = 1 TO n
        IF Dispatch(nums(i), %DISP_POSITIVE) THEN sum = sum + nums(i)
    NEXT i
    PRINT "Sum of positive numbers: " & STR$(sum)
    PRINT

    n = 6
    nums(1) = 4
    nums(2) = 7
    nums(3) = 2
    nums(4) = 9
    nums(5) = 1
    nums(6) = 5

    PRINT "=== REDUCER PATTERN ==="
    PRINT "Array:"
    FOR i = 1 TO n
        PRINT STR$(nums(i))
    NEXT i
    PRINT

    sum = 0
    product = 1
    maxVal = nums(1)
    minVal = nums(1)
    FOR i = 1 TO n
        sum = sum + nums(i)
        product = product * nums(i)
        IF nums(i) > maxVal THEN maxVal = nums(i)
        IF nums(i) < minVal THEN minVal = nums(i)
    NEXT i
    PRINT "Sum = " & STR$(sum)
    PRINT "Product = " & STR$(product)
    PRINT "Max = " & STR$(maxVal)
    PRINT "Min = " & STR$(minVal)
    PRINT "Average = " & FORMAT$(sum / 6, "##.##")
    PRINT

    n = 6
    nums(1) = 42
    nums(2) = 7
    nums(3) = 99
    nums(4) = 13
    nums(5) = 55
    nums(6) = 3

    PRINT "=== SORT CALLBACK PATTERN ==="
    PRINT "Before:"
    FOR i = 1 TO n
        PRINT STR$(nums(i))
    NEXT i
    PRINT

    FOR i = 1 TO 5
        FOR j = i + 1 TO 6
            IF nums(i) > nums(j) THEN
                temp = nums(i)
                nums(i) = nums(j)
                nums(j) = temp
            END IF
        NEXT j
    NEXT i

    PRINT "After ascending:"
    FOR i = 1 TO n
        PRINT STR$(nums(i))
    NEXT i
    PRINT
    PRINT

    PRINT "Callback patterns complete."
    FUNCTION = 0
END FUNCTION
