CLEAR ALL
BACKGROUND RGB(32,32,32)
'SCREEN LOAD ROOTDIR$+"Colors.jpg" FILL

CONST STATIC_UP_ARROW=156, STATIC_DOWN_ARROW=157
CONST CUSTOM_UP_ARROW=126, CUSTOM_DOWN_ARROW=127

gap=50

TYPE Thumbnail
    FIELD x,y
    FIELD sx,sy,minS
    FIELD tx,ty,minT
END TYPE

DIM GLOBAL tn AS Thumbnail
tn.x=1280-320-gap+160
tn.y=800-200-gap+100-25-25
tn.sx=1
tn.sy=1
tn.minS=1
tn.tx=1
tn.ty=1
tn.minT=1

CONST BMP_WALLPAPER=1
CONST BMP_DEFAULT_WALLPAPER=2
CONST BMP_MASK=3
CONST BMP_BACKGROUND=4
CONST BMP_PREVIEW=5
CONST BMP_BACKGROUND_OUTLINE=6

CONST FNT_PREVIEW=1

CONST TS_BASIC=1
CONST TS_PREVIEW=2

CONST TM_PREVIEW=1
CONST TM_STATUS=2

CONST SDR_PREVIEW=1

CONST SND_PREVIEW=1

CONST SPR_WALLPAPER=1
CONST SPR_MASK=2
CONST SPR_BACKGROUND=3
CONST SPR_PREVIEW=4
CONST SPR_BACKGROUND_OUTLINE=5
CONST SPR_STATUS=6

BITMAP BMP_DEFAULT_WALLPAPER LOAD ROOTDIR$+"Colors.jpg"

BITMAP BMP_WALLPAPER COPY BITMAP BMP_DEFAULT_WALLPAPER

BITMAP BMP_MASK NEW 16,16
TARGET BITMAP BMP_MASK
FILL RGB(0,0,0,160)
SPRITE SPR_MASK BIND BITMAP BMP_MASK SHOW STRETCH

BITMAP BMP_BACKGROUND NEW 320,200
TARGET BITMAP BMP_BACKGROUND
FILL RGB(32,32,32)

BITMAP BMP_BACKGROUND_OUTLINE NEW 322,202
TARGET BITMAP BMP_BACKGROUND_OUTLINE
INK RGB(255,255,255)
RECT 0,0,321,201

TILESET TS_BASIC NEW "BASIC"

TILEMAP TM_STATUS NEW 32,14,TS_BASIC

TARGET TILESET TS_BASIC
COPY TILE TCHAR(CUSTOM_UP_ARROW),STATIC_UP_ARROW-32
COPY TILE TCHAR(CUSTOM_DOWN_ARROW),STATIC_DOWN_ARROW-32

TARGET TILESET 0
COPY TILE TCHAR(CUSTOM_UP_ARROW),STATIC_UP_ARROW-32
COPY TILE TCHAR(CUSTOM_DOWN_ARROW),STATIC_DOWN_ARROW-32

SPRITE SPR_WALLPAPER BIND BITMAP BMP_WALLPAPER SHOW FILL

SPRITE SPR_BACKGROUND BIND BITMAP BMP_BACKGROUND PRIORITY 16384+1 MOVE tn.x,tn.y
SPRITE SPR_PREVIEW BIND BITMAP BMP_BACKGROUND PRIORITY 16384+2 MOVE tn.x,tn.y
SPRITE SPR_BACKGROUND_OUTLINE BIND BITMAP BMP_BACKGROUND_OUTLINE PRIORITY 16384+3 MOVE tn.x,tn.y
SPRITE SPR_STATUS BIND TILEMAP TM_STATUS PRIORITY 16384+1 MOVE tn.x,tn.y+1

showPreview=FALSE
showThumbnail=FALSE
previewLoaded=FALSE

maxLines=1000
DIM buf$(maxLines)
lineCount=0
bufOffset=0

