/*

	intuiloop.c - the intuition message handling routines

*/


/*
	Gadget selection routines

*/

int gadsDown(struct IntuiMessage *msg)
{
    struct Gadget *g;
    int i;

    /*	Copy data and reply
    */
    g = (struct Gadget *) msg->IAddress;
    ReplyMsg((struct Message *)msg);

    i = g->GadgetID;
    switch (i) {
	;   /* no gadgets to handle, at present */
    }

    return(0);
}


int gadsUp(struct IntuiMessage *msg)
{
    struct Gadget *g;
    int i;

    /*	Copy data and reply
    */
    g = (struct Gadget *) msg->IAddress;
    ReplyMsg((struct Message *)msg);

    i = g->GadgetID;
    switch (i) {
	;   /* no reactions to gadsup, for now */
    }

    return(0);
}



/*
	Menu selection routines

*/
int menuPick(struct IntuiMessage *msg)
{
    struct MenuItem *itemPtr;
    USHORT number;
    SHORT menu, item, subitem;
    int v = 0;	/* Exit Program flag */

    /*	copy data and reply
    */
    number = msg->Code;
    ReplyMsg((struct Message *)msg);

    while (number != MENUNULL) {
	itemPtr = (struct MenuItem *) ItemAddress(&mainmenu[0], number);
	menu = MENUNUM(number);
	item = ITEMNUM(number);
	subitem = SUBNUM(number);

	switch(menu) {

	    case 0:			/* System menu */
		switch(item) {
		    case 0:			/* Save Prefs */
			{
			    short err = 0;
			    BPTR f = Open(SP_PREFSNAME, MODE_NEWFILE);

			    if (f == NULL) err = 1;
			    else {
				if (Write(f, &specPrefs, sizeof(specPrefs))
				    != sizeof(specPrefs)) err = 1;

				Close(f);
			    }

			    if (err) SetWindowTitles(backWin, (UBYTE *) -1,
				"Couldn't save prefs.");
			}
			break;

		    case 1:			/* Quit */
			v = 1;
			break;
		}
		break;

	    case 1:			/* Processor menu */
		switch(item) {
		    case 0:			/* INT */
			Z80_INTreq(Zctrl);
			break;

		    case 1:			/* NMI */
			Z80_NMIreq(Zctrl);
			break;

		    case 2:			/* RESET */
			Z80_RESETreq(Zctrl);
			break;
		}
		break;
	}

	number = itemPtr->NextSelect;
    }

    return(v);
}



/*
	Some assisting functions

*/

void verifyMenuBegin(void)
{
    verify = VERIFY_MENU;

    /*	turn off screen updating
    */
    intControl.UPDtype = 3;
    Wait(updateSig);
}

void verifyMenuEnd(void)
{
    verify = 0;

    /*	turn screen updating back on, redrawing the bitplanes
    */
    intControl.UPDtype = 2;
}



/*
 *	Intuition message handling for the different windows
 *
 */

/*
	The backdrop window (the "global" message handler)

*/
int backWinMsg_handler(struct IntuiMessage *msg, int exit)
{
    /* Each handled case must ReplyMsg on its own! */

    switch (msg->Class) {
	case IDCMP_GADGETDOWN:
	    exit = gadsDown(msg);
	    break;

	case IDCMP_GADGETUP:
	    exit = gadsUp(msg);
	    break;

	case IDCMP_MENUPICK:
	    if (verify == VERIFY_MENU) verifyMenuEnd();
	    exit = menuPick(msg);
	    break;

	case IDCMP_MOUSEBUTTONS:
	    if (msg->Code = MENUUP)
		if (verify == VERIFY_MENU) verifyMenuEnd();
	    ReplyMsg((struct Message *)msg);
	    break;

	case IDCMP_RAWKEY:
	    exit = rawKey(msg);
	    break;

	default:
	    /* Messages of unknown class */
	    ReplyMsg((struct Message *)msg);
    }

    return exit;
}



/*
	The Spectrum window

*/
int specWinMsg_handler(struct IntuiMessage *msg, int exit)
{
    /* Each handled case must ReplyMsg on its own! */

    switch (msg->Class) {
	case IDCMP_MENUVERIFY:
	    verifyMenuBegin();
	    ReplyMsg((struct Message *)msg);	/* now allow rendering */
	    break;

	default:
	    /* Pass it on to the backdrop window handler */
	    exit = backWinMsg_handler(msg, exit);
    }

    return exit;
}




/*
 *	The Intuition message loop
 *
 */

void parseSignals(void)
{
    ULONG wakeflags =
	SIGBREAKF_CTRL_C | specWinSig | backWinSig | audioSig;
    register int exit = 0;
    register struct IntuiMessage *msg;
    register ULONG sigs;

    /*	If the (global) verify variable is nonzero, we must wait until a
	Menupick or Mousebuttons-Menup message is received before turning
	the screen updating back on. Until then, exit will be delayed.
    */
    while (!exit || verify) {
	sigs = Wait(wakeflags);

	if (sigs & SIGBREAKF_CTRL_C) exit = 1;

	if (sigs & specWinSig) {
	    while ((msg = (struct IntuiMessage *)
		GetMsg(specWin->UserPort)) != NULL) {
		if (exit) ReplyMsg((struct Message *)msg);
		else exit = specWinMsg_handler(msg, exit);
	    }
	}

	if (sigs & backWinSig) {
	    while ((msg = (struct IntuiMessage *)
		GetMsg(backWin->UserPort)) != NULL) {
		if (exit) ReplyMsg((struct Message *)msg);
		else exit = backWinMsg_handler(msg, exit);
	    }
	}

	if (sigs & audioSig) {
	    /* ignored, at present */
	}
    }
}

