'
' This is a remake of my Scriptbasic client for the DICT protocol (RFC 2229)
'
' Peter van Eerten - December 10, 2009 - GPL.
'
' Requires BaCon beta 4 or higher and H.U.G. version 0.12 or higher.
'
' Version 1.0: Initial release
' Version 1.1: Using STOCK buttons
' Version 1.2: Adapted for HUG 0.8
' Version 1.3: Fixed empty ABOUT window on some platforms
'
'-----------------------------------------------------------------------------------

SETENVIRON "LANG", "C"

INCLUDE "hug.bac"

'-----------------------------------------------------------------------------------

SUB Show_About

    SHOW(aboutwin)

END SUB

'-----------------------------------------------------------------------------------

SUB Hide_About

    HIDE(aboutwin)

END SUB

'-----------------------------------------------------------------------------------

SUB Clear_Edit

    TEXT(text, "")
    TEXT(list, "")

END SUB

'-----------------------------------------------------------------------------------

SUB Get_Dicts

    LOCAL dat$, total$
    LOCAL mydict TYPE int
    LOCAL dimension, i

    total$ = ""

    TEXT(list, "")

    OPEN CONCAT$(GRAB$(drop), ":2628") FOR NETWORK AS mydict

    ' Get the available dictionaries
    SEND "SHOW DB\n" TO mydict

    REPEAT
        RECEIVE dat$ FROM mydict
        total$ = CONCAT$(total$, dat$)
    UNTIL ISFALSE(WAIT(mydict, 500))

    SEND "QUIT\n" TO mydict
    CLOSE NETWORK mydict

    SPLIT total$ BY NL$ TO line$ SIZE dimension

    ' Put results into the list
    FOR i = 2 TO dimension - 3
        IF NOT(INSTR(line$[i], "exit")) THEN
            TEXT(list, CONCAT$(MID$(line$[i], INSTR(line$[i], "\"") + 1, INSTRREV(line$[i], "\"") - INSTR(line$[i], "\"") - 1), \
                " - ", LEFT$(line$[i], INSTR(line$[i], " ") - 1) ))
        END IF
    NEXT

END SUB

'-----------------------------------------------------------------------------------

SUB Lookup_Word

    LOCAL dict$
    LOCAL mydict TYPE int
    LOCAL i, display, dimension

    total$ = ""

    TEXT(mainwin, CONCAT$(wintitle$, " - \"", GRAB$(entry), "\""))

    TEXT(text, "")
    TEXT(text, "Fetching....")
    SYNC

    dict$ = MID$(GRAB$(list), INSTRREV(GRAB$(list), " ") + 1)

    OPEN CONCAT$(GRAB$(drop), ":2628") FOR NETWORK AS mydict

    IF ISTRUE(GET(dflt)) THEN
        SEND CONCAT$("DEFINE * ", GRAB$(entry), "\n") TO mydict
    ELSE
        SEND CONCAT$("DEFINE ", dict$, " ",  GRAB$(entry), "\n") TO mydict
    END IF

    REPEAT
        RECEIVE dat$ FROM mydict
        total$ = CONCAT$(total$, dat$)
    UNTIL ISFALSE(WAIT(mydict, 500))

    SEND "QUIT\n" TO mydict
    CLOSE NETWORK mydict

    TEXT(text, "")
    display = FALSE

    SPLIT total$ BY NL$ TO line$ SIZE dimension

    ' Parse result on error codes and results
    FOR i = 0 TO dimension - 1

        IF EQUAL(LEFT$(line$[i], 1), ".") THEN
            TEXT(text, NL$)
            display = FALSE
        END IF

        IF ISTRUE(display) AND LEN(line$[i]) > 1 THEN
            TEXT(text, line$[i])
        END IF

        IF EQUAL(LEFT$(line$[i], 3), "501") THEN
            TEXT(text, "Select a dictionary or use the 'all' option!")
            BREAK
        END IF

        IF EQUAL(LEFT$(line$[i], 3), "550") THEN
            TEXT(text, "Invalid database!")
            BREAK
        END IF

        IF EQUAL(LEFT$(line$[i], 3), "552") THEN
            TEXT(text, "No match found.")
            BREAK
        END IF

        IF EQUAL(LEFT$(line$[i], 3), "151") THEN
            TEXT(text, "------------------------------\n")
            dict$ = MID$(line$[i], LEN(GRAB$(entry)) + 8)
            TEXT(text, MID$(dict$, INSTR(dict$, "\"") + 1, INSTRREV(dict$, "\"") - INSTR(dict$, "\"") - 1) )
            TEXT(text, "\n------------------------------\n")
            display = TRUE
        END IF
    NEXT

    FOCUS(entry)