w=TEXT.COLUMNS
h=TEXT.ROWS
h2=h-3
DIM fn$(1)
reload=TRUE
cw=FALSE

st1$=""
st2$=""

ToggleThumbnail(f$)

mainLoop:

IF reload THEN
    dirs$=DIR$("*.*",2)
    files$=DIR$("*.*",1)
    IF dirs$="" THEN
        dirs$=".."
    ELSE
        dirs$="..,"+dirs$
    END IF
    d=PARSECOUNT(dirs$)
    IF files$="" THEN
        p$=dirs$
    ELSE
        p$=dirs$+","+files$
    END IF
    c=PARSECOUNT(p$)
    REDIM fn$(c)
    FOR i=1 TO c
        fn$(i)=PARSE$(p$,i)
    NEXT i

    IF EXISTS("wallpaper.jpg") THEN
        BITMAP BMP_WALLPAPER LOAD "wallpaper.jpg"
        cw=TRUE
    ELSE IF cw THEN
        BITMAP BMP_WALLPAPER COPY BITMAP BMP_DEFAULT_WALLPAPER
        cw=FALSE
    END IF
    SPRITE SPR_WALLPAPER BIND BITMAP BMP_WALLPAPER SHOW FIT

    o=1
    p=0
    reload=FALSE
END IF

s=o+p
f$=fn$(s)

previewLoaded=FALSE
IF showThumbnail THEN LoadPreview(f$)

DO
    IF NOT showPreview THEN
        PrintMenu()
        s=o+p
        f$=fn$(s)
        'GETKEY a$
        TARGET TILESET 0
        DO
            a$=INKEY$
            ROLL TILE TCHAR(CUSTOM_UP_ARROW) UP 1
            ROLL TILE TCHAR(CUSTOM_DOWN_ARROW) DOWN 1
            PAUSE 0
        LOOP WHILE a$=""
        IF a$=CHR$(VK_UP) THEN
            IF p>0 THEN
                p=p-1
            ELSE IF o>1 THEN
                o=o-1
            END IF
            EXIT DO
        ELSE IF a$=CHR$(VK_DOWN) THEN
            IF p<h2 AND p<c-1 THEN
                p=p+1
            ELSE IF o<c-h2 THEN
                o=o+1
            END IF
            EXIT DO
        ELSE IF a$=CHR$(VK_TAB) THEN
            ToggleThumbnail(f$)
        ELSE IF a$=CHR$(VK_SPACE) THEN
            TogglePreview(f$)
        ELSE IF a$=CHR$(VK_ENTER) THEN
            IF s<=d THEN
                CHDIR f$
                reload=TRUE
                EXIT DO
            ELSE IF FILE.EXTENSION$(f$)=".bas" THEN
                CLEAR ALL
                NEST f$
                'EXIT DO
            END IF
        ELSE IF a$=CHR$(VK_ESC) THEN
            CLEAR ALL
            END
        END IF
    ELSE
        'GETKEY a$
        TARGET TILESET TS_BASIC
        DO
            a$=INKEY$
            ROLL TILE TCHAR(CUSTOM_UP_ARROW) UP 1
            ROLL TILE TCHAR(CUSTOM_DOWN_ARROW) DOWN 1
            PAUSE 0
        LOOP WHILE a$=""
        IF a$=CHR$(VK_UP) THEN
            IF bufOffset>0 THEN
                bufOffset=bufOffset-1
                PrintText(f$)
            END IF
        ELSE IF a$=CHR$(VK_DOWN) THEN
            IF bufOffset<=lineCount-h+1 THEN
                bufOffset=bufOffset+1
                PrintText(f$)
            END IF
        ELSE IF a$=CHR$(VK_SPACE) OR a$=CHR$(VK_ESC) THEN
            TogglePreview(f$)
        END IF
    END IF
LOOP

GOTO mainLoop

