' Digital clock with GDI TEXT, TIMER update loop via DECLARE
#COMPILE EXE
#DIM ALL

DECLARE FUNCTION GetDC LIB "USER32.DLL" (BYVAL hWnd AS LONG) AS LONG
DECLARE FUNCTION ReleaseDC LIB "USER32.DLL" (BYVAL hWnd AS LONG, BYVAL hDC AS LONG) AS LONG
DECLARE FUNCTION TextOut LIB "GDI32.DLL" ALIAS "TextOutA" (BYVAL hDC AS LONG, BYVAL x AS LONG, BYVAL y AS LONG, BYVAL lpString AS ASCIIZ, BYVAL nCount AS LONG) AS LONG
DECLARE FUNCTION SetBkColor LIB "GDI32.DLL" (BYVAL hDC AS LONG, BYVAL crColor AS LONG) AS LONG
DECLARE FUNCTION SetTextColor LIB "GDI32.DLL" (BYVAL hDC AS LONG, BYVAL crColor AS LONG) AS LONG
DECLARE FUNCTION CreateFont LIB "GDI32.DLL" ALIAS "CreateFontA" (BYVAL nHeight AS LONG, BYVAL nWidth AS LONG, BYVAL nEscapement AS LONG, BYVAL nOrientation AS LONG, BYVAL fnWeight AS LONG, BYVAL fdwItalic AS LONG, BYVAL fdwUnderline AS LONG, BYVAL fdwStrikeOut AS LONG, BYVAL fdwCharSet AS LONG, BYVAL fdwOutputPrecision AS LONG, BYVAL fdwClipPrecision AS LONG, BYVAL fdwQuality AS LONG, BYVAL fdwPitchAndFamily AS LONG, BYVAL lpszFace AS ASCIIZ) AS LONG
DECLARE FUNCTION SelectObject LIB "GDI32.DLL" (BYVAL hDC AS LONG, BYVAL hObject AS LONG) AS LONG
DECLARE FUNCTION DeleteObject LIB "GDI32.DLL" (BYVAL hObject AS LONG) AS LONG

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
    IF y MOD 100 = 0 THEN FUNCTION = 0
    IF y MOD 4 = 0 THEN FUNCTION = 1
    FUNCTION = 0
END FUNCTION

FUNCTION DaysInMonth(BYVAL mo AS LONG, BYVAL y AS LONG) AS LONG
    LOCAL d(0: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 "; STR$(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 m  AS LONG
    LOCAL s  AS LONG
    LOCAL ms  AS LONG
    PRINT "Stopwatch simulation (30 ticks):"
    FOR m = 0 TO 2
        FOR s = 0 TO 9
            ms = s * 100
            PRINT "  "; FormatTwoDigits(m); ":"; FormatTwoDigits(s); "."; STR$(ms)
        NEXT s
    NEXT m
END SUB

SUB AlarmClockSim()
    LOCAL h  AS LONG
    LOCAL m  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
    m = 55
    s = 0
    LOCAL tick AS LONG
    FOR tick = 1 TO 60
        s = s + 5
        IF s >= 60 THEN
            s = s - 60
            m = m + 1
            IF m >= 60 THEN
                m = 0
                h = h + 1
                IF h >= 24 THEN h = 0
            END IF
        END IF
        IF h = alarmH AND m = alarmM THEN
            PRINT "  ALARM! "; FormatTime(h, m, s)
        ELSEIF tick MOD 10 = 0 THEN
            PRINT "  "; FormatTime(h, m, s)
        END IF
    NEXT tick
END SUB

FUNCTION PBMAIN() AS LONG
    PRINT "=== Digital Clock Demo ==="
    PRINT "GDI: TextOut, CreateFont via DECLARE"
    PRINT ""
    PRINT "Running clock simulation (10 ticks):"
    RunClock(10)
    PRINT ""
    StopwatchDemo()
    PRINT ""
    AlarmClockSim()
    PRINT ""
    PRINT "=== End Digital Clock ==="
    FUNCTION = 0
END FUNCTION
