/*
*	display.c
*
*	NewWindow and WinTexts for OneKeyII.
*
*	Layout is:
*
*	01234567890123456789
*	Ctrl Qualifiers
*	Shift     Shift
*	 Alt A   A Alt
*
*	MWS, 11/92.
*/

#include <exec/types.h>
#include <intuition/intuition.h>
#include "wintext.h"
#include "menu.h"

#define ABOUT_TXT "\
   OneKeyII Version 1.0\n\
    by Martin W. Scott\n\
\n\
email: mws@castle.ed.ac.uk\n\
       (until June 1993)\n\
\n\
      Public Domain.\
"

void DrawState(UWORD);
void InitWindowPos(void);
BOOL ShowWindow(void);
void HideWindow(void);
BOOL HandleIDCMP(void);		/* returns FALSE if window to close */

/* character dimensions */
#define CHARS_ACROSS	15
#define CHARS_DOWN	3

/* initial position */
#define LEFTEDGE 40
#define TOPEDGE 20

#define WIN_TITLE NULL /*"OneKeyII"*/

struct Gadget drag_gadget = {
    /* whole window */
	NULL,
	0, 0, 0, 0,				/* not the right/bottom edges */
	GRELWIDTH | GRELHEIGHT | GADGHNONE,	/* no highlighting...*/
	GADGIMMEDIATE,
	GTYP_WDRAGGING
	/* rest is 0/NULL */
};

struct NewWindow nw =
{
    LEFTEDGE, TOPEDGE, 0, 0, -1, -1,	/* dimension, pens */
    CLOSEWINDOW | MENUPICK,	/* IDCMP flags */	
    WFLG_SMART_REFRESH,		/* window flags */
    &drag_gadget, NULL,		/* gadgets, checkmark */
    WIN_TITLE,			/* title */
    NULL, NULL,			/* screen, bitmap */
    0, 0, 0, 0,			/* extrema of dimensions */
    WBENCHSCREEN		/* screen to open onto */
};

struct TagItem wtags[] =
{
    {TAG_DONE}
};

struct Window *window;
struct Menu *menu;
static WINTEXTINFO wtinfo;	/* to be initialised later */
ULONG winsigflag;
UWORD oldqual = -1;

/*********************** SHOW QUALIFIER SITUATION *****************************/
#define STD	1		/* normal state */
#define HIGH	2		/* active state */
#define TXT	3

#define QUALS()		WinText(&wtinfo, "Qualifiers", 5, 0, TXT, 0)
#define LSHIFT(qual)	WinText(&wtinfo, "Shift", 0, 1, (qual & IEQUALIFIER_LSHIFT) ? HIGH : STD, 0)
#define RSHIFT(qual)	WinText(&wtinfo, "Shift", 10, 1, (qual & IEQUALIFIER_RSHIFT) ? HIGH : STD, 0)
#define LALT(qual)	WinText(&wtinfo, "Alt", 1, 2, (qual & IEQUALIFIER_LALT) ? HIGH : STD, 0)
#define RALT(qual)	WinText(&wtinfo, "Alt", 11, 2, (qual & IEQUALIFIER_RALT) ? HIGH : STD, 0)
#define LAMIGA(qual)	WinText(&wtinfo, "A", 5, 2, (qual & IEQUALIFIER_LCOMMAND) ? HIGH : STD, 0)
#define RAMIGA(qual)	WinText(&wtinfo, "A", 9, 2, (qual & IEQUALIFIER_RCOMMAND) ? HIGH : STD, 0)
#define CTRL(qual)	WinText(&wtinfo, "Ctrl", 0, 0, (qual & IEQUALIFIER_CONTROL) ? HIGH : STD, 0)

void
DrawState(UWORD qual)
{
    if (oldqual != qual)
    {
	QUALS();
	LSHIFT(qual);
	RSHIFT(qual);
	LALT(qual);
	RALT(qual);
	LAMIGA(qual);
	RAMIGA(qual);
	CTRL(qual);
	oldqual = qual;
    }
}

/********************* DISPLAY OPEN/CLOSE ROUTINES ****************************/

/***** GRATEFULLY LIFTED FROM UHR.C BY STEFAN STICHT *****/
/*
 *  request(): a glue routine to EasyRequest as simple as printf plus
 *             titlestring, gadgettexts
 *
 *  Input: char *title:         pointer to the title of the requester
 *         char *gadgets:       pointer to gadgettext
 *         char *text:          text displayed in requester
 *
 *  Result: same as EasyrequestArgs()
 *
 * !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
 */
