/* ------------------------- Ue8.c ------------------------------ */

#include "uedit.h"

stop()
{
    if (msgList->lh_Head->ln_Succ) {
        while (getRaw());
    }
	return(stopPause);
}

FinputWaiting()
{
	if (msgList->lh_Head->ln_Succ) {
        while (getRaw());
    }
	if (curMsgIn!=curMsgOut || stopPause) return(TRUE);
	return(execLearn);
}

getRaw()
{
register struct IntuiMessage *msg;
register struct   MenuItem  *itemPtr;
register ULONG  			i,j,k,l;
register long				delta,diff;
static struct IntuiMessage  mmsg;

/* ------ probably can DELETE this line
    if (uport==NULL) return(FALSE);
 ----------- */
NEWMSG:
	msg = (struct IntuiMessage *)GetMsg(uport);
	if (msg == NULL) return(FALSE);

	j = msg->Class;
	itemPtr = (struct MenuItem *)&mmsg;
	((struct IntuiMessage *)itemPtr)->Code  = msg->Code;
	((struct IntuiMessage *)itemPtr)->Qualifier = msg->Qualifier;
	if (msg->MouseY<0) msg->MouseY = 0;
	((struct IntuiMessage *)itemPtr)->MouseX = msg->MouseX;
	((struct IntuiMessage *)itemPtr)->MouseY = msg->MouseY;
	((struct IntuiMessage *)itemPtr)->Seconds = msg->Seconds;
	((struct IntuiMessage *)itemPtr)->Micros  = msg->Micros;
	ReplyMsg(msg);

	msg = &mmsg;
	if (j==MOUSEMOVE) {
		mouseX = msg->MouseX;
		mouseY = msg->MouseY;
		goto NEWMSG;
	}

	msg->Class = j;
	i = msg->Code;

	if (j==MOUSEBUTTONS) {
		if (i == SELECTDOWN) {
			diff = ((long)msg->Seconds - seccs)*100;
			delta = ((long)msg->Micros - miccs)/10000;
			diff += delta;
			seccs = (long)msg->Seconds;
			miccs = (long)msg->Micros;
			msg->Seconds = diff;	/* store double-click time in Sec field */
			if (stackDepth) {  /* IN A COMMAND! */
				if (tiny) {
					if (msg->MouseY>=charHeight) { gChar = ESC; goto NEWMSG; }
				} else {
					if (msg->MouseY<charHeight &&
					  (msg->MouseX<t1 || msg->MouseX>=t2)) {
						if (cmdTable[onTitle]) {
							takeMsg(msg,ON_TITLE);
							return(TRUE);
						}
						toTiny = TRUE;
						goto NEWMSG;
					}
				}
			}
		}
		unsaveFlags();
	} else if (reportMouse) unsaveFlags();
	if (j==RAWKEY && i>0x5f) goto NEWMSG;

	if ( msg->Qualifier & 0xc0 ) {
		if (i==0X45 || j==256L ) {
			Fnull();
			if (!primitive) goto NEWMSG;
		}
	}
	if (msgQ[curMsgIn].Count) goto NEWMSG;  			 /* msg buffer full */
	if (j==MENUPICK) {
		while (i!=MENUNULL) {
			itemPtr = ItemAddress(edMenu[0],i);
			j = MENUNUM(i) * MAXITEMS * MAXSUBITEMS;
			k = ITEMNUM(i) * MAXSUBITEMS;
			if ((l = SUBNUM(i))==NOSUB) l = 0L;
			takeMsg(msg,(USHORT)(j + k + l));
			i = itemPtr->NextSelect;
		}
		WaitBlit();
		if (!suppressClear) recoverMsg();
	} else takeMsg(msg,(short)i);
	return(TRUE);
}

