/**************************************************************************/
/* $VER: spell.ed 1.0 (25 Nov 1995)                                       */
/* Script to use AlphaSpell with Varexx                                   */
/**************************************************************************/

IF EXISTS("libs:rexxsupport.library") THEN DO
    IF ~SHOW("L","rexxsupport.library") THEN
        IF ~ADDLIB("rexxsupport.library",0,-30,0) THEN EXIT
END
ELSE EXIT

IF EXISTS("libs:rexxtricks.library") THEN DO
    IF ~SHOW("L","rexxtricks.library") THEN
        IF ~ADDLIB("rexxtricks.library",0,-30) THEN EXIT
END
ELSE EXIT

IF EXISTS("libs:rexxreqtools.library") THEN DO
    IF ~SHOW("L","rexxreqtools.library") THEN
        IF ~ADDLIB("rexxreqtools.library",0,-30) THEN EXIT
END
ELSE EXIT

/* GOLDED SPECIFIC */

if (LEFT(ADDRESS(), 6) ~= "GOLDED") then    /* not started by GoldEd ? */
    address 'GOLDED.1'

'LOCK CURRENT'                              /* lock GUI, gain access   */

/* END GOLDED SPECIFIC */

OPTIONS RESULTS
OPTIONS FAILAT 20
SIGNAL ON SYNTAX
SIGNAL ON FAILURE

/**************************************************************************/
/* Set Variables                                                          */
/**************************************************************************/

tempfile = "T:Temp" || TIME(s)
GUI = GetENV("ENV:ASpellGUI")
win.title = "Select a Word:"
win.gadgettext = "_Accept|_Cancel"
win.width = 100
win.sort = "FALSE"
win.multiselect = "FALSE"

/**************************************************************************/
/* Launch Varexx                                                          */
/**************************************************************************/

/* Check Varexx is loaded if not load it */

IF SHOW( 'p', 'VAREXX' ) ~= 1 THEN DO
    ADDRESS COMMAND "run >NIL: varexx"
    ADDRESS COMMAND "WaitForPort VAREXX"
END
ADDRESS VAREXX

IF OPENPORT("HOLLY") = 0 THEN DO
    CALL rtezrequest ("Could not open a port.", "_Abort", "Varexx Error:")
    EXIT
END

"load" GUI "HOLLY"
vhost = RESULT
ADDRESS
ADDRESS VALUE vhost
show about
CALL ReadPrefs()

/**************************************************************************/
/* EDITOR SPECIFIC -- Write current file to the temporary file tempfile   */
/**************************************************************************/

ADDRESS
'QUERY DOC VAR OLDNAME' /* remember current file name */
'SAVE NAME' tempfile 'ALL'
'NAME' oldname          /* Restore original name */
ADDRESS

/**************************************************************************/
/* END EDITOR SPECIFIC                                                    */
/**************************************************************************/

/**************************************************************************/
/* Spell check tempfile with AlphaSpell                                   */
/**************************************************************************/

ADDRESS COMMAND "AlphaSpell -Ss" tempfile "-o" tempfile "-d" dict_path dict_list

/**************************************************************************/
/* Set Lists                                                              */
/**************************************************************************/

CALL ReadList "UNFOUND"
IF UNFOUND.0 = 0 THEN DO
    CALL rtezrequest ("No misspellings found.", "_Exit", "Spell Checked Finished:")
    EXIT
END
current = 1
LWORDS.0 = 0
MWORDS.0 = 0

hide
show main
window front activate
CALL SetTarget UNFOUND.1

/**************************************************************************/
/* MAIN LOOP -- Check for GUI events                                      */
/**************************************************************************/

DO FOREVER
    CALL WAITPKT("HOLLY")
    packet = GETPKT("HOLLY")
    IF packet ~= '00000000'x THEN DO
        class = GETARG(packet)
        SELECT
            WHEN class = "CLOSEWINDOW" THEN LEAVE
            WHEN class = "LEARN" THEN CALL Learn()
            WHEN class = "FIND" THEN CALL FindWord()
            WHEN class = "REPLACE" THEN CALL ReplaceWord()
            WHEN class = "ANAGRAMS" THEN CALL ASearch("A")
            WHEN class = "GUESS" THEN CALL ASearch("G")
            WHEN class = "NEXT" THEN CALL SetTarget("+1")
            WHEN class = "PREV" THEN CALL SetTarget("-1")
            WHEN class = "FIRST" THEN CALL SetTarget(1)
            WHEN class = "LAST" THEN CALL SetTarget(UNFOUND.0)
            WHEN class = "SELECT" THEN CALL ChooseWord()
            WHEN class = "PREFS" THEN CALL Preferences()
            OTHERWISE NOP
        END
        window front activate
    END
