/************
 *
 * 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,*pnr;

	for (n = 0, z = actualEditor->zlinesptr,
			pnr = actualEditor->zlinesnr;
			n <= actualEditor->wch; n++, z++, pnr++)
		printf("Zline %d an Adresse %6lx.\n",*pnr,*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 > ptr -> 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(" Unknown 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 ( !l || (s[l-1] != ' '))
		{
			s[l++] = 13;
			s[l] = 0;
		}
		if (z = newZline(l))
		{
			strncpy(z+1,s,l);
			AddTail(&(actualEditor->zlines),z);
			actualEditor->num_lines++;
		}
		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);
		actualEditor->num_lines--;
	}
}

void init_zlinesptr()
{
	register struct Zline *z,**zptr;
	register UWORD n,*pnr,fold = 0;
	UWORD znr;

	for (z = actualEditor->zlines.head; z->succ; z = z->succ)
	{
		z->flags = ((z->flags & ~ZLF_FOLD) | (fold & ZLF_FOLD));
		if (z->len >= 8)
		{
			if ((*((ULONG *)(z+1))=='/*#F') && (*((ULONG *)(z+1)+1)=='OLD:'))
			{
				fold++;
				z->flags |= ZLF_FSE;
			}
			if ((*((ULONG *)(z+1))=='/*#E') && (*((ULONG *)(z+1)+1)=='NDFD'))
			{
				fold--;
				z->flags |= ZLF_FSE;
			}
		}
	}

	for (n = 0, z = actualEditor->zlines.head,
					zptr = actualEditor->zlinesptr,
					pnr = actualEditor->zlinesnr, znr = 1;
					n < MAXHEIGHT; n++)
	{
		*zptr++	= z;
		*pnr++	= znr;
		z = nextLine(z,&znr);
	}
}

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(">");
	}

	printAll();
}