void takeMsg(register struct IntuiMessage *msg,
			 register USHORT code)
{
register struct   msgQueue  *curIn;
register long				l;

	curIn	= (struct msgQueue *)&(msgQ[curMsgIn]);
	l = msg->Seconds;
	if (l<=0) l = 1;
	else if (l>=32767) l = 32767;
	curIn->Count =   l;
	curIn->Code  =   code;
	curIn->Class =   msg->Class;
	curIn->Qualifier =   msg->Qualifier;
	curIn->MouseX	 =   msg->MouseX;
	curIn->MouseY	 =   msg->MouseY;
	if (++curMsgIn>MAXMSGS) curMsgIn = 0;
}


collectRaw()
{
   	if (msgList->lh_Head->ln_Succ) {
        while (getRaw());
        return(TRUE);
    }
    return(FALSE);
}

#define MIDDLEDOWN	(IECODE_MBUTTON)
#define MIDDLEUP	(IECODE_MBUTTON | IECODE_UP_PREFIX)

static UCHAR *upperKeys = (UCHAR *)" \x09123-4()/*+"; 	 /* 17 UPPERKEYS */

nextEvent()
{
register struct msgQueue	*inMsg;
register UCHAR  			*x;
register short  			qual,code,macnum,ichar,lh;

	if (noDisplay && !hideDisplay) onDisplay();

   	if (msgList->lh_Head->ln_Succ) {
	    while (getRaw());
	}
    ichar = macnum = 0;
	gChar = macroNum = inputChar = inputQualifier = 0;

	if (execLearn==EXEC_LEARN) {
		inMsg = (struct msgQueue *)&(learnQ[curLearn]);
		if (learnMode || curLearn++>MAXLEARN || inMsg->Count==0) {
			execLearn = STOP_EXEC_LEARN;
			curLearn=0;
			goto TRUERTN;
		}
	} else {
		inMsg = (struct msgQueue *)&(msgQ[curMsgOut]);
		code = curMsgOut;
		if (++curMsgOut>MAXMSGS) curMsgOut = 0;
		if (inMsg->Count==0) { curMsgOut = code; return(FALSE); }
	}
	code = inMsg->Qualifier;
	qual = 0;
	if (code & 0x04)	capsLock = TRUE;
	else				capsLock = FALSE;

	if (code & 0x03) qual |= SHIFTKEYED;
	if (code & 0x30) qual |= ALTKEYED;
	if (code & 0x08) qual |= CONTROLKEYED;
	if (qual==0) {
		if (code & 0x80) qual = RAMIGA;
		if (code & 0x40) qual = LAMIGA;
	}

	code = inMsg->Code;
	if (code==ON_TITLE) {
ONTITLE:
		macnum = onTitle;
		goto TAKEIT;
	}
	switch (inMsg->Class) {
	case  MENUPICK:
		macnum = menuMacroNum[code];
		break;
	case  MOUSEBUTTONS:
		unsaveFlags();
		lh = lineHeight[0];
		switch(code) {
		case  MIDDLEDOWN:	macnum = middleDown;
		case  MENUDOWN: 	if (macnum==0) macnum = menuDown;
		case  SELECTDOWN:
			code = inMsg->MouseY;
			clickTime = inMsg->Count;
			if (tiny) {
				if (primitive!=2) ichar = ESC;
				break;
			}
			if (code<=charHeight) {
				macnum = -1;
				code = inMsg->MouseX;
				if (code<t1 || code>=t2) {
TOTINY:
					if (cmdTable[onTitle]) goto ONTITLE;
					toTiny = 1;
					break;
				}
				if (curBuf!=NULL) {
					code -= t1;
					code /= charWidth;
					if (code <= 11) {
						if (curBuf && !(code==4 && (curBuf->Flags & FOLDED))) 
							curBuf->Flags ^= (1L << code);
					} else if (primitive==2) {
						if (pmEsc==ESC) { pmEsc=eol; x="ENTER"; }
						else			{ pmEsc=ESC; x="ESC  "; }
						movdat(x,&(curBuf->FileName[29]),(short)5);
					} else goto TOTINY;
					showTitle = TRUE;
				}
				break;
			}
			if (primitive==2) break;
			if ( code > charHeight && code <= lh) {
				macnum = gadget1 +
							(inMsg->MouseX/charWidth)/(maxLineChars >> 2);
				if (macnum>gadget4) macnum = gadget4;
				goto GETXY;
			}
			if (nSplit) newSplit = inSplit(code); /* primitive!=2 here! */
			if (code>lh) {
				if (macnum==0) macnum=buttonDown;
GETXY:
				mouseX = inMsg->MouseX;
				mouseY = code;
			}
			if (macnum) {
				mouseDown=TRUE;
MACNUM:
				code = qual << 3;
				macnum += code;
				code += code;
				code += code;
				macnum += code;
				code += code;
				macnum += code;
/* ----------------
NEW NEW NEW NEW  - above tries to do this quicker
				macnum += (MAXRAW * qual);
				same as
				macnum += ((qual<<6)+(qual<<5)+(qual<<3));
------------------- */
			}
			break;
		case  MIDDLEUP:  macnum = middleUp;
		case  MENUUP:	 if (macnum==0) macnum = menuUp;
		case  SELECTUP:
			code = inMsg->MouseY;
			if (code <= charHeight) macnum = 0;
			else {
				if (primitive==2) {
					if (tiny) ichar = ESC;
					else ichar = pmEsc;
				} else if (code>lh) {
					if (macnum==0) macnum = buttonUp;
					mouseX = inMsg->MouseX;
					mouseY = code;
					goto MACNUM;
				}
			}
			break;
		}
		break;
/* 	case  NEWPREFS:  if (tiny==0) makeWindow(); break;
*/
	case  CLOSEWINDOW:
			if (primitive==2) ichar=pmEsc;
			else { macnum = closeBox; goto MACNUM; }
			break;
	case  RAWKEY:
			macnum = code;
			if (macnum==0) macnum = zeroChar;	 /* 103: squig char is 0x00 */

			macnum +=
			  ( (qual<<6)+(qual<<5)+(qual<<3) ); /*  macnum += (MAXRAW * qual);  */

			if (code<64) {
				if (qual==ALTKEYED)
					{ ichar = altKeys[code]; goto ICHAR; }
				if (qual==(ALTKEYED | SHIFTKEYED))
					{ichar = altKeys[MAXPRINTABLES + code]; goto ICHAR; }
				ichar = printKeys[code];
			}
			else if (code<76) 				ichar = upperKeys[code - 64];
			else if (code>=90 && code<=94)  ichar = upperKeys[code + (12 - 90)];
ICHAR:
			if (ichar) {
				if (ichar==0X0D) ichar = eol;
				else {
					if (qual==CONTROLKEYED) {
							if (ichar>='a' && ichar<='z') gChar = ichar + (1 - 'a');
							else if (ichar>='[' && ichar<=']') gChar=ichar+(ESC - '[');
							else if (ichar=='6') gChar = 30;
							else if (ichar=='-') gChar = 31;
							if (gChar && primitive==2) ichar = gChar;
					}
					else if (code<64) {
						if (qual==SHIFTKEYED
							|| (qual==0 && capsLock && ichar<='z' && ichar>='a'))
								ichar = printKeys[MAXPRINTABLES + code];
					}
				}
			}
			break;
			default: break;
		}
	if (ichar || macnum) {
TAKEIT:
		if (macnum<0) { macnum=0; goto CONT; }
		if (gChar==0) gChar = ichar;
		if (primitive) {
    		if (primitive>1) macnum = 0;
            code = inMsg->Code;
            if (code>=76 && code<=79) {
			    primCode(code,qual);
			    ichar=0;
			    goto CONT;
            }
		} else if (ichar==ESC)  ichar = 0;
		if (qual<=(ALTKEYED | SHIFTKEYED)) {
			if (ichar==ESC && qual==0 && primitive==1) goto CONT;
			if (!useKeys && cmdTable[macnum]!=NULL) ichar = 0;
			goto CONT;
		}
		if (qual==CONTROLKEYED) {
			if (primitive!=2) ichar = 0;
			goto CONT;
		}
		ichar = 0;  							/* all other shifts */
CONT:
		inputChar = ichar;
		inpChar = ichar;
		inputQualifier = qual;
		macroNum = macnum;
		mcrNum = macnum;
		if (learnMode && !execLearn && !tiny) {
			if (curLearn<=MAXLEARN)
				movdat((UCHAR *)inMsg,(UCHAR *)&(learnQ[curLearn]),
                            (short)sizeof(struct msgQueue));
			if (++curLearn>MAXLEARN) oneMsg("Learn Mode full");
			showTitle = TRUE; /* setTitle(); */
		}
	}
	if (execLearn!=EXEC_LEARN) inMsg->Count = 0;
TRUERTN:
	return(TRUE);
}

