/* -	-	C101	-	-	*/
#define xedvars 0

#include "stdio.h"
#include "types.h"
#include "math.h"
#include "intuition/intuition.h"    
#include "graphics/gfxbase.h"
#include "graphics/text.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"
#include "exec/memory.h"

struct IntuitionBase *IntuitionBase;
struct IntuiMessage *txmsg;
struct GfxBase *GfxBase;
struct Window *txwin;
struct RastPort *txrp;
struct MsgPort *xport;
struct IOStdReq *iport;
struct Device *ConsoleDevice;

struct NewWindow frame =
{
/* Left Top		*/ 0,0,
/* Width			*/ 640, /* (N*8) + 24 */
/* Height		*/ 254, /* (N*8) + 14 */
/* DetailPen	*/ 0,
/* BlockPen		*/ 1,
/* IDCMPFlag	*/ RAWKEY,
/* Flags			*/ WINDOWDRAG| WINDOWSIZING| WINDOWDEPTH| SMART_REFRESH| ACTIVATE,
/* FirstGadget */ NULL,
/* Check_mark	*/ NULL,
/* Title       */ "J D Gray",
/* Screen		*/ NULL,
/* BitMap		*/ NULL,
/* MinWidth MinHeight */ 24,18,
/* MaxWidth MaxHeight */ -1,-1,
/* Type			*/ WBENCHSCREEN
};

struct InputEvent ievent = /*raw key input event*/
{
	NULL, /*next event*/
	IECLASS_RAWKEY, /*class*/
	0,0,0
};

/* Variables */

int MaxStLen = 256;
#define MAXSTR 256  /*maxstlen */

int TOP = 1; /*Cls*/
int BOT = 30;
int PW = 77;
int GX = 4;
int GY = 18;
ulong COLOR = 1; /* 0 brn 2 ylo 1 blk 3 grn*/
ulong BCOLOR = 0;
ulong Tstyle = 0;
int LLen;
int func; /*kbd*/
char buff[10];
char Nstr[82];
char TLine1[258];

/* -	-	C101	-	-	*/
#include "SCREEN.P";
/* -	-	SCREEN	-	-	*/
#ifndef BRN
#define BRN 0
ulong YLO = 2;
ulong BLK = 1; 
#define GRN 3
#endif
char GetKey() /* keys convert to WS control codes. del = ^G */
{
	char C = 0; int class, len;
	do {
		if((txmsg = (struct IntuiMessage *)GetMsg(txwin->UserPort)) == 0L)
		{
			Wait(1 << txwin->UserPort->mp_SigBit); continue; /* re-do */
		}
		class = txmsg->Class;
		if(class == RAWKEY)
		{ /* convert arrow keys et al to char code */
			if(txmsg->Code & IECODE_UP_PREFIX) {;}
			else
			{
				buff[0] = buff[1] = buff[2] = 0;
				ievent.ie_Code = txmsg->Code;
				ievent.ie_Qualifier = txmsg->Qualifier;
				ievent.ie_position.ie_addr = * (APTR *)txmsg->IAddress;
				len = (RawKeyConvert(&ievent,buff,10,NULL));
				if(len > 0)
				{
					if(len == 1) { C = buff[0]; if(C == 0x7f) C = 7; }
					else										/*DEL .. ^code*/
					{
						C = buff[1];
						if(buff[2] == '~') /* help & function keys */
						{
							func = '?';
							if((C >= '0') && (C <= '9')) func = C + 1;
							C = 31;
						}
						switch(C) /* arrow keys */
						{
						case 'A': C = 5;	break; /*^E ^*/
						case 'B': C = 24; break; /*^X v*/
						case 'C': C = 4;	break; /*^D >*/
						case 'D': C = 19; break; /*^S <*/
						case 'T': C = 18; break; /*^R ^^*/
						case 'S': C = 3;	break; /*^C vv*/
						case ' ':
						{
							if(buff[2] == 'A') C = 1; /*^A <<*/
							if(buff[2] == '@') C = 6; /*^F >>*/ break;
						}
						}
					}
				}
			}
		}
		ReplyMsg((struct Message *)txmsg);
	} while(C == 0);
	return(C);
}