FUNCTION PrintMenu()
    SHARE fn$(),d,s,c,o,h2
    SHARE showThumbnail
    SHARE st1$,st2$
    CLS
    PRINT LINE CENTER "Liquid BASIC Menu",RGB(255,255,0),RGB(0,0,255)
    PRINT LINE CENTER ON 31,"Use "+CHR$(STATIC_UP_ARROW)+" "+CHR$(STATIC_DOWN_ARROW)+" keys to move highlight. Press Enter to run, Space to preview, or Tab to toggle thumbnail. Press ESC to quit.",RGB(255,255,0),RGB(0,0,0)
    LOCATE 1,2
    INK RGB(0,0,0)
    HIGHLIGHT RGB(240,240,240)
    t$=CURDIR$+"\*.*"
    PRINT LSET$(t$,w);
    INK RGB(255,255,255)
    HIGHLIGHT 0
    i=o
    DO
        f$=fn$(i)
        IF i<=d THEN
            INK RGB(0,255,0)
        ELSE
            IF NOT CanPreview(f$) THEN
                INK RGB(160,160,160)
            ELSE
                INK RGB(255,255,255)
            END IF
        END IF
        IF i=s THEN
            PRINT LINE CENTER f$,,RGB(255,0,0)
        ELSE
            PRINT LINE CENTER f$
        END IF
        i=i+1
    LOOP WHILE i<=c AND i<=o+h2
    IF o>1 THEN
        INK RGB(0,255,0)
        HIGHLIGHT RGB(0,0,0)
        PRINT TAB(1,31);CHR$(CUSTOM_UP_ARROW);
    END IF
    IF o+h2<c THEN
        INK RGB(0,255,0)
        HIGHLIGHT RGB(0,0,0)
        PRINT TAB(126,31);CHR$(CUSTOM_DOWN_ARROW);
    END IF
END FUNCTION

FUNCTION CanPreview(f$)
    CanPreview=FALSE
    SELECT CASE LCASE$(FILE.EXTENSION$(f$))
        CASE ".txt"
            CanPreview=TRUE
        CASE ".xml"
            CanPreview=TRUE
        CASE ".bas"
            CanPreview=TRUE
        CASE ".bmp",".gif",".ico",".iff",".jpg",".lbm",".png",".tga"
            CanPreview=TRUE
        CASE ".ttf",".otf"
            CanPreview=TRUE
        CASE ".lts",".tsx"
            CanPreview=TRUE
        CASE ".ltm",".tmx"
            CanPreview=TRUE
        CASE ".fs"
            CanPreview=TRUE
        CASE ".wav",".mp3"
            CanPreview=TRUE
    END SELECT
END FUNCTION