END
IF LWORDS.0 + MWORDS.0 > 0 THEN DO
    hide
    show learn
    CALL QSORT "LWORDS"
    LWORDS.count = LWORDS.0
    setlist lwords clear stem LWORDS
    CALL QSORT "MWORDS"
    MWORDS.count = MWORDS.0
    setlist mwords clear stem MWORDS
    DO FOREVER
        CALL WAITPKT("HOLLY")
        packet = GETPKT("HOLLY")
        IF packet ~= '00000000'x THEN DO
            class = GETARG(packet)
            SELECT
                WHEN class = "CLOSEWINDOW" THEN LEAVE
                WHEN class = "SAVE" THEN DO
                    CALL SaveList()
                    LEAVE
                END
                WHEN class = "MOVE" THEN CALL Move()
                WHEN class = "RML" THEN CALL Lose("lwords")
                WHEN class = "RMM" THEN CALL Lose("mwords")
                OTHERWISE NOP
            END
            window front activate
        END
    END
END
hide unload
CALL CLOSEPORT ("HOLLY")
ADDRESS
/* GoldEd SPECIFIC */
'UNLOCK'
/* END GoldEd SPECIFIC */
EXIT

/**************************************************************************/
/* VARIOUS SUBROUTINES                                                    */
/**************************************************************************/

/**************************************************************************/
/* SetTarget(word) -- Sets the word in the target string gadget           */
/**************************************************************************/

SetTarget:
show main
IF DATATYPE(arg(1)) = "NUM" THEN DO
    IF VERIFY(arg(1), "+-", "M") = 1 THEN current = current + arg(1)
    ELSE current = arg(1)
    IF current < 1 THEN current = UNFOUND.0
    IF current > UNFOUND.0 THEN current = 1
    settext target UNFOUND.current
    settext replacement UNFOUND.current
END
ELSE DO
    settext target arg(1)
    settext replacement arg(1)
END
flag = 0 /* Word hasn't been searched for since selection */
RETURN

/**************************************************************************/
/* SetReplace() - Sets replacement string gadget                          */
/**************************************************************************/

SetReplace:
hide
show main
settext replacement arg(1)
settext target UNFOUND.current
RETURN

/**************************************************************************/
/* Learn() -- Adds a word to the LEARN, the words to learn list           */
/**************************************************************************/

Learn:
read target
wrd = RESULT
/* Tests whether wrd is lowercase */
IF BITOR(wrd,," ") == wrd THEN DO
    IF LSEARCH(wrd, "LWORDS") == -1 THEN DO
        cnt = LWORDS.0 + 1
        LWORDS.0 = cnt
        LWORDS.cnt = wrd
    END
END
ELSE DO
    cur = LSEARCH(wrd, "MWORDS")
    DO WHILE (MWORDS.cur = wrd) & (MWORDS.cur ~== wrd)
        cur = cur + 1
    END
    IF cur == -1 THEN DO
        cnt = MWORDS.0 + 1
        MWORDS.0 = cnt
        MWORDS.cnt = wrd
    END
END
CALL SetTarget("+1")
RETURN

/**************************************************************************/
/* ASearch(mode) has AlphaSpell search for anagrams, matches, or guesses  */
/**************************************************************************/