#include <stdarg.h>
#include <dos/dosextens.h>
long request(char *title, char *gadgets, char *text, ...)
{
    /*
     *  structure textreq only needed in this function, so hide it here
     *  must be static, in order to be initialized only once
     */
    long rc = 0;
    struct EasyStruct textreq = {
        sizeof (struct EasyStruct), /* ULONG es_StructSize      */
        0l,                         /* ULONG es_Flags           */
        NULL,                       /* UBYTE *es_Title          */
        NULL,                       /* UBYTE *es_TextFormat     */
        NULL,                       /* UBYTE *es_GadgetFormat   */
        };
    struct Process *process;
    struct Window *win;
    va_list ap;

    /*
     *  get start of variable arguments
     */
    va_start(ap, text);

    if (process = (struct Process *)FindTask(NULL)) {
        if ((long)(win = process->pr_WindowPtr) != -1) {

            /*
             *  update textreq
             */
            textreq.es_Title = (UBYTE *)title;
            textreq.es_TextFormat = (UBYTE *)text;
            textreq.es_GadgetFormat = (UBYTE *)gadgets;

            rc = EasyRequestArgs(win, &textreq, NULL, ap);

            }

        }

    va_end(ap);

    return(rc);
}

void
InitWindowPos()
{
    nw.LeftEdge = TTInt("LEFTEDGE", LEFTEDGE);
    nw.TopEdge = TTInt("TOPEDGE", TOPEDGE);
}

BOOL
ShowWindow()			/* alloc wintext memory, open window */
{
    extern UWORD quals;
    extern BOOL toggle;

    if (window)			/* already open */
	return TRUE;

    if (InitWinTextInfo(&wtinfo))
    {
	/* size window to fit screen font */
	nw.Height = CHARS_DOWN * wtinfo.font_y + wtinfo.toffset + wtinfo.boffset;
	nw.Width = CHARS_ACROSS * wtinfo.font_x + wtinfo.loffset + wtinfo.roffset;

	if (window = OpenWindowTagList(&nw, wtags))
	{
	    if (menu = AllocOneKeyMenu(window))
	    {
		struct MenuItem *item;

		item = ItemAddress(menu, FULLMENUNUM(ONEKEYII, TOGGLE, 0));
		if (toggle)
		    item->Flags |= CHECKED;                  
		else
		    item->Flags &= ~CHECKED;                                  

		SetMenuStrip(window, menu);
		wtinfo.window = window;
		winsigflag = 1 << window->UserPort->mp_SigBit;
		DrawState(quals);
		return TRUE;
	    }
	    else
	    {
		CloseWindow(window);
		window = NULL;
	    }
	}
    }
    return FALSE;
}

void
HideWindow()			/* close window */
{
    if (window)
    {
	nw.LeftEdge = window->LeftEdge;
	nw.TopEdge = window->TopEdge;
	CloseWindow(window);
	FreeOneKeyMenu();
	window = NULL;
	winsigflag = 0;
	oldqual = -1;
    }
}

/* return FALSE if user quits (not possible at moment) */
BOOL
HandleIDCMP()
{
    struct IntuiMessage *msg;
    struct MenuItem *item;
    /*        struct Gadget   *gadget;                        */
    ULONG class;
    UWORD code;
    extern BOOL toggle;

    if (!window)
	return FALSE;

    while (msg = (struct IntuiMessage *) GetMsg(window->UserPort))
    {
	class = msg->Class;
	code = msg->Code;
	/*                gadget = (struct Gadget *)msg->IAddress;*/
	ReplyMsg(msg);

	switch (class)
	{
	case CLOSEWINDOW:
	    HideWindow();
	    return TRUE;
	case MENUPICK:
	    while (code != MENUNULL)
	    {
		UWORD inum = ITEMNUM(code);

		if (MENUNUM(code) == ONEKEYII)
		{
		    switch (inum)
		    {
		    case TOGGLE:
			toggle ^= 1;
			break;
		    case ABOUT:
			request("OneKeyII", "OK", ABOUT_TXT);
			break;
		    case HIDE:
			HideWindow();
			return TRUE;
		    case QUIT:
			return FALSE;
		    }
		}
		item = ItemAddress(menu, code);
		code = item->NextSelect;
	    }
	}
    }
    return TRUE;
}