/* ============== primitive fcts ================= */

primCode(register short code, register short qual)
{
/* 	code %= MAXRAW; */
	popFast();
	switch(code) {
	case 76:												/* uparrow */
			if (qual==0) upLineFast();
			else sPageFast();
			break;
	case 77:											/* downarrow */
			if (qual==0) downLineFast();
			else ePageFast();
			break;
	case 78:											/* rightarrow */
			if (qual>=CONTROLKEYED) eFileFast();
			else if (qual>=ALTKEYED) eLineFast();
			else if (qual==SHIFTKEYED) eWordFast();
			else incFast();
			break;
	case 79:											/* leftarrow */
			if (qual>=CONTROLKEYED) sFileFast();
			else if (qual>=ALTKEYED) sLineFast();
			else if (qual==SHIFTKEYED) sWordFast();
			else decFast();
			break;
	default: return(FALSE);
    }
	takeFast();
	displayFlag |= SHOWCURSOR_;
	gcol = -1;
	return(TRUE);
}


/* ============================================
goes into case in nextevent above

	case  REFRESHWINDOW: BeginRefresh(edWindow);
						displayFlag |= PAGE_;
						EndRefresh(edWindow,TRUE);
						break;
	case  MOUSEMOVE:
	case  DISKINSERTED:
	case  DISKREMOVED:   break;
	case  INACTIVEWINDOW:
	case  ACTIVEWINDOW:  break;
=========================================== */
/* -----------------------
	if (j==REQCLEAR) {
		BeginRefresh(edWindow);
		EndRefresh(edWindow,(long)TRUE);
		goto NEWMSG;
	}

	if (j==REFRESHWINDOW) {
		BeginRefresh(edWindow);
		displayFlag = ALLPAGE;
		EndRefresh(edWindow,1L);
	}
------------------ */
/* ==============================
	if (j==MENUVERIFY) {
		if (msg->MouseY<=charHeight && msg->MouseX)
				{ TAKEIT: ReplyMsg(msg); goto NEWMSG; }
		i = MENUCANCEL;
		if (msg->MouseX || msg->MouseY)  { toTiny = TRUE; goto TAKEIT; }
		j = CLOSEWINDOW;
	}
================================== */
/* -----------------------
diag()
{
UCHAR zz[128];
register UCHAR *s;
register struct IB *ib;

	ib = (struct IB *)IntuitionBase;

	s = wptr;
	setColors(0);
	move(0,20);
	*zz = 0x00;
	catNumber(zz,(long)ib->MenuDrawn,127);
	strcat(zz,"    ");
	catNumber(zz,ib->Flags,127);
	wptr = zz;
	text((short)strlen(zz));
	wptr = s;
}

#define MENUDRAWN	(*menuDrawn & 0X80)
------------------------------------- */
				 /* 				none	bar 	menu  */
				 /* 1.3 65535 65506 0X12000 0X12400 0X12480 */
				 /* 2.0 0	  0 	0X16004 0X16004 0X96084 / 0X16084	 */

