#include "defs.h"

Prototype FO(WORD ac,BYTE *av[]);


FO(ac,av)
WORD ac;
BYTE *av[];
{
WORD TotalBlocks=0,i=0,j=0,Perr=0;
LONG k=0;
BYTE argn=0,val;
BYTE FileErrName[]={"t:FO2_FileErr0"};

	DiskBUSY(av[0],1);
	strncpy(drivebusy,av[0],5);
	while (isInserted(sourceDrive))
	{
		putIText("Insert Source please !              ");
		Delay(10);
	}

	FPointer=0;
	VarAdr->inCHIP=(LONG *)AllocMem(512L,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC);
	VarAdr->BuffBitMap=(LONG *)AllocMem(512L,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC);
	Read_WriteB(R,sourceDrive,BBM,880L); /* charge le Root */
	/* on trouve BitMap */
	VarAdr->BitMap=(WORD)((struct RootB *)(VarAdr->BuffBitMap))->BitMapTable[0]; 
#ifdef DEBUG
	printf("n ° du bloc BitMap :%d\n",VarAdr->BitMap);
#endif
	/* on le charge */
	Read_WriteB(R,sourceDrive,BBM,VarAdr->BitMap);
	/* on réserve le buffer de track et on charge le bootBlock oû il faut */
	BT=(LONG *)AllocMem(11*512L,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC);
	Read_WriteB(R,sourceDrive,BT,0L);
	Read_WriteB(R,sourceDrive,BT+128L,1L);
	if (BT[0]==ID_FFS_DISK) FFS=1; else FFS=0;
	if (FFS) puts ("FFS enclenché");
#ifdef DEBUG
	printf("Adr du Buff de Track : %p\n",BT);
#endif
	VarAdr->Empty=(LONG *)AllocMem(512L,MEMF_CLEAR|MEMF_PUBLIC);
	if (VarAdr->Empty==0) Perr++;
	VarAdr->TotalBlocks=HowBlockUsed(BBM);
#ifdef DEBUG
	printf("Total des Blocks Alloués : %d\n",VarAdr->TotalBlocks);
#endif
	VarAdr->TableMem=(LONG *)AllocMem(VarAdr->TotalBlocks*4+4,MEMF_CLEAR|MEMF_PUBLIC);
#ifdef DEBUG
	printf("Adr de TableMem : %p\n",&VarAdr->TableMem);
#endif
	j=0;
	for (i=0;i!=VarAdr->TotalBlocks;i++)
	{
	k=AllocMem(512L,MEMF_CLEAR|MEMF_PUBLIC);
	if (k==0 || (AvailMem(MEMF_PUBLIC) < 20480)) {Perr=103; break;}
	(*VarAdr->TableMem)[j++]=k;
	}
	(*VarAdr->TableMem)[j]=0L;
	VarAdr->EndTMem=j-1;
	
	if (Perr)
	{
		putIText("Sorry, No Memory for that disk      ");
		MtrOff(sourceDrive);
		RendMem();
		return(0);
	}
	/*	On initialise la strucure DiskList */
	dsklist=(struct SinitB*)AllocMem(sizeof(struct SinitB),MEMF_CLEAR|MEMF_PUBLIC);
	dsklist->dl_Bloc=-9;
	((struct SinitB*)dsklist)->dl_Type=0;

	/*	Avec un bloc initial qui ne sert à rien mais est bien pratique */

	if (LoadBinMem()) {Aborted(); return(0);}
	MtrOff(sourceDrive);
	if (CHECK)
	{
		putIText("Checking Dos Structure of disk      ");
		FPointer=fopen(FileErrName,"w");
		if (!FPointer) putIText("Can't open t:FO2_FileErr0           ");
		if (CheckDosStruct()==2) {Aborted(); return(0);}
		if (FPointer) {fclose(FPointer); FPointer=0;}
		if (!err)
		{
			putIText("No Error in Dos Structure           ");
			remove(FileErrName);
		}
		else {putIText("ERRORS on disk !! see t:FO2_FileErr "); return(0);}
		Delay(20);
	}
	MtrOff(sourceDrive);
	putIText("Now I optimize ...                  ");
	Optimize();
	BitMap();
	ChangeBlocks();
	do
	{
		if (MemToDisk()==2) {Aborted(); return(0);}
		if (MULTI)
		if (val=WaitChangeDisk(destDrive,-1)==2) {Aborted(); return(0);}
	}
	while (MULTI);

	MtrOff(destDrive);
	putIText("Fast Optimization done.             ");
	DiskBUSY(drivebusy,0);
	RendMem();
            
	return(0);
}
