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

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

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

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

struct Zline *newZline(),*nextLine();
UBYTE *gets(),getchar();
UWORD strlen();
void strncpy(), AddTail(),deleteZline(),printAll();

/*********************
 *
 * External variables:
 *
 *********************/ 

extern struct Editor *actualEditor;

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

void print()
{
	register struct Zline **z;
	register UWORD n;

	for (n = 0, z = actualEditor->zlinesptr; n <= actualEditor->wch;
			n++,z++)
		printf("Zline %d an Adresse %6lx.\n",n,*z);
}

void print_blocks()
{
	register struct Memoryblock *blk;

	printf("Block list:\n\n");
	for (blk = actualEditor->block.head; blk->succ; blk = blk->succ)
		printf("Block %8lx, Lenght = %ld, Free = %ld\n",
					blk,blk->length,blk->free);

	printf("\n");
}

void print_memory()
{
	struct Memoryblock *blk;
	register UBYTE *ptr,*end;
	register struct Zline *z;
	register struct Memorysection *st;
	struct Zline *fz;
	struct Memorysection *fst;

	printf("Memory construction:\n");
	for (blk = actualEditor->block.head; blk->succ; blk = blk->succ)
	{
		printf("\nBlock %8lx, Lenght = %ld, Free = %ld\n",
					blk,blk->length,blk->free);

		ptr = (UBYTE *)(blk + 1);
		end = ptr + blk->length;
		while (ptr < end)
		{
			fz = NULL;
			fst = NULL;

			/* search for the line that is next to the ptr: */
			for (z = actualEditor->zlines.head; z->succ; z = z->succ)
				if ((z >= ptr) && (z < end))
					if (z < ((fz)? fz : (struct Zline *)end))
						fz = z;

			/* No line found or line > prt -> search memory section */
			if ((fz > ptr) || !fz)
			{
				for (st = blk->freeliste.head; st->succ; st = st->succ)
					if ((st >= ptr) && (st < end))
						if (st < ((fst)? fst : (struct Memorysection *)end))
							fst = st;

				/* In case memory section > ptr -> error!!!!! */
				if ((fst > ptr) || !fst)
				{
					printf(" Unused memory section!\n");

					if (fz)
						if (fst)
							if (fst < fz)
								ptr = (UBYTE *)fst;
							else
								ptr = (UBYTE *)fz;
						else
							ptr = (UBYTE *)fz;
					else
						if (fst)
							ptr = (UBYTE *)fst;
						else
							break;
				}
				else
				{
					/* Memorysection: */
					printf("Memory section (%d)\n",fst->len);

					ptr += sizeof(struct Memorysection) + fst->len;
				}
			}
			else
			{
				/* Zline */
				printf("Line: %s\n",fz+1);

				ptr += sizeof(struct Zline) + EVENLEN(fz->len);
			}

		}
	}

	printf("\n");
}

void input()
{
	UBYTE s[80];
	register struct Zline *z;
	register UWORD l;

	printf("New Line: ");
	if (gets(s))
	{
		l = strlen(s);
		if (s[l-1] != ' ')
		{
			s[l++] = 13;
			s[l] = 0;
		}
		if (z = newZline(l))
		{
			strncpy(z+1,s,l);
			AddTail(&(actualEditor->zlines),z);
		}
		else
			printf("Error in new line!!!\n");
	}
	else
		printf("Error with gets!!!\n");
}

void delete_line()
{
	register struct Zline *z;
	UWORD nr;

	printf("Number of line that should be erased: [0..n] ");
	scanf("%d",&nr);
	while (getchar() != 10) ;		/* read one CR! */

	for (z = actualEditor->zlines.head; z->succ && nr; z = z->succ, nr--);

	if (z->succ)
	{
		printf("Delete: %s\n",z+1);
		deleteZline(z);
	}
}

void init_zlinesptr()
{
	register struct Zline *z,**zptr;
	register UWORD n;

	for (n = 0, z = (struct Zline *) &(actualEditor->zlines.head),
					zptr = actualEditor->zlinesptr; n < MAXHEIGHT; n++)
		*zptr++ = (z = nextLine(z));
}

void Test()
{
	register UBYTE c;

	printf(">");
	while ((c = getchar()) != 27)
	{
		while (getchar() != 10) ;		/* read one CR! */
		switch (c)
		{
			case 'a':
				input();
				init_zlinesptr();
				break;
			case 'p':
				print();
				printAll();
				break;
			case 'b':
				print_blocks();
				break;
			case 's':
				print_memory();
				break;
			case 'd':
				delete_line();
				init_zlinesptr();
				break;
		}

		printf(">");
	}
}