SetAttr(S) /* Normal = 0 Uline = 1/2 Bold = 3/4 italic = 5/6 */
int S;
{
	ulong en;
	switch(S)
	{
	case 0: Tstyle = 0; break;
	case 1: Tstyle = Tstyle | 1; break;
	case 2: Tstyle = Tstyle & 6; break;
	case 3: Tstyle = Tstyle | 2; break;
	case 4: Tstyle = Tstyle & 5; break;
	case 5: Tstyle = Tstyle | 4; break;
	case 6: Tstyle = Tstyle & 3; break;
	}
	en = AskSoftStyle(txrp); SetSoftStyle(txrp,Tstyle,en);
}

SetCols() { SetAPen(txrp,COLOR); SetBPen(txrp,BCOLOR); }
YR() { COLOR = YLO; BCOLOR = BRN; SetCols(); SetAttr(0); }
UYR(){ COLOR = YLO; BCOLOR = BRN; SetCols(); Tstyle = 0; SetAttr(1); }
YK() { COLOR = YLO; BCOLOR = BLK; SetCols(); SetAttr(0); }
KY() { COLOR = BLK; BCOLOR = YLO; SetCols(); SetAttr(0); }
KR() { COLOR = BLK; BCOLOR = BRN; SetCols(); SetAttr(0); }
UKR(){ COLOR = BLK; BCOLOR = BRN; SetCols(); Tstyle = 0; SetAttr(1); }
KG() { COLOR = BLK; BCOLOR = GRN; SetCols(); SetAttr(0); }
GK() { COLOR = GRN; BCOLOR = BLK; SetCols(); SetAttr(0); }

L1() { GX = 4; GY = 18; }
Nl() { GX = 4; GY += 8; }

int SetStLen(istr) char *istr;
{
	char C, *str; int E = 0, L = -1;
	str = istr;
	do { C = *(str++); ++L; if((C == 0) || (C == 10) || (L >= MAXSTR)) E = 1; } while(E == 0);
	*(--str) = 0;
	if(L >= MAXSTR) {
		do { C = *(--str); --L; if((C > 32) || (L < 0)) E = 2; } while(E == 1);
		*(++str) = 0;
	}
	return(L);
}

WriteStr(str)
char *str;
{
	ulong L;
	Move(txrp,(long)GX,(long)GY); L = (ulong)SetStLen(str); Text(txrp,str,L); GX +=(L << 3);
}

WriteStN(str,L)
char *str;
int L;
{
	Move(txrp,(long)GX,(long)GY); Text(txrp,str,(ulong)L); GX +=(L << 3);
}

WriteCh(C) /* due to the extra Moves it's faster to compose a str */
char C;
{
	Move(txrp,(long)GX,(long)GY); Nstr[0] = C; Text(txrp,Nstr,(ulong)1); GX += 8;
}

WriteCN(C,N)
char C;
int N;
{
	int L; char *str;
	str = Nstr;
	for(L = 0; L < N; L++) *str++ = C; WriteStN(Nstr,N);
}

WriteLong(W)
long W;
{
	int M = 79, S = 0; char *str;
	str = Nstr+M; *(str--) = 0;
	if(W < 0) { W = -W; S = 1; }
	do { *(str--) = ((W % 10) + 48); W /= 10; --M; } while((W > 0) && (M > 1));
	if(S == 1) *(str--) = '-';
	WriteStr(++str);
}
WriteInt(N) int N; {	 WriteLong((long)N); }

/*origin 1,1*/
GotoY(L) int L; {	 GX = 4; GY = (L << 3) + 10; }
GotoXY(N,L) int N,L; {	GX = (N << 3) - 4; GY = (L << 3) + 10; }
Cel() { int N; N = (PW - (GX >> 3)); WriteCN(' ',N); GX -= (N << 3); }
Cll(L) int L; {  GotoY(L); WriteCN(' ',PW); GX = 4; }
Cls()
{
	int L;
	YR(); Tstyle = 0; SetAttr(3); SetAttr(5); /*Bold ital wide cls*/
	for(L = TOP; L <= BOT; L++) Cll(L);
	SetAttr(0);
}

char UPcase(C) char C; { if((C < 97) || (C > 122)) {;} else C -= 32; return(C); }