END SUB

'-----------------------------------------------------------------------------------

' Create main window
CONST wintitle$ = "Thesaurus"
mainwin = WINDOW(wintitle$, 520, 480)

' Create droplist part
frame1 = FRAME(250, 65)
ATTACH(mainwin, frame1, 10, 10)
TEXT(frame1, " Servers ")

drop = COMBO("dict.org", 130, 35)
ATTACH(mainwin, drop, 20, 30)
fetch = STOCK("gtk-refresh", 90, 35)
ATTACH(mainwin, fetch, 160, 30)

TEXT(drop, "dict.tugraz.at")
TEXT(drop, "dict.tu-chemnitz.de")
TEXT(drop, "dict.trit.org")
TEXT(drop, "www.lojban.org")
TEXT(drop, "dict.arabeyes.org")
TEXT(drop, "dict.saugus.net")
TEXT(drop, "dictionary.bishopston.net")
TEXT(drop, "la-sorciere.de")

' Create control panel
frame2 = FRAME(240, 65)
ATTACH(mainwin, frame2, 270, 10)
TEXT(frame2, " Control ")
about = STOCK("gtk-about", 70, 35)
ATTACH(mainwin, about, 280, 30)
clear = STOCK("gtk-clear", 70, 35)
ATTACH(mainwin, clear, 355, 30)
exbut = STOCK("gtk-quit", 70, 35)
ATTACH(mainwin, exbut, 430, 30)

' Create dictionary panel
frame3 = FRAME(500, 155)
TEXT(frame3, " Dictionaries ")
ATTACH(mainwin, frame3, 10, 85)
list = LIST(480, 120)
ATTACH(mainwin, list, 20, 110)

' Create text part
frame4 = FRAME(500, 190)
TEXT(frame4, " Translation ")
ATTACH(mainwin, frame4, 10, 250)
text = EDIT(480, 155)
ATTACH(mainwin, text, 20, 275)
'DISABLE(text)

' Create entry and lookup button
entry = ENTRY("", 440, 25)
ATTACH(mainwin, entry, 10, 450)
dflt = CHECK("All", 40, 30)
ATTACH(mainwin, dflt, 460, 445)

' Create about window
aboutwin = WINDOW("About", 300, 120)
label1 = MARK("Demo program with HUG", 280, 20)
ATTACH(aboutwin, label1, 15, 5)
label2 = MARK(CONCAT$("Using BaCon ", VERSION$), 280, 20)
ATTACH(aboutwin, label2, 10, 25)
label3 = MARK("(C) Peter van Eerten - December 10, 2009", 280, 20)
ATTACH(aboutwin, label3, 10, 45)
okbut = STOCK("gtk-close", 120, 35)
ATTACH(aboutwin, okbut, 90, 80)
' Make sure the ABOUT window is hidden
HIDE(aboutwin)

FOCUS(entry)

' Now attach callbacks to widgets
CALLBACK(about, Show_About)
CALLBACK(okbut, Hide_About)
CALLBACK(exbut, QUIT)
CALLBACK(clear, Clear_Edit)
CALLBACK(fetch, Get_Dicts)
CALLBACK(entry, Lookup_Word)

' Walk through queue of all events
SYNC

' Endless GTK mainloop
DISPLAY