' Digital clock with console-based time display
#COMPILE EXE
#DIM ALL

FUNCTION FormatTwoDigits(BYVAL n AS LONG) AS STRING
    IF n < 10 THEN
        FUNCTION = "0" + STR$(n)
    ELSE
        FUNCTION = STR$(n)
    END IF
END FUNCTION

FUNCTION FormatTime(BYVAL h AS LONG, BYVAL m AS LONG, BYVAL s AS LONG) AS STRING
    FUNCTION = FormatTwoDigits(h) + ":" + FormatTwoDigits(m) + ":" + FormatTwoDigits(s)
END FUNCTION

FUNCTION FormatDate(BYVAL y AS LONG, BYVAL mo AS LONG, BYVAL d AS LONG) AS STRING
    FUNCTION = FormatTwoDigits(mo) + "/" + FormatTwoDigits(d) + "/" + STR$(y)
END FUNCTION

FUNCTION IsLeapYear(BYVAL y AS LONG) AS LONG
    IF y MOD 400 = 0 THEN FUNCTION = 1: EXIT FUNCTION
    IF y MOD 100 = 0 THEN FUNCTION = 0: EXIT FUNCTION
    IF y MOD 4 = 0 THEN FUNCTION = 1: EXIT FUNCTION
    FUNCTION = 0
END FUNCTION

FUNCTION DaysInMonth(BYVAL mo AS LONG, BYVAL y AS LONG) AS LONG
    LOCAL d(11) AS LONG
    d(0) = 31
    d(1) = 28
    d(2) = 31
    d(3) = 30
    d(4) = 31
    d(5) = 30
    d(6) = 31
    d(7) = 31
    d(8) = 30
    d(9) = 31
    d(10) = 30
    d(11) = 31
    IF mo = 2 AND IsLeapYear(y) THEN
        FUNCTION = 29
    ELSE
        FUNCTION = d(mo - 1)
    END IF
END FUNCTION

SUB AdvanceTime(BYREF h AS LONG, BYREF m AS LONG, BYREF s AS LONG)
    s = s + 1
    IF s >= 60 THEN
        s = 0
        m = m + 1
        IF m >= 60 THEN
            m = 0
            h = h + 1
            IF h >= 24 THEN
                h = 0
            END IF
        END IF
    END IF
END SUB

SUB AdvanceDate(BYREF y AS LONG, BYREF mo AS LONG, BYREF d AS LONG)
    d = d + 1
    IF d > DaysInMonth(mo, y) THEN
        d = 1
        mo = mo + 1
        IF mo > 12 THEN
            mo = 1
            y = y + 1
        END IF
    END IF
END SUB

SUB PrintClock(BYVAL h AS LONG, BYVAL m AS LONG, BYVAL s AS LONG, BYVAL tick AS LONG)
    LOCAL timeStr AS STRING
    LOCAL dateStr AS STRING
    timeStr = FormatTime(h, m, s)
    dateStr = FormatDate(2026, 6, 3)
    IF tick MOD 2 = 0 THEN
        MID$(timeStr, 3, 1) = ":"
        MID$(timeStr, 6, 1) = ":"
    ELSE
        MID$(timeStr, 3, 1) = " "
        MID$(timeStr, 6, 1) = " "
    END IF
    PRINT "Tick "; tick; ": "; dateStr; " "; timeStr
END SUB

SUB RunClock(BYVAL steps AS LONG)
    LOCAL h AS LONG
    LOCAL m AS LONG
    LOCAL s AS LONG
    LOCAL y AS LONG
    LOCAL mo AS LONG
    LOCAL d AS LONG
    LOCAL tick AS LONG
    h = 10
    m = 30
    s = 0
    y = 2026
    mo = 6
    d = 3
    FOR tick = 1 TO steps
        PrintClock(h, m, s, tick)
        AdvanceTime(h, m, s)
        IF tick MOD 60 = 0 THEN
            AdvanceDate(y, mo, d)
        END IF
        LOCAL delay AS LONG
        FOR delay = 1 TO 100000
        NEXT delay
    NEXT tick
END SUB

SUB StopwatchDemo()
    LOCAL mins AS LONG
    LOCAL secs AS LONG
    LOCAL ms AS LONG
    PRINT "Stopwatch simulation (30 ticks):"
    FOR mins = 0 TO 2
        FOR secs = 0 TO 9
            ms = secs * 100
            PRINT "  "; FormatTwoDigits(mins); ":"; FormatTwoDigits(secs); "."; ms
        NEXT secs
    NEXT mins
END SUB

SUB AlarmClockSim()
    LOCAL h AS LONG
    LOCAL mins AS LONG
    LOCAL s AS LONG
    LOCAL alarmH AS LONG
    LOCAL alarmM AS LONG
    alarmH = 12
    alarmM = 0
    PRINT "Alarm set for "; FormatTwoDigits(alarmH); ":"; FormatTwoDigits(alarmM)
    h = 11
    mins = 55
    s = 0
    LOCAL tick AS LONG
    FOR tick = 1 TO 60
        s = s + 5
        IF s >= 60 THEN
            s = s - 60
            mins = mins + 1
            IF mins >= 60 THEN
                mins = 0
                h = h + 1
                IF h >= 24 THEN h = 0
            END IF
        END IF
        IF h = alarmH AND mins = alarmM THEN
            PRINT "  ALARM! "; FormatTime(h, mins, s)
        ELSEIF tick MOD 10 = 0 THEN
            PRINT "  "; FormatTime(h, mins, s)
        END IF
    NEXT tick
END SUB

FUNCTION PBMAIN() AS LONG
    PRINT "=== Digital Clock Demo ==="
    PRINT "Console-based time display:"
    RunClock(10)
    PRINT ""
    StopwatchDemo()
    PRINT ""
    AlarmClockSim()
    PRINT ""
    PRINT "=== End Digital Clock ==="
    FUNCTION = 0
END FUNCTION