/*
    ####             #    #     # #
    #   #            #    #       #          The FreeWare C library for
    #   #  ##   ###  #  # #     # ###             RISC OS machines
    #   # #  # #     # #  #     # #  #   ___________________________________
    #   # ####  ###  ##   #     # #  #
    #   # #        # # #  #     # #  #    Please refer to the accompanying
    ####   ### ####  #  # ##### # ###    documentation for conditions of use
    ________________________________________________________________________

    File:    Import.Import.c
    Author:  Copyright  1995 Julian Smith
    Version: 1.01 (14 Nov 1995)
    Purpose: File import handling.
    History: 1.00 (17 Jan 1995)
             1.01 (14 Nov 1995) JS Made SDLS compatible.
*/


#include <stdlib.h>
#include <string.h>

#include "Desk.WimpSWIs.h"
#include "Desk.Error.h"
#include "Desk.Event.h"
#include "Desk.File.h"
#include "Desk.DeskMem.h"

#include "Desk.Import.h"




typedef struct	{
	Desk_import_fileimporter	fn;		/* Function which loads the file.	*/
	Desk_import_ramimporter      ramfn;		/* Function which ram-transfers (NIY)	*/
	void			*reference;	/* Reference to pass to 'fn'.		*/
	unsigned int		ourref;		/* wimp message 'ourref' for the last	*/
						/* message that we have sent.		*/
	}
	Desk_import_block;




Desk_SDLS_PtrFn(
	static,
	Desk_bool,
	Desk_Import__DataLoadHandler( Desk_event_pollblock *event, void *reference)
	)
/*static Desk_bool	Desk_Import__DataLoadHandler( Desk_event_pollblock *event, void *reference)*/
/* cc warns about extern ... not declared in header in SDLS compiles	*/
{
Desk_import_block	*import	= (Desk_import_block *) reference;


if ( event->data.message.header.action != Desk_message_DATALOAD)	return Desk_bool_FALSE;

if ( import->ourref && ( event->data.message.header.yourref != import->ourref))	return Desk_bool_FALSE;
	/* 
	import->ourref != 0 means that we have just received a 
	Desk_message_DATASAVE and replied with a Desk_message_DATASAVEACK, so 
	we are expecting a Desk_messsage_DATALOAD which is a reply to our 
	Desk_message_DATASAVEACK. This Desk_messsage_DATALOAD doesn't have 
	a matching 'yourref' so we return.
	*/

import->fn( &event->data.message.data.dataload, import->reference);
	/* Call the function which does the actual loading.	*/


/* Now finish the file-transfer protocol...	*/

if ( import->ourref)	{
	/* 
	This DATALOAD is a bona-fide response to our previous 
	Desk_message_DATASAVEACK, so the file will be <Wimp$Scrap>. Hence
	we should delete <Wimp$Scrap> 'cos we've just loaded it.
	*/

	import->ourref = 0;
		/* Clear things ready for the next Desk_message_DATALOAD	*/
	
	if ( strcmp( event->data.message.data.dataload.filename, "<Wimp$Scrap>"))	{
		Desk_Error_Report( 
			0, 
			"Scrapfile transfer, but filename is '%s' instead of "
			"'<Wimp$Scrap>' - not deleting file", 
			event->data.message.data.dataload.filename
			);
		}
		
	else Desk_File_Delete( "<Wimp$Scrap>");
	}

/* Tell whoever is giving us the file that we have loaded it.	*/
	{
	Desk_message_block	reply	= event->data.message;
	
	reply.header.action	= Desk_message_DATALOADACK;
	reply.header.yourref	= event->data.message.header.myref;
	
	Desk_Wimp_SendMessage( Desk_event_SEND, &reply, event->data.message.header.sender, 0);
	}

return Desk_bool_TRUE;
}





Desk_SDLS_PtrFn(
	static,
	Desk_bool,
	Desk_Import__DataSaveHandler( Desk_event_pollblock *event, void *reference)
	)
/*static Desk_bool	Desk_Import__DataSaveHandler( Desk_event_pollblock *event, void *reference)*/
/* cc warns about extern ... not declared in header in SDLS compiles	*/
{
Desk_import_block	*import	= (Desk_import_block *) reference;
Desk_message_block	reply;


if ( event->data.message.header.action != Desk_message_DATASAVE)	return Desk_bool_FALSE;

/* 
We need to tell the sender of this message)DATASAVE to do the transfer
via  <Wimp$Scrap>. We also tell them that we aren't the filer, so their
file  won't be 'safe' after we've loaded it.
*/

reply				= event->data.message;
reply.header.action		= Desk_message_DATASAVEACK;
reply.header.yourref		= event->data.message.header.myref;
reply.data.datasaveack.estsize	= -1;	/* = Unsafe	*/

strcpy( reply.data.datasaveack.filename, "<Wimp$Scrap>");
	/* Should really check that <Wimp$Scrap> exists.	*/

reply.header.size = sizeof( Desk_message_block);
	/* 
	We've changed the message size by strcpy-ing into ...filename.
	Should really calculate the correct length here, not just use the
	maximum possible.
	*/

Desk_Wimp_SendMessage( Desk_event_SEND, &reply, reply.header.sender, 0);

import->ourref	= reply.header.myref;
	/* 
	So we can check that a subsequent Desk_message_DATALOAD is a response to
	this.
	*/

return Desk_bool_TRUE;
}






void	Desk_Import_RegisterFileLoader( 
		Desk_import_fileimporter	fn, 
		Desk_import_ramimporter	ramfn,
		Desk_window_handle		window, 
		Desk_icon_handle		icon, 
		void			*reference
		)
{
Desk_import_block	*import;

import = Desk_DeskMem_Malloc( sizeof( Desk_import_block));

import->fn		= fn;
import->ramfn		= ramfn;
import->reference	= reference;
import->ourref		= 0;	/* Only non-zero for DATASAVE transfer.	*/

Desk_Event_Claim( Desk_event_USERMESSAGE, window, icon, 		Desk_SDLS_dllEntry( Desk_Import__DataLoadHandler), import);
Desk_Event_Claim( Desk_event_USERMESSAGERECORDED, window, icon, 	Desk_SDLS_dllEntry( Desk_Import__DataLoadHandler), import);
Desk_Event_Claim( Desk_event_USERMESSAGE, window, icon, 		Desk_SDLS_dllEntry( Desk_Import__DataSaveHandler), import);
Desk_Event_Claim( Desk_event_USERMESSAGERECORDED, window, icon, 	Desk_SDLS_dllEntry( Desk_Import__DataSaveHandler), import);

return;

}