long StoL(str)
char *str;
{
	char C; int L, M = 0; long N = 0;
	L = SetStLen(str);
	if((L > 0) && (*str != 10)) {
		do {
			C = *str++ - 48; M++;
			if((C >= 0) && (C <= 9)) N = (N * 10) + C; else N = 0;
		} while((M < L) && (N != 0));
	}
	return(N);
}

StJoin(str,str2) /*str(LLen) + str2*/
char *str; char *str2;
{
	char C; int E = 0, L, P = 0;
	L = LLen; str += L; L--;
	do { C = *(str2++); *str++ = C; ++L; if((C == 0) || (L >= MaxStLen)) E = 1; } while(E == 0);
	*str = 0; LLen = L;
}

StCat(str,str2) /*str + str2 sets LLen*/
char *str; char *str2;
{	LLen = SetStLen(str); StJoin(str,str2); }

StCopy(str,str2) /*str << str2 sets LLen */
char *str; char *str2;
{	LLen = 0; StJoin(str,str2); }
/* -	-	SCREEN	-	-	*/

RET()
{
   char C; GotoY(8); GK(); WriteStN((char *)"Press Return",9); KR(); C = GetKey();
}

Start()
{
	int C; byte B; char D; int N;
	RET();
   GotoY(10); StCopy(TLine1,(char *)"first");
	WriteStr(TLine1); WriteCh('#'); WriteInt(SetStLen(TLine1)); WriteCh('#');
	GotoY(11); YR();
   StJoin(TLine1,(char *)"second");
	WriteStr(TLine1); WriteCh('#'); WriteInt(SetStLen(TLine1)); WriteCh('#');
	RET();
	L1(); for(N = 0; N < BOT; N++) { WriteInt(N); GY += 8; }
	RET(); Cls();
   B = 0; --B; Cll(1); WriteStN((char *)"byte",4); Nl();
	for(N = 0; N < 257; N++) { ++B; WriteInt((int )B); if(GX > 580) { Nl(); } }
	RET(); Cls();
   D = 0; --D; Cll(1); WriteStN((char *)"char",4); Nl();
	for(N = 0; N < 257; N++) { ++D; WriteInt((int )D); if(GX > 580) { Nl(); } }
	RET(); Cls();
   C = 0; --C; Cll(1); WriteStN((char *)"int ",4); Nl();
	for(N = 0; N < 257; N++) { ++C; WriteInt(C); if(GX > 580) { Nl(); } }
	RET();
}
/* -	-	C101	-	-	*/

 int error;
main(argc,argv)
int argc;
char *argv[];
{
	long d;
	fflush(stdin); fflush(stdout);
   if((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L)) != 0L)
	{
      if((GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0)) != 0L)
		{
			if((txwin = (struct Window *)OpenWindow(&frame)) != 0L)
			{
				txrp = (struct RastPort *)txwin->RPort;
            if((xport = (struct MsgPort *)CreatePort("conread",0)) != 0L)
				{
					if((iport = (struct IOStdReq *)CreateStdIO(xport)) != 0L)
					{
                  if((d = OpenDevice("console.device",-1,iport,0)) == 0)
						{
							ConsoleDevice = iport->io_Device;

							/* At last the keyboard and WBscreen are accessible*/

								Start();

							if((d = CheckIO(iport)) == FALSE) AbortIO(iport);
						} else error = 32;
						DeleteStdIO(iport);
					} else error = 16;
					DeletePort(xport);
				} else error = 8;
				CloseWindow(txwin);
			} else error = 4;
			CloseLibrary(GfxBase);
		} else error = 2;
		CloseLibrary(IntuitionBase);
	} else error = 1;
	if(error)
	{
	switch(error)
	{
   case  1: fputs("intui",stderr);  break;
   case  2: fputs("gfx",stderr);    break;
   case  4: fputs("window",stderr); break;
   case  8: fputs("msgport",stderr);break;
   case 16: fputs("iport",stderr);  break;
   case 32: fputs("condev",stderr); break;
   case 64: fputs("ram",stderr);    break;
	}
   fputs(" error",stderr);
	}
}
/* -	-	C101	-	-	*/
