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

#include "swis.h"

#include "Desk.Event.h"
#include "Desk.WimpSWIs.h"
#include "Desk.Icon.h"
#include "Desk.Keycodes.h"
#include "Desk.Error2.h"
#include "Desk.Str.h"
#include "Desk.File.h"
#include "Desk.DeskMem.h"
#include "Desk.Debug.h"
#include "Desk.Save2.h"







static void CleanIconText(Desk_window_handle window, Desk_icon_handle icon)
/* used to clean up writable-icon text - these seem to be
 * terminated by '\n', which is no use to <string.h> functions.
 */
	{
	Desk_icon_block iconblock;
	Desk_Wimp_GetIconState( window, icon, &iconblock);
	Desk_Str_MakeASCIIZ( iconblock.data.indirecttext.buffer, iconblock.data.indirecttext.bufflen-1);
	}


static void	OkFn( Desk_dialog2_block* dialog2)
	{
	Desk_icon_block		iconblock;
	Desk_save2_block	*save2 = (Desk_save2_block*) dialog2->reference;
	char			*filename;
	
	Desk_Wimp_GetIconState( dialog2->window, save2->filenameicon, &iconblock);
	filename = iconblock.data.indirecttext.buffer;
	
	if ( Desk_LeafName(filename) != filename)    {
		/* not just a leafname in icon */
		if ( 0!=save2->filesaver( filename, save2->reference))	{
			// File saveer failed.
			if (save2->resulthandler)	save2->resulthandler( Desk_export_result_FILESAVERFAILED, save2->reference);
			return;
			}
		Desk_File_SetType( filename, save2->filetype);
		if (save2->resulthandler)	save2->resulthandler( Desk_export_result_OK, save2->reference);
		}
	else	{
		//Desk_Error_Report(0, "To save, drag the icon to a directory display");
		}
	}


static Desk_bool	DragHandler( Desk_event_pollblock* event, void* reference)
	{
	Desk_save2_block*	save2 = (Desk_save2_block*) reference;
	Desk_icon_block		iconblock;
	char			*filename;
	Desk_mouse_block	mouse;
	
	Desk_Wimp_GetPointerInfo( &mouse);
	
	Desk_Wimp_GetIconState( save2->dialog2->window, save2->filenameicon, &iconblock);
	filename = iconblock.data.indirecttext.buffer;
	Desk_Export_ExportData( 
		NULL, 
		&mouse, 
		Desk_Str_LeafName( filename),
		save2->filesaver, 
		save2->ramsaver, 
		save2->resulthandler,
		save2->estimatedsize, 
		save2->filetype, 
		save2->reference
		);
	
	if ( save2->dragbutton != Desk_button2_DRAGADJUST)	Desk_Dialog2_CloseDialog( save2->dialog2);
	return Desk_bool_TRUE;
	
	Desk_UNUSED( event);
	
	}

static Desk_bool	ClickHandler( Desk_event_pollblock* event, void* reference)
	{
	Desk_save2_block*	save2 = (Desk_save2_block*) reference;
	if ( !event->data.mouse.button.data.dragselect && !event->data.mouse.button.data.dragadjust)	{
		return Desk_bool_FALSE;
		}
	save2->dragbutton = event->data.mouse.button.value;
	Desk_Icon_StartSolidDrag( save2->dialog2->window, save2->dragsprite);
	Desk_Event_Claim( Desk_event_USERDRAG, Desk_event_ANY, Desk_event_ANY, DragHandler, save2);
	return Desk_bool_TRUE;
	}

static void	OpenFn( Desk_dialog2_block* dialog2)
	{
	Desk_save2_block*	save2 = (Desk_save2_block*) dialog2->reference;
	if ( dialog2->flags.data.type == Desk_dialog2_type_CLOSED)	{
		if ( (int) save2->dragbutton)	Desk_Event_Release( Desk_event_USERDRAG, Desk_event_ANY, Desk_event_ANY, DragHandler, save2);
		}
	else	{
		Desk_Debug_Printf( Desk_error_PLACE "Save2 OpenFn: filetype=%i, icon hand=%i, window=0x%p\n", 
			save2->filetype, save2->dragsprite, (void*) dialog2->window
			);
		
		CleanIconText( dialog2->window, save2->filenameicon);
		Desk_Icon_FileIcon( dialog2->window, save2->dragsprite, save2->filetype);
		
		Desk_Event_Claim( Desk_event_CLICK, dialog2->window, save2->dragsprite, ClickHandler, save2);
		save2->dragbutton = 0;	// So we know we aren't dragging.
		}
	}



Desk_save2_block*	Desk_Save2_Create(
				Desk_dialog2_block*		dialog2,
				Desk_icon_handle		dragsprite,
				Desk_icon_handle		filenameicon,
				Desk_export_filesaver		filesaver,
				Desk_export_ramsaver		ramsaver,
				Desk_export_resulthandler	resulthandler,
				size_t				estimatedsize,
				int				filetype,
				void*				reference
				)
	{
	Desk_save2_block*	save2 = Desk_DeskMem_MallocType( Desk_save2_block);
	
	Desk_Debug_Assert( filesaver);
	save2->dialog2		= dialog2;
	save2->dragsprite	= dragsprite;
	save2->filenameicon	= filenameicon;
	save2->filesaver	= filesaver;
	save2->ramsaver		= ramsaver;
	save2->resulthandler	= resulthandler;
	save2->estimatedsize	= estimatedsize;
	save2->filetype		= filetype;
	save2->reference	= reference;
	
	dialog2->openfn 	= OpenFn;
	dialog2->okfn		= OkFn;
	dialog2->reference	= save2;
	

	Desk_Dialog2_NotifyClose( dialog2);
	
	return save2;
	}

