;APS00000000000000000000000000000000000000000000000000000000000000000000000000000000
; Simple example of single data items per tag

	incdir	include:
	include	exec/types.i
	include	lvo/dos_lib.i
	include	lvo/exec_lib.i
	include	lvo/preferences_lib.i
	include	libraries/iffparse.i
	include	scalos/preferences.i


start:	movem.l	d1-d7/a0-a6,-(a7)
	move.l	4.w,a6			; Get pointer to execbase

	lea	doslibname(pc),a1	; SPRPTR "dos.library" -> a1
	moveq.l	#36,d0			; 36 (version to open) -> d0
	jsr	_LVOOpenLibrary(a6)	; Open dos.library
	move.l	d0,dosbase		; store/check pointer to dos.library base
	beq	.nodoslib		; if NULL, branch to end of program
	
	lea	prefslibname(pc),a1	; STRPTR "preferences.library" -> a1
	moveq.l	#39,d0			; 39 (version to open) -> d0
	jsr	_LVOOpenLibrary(a6)	; Open preferences.library
	move.l	d0,prefsbase		; store/check pointer to prefsbase
	beq	.noprefslib		; if NULL, branch to end of program

;	First we need to allocate a PrefsHandle by name
	move.l	d0,a6			; pointer to prefsbase
	lea	prefname(pc),a0		; Get name to refer to this PrefsHandle -> a1
	jsr	_LVOAllocPrefsHandle(a6); try to allocate preferences handle
	move.l	d0,prefhandle		; store/check pointer to PrefsHandle
	beq	.noph			; if NULL, wasn't allocated so quit

	move.l	dosbase(pc),a6		; dos.library base -> a6
	move.l	#phallocok,d1		; pointer to string -> d1
	jsr	_LVOPutStr(a6)		; print string to CLI (just to say we allocated PrefsHandle OK)

;	We need an ID and a Tag value to refer to a specific preference item
;	Remember that the ID must be made from 4 ASCII characters and the Tag
;	value must not be 0
	move.l	#'MAIN',d6		; Set the ID (stored in d6) to 4 char ascii string "MAIN"
	moveq.l	#1,d7			; Set the Tag to 1 (imaginative, huh? ;)


;	Store the example preference data (string) under the ID and Tag
;	(as set a couple of lines ago). We pass a length of string length + 1
;	so that the NULL terminator will get stored in the preference.
	lea	prefdata(pc),a0		; get pointer to string to store
	move.l	a0,a1			; store in correct register for lib call
	jsr	strlen			; calculate length of string
	addq.l	#1,d0			; increase by 1 for NULL terminator
	move.l	d0,d2			; set it as the size of data to store
	move.l	prefhandle(pc),a0	; pointer to previously allocated preferences handle
	move.l	d6,d0			; get ID
	move.l	d7,d1			; get Tag
	move.l	prefsbase(pc),a6	; pointer to prefsbase -> a6
	jsr	_LVOSetPreferences(a6)	; store data in preferences


;	Use FindPreferences to find out if the item was stored OK
	move.l	d6,d0			; get ID
	move.l	d7,d1			; get Tag
	move.l	prefhandle(pc),a0	; get pointer to PrefsHandle
	move.l	prefsbase(pc),a6	; get pointer to prefsbase
	jsr	_LVOFindPreferences(a6)	; try to get pointer to the preference Tag
	tst.l	d0			; check pointer to Tag
	beq	.nofind			; if NULL, skip past all this stuff, because it didn't exist
	move.l	d0,a2			; otherwise, keep copy of the pointer in a2

	move.l	dosbase(pc),a6		; print a message to say that
	move.l	#findok,d1		; the preferences were found OK
	jsr	_LVOPutStr(a6)

	lea	prefdata(pc),a0		; get string that we stored
	jsr	strlen			; get length of string we stored
	addq.l	#1,d0			; increase by 1 for NULL character
	move.l	d0,-(a7)		; store on stack as data for sprintf
	move.l	#str_sizeof,-(a7)	; store format string on stack
	move.l	#temp,-(a7)		; store output buffer on stack
	jsr	sprintf			; call sprintf
	lea	12(a7),a7		; fix stack
	move.l	#temp,d1		; get pointer to output buffer
	jsr	_LVOPutStr(a6)		; print it

	move.w	ps_Size(a2),-(a7)	; get size of data from preference Tag pointer
	move.l	#str_sizepd,-(a7)	; get format string for message
	move.l	#temp,-(a7)		; output buffer
	jsr	sprintf			; sprintf
	lea	10(a7),a7		; clean up stack
	move.l	#temp,d1		; pointer to output buffer
	jsr	_LVOPutStr(a6)		; print string


