/*
 * ----------------------------------------------------------------------------------------------
 *		JAGUAR TOOLBOX APPLICATION PROGRAM INTERFACE
 *		FOR ALL TOS ATARI AND COMPATIBLE
 *
 *	File:		DiskJag.c
 *	Author:		FAVARD LAURENT, FunShip(c)
 *	Date:		25 March 1998
 *	Release:	28 September 1998
 *
 *	VERSION : 1.0
 *
 * ----------------------------------------------------------------------------------------------
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <tos.h>
#include <aes.h>

#include	<JToolBox.h>
#include	"toolsdef.h"

/* ----------------------------------------------------------------------------------------------*/
int JagToDisk(char *chFileName, TJagMemDesc *JagMem)
/*
	Perform a download from the jaguar memory directly to a file.
*/
{
	char			*L_chBuffer;
	unsigned long	L_lCount, L_lSizeAllocate;
	int				L_inFichier;

	/*	First - try to allocate a buffer to get all datas to download	*/
	L_lSizeAllocate	=	JagMem->Lenght;
	L_chBuffer	=	malloc( L_lSizeAllocate );

	if( L_chBuffer == NULL )
	{
		L_lSizeAllocate	=	JagMem->Lenght / 2;
		while( (L_chBuffer == NULL) && (L_lSizeAllocate > MINIMAL_BUFFER))
		{
			L_lSizeAllocate	=	L_lSizeAllocate / 2;
			L_chBuffer	=	malloc( L_lSizeAllocate );
		}

		if( L_chBuffer == NULL )
		{
			form_error(3);
			return	FALSE;
		}
	}

	/*	Second - Download datas */
	L_inFichier	=	creat( chFileName );

	if( L_inFichier < 0 )
	{
		form_error(2);
		return	FALSE;			
	}

	L_lCount	=	JagMem->Lenght;	
	while( L_lCount > 0 )
	{
		JagMem->Lenght			=	( L_lCount >= L_lSizeAllocate ) ? L_lSizeAllocate :  L_lCount;

		MemoryGet( L_chBuffer, JagMem );
		write( L_inFichier, (void *)L_chBuffer, (size_t)JagMem->Lenght);
 
		/*	Decrement count to receive and increment next jaguar location address */
		L_lCount				-=	(unsigned long)JagMem->Lenght;
		JagMem->StartAddress	=	(void *)((unsigned long)JagMem->StartAddress + (unsigned long)JagMem->Lenght);
	}	

	free(L_chBuffer);
	close(L_inFichier);
	return	TRUE;		
}

/* ----------------------------------------------------------------------------------------------*/
int DiskToJag(	char *PathName, unsigned long OffsetFromStart,
				TJagMemDesc		*JagMemoire,
				void (*UserFonctionJauge)(unsigned long CountToDo, unsigned long CountPerfomed))
/*
	Send any binaries file to the jaguar.
*/
{
	int					L_File, NoErreur;
	char				*L_chBuffer, *L_PtrCourant;
	size_t				L_CountRead;
	DTA					*L_Dta;
	unsigned long		L_lCountToDo, L_lCountPerfomed, L_lSizeAllocate;
	TJagMemDesc			JagMem;
	
	graf_mouse(BUSYBEE, NULL);
	L_File	=	open(PathName, O_RDONLY);

	Fsfirst(PathName,0);																	/* Pour fixer une zone DTA du fichier */
	L_Dta		=	Fgetdta();																/* Lecture de la DTA */

	L_lCountToDo		=	L_Dta->d_length;
	L_lCountPerfomed	=	0L;

	if( L_Dta->d_length == 0L)																	/* Taille fichier = 0 octets !! */
	{
		graf_mouse(ARROW, NULL);
		form_alert(1, "[2][ this file is empty ][ Cancel ]");
		return FALSE;		
	}
	
	if(L_File < 0)
	{
		graf_mouse(ARROW, NULL);
		form_error(2);
 		return FALSE;
	}
	
	/*	First - try to allocate a buffer to get all datas to download	*/
	L_lSizeAllocate	=	SIZE_BUFFER;
	L_chBuffer		=	malloc( L_lSizeAllocate );
	
	if( L_chBuffer == NULL )
	{
		L_lSizeAllocate	=	L_lSizeAllocate / 2;
		while( (L_chBuffer == NULL) && (L_lSizeAllocate > MINIMAL_BUFFER))
		{
			L_lSizeAllocate	=	L_lSizeAllocate / 2;	
			L_chBuffer	=	malloc( L_lSizeAllocate );
		}

		if( L_chBuffer == NULL )
		{
			form_error(3);
			return	FALSE;
		}
	}
		
	L_CountRead		=	read(L_File, L_chBuffer, L_lSizeAllocate);
	L_PtrCourant	= (char *)((unsigned long)L_chBuffer + OffsetFromStart);

	NoErreur	=	TRUE;
	JagMem.StartAddress	=	(void *)JagMemoire->StartAddress;
	JagMem.Lenght			=	L_CountRead - OffsetFromStart;
	while( L_CountRead > (size_t)0 && NoErreur)
	{	
		L_lCountPerfomed	+=	( L_CountRead / 2 );
		(*UserFonctionJauge)(L_lCountToDo, L_lCountPerfomed);

		JagMem.Lenght	=	L_CountRead - OffsetFromStart;
		if( !MemorySend(L_PtrCourant, &JagMem) )
		{
			form_alert(1, "[2][ error while transfer ][ Cancel ]");
			NoErreur	=	FALSE;
		}
		else
		{
			L_lCountPerfomed	+=	( L_CountRead / 2 );
			(*UserFonctionJauge)(L_lCountToDo, L_lCountPerfomed);

			L_CountRead			=	read(L_File, L_chBuffer, L_lSizeAllocate);
			L_PtrCourant		=	L_chBuffer;
			JagMem.StartAddress	=	(void *)((unsigned long)JagMem.StartAddress + JagMem.Lenght);		
			JagMem.Lenght		=	L_CountRead;
		}
	}
	close(L_File);
	free(L_chBuffer);
 	graf_mouse(ARROW, NULL);

	return TRUE;
}
