#include <types.h>
#include <stdio.h>
#include <quickdraw.h>
#include <qdaux.h>
#include <window.h>
#include <memory.h>
#define dtItemListLength    10
#include <event.h>
#include <dialog.h>
#include <control.h>
#include <lineedit.h>
#include <string.h>
#include <prodos.h>
#include "bl.h"
#include "th.h"
#include "driver.h"

#define max(x, y)       ((x) > (y) ? (x) : (y))

static pascal unsigned thfilter();
static pascal void drawDefBox();
static pascal void drawWord();
static pascal void selProc();

static char prevStr[] = "\pPrev. Meaning";
static ItemTemplate prevButt =
{ 2, {110, 24, 122, 134}, buttonItem, prevStr, 0, 0, 0L };

static char cancelStr[] = "\pDone";
static ItemTemplate cancelButt =
{ 1, {110, 154, 122, 264}, buttonItem, cancelStr, 0, 0, 0L };

static char replaceStr[] = "\pReplace";
static ItemTemplate replaceButt =
{ 3, {110, 284, 122, 394}, buttonItem, replaceStr, 0, 0, 0L };

static char nextStr[] = "\pNext Meaning";
static ItemTemplate nextButt =
{ 4, {110, 414, 122, 524}, buttonItem, nextStr, 0, 0, 0L };

char defStr[] = "\p^0: ^1 ";
static ItemTemplate defLine =
{ 5, {7, 24, 37, 524}, statText + itemDisable, defStr, 0, 0, 0L };

static char synStr[] = "\pSynonyms:";
static ItemTemplate synLine =
{ 6, {43, 24, 53, 100}, statText + itemDisable, synStr, 0, 0, 0L };

static ItemTemplate defBox =
{ 9, {5, 21, 38, 527}, userItem + itemDisable, (Pointer) drawDefBox, 0, 0, 0L };

static DialogTemplate myDlg =
{
    {40, 40, 170, 590}, 1, 0L, {&prevButt, &cancelButt, &replaceButt,
      &nextButt, &defLine, &synLine, &defBox, NULL}
};

static ListRec theList = {
	0L,					
	{42, 112, 104, 414},	/* Box Rect */
	{42, 412, 104, 440},	/* ScrollBar Rect */
	0,
	10,					/* Height of 10 (for Shaston) */
	3,					/* Dbl-Click -> Replace button */
	drawWord,			/* Draw Proc */
	selProc,			/* Select Proc */
	0L					/* No changed proc */
	/* reserved array is zeroed too. */
};

static GrafPortPtr dlgPort;
static unsigned replable;
static char *def;
static int didfix;
static char *theword;
static char **wlist;

pascal char *THDlg(word)
char *word;
{
unsigned nummean, x, done = 0;
char **lists[5];
unsigned thismean = 1;
char *retval;

    setbank;
    replable = didfix = 0;
    theword = word;                 /* for fixdef */
	
	/* this may take a while... */
	D_BEACHBALL();

    if (!(nummean = THWord(word)))
    {
        ParamText(word, "\pNo entries in thesaurus", NULL, NULL);
        x = 0;
    }
    else
    {
        def = THInfo(1, lists);
        ParamText(word, def, NULL, NULL);
        for (x = 0; lists[0][x]; ++x)
            ;
    }

    dlgPort = GetNewModalDialog(&myDlg);
	theList.Dialog = dlgPort;
	theList.ListSize = x;
	D_BEACHBALL();
	D_BLMAKELIST(&theList);
	D_BEACHBALL();

    HiliteControl(255, GetControlDItem(dlgPort, 2));
    HiliteControl(255, GetControlDItem(dlgPort, 3));
    if (nummean < 3)
        HiliteControl(255, GetControlDItem(dlgPort, 4));

	D_SETCURSOR(arrowCursor);
    while (!done) {
		wlist = lists[0];
        switch (D_SETCURSOR(arrowCursor),D_BLMODALDIALOG(thfilter))
        {
            case 2:         /* Prev mean */
                def = THInfo(--thismean, lists);
                SetPort(dlgPort);
                fixdef();
                ParamText(NULL, def, NULL, NULL);
                SetIText(dlgPort, 5, defStr);
                for (x = 0; lists[0][x]; ++x)
                    ;
                D_BLSELECT(&theList, -1);
                D_BLSETPARMS(&theList, x, 0);
                if (thismean == 1)
                    HiliteControl(255, GetControlDItem(dlgPort, 2));
                HiliteControl(0, GetControlDItem(dlgPort, 4));
                break;
            case 1:         /* Cancel */
                retval = NULL;
                done = 1;
                break;
            case 3:         /* Replace */
                retval = lists[0][D_BLGETSEL(&theList)];
                done = 1;
                break;
            case 4:         /* Next mean */
                def = THInfo(++thismean, lists);
                SetPort(dlgPort);
                fixdef();
                ParamText(NULL, def, NULL, NULL);
                SetIText(dlgPort, 5, defStr);
                for (x = 0; lists[0][x]; ++x)
                    ;
                D_BLSELECT(&theList, -1);
                D_BLSETPARMS(&theList, x, 0);
                if (thismean == nummean)
                    HiliteControl(255, GetControlDItem(dlgPort, 4));
                HiliteControl(0, GetControlDItem(dlgPort, 2));
                break;
        }
	}
	
    D_BLFORGETLISTS();
    CloseDialog(dlgPort);
    restorebank;
    return(retval);
}

static pascal void drawDefBox(dlg, item)
long dlg;
int item;
{
    PenNormal();
    FrameRect(&defBox.itemRect);
}

static pascal void drawWord(foo,wnum)
char *foo;
int wnum;
{
	setbank;
    Move(3, 8);
    DrawString(wlist[wnum]);
	restorebank;
}

static pascal void selProc(foo,wnum)
char *foo;
int wnum;
{
    setbank;
    if (wnum >= 0)
    {
        if (!replable)
        {
            replable = 1;
            HiliteControl(0, GetControlDItem(dlgPort, 3));
        }
    }
    else if (replable)
    {
        replable = 0;
        HiliteControl(255, GetControlDItem(dlgPort, 3));
    }
    restorebank;
}

/* This is stupid... must do first fixdef here, in dlg update, so we can
   use its port and not ruin Kevin's font info.  Must even set sysfont. */

static pascal unsigned thfilter(dlg, evt, item)
GrafPortPtr dlg;
EventRecordPtr evt;
int *item;
{
    setbank;

    if (evt->what == updateEvt && !didfix)
    {
        SetPort(evt->message);
        SetFont(GetSysFont());
        fixdef();
        ++didfix;
    }

    restorebank;
    return(0);
}

/* Wrap the definition string at word breaks if it's too long */

fixdef()
{
unsigned x;
unsigned lastspace;
unsigned prewid;
char *linestart = def + 1;
char c;

    prewid = StringWidth(theword);

    for (x = 1; x <= def[0]; ++x)
        if (def[x] == ' ' || x == def[0])
        {
            c = def[x];
            def[x] = 0;
            if (CStringWidth(linestart) + prewid > 490)
            {
                def[lastspace] = 0x0d;
                linestart = def + lastspace + 1;
                prewid = 0;
            }
            def[x] = c;
            lastspace = x;
        }
}
