/************
 *
 * Includes:
 *
 ************/

#include <exec/types.h>
#include <intuition/intuition.h>
#include "src/Editor.h"

/***********
 *
 * Defines:
 *
 ***********/

#define REV 33L
#define MAXINPUTLEN 128L

/**********************
 *
 * External Functions:
 *
 **********************/

void Test(),print();

struct Library *OpenLibrary();
struct Window *OpenWindow();
void CloseLibrary(),NewList(),AddTail(),CloseWindow(),free();
void DeletePort(),ModifyIDCMP(),ReplyMsg(),freeMemoryblock();
struct Editor *malloc(),*RemHead();
struct MsgPort *CreatePort();
struct IntuiMessage *GetMsg();
ULONG Wait(),OpenDevice();
SHORT RawKeyConvert();

/*********************
 *
 * Global Variables:
 *
 *********************/ 

struct Library *IntuitionBase = NULL, *GfxBase = NULL, *DosBase = NULL;
struct Device *ConsoleDevice = NULL;

struct EList editorList;
struct Editor *actualEditor;

struct NewWindow newEdWindow =
{
	100,40,440,156,
	AUTOFRONTPEN,AUTOBACKPEN,
	REFRESHWINDOW | MOUSEBUTTONS | RAWKEY | CLOSEWINDOW,
	WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SIZEBBOTTOM
	| SIMPLE_REFRESH | ACTIVATE,
	NULL,NULL,
	(UBYTE *)"Editor",
	NULL,NULL,
	100,50,640,200,
	WBENCHSCREEN
};

struct MsgPort *edUserPort = NULL;

struct IOStdReq ioStdReq;

UBYTE inputBuffer[MAXINPUTLEN];
UWORD inputLen = 0;

struct InputEvent inputEvent =
{
	0,
	IECLASS_RAWKEY,0,
	0,0
};

/***************
 *					*
 * Functions: *
 *					*
 ***************/

/***********************************
 *
 * OpenEditor()
 *
 * Open Editor window and
 * initalize Editor structure
 *
 * Returns pointer to Editor structure
 * or is zero in case of an error
 *
 ***********************************/

struct Editor *OpenEditor()
{
	register struct Editor *ed = NULL;
	register struct Window *wd;
	register ULONG flags;

	/* IDCMPFlags saved, sets it to zero in structure
		=> use your own UserPort! */
	flags = newEdWindow.IDCMPFlags;
	newEdWindow.IDCMPFlags = NULL;

	/* Memory for editor structure allocated: */
	if (ed = malloc(sizeof(struct Editor)))
		/* Window open: */
		if (wd = OpenWindow(&newEdWindow))
		{
			ed->window = wd;

			/* UserPort established: */
			wd->UserPort = edUserPort;
			ModifyIDCMP(wd,flags);

			/* Parameter initialization: */
			NewList(&(ed->block));
			NewList(&(ed->zlines));
			ed->num_lines = 0;
			ed->actual = NULL;
			ed->top = NULL;
			ed->toppos = 0;
			ed->xpos = 1;
			ed->ypos = 1;
			ed->changed = 0;
			ed->insert = 1;
		}
		else
		{
			free(ed);
			ed = NULL;
		}

	newEdWindow.IDCMPFlags = flags;
	return (ed);
}

/***************************
 *
 * CloseEditor(ed)
 *
 * Close editor window.
 *
 * ed ^ Editor structure.
 *
 ***************************/

void CloseEditor(ed)
struct Editor	 *ed;
{
	register struct Memoryblock *blk;

	/* Free first memory block: */
	while (blk = (struct Memoryblock *)RemHead(&(ed->block)))
		freeMemoryblock(blk);

	/* Then Close window: */
	ed->window->UserPort = NULL;
	CloseWindow(ed->window);
	free(ed);
}

/*****************
 *
 * Main program:
 *
 *****************/

main()
{
	register struct Editor *ed;
	BOOL running = TRUE;
	register struct IntuiMessage *imsg;
	ULONG signal,class;
	UWORD code,qualifier;
	APTR iaddress;
	register UWORD n = 1;
	SHORT l;

	/* Libraries open: */
	if ( !(IntuitionBase = OpenLibrary("intuition.library",REV)))
		goto Ende;
	if ( !(GfxBase = OpenLibrary("graphics.library",REV)))
		goto Ende;
	if ( !(DosBase = OpenLibrary("dos.library",REV)))
		goto Ende;
	if ( !(OpenDevice("console.device",-1L,&ioStdReq,0L)))
		ConsoleDevice = ioStdReq.io_Device;
	else
		goto Ende;

	/* UserPort open */
	if (! (edUserPort = CreatePort(NULL,0L))) goto Ende;

	/* Editor list initialization: */
	NewList(&editorList);

	/* Open first editor window: */
	if (ed = OpenEditor())
	{
		AddTail(&editorList,ed);
		actualEditor = ed;
	}
	else
		goto Ende;

	Test();

	do
	{
		signal = Wait(1L << edUserPort->mp_SigBit);

		while (imsg = GetMsg(edUserPort))
		{
			class			= imsg->Class;
			code			= imsg->Code;
			qualifier	= imsg->Qualifier;
			iaddress		= imsg->IAddress;

			ReplyMsg(imsg);

			/* Event processing: */
			switch (class)
			{
				case RAWKEY:
					if (! (code & IECODE_UP_PREFIX))
					{
						inputEvent.ie_Code		= code;
						inputEvent.ie_Qualifier = qualifier;
						if ((l = RawKeyConvert(
									&inputEvent,inputBuffer,MAXINPUTLEN,NULL)
									) >= 0)
						{
							inputBuffer[l] = 0;
							printf("%3d> Lenght = %d: ",n++,l);
							for (l = 0; inputBuffer[l]; l++)
								printf("%2x",(UWORD)inputBuffer[l]);
							if (inputBuffer[0] >= 32 && inputBuffer[0] <= 127)
								printf(" %s",inputBuffer);
							printf("\n");
						}
					}
					break;

				case CLOSEWINDOW:
					running = FALSE;
					break;

				default:
					printf("Not a processable event: %lx\n",class);

			} /* of case */
		} /* of while (GetMsg()) */
	} while (running);

Ende:
	/* Close all editor windows: */
	while (ed = RemHead(&editorList))
		CloseEditor(ed);

	/* Close UserPort: */
	if (edUserPort) DeletePort(edUserPort);

	/* Close Libraries: */
	if (DosBase) CloseLibrary(DosBase);
	if (GfxBase) CloseLibrary(GfxBase);
	if (IntuitionBase) CloseLibrary(IntuitionBase);
}
