;
; xfer.saveAs.s
;
; Implementation of a save as dialogue box (MDW)
;
;  1994 Straylight
;

;----- Standard header ------------------------------------------------------

		GET	libs:header
		GET	libs:swis

;----- External dependencies ------------------------------------------------

		GET	sapphire:dbox
		GET 	sapphire:help
		GET 	sapphire:msgs
		GET 	sapphire:note
		GET	sapphire:sapphire

		GET	sapphire:dbx.dbx
		GET	sapphire:dbx.fileIcon

		GET	sapphire:xfer.save

;----- Main code ------------------------------------------------------------

		AREA	|Sapphire$$Code|,CODE,READONLY

; --- saveAs ---
;
; On entry:	R0 == estimated size of data
;		R1 == file type of the data
;		R2 == pointer to name of the file
;		R3 == pointer to handler block
;		R4 == value to pass to handlers in R10
;		R5 == value to pass to handlers in R12
;
; On exit:	May return an error
;
; Use:		Displays a save as dialogue box for you to save some data.

		EXPORT	saveAs
saveAs		ROUT

		STMFD	R13!,{R0-R6,R12,R14}	;Save some registers
		WSPACE	sa__wSpace		;Find my workspace address

		; --- Find the end of the string ---

		MOV	R6,R3			;Take a copy of the title tag