;	To show that the data was actually stored, we use GetPreferences
;	to retrieve the data from storage
	move.l	prefhandle(pc),a0	; pointer to PrefsHandle
	move.l	d6,d0			; ID
	move.l	d7,d1			; Tag
	lea	temp(pc),a1		; pointer to storage memory
	move.l	#128,d2			; size of memory to store in (only 128 bytes since we want to use half for the pref string and half for the sprintf strings we will have)
	move.l	prefsbase(pc),a6	; pointer to prefsbase
	jsr	_LVOGetPreferences(a6)	; GetPreferences
	tst.l	d0			; test size of data retrieved
	beq	.nodata			; if =0 then no data was retrieved, no point in showing it :)


	move.l	d0,-(a7)		; put amount of bytes retrieved on stack
	move.l	#str_bytesret,-(a7)	; format string on stack
	move.l	#temp+128,-(a7)		; use second half of temp memory for this sprintf string, since the first half is being used by the contents of GetPreferences
	jsr	sprintf			; sprintf
	lea	12(a7),a7		; clean up stack
	move.l	dosbase(pc),a6		; dosbase into a6
	move.l	#temp+128,d1		; get pointer to string created with sprintf
	jsr	_LVOPutStr(a6)		; print that string
	move.l	#str_contents,d1	; pointer to string
	jsr	_LVOPutStr(a6)		; print it
	move.l	#temp,d1		; pointer to data retrieved by GetPreferences
	jsr	_LVOPutStr(a6)		; print it
	move.l	#str_newline,d1		; pointer to a string with a newline
	jsr	_LVOPutStr(a6)		; print it

.nodata:
	
	bra	.endif001
.nofind:
	move.l	dosbase(pc),a6		; print a message to say that
	move.l	#findnotok,d1		; the preferences were not
	jsr	_LVOPutStr(a6)		; found OK
	
.endif001:

;	Finally we free the PrefsHandle when we no longer need it
	move.l	prefsbase(pc),a6	; prefsbase pointer -> a6
	move.l	prefhandle(pc),a0	; PrefsHandle pointer -> a0
	jsr	_LVOFreePrefsHandle(a6)	; Free preferences handle

.noph:
	move.l	4.w,a6			; execbase pointer -> a6
	move.l	prefsbase(pc),a1	; prefsbase pointer -> a1
	jsr	_LVOCloseLibrary(a6)	; close preferences.library

.noprefslib:
	move.l	dosbase(pc),a1		; pointer to dos.library base -> a1
	jsr	_LVOCloseLibrary(a6)	; close dos.library

.nodoslib:	
	movem.l	(a7)+,d1-d7/a0-a6
	moveq.l	#0,d0
	rts
	

; Length of string
; a0 = STRPTR
strlen:
	moveq.l	#0,d0		; clear count of length of string
.loop:	tst.b	(a0)+		; check char in string for NULL and move onto next
	beq	.endloop	; if NULL, skip to end of loop
	addq.l	#1,d0		; otherwise increase length of string
	bra	.loop		; repeat loop
.endloop:
	rts


; C-like sprintf (from autodocs)
; parameters on stack from right to left
; (except the data items, they are on from left to right)
; output, format [, data]
sprintf:
	movem.l	a2/a3/a6,-(a7)

	move.l	16(a7),a3
	move.l	20(a7),a0
	lea	24(a7),a1
	lea	stuffChar(pc),a2
	move.l	4.w,a6
	jsr	_LVORawDoFmt(a6)

	movem.l	(a7)+,a2/a3/a6
	rts

stuffChar:
	move.b	d0,(a3)+
	rts
	

; Storage space for variables/strings etc
;execbase:	dc.l	0	; exec.library base
dosbase:	dc.l	0	; dos.library base
prefsbase:	dc.l	0	; Pointer to preferences.library base

prefhandle:	dc.l	0	; Pointer to our PrefsHandle
temp:		ds.b	256	; Temporary area for storing preferences

doslibname:	dc.b	"dos.library",0
prefslibname:	dc.b	"preferences.library",0
prefname:	dc.b	"Example",0		; Name to refer to our PrefHandle with
prefdata:	dc.b	"This is some example preference data",0
phallocok:	dc.b	"PrefsHandle allocated OK",10,0
findok:		dc.b	"Preference data found",10,0
findnotok:	dc.b	"Preference data not stored",10,0
str_sizeof:	dc.b	"Size of data stored:   %ld",10,0
str_sizepd:	dc.b	"Size of preference data: %d",10,0
str_bytesret:	dc.b	"Bytes retrieved from PrefsHandle: %ld",10,0
str_contents:	dc.b	"Contents of preference data:",10,"    ",0
str_newline:	dc.b	10,0
		cnop	0,4