FUNCTION LoadPreview(f$)
    SHARE showPreview,showThumbnail,previewLoaded
    SHARE st1$,st2$
    SHARE lineCount
    f=0
    st$=""
    st1$=""
    st2$=""

    INK RGB(255,255,255)
    TRAP RESUME NEXT
    SELECT CASE LCASE$(FILE.EXTENSION$(f$))
        CASE ".txt"
            TILEMAP TM_PREVIEW NEW 128,32,TS_BASIC
            TARGET TILEMAP TM_PREVIEW
            LoadTextFile(f$)
            PrintText(f$)
            st$=STR$(lineCount)+" lines"
            SPRITE SPR_PREVIEW BIND TILEMAP TM_PREVIEW
        CASE ".xml"
            TILEMAP TM_PREVIEW NEW 128,32,TS_BASIC
            TARGET TILEMAP TM_PREVIEW
            LoadXMLFile(f$)
            PrintText(f$)
            st$=STR$(lineCount)+" lines"
            SPRITE SPR_PREVIEW BIND TILEMAP TM_PREVIEW
        CASE ".bas"
            TILEMAP TM_PREVIEW NEW 128,32,TS_BASIC
            TARGET TILEMAP TM_PREVIEW
            LoadTextFile(f$)
            PrintText(f$)
            st$=STR$(lineCount)+" lines"
            SPRITE SPR_PREVIEW BIND TILEMAP TM_PREVIEW
        CASE ".bmp",".gif",".ico",".iff",".jpg",".lbm",".png",".tga"
            BITMAP BMP_PREVIEW LOAD f$
            bw=BITMAP.WIDTH(BMP_PREVIEW)
            bh=BITMAP.HEIGHT(BMP_PREVIEW)
            st$=STR$(bw)+"x"+STR$(bh)+" pixels"
            SPRITE SPR_PREVIEW BIND BITMAP BMP_PREVIEW
        CASE ".ttf",".otf"
            FONT FNT_PREVIEW LOAD f$,48
            t$="The quick brown fox jumps over the lazy dog. 1234567890 .,:;'"+CHR$(34)+" ([!?]) +-*/="
            bw=FONT.WIDTH(FNT_PREVIEW,t$)
            bh=FONT.HEIGHT(FNT_PREVIEW)
            BITMAP BMP_PREVIEW NEW bw,bh
            TARGET BITMAP BMP_PREVIEW
            SET FONT FNT_PREVIEW
            TEXT bw/2,bh/2,t$ ALIGN 0,0
            st$=STR$(FONT.COUNT(FNT_PREVIEW))+" chars"
            SPRITE SPR_PREVIEW BIND BITMAP BMP_PREVIEW
            f=1
        CASE ".lts",".tsx"
            TILESET TS_PREVIEW LOAD f$
            tc=TILESET.COUNT(TS_PREVIEW)
            n=CEIL(SQR(tc))
            TILEMAP TM_PREVIEW NEW n,n,TS_PREVIEW
            TARGET TILEMAP TM_PREVIEW
            FOR j=0 TO tc-1
                IF TILESET.ISAVAILABLE(TS_PREVIEW,j) THEN TPOKE j,j
            NEXT j
            st$=STR$(TILESET.COUNT(TS_PREVIEW))+" tiles"
            SPRITE SPR_PREVIEW BIND TILEMAP TM_PREVIEW
        CASE ".ltm",".tmx"
            TILEMAP TM_PREVIEW LOAD f$
            tw=TILEMAP.COLUMNS(TM_PREVIEW)
            th=TILEMAP.ROWS(TM_PREVIEW)
            st$=STR$(tw)+"x"+STR$(th)+" tiles"
            SPRITE SPR_PREVIEW BIND TILEMAP TM_PREVIEW
        CASE ".fs"
            SHADER SDR_PREVIEW LOAD f$
            IF SHADER.EXISTS(SDR_PREVIEW) THEN
                lc=FILE.LINECOUNT(f$)
                st$=STR$(lc)+" lines"
                SPRITE SPR_PREVIEW BIND BITMAP BMP_BACKGROUND SET SHADER SDR_PREVIEW
            ELSE
                TILEMAP TM_PREVIEW NEW 128,32,TS_BASIC
                TARGET TILEMAP TM_PREVIEW
                LoadTextFile(f$)
                PrintText(f$)
                st$=STR$(lineCount)+" lines"
                SPRITE SPR_PREVIEW BIND TILEMAP TM_PREVIEW
            END IF
        CASE ".wav",".mp3"
            SOUND SND_PREVIEW LOAD f$
            s=SOUND.LENGTH(SND_PREVIEW)
            st$=LTRIM$(USING$("#####.##",s))+" seconds"
            SPRITE SPR_PREVIEW BIND BITMAP BMP_BACKGROUND
        CASE ELSE
            SPRITE SPR_PREVIEW BIND BITMAP BMP_BACKGROUND
    END SELECT
    TRAP OFF

    IF IS.FILE(f$) THEN
        st1$=FORMAT.MEMORY$(FILE.SIZE(f$))
        IF st$<>"" THEN st1$=st1$+" ("+st$+")"
        st2$=FILE.DATE$(f$)
    ELSE IF IS.DIRECTORY(f$) THEN
        st1$="Directory"
    END IF

    sw=SPRITE.WIDTH(SPR_PREVIEW)
    sh=SPRITE.HEIGHT(SPR_PREVIEW)

    tn.sx=320/sw
    tn.sy=200/sh
    tn.minS=MIN(tn.sx,tn.sy)
    IF tn.minS>2 THEN tn.minS=2

    tn.tx=1280/sw
    tn.ty=800/sh
    IF f=0 THEN tn.minT=MIN(tn.tx,tn.ty) ELSE tn.minT=1
    IF tn.minT>8 THEN tn.minT=8

    SPRITE SPR_PREVIEW SHOW MOVE tn.x,tn.y PRIORITY 16384+2 SCALE tn.minS,tn.minS

    TARGET TILEMAP TM_STATUS
    TCLS
    INK RGB(255,255,255)
    HIGHLIGHT 0
    TPRINT TAB(0,12);CSET$(st1$,32);
    TPRINT TAB(0,13);CSET$(st2$,32);

    previewLoaded=TRUE
