' Bitwise Flag Manipulation — permission flags, 32-bit combinations
#COMPILE EXE
#DIM ALL

CONST FLAG_READ = 1
CONST FLAG_WRITE = 2
CONST FLAG_EXECUTE = 4
CONST FLAG_DELETE = 8
CONST FLAG_SHARE = 16
CONST FLAG_ADMIN = 32
SUB ShowFlags(flags AS LONG)
    PRINT "Flags: " & STR$(flags) & " ("
    IF flags AND FLAG_READ THEN PRINT "READ "
    IF flags AND FLAG_WRITE THEN PRINT "WRITE "
    IF flags AND FLAG_EXECUTE THEN PRINT "EXECUTE "
    IF flags AND FLAG_DELETE THEN PRINT "DELETE "
    IF flags AND FLAG_SHARE THEN PRINT "SHARE "
    IF flags AND FLAG_ADMIN THEN PRINT "ADMIN "
    PRINT ")"
END SUB

SUB FlagCombinations()
    LOCAL i AS LONG
    LOCAL flags AS LONG
    PRINT "=== FLAG COMBINATIONS ==="
    FOR i = 0 TO 15
        flags = i
        PRINT "Value " & STR$(i) & ": "
        IF flags AND FLAG_READ THEN PRINT "R";
        IF flags AND FLAG_WRITE THEN PRINT "W";
        IF flags AND FLAG_EXECUTE THEN PRINT "X";
        IF flags AND FLAG_DELETE THEN PRINT "D";
        PRINT
    NEXT i
    PRINT
END SUB

SUB PermissionsDemo()
    LOCAL userFlags AS LONG
    LOCAL adminFlags AS LONG
    userFlags = FLAG_READ OR FLAG_WRITE
    adminFlags = FLAG_READ OR FLAG_WRITE OR FLAG_EXECUTE OR FLAG_DELETE OR FLAG_ADMIN
    PRINT "=== PERMISSIONS DEMO ==="
    PRINT "User permissions:"
    CALL ShowFlags(userFlags)
    PRINT "Admin permissions:"
    CALL ShowFlags(adminFlags)
    PRINT
    PRINT "Can user execute? "
    IF userFlags AND FLAG_EXECUTE THEN PRINT "Yes" ELSE PRINT "No"
    PRINT "Can admin delete? "
    IF adminFlags AND FLAG_DELETE THEN PRINT "Yes" ELSE PRINT "No"
    PRINT
    PRINT "Granting execute to user..."
    userFlags = userFlags OR FLAG_EXECUTE
    CALL ShowFlags(userFlags)
    PRINT "Revoking write from admin..."
    adminFlags = adminFlags AND (NOT FLAG_WRITE)
    CALL ShowFlags(adminFlags)
    PRINT
END SUB

SUB ToggleDemo()
    LOCAL flags AS LONG
    LOCAL i AS LONG
    LOCAL bits(0 TO 7) AS LONG
    bits(0) = 1
    bits(1) = 2
    bits(2) = 4
    bits(3) = 8
    bits(4) = 16
    bits(5) = 32
    bits(6) = 64
    bits(7) = 128
    PRINT "=== TOGGLE DEMO ==="
    flags = 0
    FOR i = 0 TO 7
        flags = flags XOR bits(i)
        PRINT "After toggle bit " & STR$(i) & ": " & STR$(flags)
    NEXT i
    PRINT
    PRINT "Toggling all bits back off:"
    FOR i = 0 TO 7
        flags = flags XOR bits(i)
        PRINT "After toggle bit " & STR$(i) & ": " & STR$(flags)
    NEXT i
    PRINT
END SUB

SUB BitMaskExtract()
    LOCAL value AS LONG
    LOCAL lowNibble AS LONG
    LOCAL highNibble AS LONG
    LOCAL byte0 AS LONG
    LOCAL byte1 AS LONG
    value = &HA5B3
    PRINT "=== BIT MASK EXTRACTION ==="
    PRINT "Value: &H" & STR$(value)
    lowNibble = value AND &HF
    highNibble = (value \ 16) AND &HF
    byte0 = value AND &HFF
    byte1 = (value \ 256) AND &HFF
    PRINT "Low nibble:  &H" & STR$(lowNibble) & " = " & STR$(lowNibble)
    PRINT "High nibble: &H" & STR$(highNibble) & " = " & STR$(highNibble)
    PRINT "LONG 0:      &H" & STR$(byte0) & " = " & STR$(byte0)
    PRINT "LONG 1:      &H" & STR$(byte1) & " = " & STR$(byte1)
    PRINT
END SUB

FUNCTION BitCount(n AS LONG) AS LONG
    LOCAL c AS LONG
    LOCAL x AS LONG
    x = n
    WHILE x <> 0
        x = x AND (x - 1)
        c = c + 1
    WEND
    FUNCTION = c
END FUNCTION

SUB BitCountDemo()
    LOCAL v AS LONG
    LOCAL c AS LONG
    PRINT "=== POPULATION COUNT (32-bit) ==="
    FOR v = 0 TO 31
        c = BitCount(v)
        PRINT STR$(v) & ") = " & STR$(c)
    NEXT v
    PRINT
END SUB

FUNCTION PBMAIN() AS LONG
    PRINT "==========================="
    PRINT " Bitwise Flags & Permissions"
    PRINT "==========================="
    PRINT
    CALL FlagCombinations()
    CALL PermissionsDemo()
    CALL ToggleDemo()
    CALL BitMaskExtract()
    CALL BitCountDemo()
    PRINT "Flag manipulation complete."
    FUNCTION = 0
END FUNCTION
