#include "defs.h"

Prototype Organising(LONG	*buff1,struct DiskList *dlist,LONG	n);
Prototype Datas(LONG	*buff1,LONG	n,struct DiskList *dlist);
Prototype Preparing(LONG structsize,struct DiskList *adr);
Prototype Length(struct DiskList *dlist);
Prototype struct DiskList *whereB(WORD bloc);
Prototype isinfo(BYTE *buff);
Prototype Optimize();
Prototype Inc(WORD *datafree);
Prototype Nextdfree(WORD *datafree);
Prototype ChangeBlocks();


Organising(buff1,dlist,n)
LONG	*buff1;
struct DiskList *dlist;
LONG	n;

{
	switch (*buff1)
	{
		case 2L :
		{
			switch (*(buff1+127))
			{

				case 1L: /* RootBlock */
				{
					dlist=(struct DiskList *)Preparing(sizeof(struct SRootB),dsklist);
					dlist->dl_NextB=0;
					dlist->dl_Bloc=n;
					dlist->dl_Bloc2=n;
					dlist->dl_Data=0;
					dlist->dl_Type=3;
					dlist->dl_types.dl_type3.reserved1=0;
					dlist->dl_AdrB=buff1;
					break;
				}

				case -3L: /* File Header Block */
				{
					dlist=(struct DiskList *)Preparing(sizeof(struct SFileHderB),dsklist);
					dlist->dl_NextB=0;
					dlist->dl_Bloc=n;
					dlist->dl_Bloc2=0;
					dlist->dl_Type=-1;
					dlist->dl_types.dl_type1.dl_Parent=((struct FileHeaderB*)buff1)->ParentDir;
					dlist->dl_types.dl_type1.dl_NextHash=((struct FileHeaderB*)buff1)->NextHash;
					dlist->dl_types.dl_type1.dl_Extension=((struct FileHeaderB*)buff1)->Extension;
					dlist->dl_AdrB=buff1;
					dlist->dl_Data=isinfo(buff1);
					break;
				}

				case 2L: /* User Directory Block */
				{
					dlist=(struct DiskList *)Preparing(sizeof(struct SUserDirB),dsklist);
					dlist->dl_NextB=0;
					dlist->dl_Bloc=n;
					dlist->dl_Bloc2=0;
					dlist->dl_Type=4;
					dlist->dl_types.dl_type4.dl_Parent=((struct UserDirB*)buff1)->ParentDir;
					dlist->dl_types.dl_type4.dl_NextHash=((struct UserDirB*)buff1)->NextHash;
					dlist->dl_AdrB=buff1;
					dlist->dl_Data=isinfo(buff1);
					break;
				}

				default :
				{
					if (FFS) { Datas(buff1,n,dlist); break;} else
					{
						dlist=(struct DiskList *)Preparing(sizeof(struct SUnknownB),dsklist);
						dlist->dl_NextB=0;
						dlist->dl_Bloc=n;
						dlist->dl_Bloc2=n;
						dlist->dl_Data=0;
						dlist->dl_Type=-2;
						dlist->dl_AdrB=buff1; 
						break;
					}
				}
			}
			break;
		}

		case 16L: if (*(buff1+127)==-3) /* FileList Block */
		{
			dlist=(struct DiskList *)Preparing(sizeof(struct SFileListB),dsklist);
			dlist->dl_NextB=0;
			dlist->dl_Bloc=n;
			dlist->dl_Bloc2=0;
			dlist->dl_Data=0;
			dlist->dl_Type=13;
			dlist->dl_types.dl_type13.dl_FileHeader=((struct FileListB*)buff1)->ParentFH;
			dlist->dl_types.dl_type13.dl_Extension=((struct FileListB*)buff1)->Extension;
			dlist->dl_AdrB=buff1;
			break;
		}

		case 8L: /* Data Block */
		{
			Datas(buff1,n,dlist);
			break;
		}
	
		default :
		{
			if (FFS) {Datas(buff1,n,dlist); break;}
			else
			{
			if (n==VarAdr->BitMap) break;
			dlist=(struct DiskList *)Preparing(sizeof(struct SUnknownB),dsklist);
			dlist->dl_NextB=0;
			dlist->dl_Bloc=n;
			dlist->dl_Bloc2=n;
			dlist->dl_Data=0;
			dlist->dl_Type=-2;
			dlist->dl_AdrB=buff1;
			break;
		}
		}
	}
}