END FUNCTION

FUNCTION LoadTextFile(f$)
    SHARE maxLines,buf$(),lineCount,bufOffset
    SHARE w,h
    TRAP badError
    n=FREEFILE
    OPEN f$ FOR INPUT AS #n
    i=0
    j=maxLines-1
    WHILE j>0 AND NOT EOF(n)
        INPUT #n,b$
        b$=STRREPLACE$(b$,CHR$(9),"    ")
        c$=LEFT$(b$,w)
        buf$(i)=c$
        i=i+1
        j=j-1
    WEND
    i=i-1
badError:
    lineCount=i
    bufOffset=0
    CLOSE #n
END FUNCTION

FUNCTION LoadXMLFile(f$)
    SHARE maxLines,buf$(),lineCount,bufOffset
    SHARE w,h
    TRAP badError
    n=FREEFILE
    OPEN f$ FOR INPUT AS #n
    i=0
    j=maxLines-1
    IF NOT EOF(n) THEN
        INPUT #n,b$
        s=INSTR(b$,CHR$(9))
        WHILE j>0 AND s>0
            c$=LEFT$(LEFT$(b$,s-1),w)
            buf$(i)=c$
            i=i+1
            j=j-1
            b$=MID$(b$,s+1)
            s=INSTR(b$,CHR$(9))
        WEND
    END IF
    i=i-1
badError:
    lineCount=i
    bufOffset=0
    CLOSE #n
END FUNCTION

FUNCTION PrintText(f$)
    SHARE maxLines,buf$(),lineCount,bufOffset
    SHARE w,h
    IF FILE.EXTENSION$(f$)=".bas" THEN c=1
    TARGET TILEMAP TM_PREVIEW
    TCLS
    INK RGB(255,255,255)
    FOR i=0 TO MIN(lineCount,h-2)
        c$=buf$(bufOffset+i)
        IF c=0 THEN
            IF LEN(c$)=w THEN TPRINT c$; ELSE TPRINT c$
        ELSE
            IF LEN(c$)=w THEN TPRINT CODE c$; ELSE TPRINT CODE c$
        END IF
    NEXT i
    TPRINT LINE CENTER ON 31,"Use "+CHR$(STATIC_UP_ARROW)+" "+CHR$(STATIC_DOWN_ARROW)+" keys to scroll. Press Space or ESC to end preview."; INK RGB(255,255,0) HIGHLIGHT RGB(0,0,0)
    IF bufOffset>0 THEN
        INK RGB(0,255,0)
        HIGHLIGHT RGB(0,0,0)
        TPRINT TAB(1,31);CHR$(CUSTOM_UP_ARROW);
    END IF
    IF bufOffset+h-1<=lineCount THEN
        INK RGB(0,255,0)
        HIGHLIGHT RGB(0,0,0)
        TPRINT TAB(126,31);CHR$(CUSTOM_DOWN_ARROW);
    END IF
    HIGHLIGHT 0
