' Day of Year — computes day number within the year for any date
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL year AS LONG
    LOCAL month AS LONG
    LOCAL day AS LONG
    LOCAL dayOfYear AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL isLeapVal AS LONG
    LOCAL daysInFeb AS LONG
    LOCAL daysInMonths(12) AS LONG
    LOCAL invDays(12) AS LONG
    LOCAL testCount AS LONG
    LOCAL passCount AS LONG
    LOCAL failCount AS LONG
    LOCAL monthName AS STRING
    LOCAL lineStr AS STRING
    testCount = 0
    passCount = 0
    failCount = 0
    dayOfYear = 0
    PRINT "============================================"
    PRINT "         DAY OF YEAR CALCULATOR"
    PRINT "============================================"
    PRINT ""
    FOR year = 2023 TO 2025
        PRINT "Year " + STR$(year) + ":"
        PRINT ""
        FOR month = 1 TO 12
            day = 15
            IF month = 2 THEN
                isLeapVal = 0
                IF year MOD 400 = 0 THEN
                    isLeapVal = 1
                ELSE
                    IF year MOD 100 = 0 THEN
                        isLeapVal = 0
                    ELSE
                        IF year MOD 4 = 0 THEN
                            isLeapVal = 1
                        END IF
                    END IF
                END IF
                IF isLeapVal = 1 THEN
                    daysInFeb = 29
                ELSE
                    daysInFeb = 28
                END IF
                dayOfYear = 0
                FOR i = 1 TO month - 1
                    IF i = 2 THEN
                        dayOfYear = dayOfYear + daysInFeb
                    ELSE
                        IF i = 4 OR i = 6 OR i = 9 OR i = 11 THEN
                            dayOfYear = dayOfYear + 30
                        ELSE
                            dayOfYear = dayOfYear + 31
                        END IF
                    END IF
                NEXT i
                dayOfYear = dayOfYear + day
            ELSE
                IF month = 4 OR month = 6 OR month = 9 OR month = 11 THEN
                    daysInFeb = 30
                ELSE
                    daysInFeb = 31
                END IF
                dayOfYear = 0
                FOR i = 1 TO month - 1
                    IF i = 2 THEN
                        isLeapVal = 0
                        IF year MOD 400 = 0 THEN
                            isLeapVal = 1
                        ELSE
                            IF year MOD 100 = 0 THEN
                                isLeapVal = 0
                            ELSE
                                IF year MOD 4 = 0 THEN
                                    isLeapVal = 1
                                END IF
                            END IF
                        END IF
                        IF isLeapVal = 1 THEN
                            dayOfYear = dayOfYear + 29
                        ELSE
                            dayOfYear = dayOfYear + 28
                        END IF
                    ELSE
                        IF i = 4 OR i = 6 OR i = 9 OR i = 11 THEN
                            dayOfYear = dayOfYear + 30
                        ELSE
                            dayOfYear = dayOfYear + 31
                        END IF
                    END IF
                NEXT i
                dayOfYear = dayOfYear + day
            END IF
            IF month = 1 THEN monthName = "Jan"
            IF month = 2 THEN monthName = "Feb"
            IF month = 3 THEN monthName = "Mar"
            IF month = 4 THEN monthName = "Apr"
            IF month = 5 THEN monthName = "May"
            IF month = 6 THEN monthName = "Jun"
            IF month = 7 THEN monthName = "Jul"
            IF month = 8 THEN monthName = "Aug"
            IF month = 9 THEN monthName = "Sep"
            IF month = 10 THEN monthName = "Oct"
            IF month = 11 THEN monthName = "Nov"
            IF month = 12 THEN monthName = "Dec"
            lineStr = " " + monthName + " " + STR$(day) + ": Day " + STR$(dayOfYear)
            PRINT lineStr
        NEXT month
        PRINT ""
    NEXT year
    PRINT "============================================"
    PRINT "     REVERSE LOOKUP (day -> date)"
    PRINT "============================================"
    PRINT ""
    year = 2024
    isLeapVal = 0
    IF year MOD 400 = 0 THEN
        isLeapVal = 1
    ELSE
        IF year MOD 100 = 0 THEN
            isLeapVal = 0
        ELSE
            IF year MOD 4 = 0 THEN
                isLeapVal = 1
            END IF
        END IF
    END IF
    IF isLeapVal = 1 THEN
        daysInMonths(1) = 31
        daysInMonths(2) = 29
        daysInMonths(3) = 31
        daysInMonths(4) = 30
        daysInMonths(5) = 31
        daysInMonths(6) = 30
        daysInMonths(7) = 31
        daysInMonths(8) = 31
        daysInMonths(9) = 30
        daysInMonths(10) = 31
        daysInMonths(11) = 30
        daysInMonths(12) = 31
    ELSE
        daysInMonths(1) = 31
        daysInMonths(2) = 28
        daysInMonths(3) = 31
        daysInMonths(4) = 30
        daysInMonths(5) = 31
        daysInMonths(6) = 30
        daysInMonths(7) = 31
        daysInMonths(8) = 31
        daysInMonths(9) = 30
        daysInMonths(10) = 31
        daysInMonths(11) = 30
        daysInMonths(12) = 31
    END IF
    PRINT "Reverse lookup for " + STR$(year) + ":"
    PRINT ""
    FOR dayOfYear = 1 TO 365 STEP 30
        day = dayOfYear
        month = 1
        DO WHILE day > daysInMonths(month)
            day = day - daysInMonths(month)
            month = month + 1
            IF month > 12 THEN
                EXIT DO
            END IF
        LOOP
        IF month > 12 THEN
            month = 12
            day = 31
        END IF
        IF month = 1 THEN monthName = "Jan"
        IF month = 2 THEN monthName = "Feb"
        IF month = 3 THEN monthName = "Mar"
        IF month = 4 THEN monthName = "Apr"
        IF month = 5 THEN monthName = "May"
        IF month = 6 THEN monthName = "Jun"
        IF month = 7 THEN monthName = "Jul"
        IF month = 8 THEN monthName = "Aug"
        IF month = 9 THEN monthName = "Sep"
        IF month = 10 THEN monthName = "Oct"
        IF month = 11 THEN monthName = "Nov"
        IF month = 12 THEN monthName = "Dec"
        lineStr = " Day " + STR$(dayOfYear) + " = " + monthName + " " + STR$(day)
        PRINT lineStr
    NEXT dayOfYear
    PRINT ""
    PRINT "============================================"
    PRINT "     DAY 1-365 TABLE"
    PRINT "============================================"
    PRINT ""
    FOR dayOfYear = 1 TO 365
        day = dayOfYear
        month = 1
        DO WHILE day > daysInMonths(month)
            day = day - daysInMonths(month)
            month = month + 1
        LOOP
        IF dayOfYear MOD 30 = 1 THEN
            IF month = 1 THEN monthName = "Jan"
            IF month = 2 THEN monthName = "Feb"
            IF month = 3 THEN monthName = "Mar"
            IF month = 4 THEN monthName = "Apr"
            IF month = 5 THEN monthName = "May"
            IF month = 6 THEN monthName = "Jun"
            IF month = 7 THEN monthName = "Jul"
            IF month = 8 THEN monthName = "Aug"
            IF month = 9 THEN monthName = "Sep"
            IF month = 10 THEN monthName = "Oct"
            IF month = 11 THEN monthName = "Nov"
            IF month = 12 THEN monthName = "Dec"
            lineStr = " Day " + STR$(dayOfYear) + " = " + monthName + " " + STR$(day)
            PRINT lineStr
        END IF
    NEXT dayOfYear
    PRINT ""
    PRINT "============================================"
    PRINT "     LEAP YEAR DAY COMPARISON"
    PRINT "============================================"
    PRINT ""
    FOR year = 2023 TO 2024
        isLeapVal = 0
        IF year MOD 400 = 0 THEN
            isLeapVal = 1
        ELSE
            IF year MOD 100 = 0 THEN
                isLeapVal = 0
            ELSE
                IF year MOD 4 = 0 THEN
                    isLeapVal = 1
                END IF
            END IF
        END IF
        IF isLeapVal = 1 THEN
            PRINT STR$(year) + " has 366 days"
        ELSE
            PRINT STR$(year) + " has 365 days"
        END IF
    NEXT year
    PRINT ""
    PRINT "Day of year calculations complete"
    FUNCTION = 0
END FUNCTION