Datas(buff1,n,dlist)
LONG	*buff1;
LONG	n;
struct DiskList *dlist;
{
		dlist=(struct DiskList *)Preparing(sizeof(struct SDataB),dsklist);
		dlist->dl_NextB=0;
		dlist->dl_Bloc=n;
		dlist->dl_Bloc2=0;
		dlist->dl_Data=0;
		dlist->dl_Type=8;
		dlist->dl_types.dl_type8.dl_FileHeader=((struct DataB*)buff1)->HeaderKey;
		dlist->dl_types.dl_type8.dl_NextData=((struct DataB*)buff1)->NextDataBlock;
		dlist->dl_AdrB=buff1;
}

Preparing(structsize,adr)
LONG structsize;
struct DiskList *adr;

{
static struct DiskList *Sadr=0;

	if (Sadr==0 || (INIT & PREPARING) ) 
	{
		Sadr=adr;
		INIT &= ~PREPARING; 
	}
	else adr=Sadr;

	if (adr->dl_NextB==0)
	{
		adr->dl_NextB=(struct DiskList *)AllocMem(structsize,MEMF_PUBLIC);
		if (adr->dl_NextB==0 || (AvailMem(MEMF_PUBLIC) < 20480))
		{
			if (adr->dl_NextB) {FreeMem(adr->dl_NextB,structsize);
				adr->dl_NextB=0;}
			puts("No mem for Preparing()\nFree a few mem an retry");
			exit(0);
		}
		Sadr=adr->dl_NextB;
		return(adr->dl_NextB);
	}
	else return(Preparing(structsize,adr->dl_NextB));
}

Length(dlist)
struct DiskList *dlist;
{
LONG length;
	switch (dlist->dl_Type)
	{
		case -2: length=sizeof(struct SUnknownB); break;
		case 13: length=sizeof(struct SFileListB); break;
		case  8: length=sizeof(struct SDataB); break;
		case  4: length=sizeof(struct SUserDirB); break;
		case  3: length=sizeof(struct SRootB); break;
		case -1: length=sizeof(struct SFileHderB); break;
		case  0: length=sizeof(struct SinitB); break;
		default : length=0; break;
	}
	return(length);	
}

struct DiskList *whereB(bloc)
WORD bloc;
{
struct DiskList *dlist;

	dlist=VarAdr->disklist;
	while (dlist->dl_Bloc!=bloc && dlist!=0) dlist=dlist->dl_NextB;
	return(dlist);
}
isinfo(buff)
BYTE *buff;
{
BYTE name[30],length,n;


	length=buff[108*4];
	strncpy(name,buff+108*4+1,length);
	name[length]=0;
	for (n=length; n>=0 && name[n] != '.';n--);
	if (stricmp(name+n,".info")==0)
	return(1);
	else return(0);
}

Optimize()
{
WORD UDB[100];
WORD i=1;

	UDB[0]=880;
	UDB[1]=0;
	/*printf("UDB[0] : %d\n",UDB[0]);*/
	while (UDB[0])
	{if (!arrange(UDB,&i)) break;} 

}


Inc(datafree)
WORD *datafree;
{
#ifdef DEBUG
/*	 printf("in Inc() datafree: %d\n",*datafree);*/
#endif
	if (*datafree<879) (*datafree)++; /* Ainsi 879 est donné mais pas 880 */
	else
	{
		if (*datafree==879) *datafree=1759;
		else (*datafree)--;
	}
	return(*datafree);
}

Nextdfree(datafree)
WORD *datafree;
{
	if (*datafree<879) return(*datafree+1); 
	else
	{
		if ((*datafree+1)==880) return(1759);
		else return(*datafree-1);
	}
}

ChangeBlocks()
{
struct DiskList *dlist;

	dlist=(struct DiskList *)VarAdr->disklist;

	while (dlist) 
	{
		dlist->dl_Bloc=dlist->dl_Bloc2;
		dlist=dlist->dl_NextB;
	}

}