END FUNCTION

FUNCTION ToggleThumbnail(f$)
    SHARE showPreview,showThumbnail,previewLoaded
    showThumbnail=NOT showThumbnail
    IF showThumbnail THEN
        IF NOT previewLoaded THEN LoadPreview(f$)
        SPRITE SPR_BACKGROUND SHOW PRIORITY 16384+1 MOVE tn.x,tn.y SCALE 1,1
        SPRITE SPR_PREVIEW SHOW PRIORITY 16384+2 MOVE tn.x,tn.y SCALE tn.minS,tn.minS
        SPRITE SPR_BACKGROUND_OUTLINE SHOW PRIORITY 16384+3 MOVE tn.x,tn.y SCALE 1,1
        SPRITE SPR_STATUS SHOW PRIORITY 16384+1 MOVE tn.x,tn.y+1 SCALE 1,1
    ELSE
        SPRITE SPR_BACKGROUND HIDE
        SPRITE SPR_PREVIEW HIDE
        SPRITE SPR_BACKGROUND_OUTLINE HIDE
        SPRITE SPR_STATUS HIDE
    END IF
END FUNCTION

FUNCTION TogglePreview(f$)
    SHARE showPreview,showThumbnail,previewLoaded
    IF NOT showPreview THEN
        IF CanPreview(f$) THEN
            IF NOT previewLoaded THEN LoadPreview(f$)
            IF NOT showThumbnail THEN
                SPRITE SPR_BACKGROUND SHOW PRIORITY 16384+1 MOVE 640,400 SCALE 0,0 SCALE TO 4,4,250
                SPRITE SPR_PREVIEW SHOW PRIORITY 16384+2 MOVE 640,400 SCALE 0,0 SCALE TO tn.minT,tn.minT,250
                SPRITE SPR_BACKGROUND_OUTLINE SHOW PRIORITY 16384+3 MOVE 640,400 SCALE 0,0 SCALE TO 4,4,250
                SPRITE SPR_STATUS HIDE
            ELSE
                SPRITE SPR_BACKGROUND MOVE TO 640,400,250 SCALE TO 4,4,250
                SPRITE SPR_PREVIEW MOVE TO 640,400,250 SCALE TO tn.minT,tn.minT,250
                SPRITE SPR_BACKGROUND_OUTLINE MOVE TO 640,400,250 SCALE TO 4,4,250
                SPRITE SPR_STATUS HIDE
            END IF
            IF FILE.EXTENSION$(f$)=".wav" OR FILE.EXTENSION$(f$)=".mp3" THEN
                SOUND SND_PREVIEW PLAY
            END IF
            showPreview=TRUE
        END IF
    ELSE
        IF NOT showThumbnail THEN
            SPRITE SPR_BACKGROUND SCALE TO 0,0,250
            SPRITE SPR_PREVIEW SCALE TO 0,0,250
            SPRITE SPR_BACKGROUND_OUTLINE SCALE TO 0,0,250
            PAUSE 300
            SPRITE SPR_BACKGROUND HIDE
            SPRITE SPR_PREVIEW HIDE
            SPRITE SPR_BACKGROUND_OUTLINE HIDE
        ELSE
            SPRITE SPR_BACKGROUND MOVE TO tn.x,tn.y,250 SCALE TO 1,1,250
            SPRITE SPR_PREVIEW MOVE TO tn.x,tn.y,250 SCALE TO tn.minS,tn.minS,250
            SPRITE SPR_BACKGROUND_OUTLINE MOVE TO tn.x,tn.y,250 SCALE TO 1,1,250
            PAUSE 300
            SPRITE SPR_STATUS SHOW
        END IF
        IF FILE.EXTENSION$(f$)=".wav" OR FILE.EXTENSION$(f$)=".mp3" THEN
            SOUND SND_PREVIEW STOP
        END IF
        showPreview=FALSE
    END IF
END FUNCTION