ASearch:
ARG mode /* G = Guess, A = Anagrams, P = Pattern Match" */
busy set
read replacement
targ = RESULT
IF VERIFY(target, "[]!^*?\", "M") > 0 THEN mode = "P"
com = "AlphaSpell -" || mode "-d" dict_path "-w" targ "-n" edit_dist "-o" tempfile dict_list
ADDRESS COMMAND com
CALL ReadList "GUESS"
busy
IF GUESS.0 > 0 THEN DO
    IF VIEWLIST("GUESS", "win", "dest") = 1 THEN CALL SetReplace(dest.1)
END
ELSE CALL rtezrequest ("No match found.", "_Continue", "Search Complete:")
RETURN

/**************************************************************************/
/* ChooseWord() -- Select word from listview of unfound words             */
/**************************************************************************/

ChooseWord:
IF VIEWLIST("UNFOUND", "win", "dest") = 1 THEN CALL SetTarget(dest.1)
IF wrd ~= "" THEN DO
    current = LSEARCH(wrd, "UNFOUND")
    uwrd = UPPER(wrd)
    DO WHILE (UPPER(UNFOUND.current) = uwrd) & (UNFOUND.current ~= wrd)
        current = current + 1
    END
END
RETURN

/**************************************************************************/
/* SaveList() -- Saves words in the "LEARN" list to user dictionary       */
/**************************************************************************/

SaveList:
udict.low = MAKEPATH(dict_path, user_dict || ".low")
udict.mix = MAKEPATH(dict_path, user_dict || ".mix")
read lwords LEARN
LEARN.0 = LEARN.count
IF LEARN.0 > 0 THEN DO
    CALL WRITEFILE tempfile, "LEARN"
    com = "AlphaSpell -Lco" udict.low tempfile
    IF Exists(udict.low) THEN com = com udict.low
    ADDRESS COMMAND com
END
read mwords LEARN
LEARN.0 = LEARN.count
IF LEARN.0 > 0 THEN DO
    CALL WRITEFILE tempfile, "LEARN"
    com = "AlphaSpell -Lco" udict.mix tempfile
    IF Exists(udict.mix) THEN com = com udict.mix
    ADDRESS COMMAND com
END
CALL DELETE tempfile
RETURN

/**************************************************************************/
/* Move() -- Moves word from mixed case listview to lowercase listview    */
/**************************************************************************/

Move:
CALL Lose("mwords")
wrd = BITOR(wrd,," ")
setlist lwords wrd
RETURN

/**************************************************************************/
/* ReadList -- Reads words from tempfile to a list and sorts the list     */
/**************************************************************************/

ReadList:
CALL READFILE tempfile, arg(1)
INTERPRET arg(1) || ".count =" arg(1) || ".0"
CALL QSORT arg(1)
RETURN

/**************************************************************************/
/* Lose() -- Deletes a word from a listview                               */
/**************************************************************************/

Lose:
INTERPRET "read" arg(1)
wrd = RESULT
INTERPRET "setlist" arg(1) "wrd del"
RETURN

/**************************************************************************/
/* Preferences() -- Preferences GUI                                       */
/**************************************************************************/

Preferences:
hide
show prefs
settext dir dict_path
settext dict dict_list
settext udict user_dict
setnum ed edit_dist
IF ~EXISTS("S:Alpha-Key") THEN setbar ed max 2
DO FOREVER
    CALL WAITPKT("HOLLY")
    packet = GETPKT("HOLLY")
    IF packet ~= '00000000'x THEN DO
        class = GETARG(packet)
        SELECT
            WHEN class = "CLOSEWINDOW" | class = "CANCEL" THEN LEAVE
            WHEN class = "SAVE" | class = "USE" THEN DO
                read dir
                dict_path = RESULT
                read dict
                dict_list = RESULT
                read udict
                user_dict = RESULT
                read ed
                edit_dist = RESULT
                CALL WritePrefs "ENV:ASpell.prefs"
                IF class = "SAVE" THEN CALL WritePrefs "ENVARC:ASpell.prefs"
                LEAVE
            END
            OTHERWISE NOP
        END
    END
END
hide
CALL SetTarget(current)
RETURN

/**************************************************************************/
/* WritePrefs() -- Writes Preferences to a file                           */
/**************************************************************************/

WritePrefs:
IF OPEN(output, arg(1), "W") = 1 THEN DO
    CALL WRITELN output, dict_path
    CALL WRITELN output, dict_list
    CALL WRITELN output, user_dict
    CALL WRITELN output, edit_dist
    CALL CLOSE output
END
RETURN

/**************************************************************************/
/* ReadPrefs() -- Read Preferences from ENV:ASpell.prefs or use defaults  */
/**************************************************************************/

ReadPrefs:
IF OPEN(output, "ENV:ASpell.prefs", "R") = 1 THEN DO
    dict_path = READLN(output)
    dict_list = READLN(output)
    user_dict = READLN(output)
    edit_dist = READLN(output)
    CALL CLOSE output
END
ELSE DO
    dict_path = "Work:AlphaSpell/English/"
    dict_list = "*.low *.mix"
    user_dict = "User"
    edit_dist = 0
    CALL Preferences()
END
RETURN

/**************************************************************************/
/* EDITOR SPECIFIC SUBROUTINES                                            */
/**************************************************************************/

/**************************************************************************/
/* FindWord() -- Finds selected word in document                          */
/**************************************************************************/

FindWord:
read target
wrd = RESULT /* Reads find word */
ADDRESS
IF flag = 0 THEN DO
    'FIND STRING' wrd 'FIRST case 1 WORDS 1'
    flag = 1
END
ELSE DO
    'FIND STRING' wrd 'NEXT case 1 WORDS 1'
END
ADDRESS
RETURN

/**************************************************************************/
/* ReplaceWord() -- Replaces selected word with word in string gadget     */
/**************************************************************************/

ReplaceWord:
read target
wrd = RESULT
read replacement
replacement = RESULT
ADDRESS
'REPLACE BY' replacement 'STRING' wrd 'NEXT'
ADDRESS
RETURN

/* Error messages */
failure:
syntax:
    IF SHOWLIST("P", "HOLLY") = 1 THEN DO
        hide unload
        CALL CLOSEPORT ("HOLLY")
    END
    say "Error" rc  "-- Line" SIGL
    say errortext(rc)
    say sourceline(SIGL)
exit