00saveAs	LDRB	R14,[R3],#1		;Load a byte from the table
		CMP	R14,#32			;Is it the end yet?
		BGE	%00saveAs		;No -- go round again then
		ADD	R3,R3,#3		;Add on a little bit
		BIC	R3,R3,#3		;And word align the result

		; --- Save the fixed information away ---

		STMIA	R12,{R0-R5}		;Save the stuff in workspace

		; --- Now create a dialogue box ---

		ADR	R0,sa__dbName		;Point to my dialogue name
		BL	dbox_create		;Try to create the dialogue
		BVS	%99saveAs		;If it failed, tidy up
		STR	R0,sa__dbox		;Save the dialogue handle

		ADR	R1,sa__dbHandler	;Point to my handler routine
		MOV	R2,R0			;Pass dialogue handle in R10
		MOV	R3,R12			;And workspace in R12 please
		BL	dbox_eventHandler	;Set up the event handler

		ADR	R1,sa__dbxDef		;Point to my dialogue def
		BL	dbx_declare		;Let dbx handle the dialogue

		; --- Set up the dialogue ---

		MOV	R1,#saIcon__write	;Get the writable icon handle
		LDR	R2,[R13,#8]		;Get the default filename
		BL	dbox_setField		;Write it into the icon

		MOV	R3,R0			;Save the dialogue handle
		MOV	R0,R6			;Get the title string tag
		BL	msgs_lookup		;Translate it nicely
		MOV	R2,R0			;Copy it into R2 now
		MOV	R0,R3			;Restore the dialogue handle
		MOV	R1,#-1			;Fill in the title bar
		BL	dbox_setField		;And fill in the title

		; --- Now display it and return ---

		MOV	R1,#dbOpen_trans :OR: dbOpen_pointer
		BL	dbox_open		;Open the dialogue box
		LDMFD	R13!,{R0-R6,R12,R14}	;Restore all the registers
		BICS	PC,R14,#V_flag		;And don't return any errors

		; --- Couldn't create the dialogue box ---

99saveAs	ADD	R13,R13,#4		;Don't restore R0 on exit
		LDMFD	R13!,{R1-R6,R12,R14}	;Restore the other registers
		ORRS	PC,R14,#V_flag		;And return the error

sa__dbName	DCB	"save",0

sa__dbxDef	FILEICN	saIcon__file,R12,:INDEX: sa__fileType
		DBXEND

		LTORG

; --- sa__dbHandler ---
;
; On entry:	R0 == dialogue box event code
;		R1-R9 == event-dependent information
;
; On exit:	--
;
; Use:		Handles events for the save dialogue box.

sa__dbHandler	ROUT

		CMP	R0,#saIcon__ok		;Is it the OK button clicked?
		CMPNE	R0,#dbEvent_OK		;Or maybe a return key?
		BEQ	%10sa__dbHandler	;Either -- handle it

		CMP	R0,#dbEvent_close	;Has the window been closed?
		BEQ	%20sa__dbHandler	;Yes -- deal with this then

		CMP	R0,#fIcon_event		;Or is it the fileicon drag?
		BEQ	%30sa__dbHandler	;Yes -- deal with that

		CMP	R0,#dbEvent_help	;Is it a help request?
		BEQ	%40sa__dbHandler	;Yes -- send some help along

		MOVS	PC,R14			;Return -- unknown event

		; --- Deal with a click on the OK button ---

10sa__dbHandler	STMFD	R13!,{R0-R3,R10,R12,R14} ;Save some registers
		MOV	R3,R1			;Keep the button status safe

		; --- Slab the OK button ---

		MOV	R0,R10			;Get my dialogue handle
		MOV	R1,#saIcon__ok		;And the OK button handle
		BL	dbox_slab		;Slab the icon in nicely

		; --- Try to find a `.' character ---

		MOV	R1,#saIcon__write	;Find the writable icon
		BL	dbox_getField		;Read the string value
		MOV	R0,R2			;Keep pointer to string
13sa__dbHandler	LDRB	R14,[R2],#1		;Load a byte from it
		CMP	R14,#32			;Is it a control character?
		BLO	%17sa__dbHandler	;Yes -- tell user he's silly
		CMP	R14,#'.'		;Is it a dot character?
		BNE	%13sa__dbHandler	;No -- loop round again

		; --- Tell the client to save the file ---

		MOV	R1,#1			;Say that the file's safe
		ADR	R2,sa__entries		;Find the entry point block
		LDMIA	R2,{R2,R10,R12}		;Load all the client stuff
		MOV	R14,PC			;Set up the return address
		ADD	PC,R2,#saEntry__save	;Try to send the file
		BVC	%19sa__dbHandler	;If it worked, skip to end

		; --- Handle an error from the client ---

		MOV	R1,#1			;Set icon count for errorBox
		MOV	R14,PC			;Set up the return address
		ADD	PC,R2,#saEntry__failed	;Tell client it failed
		MOV	R3,#1			;Don't close the dialogue
		B	%19sa__dbHandler	;And skip to the end

		; --- Display a note about dragging the icon ---

17sa__dbHandler	MOV	R3,#1			;Don't close the dialogue
		ADR	R0,sa__noteMsg		;Point to the note message
		BL	msgs_lookup		;Translate the note string
		BL	note			;And display it in a window

		; --- Wrap everything up nice and tight ---

19sa__dbHandler	CMP	R3,#1			;Was it an Adjust click?
		LDR	R0,[R13,#16]		;Load my dialogue handle
		BLNE	dbox_close		;No -- close the dialogue
		BL	dbox_unslab		;Unslab the OK button
		BLNE	sa__close		;And close the dialogue box
		LDMFD	R13!,{R0-R3,R10,R12,PC}^ ;Return to caller

sa__noteMsg	DCB	"saDRAGICN",0

		; --- Handle a close event for the window ---

20sa__dbHandler	B	sa__close		;Just close the window

		; --- Handle an icon drag for the window ---

30sa__dbHandler	STMFD	R13!,{R0-R8,R14}	;Save a load of registers

		; --- Find the filename string ---

		MOV	R0,R10			;Get the dialogue box handle
		MOV	R1,#saIcon__write	;Get the writable icon handle
		BL	dbox_getField		;Read the text string
		MOV	R8,R2			;Keep a pointer to it

		; --- Set up the other arguments ---

		ADD	R14,R13,#8		;Point to saved window/icon
		LDMIA	R14,{R0,R1}		;Load them into registers
		LDMIA	R12,{R2-R7}		;Load the other arguments
		ORR	R3,R3,#&80000000	;Set the extended args flag
		MOV	R4,R8			;Point to new file name
		ADD	R5,R5,#saEntry__save	;Point at save handlers
		ADR	R8,sa__extraHnd		;Point to my extra handlers
		BL	save			;Start the save operation
		LDMFD	R13!,{R0-R8,PC}^	;Return to caller

sa__extraHnd	B	sa__success		;The save attempt succeeded
		B	sa__failed		;The save attempt failed

40sa__dbHandler	STMFD	R13!,{R0,R14}		;Save some registers
		ADR	R0,sa__dbHelp		;Point to the message string
		BL	msgs_lookup		;Translate the message
		BL	help_add		;Add it to the help text
		BL	dbox_help		;Read help from the icon
		LDMFD	R13!,{R0,PC}^		;Return to caller

sa__dbHelp	DCB	"sahDB",0

		LTORG

; --- sa__close ---
;
; On entry:	--
;
; On exit:	--
;
; Use:		Closes the save as dialogue box

sa__close	ROUT

		STMFD	R13!,{R0,R10,R12,R14}	;Save some registers away

		; --- Close the dialogue box ---

		WSPACE	sa__wSpace		;Locate my workspace
		LDR	R0,sa__dbox		;Load the dialogue box handle
		BL	dbox_destroy		;Destroy the dialogue
		BL	fileIcon_closed		;Tell fileIcon it's closed

		; --- Tell the client we've done this thing ---

		ADR	R14,sa__entries		;Point to the entry table
		LDMIA	R14,{R0,R10,R12}	;Load the client data
		LDR	R14,[R0,#saEntry__closed] ;Find the closed entry word
		CMP	R14,#0			;Is there an entry defined?
		MOV	R14,PC			;Set up the return address
		ADDNE	PC,R0,#saEntry__closed	;If defined, call the entry
		LDMFD	R13!,{R0,R10,R12,PC}^	;Return to caller

		LTORG

; --- sa__success ---
;
; On entry:	--
;
; On exit:	--
;
; Use:		Handles a successful icon drag-save operation.

sa__success	ROUT

		STMFD	R13!,{R0-R3,R12,R14}	;Save a few registers

		; --- Send a close event to the dialogue ---

		WSPACE	sa__wSpace		;Find my workspace pointer
		LDR	R0,sa__dbox		;Get the dialogue box handle
		BL	dbox_window		;Get its window handle
		STR	R0,[R13,#-4]!		;Store it on the stack
		MOV	R2,R0			;Get the window handle in R2
		MOV	R1,R13			;Point to the close block
		MOV	R0,#3			;And send a close event
		SWI	Wimp_SendMessage	;Add it to my event queue
		ADD	R13,R13,#4		;Reclaim that microblock
		LDMFD	R13!,{R0-R3,R12,PC}^	;Return to caller

		LTORG

; --- sa__failed ---
;
; On entry:	R0 == pointer to an error, or 0
;		R1 == 1
;
; On exit:	--
;
; Use:		Deals with an abortive to save data.

sa__failed	ROUT

		B	fileIcon_reAppear	;Make the file icon reappear

		LTORG

sa__wSpace	DCD	0

;----- The SaveAs handler block ---------------------------------------------
;
; The block begins with the message tag for the dialogue title, followed by
; an align to word boundary and then branch instructions or 0 for:

		^	0
saEntry__closed	#	4			;Save dialogue has closed
						;Entry:
						;  --
						;Exit:
						;  --

saEntry__save	#	4			;Write to a file
						;Entry:
						;  R0 == pointer to file name
						;  R1 == 0 if file unsafe,
						;        non-0 if safe
						;Exit:
						;  --

saEntry__send	#	4			;Send a block of data
						;Entry:
						;  --
						;Exit:
						;  R0 == pointer to block
						;  R1 == size of block
						;  CS if this is the last one

saEntry__success	#	4		;Data transfer has finished
						;Entry:
						;  --
						;Exit:
						;  --

saEntry__failed	#	4			;Data transfer failed
						;Entry:
						;  R0 == 0 or ptr to error
						;  R1 == 1
						;Exit:
						;  --

;----- Icon numbers ---------------------------------------------------------

saIcon__write	EQU	1
saIcon__file	EQU	2
saIcon__ok	EQU	3

;----- Workspace ------------------------------------------------------------

		^	0,R12
sa__wStart	#	0

sa__estSize	#	4			;Estimated size of data
sa__fileType	#	4			;Filetype of data to save
sa__fileName	#	4			;Pointer to default name
sa__entries	#	4			;Pointer to branch table
sa__R10		#	4			;Caller's value of R10
sa__R12		#	4			;Caller's value of R12

sa__dbox	#	4			;My dialogue box handle

sa__wSize	EQU	{VAR}-sa__wStart

		AREA	|Sapphire$$LibData|,CODE,READONLY

		DCD	sa__wSize
		DCD	sa__wSpace
		DCD	0
		DCD	0

;----- That's all, folks ----------------------------------------------------

		END
