***********************************************************************
*
* teach uwindow.aii -- Version 3.0
*
* Copyright (c)
* Apple Computer, Inc.  1986-1990
* All Rights Reserved.
*
* Developer Technical Support Apple II Sample Code
*
* This file contains the code which implements  
* windows in the Teach program.
*
***********************************************************************

	case  on
	longi on
	longa on

	INCLUDE 'e16.types'
	INCLUDE 'm16.control'
	INCLUDE 'e16.gsos'
	INCLUDE 'm16.gsos'
	INCLUDE 'm16.memory'
	INCLUDE 'm16.quickdraw'
	INCLUDE 'e16.resources'
	INCLUDE 'e16.stdfile'
	INCLUDE 'm16.stdfile'
	INCLUDE 'e16.textedit'
	INCLUDE 'm16.textedit'
	INCLUDE 'm16.util2'
	INCLUDE 'm16.window'
	INCLUDE 'teach.equ'

***********************************************************************
*
* smartGetWTitle
*
* This function returns a pointer to the window title pascal string.
* This is a little more complicated than it used to be, given that
* NewWindow2 clones	the string for the window into an unlocked handle.
* GetWTitle returns	a handle with the hi-bit set (to distinguish it
* from a reguler pointer).  If the hi-bit is set, then we want to
* dereference the handle to a pointer, and return that instead.
*
	EXPORT smartGetWTitle
smartGetWTitle	PROC

	DefineStack

saveDPage	word
returnAddr	word

wptr	long	;Parameters.
wtitle	long	;Result.

******************

	phd	;Save directPage register.
	tsc	;Set directPage register.
	tcd

	pha	;Result space.
	pha
	pei wptr+2	;wtitle is result space
	pei wptr
	_GetWTitle
	pla
	sta wtitle
	pla
	sta wtitle+2
	bpl exit

	ldy #2
	lda [wtitle],y
	tax
	lda [wtitle]
	sta wtitle
	stx wtitle+2

exit	pld	;Restore directPage	register.
	plx	;Save return address.
	pla	;Remove passed parameters.
	pla
	phx	;Restore return address and return.
	rts

	ENDP

***********************************************************************
*
* drawThisWindow --	called from the tools (via JSL)
*
* This routine draws the contents of all the windows.
*
	EXPORT drawThisWindow
drawThisWindow	PROC

	pha
	pha
	_GetPort
	_DrawControls
	rtl

	ENDP

***********************************************************************
*
* doCloseTop
*
* This routine closes the topmost window.
*
	EXPORT doCloseTop
doCloseTop	PROC

	pha	;GetWRefCon result space
	pha
	pha	;FrontWindow result	space
	pha
	_FrontWindow
	_GetWRefCon
	lda 1,s
	ora 3,s
	beq null	;Stuff on stack will be
*		;result space for FrontWindow

	_DisposeHandle	;Get rid of the pathname handle
	pha	;that we keep in the refCon.
	pha	;Result space for FrontWindow

null	_FrontWindow
	_CloseWindow

	rts

	ENDP

***********************************************************************
*
* PutFileIntoWindow
*
* This routine opens the specified file, reads its contents	in and sets
* the text of the text edit control of the top window to that text.
*
	EXPORT putFileIntoWindow
putFileIntoWindow	PROC
	import userID

	DefineStack

theHndl	long	;Must be at 1,s
c1ptr	long

saveDPage	word
returnAddr	word

c1hndl	long

******************

	phd	;Save directPage register.
	pha	;Make space for locals.
	pha
	pha
	pha
	tsc	;Set directPage register.
	tcd

	pei c1hndl+2	;Lock down the passed handle.
	pei c1hndl
	_HLock

	ldy #2	;Dereference the handle and skip
	lda [c1hndl],y	;the C1Output buffer size word.
	tax
	lda [c1hndl]
	clc
	adc #2
	bcc aa
	inx
aa	sta c1ptr
	stx c1ptr+2

	sta obpathname	;Set up the openBlock
	stx obpathname+2
	lda #0
	sta obrequestAccess
	sta obresourceNumber
	sta oboptionList
	sta oboptionList+2
	_OpenGS openBlock	;Open the file.
	bcc ab
	jsr doErrorWindow
	brl unlockExit

ab	lda obrefNum	;Set up closeBlock.
	sta clbrefNum
	sta rbrefNum

	PushLong obeof
	PushWord userID
	lda #0
	pha	;0
	pha	;NULL
	pha
	_NewHandle	;Result in theHndl
	bcc ac
	lda #$8E	;Not enough ram -- close some windows.
	jsr doErrorWindow
	brl closeUnlockExit

ac	pei theHndl+2
	pei theHndl
	_HLock

	ldy #2	;Dereference handle	to get
	lda [theHndl],y	;the readBlock data	buffer.
	sta rbdataBuffer+2
	lda [theHndl]
	sta rbdataBuffer

	lda obeof	;How big the open eof is tells
	ldx obeof+2	;us how many bytes to request
	sta rbrequestCount	;for read.
	stx rbrequestCount+2
	_ReadGS readBlock
	bcc ad
	jsr doErrorWindow
	brl disposeCloseUnlockExit

ad	_CloseGS closeBlock
	bcc ae
	jsr doErrorWindow
	brl disposeUnlockExit

ae	pea refIsHandle*8+teDataIsTextBlock
	pei theHndl+2
	pei theHndl
	lda #0
	pha	;NULL
	pha
	pha	;0
	pha	;NULL
	pha
	pha	;GetCtlHandleFromID	result space
	pha
	pha	;FrontWindow result	space
	pha
	_FrontWindow
	PushLong #MainWindowID
	_GetCtlHandleFromID
	_TESetText

disposeUnlockExit		; 
	pei theHndl+2	;All done with this	handle.
	pei theHndl	;Dispose it, finish	up and leave.
	_DisposeHandle
	bra unlockExit

disposeCloseUnlockExit	; 
	pei theHndl+2	;All done with this	handle.
	pei theHndl
	_DisposeHandle

closeUnlockExit	_CloseGS closeBlock	;Close the file.

unlockExit	pei c1hndl+2	;Unlock handle passed to us.
	pei c1hndl
	_HUnlock

	pla	;Remove local variable space.
	pla
	pla
	pla
	pld	;Restore directPage	register.
	plx	;Save return address.
	pla	;Remove passed parameters.
	pla
	phx	;Restore return address and return.
	rts

doErrorWindow	pha
	ldx #0
	phx
	phx
	phx
	pha
	_ErrorWindow
	pla
	rts

openBlock		; 
obpCount	DC.W 15
obrefNum	DC.W 0
obpathname	DC.L 0
obrequestAccess	DC.W 0
obresourceNumber	DC.W 0
obaccess	DC.W 0
obfileType	DC.W 0
obauxType	DC.L 0
obstorageType	DC.W 0
obcreateDateTime	DS.B 8
obmodDateTime	DS.B 8
oboptionList	DC.L 0
obeof	DC.L 0
obblocksUsed	DC.L 0
obresourceEOF	DC.L 0
obresourceBlocks	DC.L 0

closeBlock		; 
clbpCount	DC.W 1
clbrefNum	DC.W 0

readBlock		; 
rbpCount	DC.W 4
rbrefNum	DC.W 0
rbdataBuffer	DC.L 0
rbrequestCount	DC.L 0
rbtransferCount	DC.L 0

	ENDP

***********************************************************************
*
* putWindowIntoFile
*
* This routine opens the specified file, writes the window contents.
*
	EXPORT putWindowIntoFile
putWindowIntoFile	PROC
	import userID

	DefineStack

theHndl	long	;Must be at 1,s
c1ptr	long
totalSize	long

saveDPage	word
returnAddr	word

c1hndl	long

******************

	phd	;Save directPage register.
	pha	;Make space for locals.
	pha
	pha
	pha
	pha
	pha
	tsc	;Set directPage register.
	tcd

	pei c1hndl+2	;Lock down the passed handle.
	pei c1hndl
	_HLock

	ldy #2	;Dereference the handle and skip
	lda [c1hndl],y	;the C1Output buffer size word.
	tax
	lda [c1hndl]
	clc
	adc #2
	bcc aa
	inx
aa	sta c1ptr
	stx c1ptr+2

	sta dbname	;Destroy block pathname.
	stx dbname+2
	sta cbpathname	;Create block pathname.
	stx cbpathname+2
	sta obpathname	;Open block pathname.
	stx obpathname+2
	_DestroyGS destroyBlock ;Destroy the file always.
	bcc ab
	cmp #fileNotFound	;It may have not been there.
	beq ab
	jsr doErrorWindow
	brl unlockExit

ab	lda #$C3
	sta cbaccess
	lda #$04
	sta cbfileType
	lda #0
	sta cbauxType
	sta cbauxType+2
	_CreateGS createBlock
	bcc ac
	jsr doErrorWindow
	brl unlockExit

ac	lda #0
	sta obrequestAccess
	sta obresourceNumber
	sta oboptionList
	sta oboptionList+2
	_OpenGS openBlock
	bcc ad
	pha	;Keep error code.
	_DestroyGS destroyBlock
	pla
	jsr doErrorWindow
	brl unlockExit

ad	lda obrefNum
	sta clbrefNum
	sta wbrefNum

	PushLong #1
	lda userID
	pha
	lda #0
	pha
	pha
	pha
	_NewHandle	;Result in theHndl
	bcc ae
	pha	;Keep error code.
	_CloseGS closeBlock
	_DestroyGS destroyBlock
	pla
	jsr doErrorWindow
	brl unlockExit

ae	pha	;Result space
	pha
	pea refIsHandle*8+teDataIsTextBlock
	pei theHndl+2
	pei theHndl
	lda #0
	pha	;NULL
	pha
	pha	;0
	pha	;NULL
	pha
	pha	;Result space for GetCtlHandleFromID
	pha
	pha	;Result space for FrontWindow
	pha
	_FrontWindow
	PushLong #MainWindowID
	_GetCtlHandleFromID
	_TEGetText
	plx
	stx totalSize
	plx
	stx totalSize+2
	bcc af
	pha
	_CloseGS closeBlock
	_DestroyGS destroyBlock
	pla
	jsr doErrorWindow
	brl disposeUnlockExit

af	pei theHndl+2
	pei theHndl
	_HLock

	ldy #2
	lda [theHndl],y
	sta wbdataBuffer+2
	lda [theHndl]
	sta wbdataBuffer
	lda totalSize
	ldx totalSize+2
	sta wbrequestCount
	stx wbrequestCount+2
	_WriteGS writeBlock
	bcc ag
	pha
	_CloseGS closeBlock
	_DestroyGS destroyBlock
	pla
	jsr doErrorWindow
	brl disposeUnlockExit

ag	_CloseGS closeBlock
	bcc disposeUnlockExit
	pha
	_DestroyGS destroyBlock
	pla
	jsr doErrorWindow


disposeUnlockExit		; 
	pei theHndl+2
	pei theHndl
	_DisposeHandle

unlockExit	pei c1hndl+2
	pei c1hndl
	_HUnlock

	pla	;Remove local variable space.
	pla
	pla
	pla
	pla
	pla
	pld	;Restore directPage	register.
	plx	;Save return address.
	pla	;Remove passed parameters.
	pla
	phx	;Restore return address and return.
	rts


doErrorWindow	pha
	ldx #0
	phx
	phx
	phx
	pha
	_ErrorWindow
	pla
	rts


destroyBlock		; 
dbpCount	DC.W 1
dbname	DC.L 0

createBlock		; 
cbpCount	DC.W 4
cbpathname	DC.L 0
cbaccess	DC.W 0
cbfileType	DC.W 0
cbauxType	DC.L 0

openBlock		; 
obpCount	DC.W 15
obrefNum	DC.W 0
obpathname	DC.L 0
obrequestAccess	DC.W 0
obresourceNumber	DC.W 0
obaccess	DC.W 0
obfileType	DC.W 0
obauxType	DC.L 0
obstorageType	DC.W 0
obcreateDateTime	DS.B 8
obmodDateTime	DS.B 8
oboptionList	DC.L 0
obeof	DC.L 0
obblocksUsed	DC.L 0
obresourceEOF	DC.L 0
obresourceBlocks	DC.L 0

closeBlock		; 
clbpCount	DC.W 1
clbrefNum	DC.W 0

writeBlock		; 
wbpCount	DC.W 4
wbrefNum	DC.W 0
wbdataBuffer	DC.L 0
wbrequestCount	DC.L 0
wbtransferCount	DC.L 0

	ENDP

***********************************************************************
*
* placeAndShowWindow
*
* This routine moves the specified window based on stagger count
* and shows it.
*
	EXPORT placeAndShowWindow
placeAndShowWindow	PROC
	import staggerCount

	DefineStack

saveDPage	word
returnAddr	word

wptr	long

******************

	phd	;Save directPage register.
	tsc	;Set directPage register.
	tcd

	lda staggerCount
	asl a
	asl a
	asl a
	adc #8
	pha
	adc #20
	pha
	pei wptr+2
	pei wptr
	_MoveWindow

	lda staggerCount
	inc a
	and #$07
	sta staggerCount

	pei wptr+2
	pei wptr
	_ShowWindow
	pei wptr+2
	pei wptr
	_SelectWindow

	pld	;Restore directPage	register.
	plx	;Save return address.
	pla	;Remove passed parameters.
	pla
	phx	;Restore return address and return.
	rts

	ENDP

***********************************************************************
*
* doOpenWindow
*
* This routine either asks the user what file to open and opens it.
*
	EXPORT doOpenWindow
doOpenWindow	PROC

	DefineStack

wptr	long	;Must be at 1,s
myReply	block oReplyRec2size
pstr	long

stkFrameSize	EndLocals

saveDPage	word
returnAddr	word

******************

	phd	;Save directPage register.
	tsc
	sec
	sbc #stkFrameSize	;Make space for locals.
	tcs
	tcd	;Set directPage register.

	pea 1
	_SFAllCaps

	lda #refIsNewHandle
	sta myReply+onameRefDesc
	sta myReply+opathRefDesc

	tsc	;Calculate pointer to myReply.
	clc
	adc #myReply
	tax
	pea 10
	pea 35
	pea refIsPointer
	PushLong #promptStr
	lda #0
	pha	;NULL
	pha
	pha	;NULL
	pha
	pha	;Pointer to myReply
	phx
	_SFGetFile2
	lda myReply+ogood
	beq exit

	pei myReply+onameRef+2
	pei myReply+onameRef
	_HLock

	ldy #2
	lda [myReply+onameRef],y
	tax
	lda [myReply+onameRef]
	sta pstr
	stx pstr+2
	shortm
	lda [pstr],y	;2 in yreg.
	iny
	sta [pstr],y
	longm
	tya	;3 in yreg.
	clc
	adc pstr
	bcc aa
	inx

aa	phx	;Pointer to window title.
	pha
	pei myReply+opathRef+2
	pei myReply+opathRef
	PushLong #drawThisWindow
	lda #0
	pha
	pha
	pea refIsResource
	PushLong #MainWindowID
	pea rWindParam1
	_NewWindow2

	pei myReply+onameRef+2
	pei myReply+onameRef
	_DisposeHandle

	pei wptr+2
	pei wptr
	jsr placeAndShowWindow

	pei myReply+opathRef+2
	pei myReply+opathRef
	jsr putFileIntoWindow

exit	tsc	;Remove local space.
	clc
	adc #stkFrameSize
	tcs
	pld	;Restore directPage	register.
	rts

promptStr	str 'Pick a file, any file.'

	ENDP

***********************************************************************
*
* doSaveAs
*
* This routine either saves the file in	the place indicated	by the user.
*
	EXPORT doSaveAs
doSaveAs	PROC
	import userID

	DefineStack

myReply	block oReplyRec2size
wtitle	long
pstr	long
wtptr	long
wthndl	long
wtlen	word
refCon	long

stkFrameSize	EndLocals

saveDPage	word
returnAddr	word

******************

	phd	;Save directPage register.
	tsc
	sec
	sbc #stkFrameSize	;Make space for locals.
	tcs
	tcd	;Set directPage register.

	pea 1
	_SFAllCaps

	lda #refIsNewHandle
	sta myReply+onameRefDesc
	sta myReply+opathRefDesc

	pha	;Point to the window title.
	pha
	pha
	pha
	_FrontWindow
	jsr smartGetWTitle
	pla
	sta wtitle
	pla
	sta wtitle+2

	lda [wtitle]	;How long is the title?
	and #$FF
	sta wtlen

	pha	;Create a handle for the title
	pha	;that will be big enough for
	pea 0	;the text and a word length.
	lda wtlen
	clc
	adc #2
	pha
	lda userID
	pha
	lda #0
	pha
	pha
	pha
	_NewHandle
	pla
	sta wthndl
	pla
	sta wthndl+2
	bcc aa

aa	ldy #2	;Point to this handle.
	lda [wthndl],y
	sta wtptr+2
	lda [wthndl]
	sta wtptr

	pha	;Re-dereference the	window
	pha	;title pointer, since it may
	pha	;be stored in a handle, and the
	pha	;handle may have moved.
	_FrontWindow
	jsr smartGetWTitle
	pla
	sta wtitle
	pla
	sta wtitle+2

	lda wtitle	;Point to the title, skipping the
	ldx wtitle+2	;length byte.
	inc a
	bne ab
	inx
ab	phx
	pha
	lda wtptr	;Point to the handle created to
	ldx wtptr+2	;hold the title, skipping the
	clc	;length word.
	adc #2
	bcc ac
	inx
ac	phx
	pha
	pea 0	;Push the number of	bytes to copy.
	pei wtlen
	_BlockMove

	lda wtlen	;Store the length word in the
	sta [wtptr]	;beginning of the handle.

	pei wthndl+2	;Lock the handle, since SFPutFile2
	pei wthndl	;may move things around.
	_HLock

	tsc	;Calculate pointer to myReply.
	clc
	adc #myReply
	tax
	pea 180
	pea 35
	pea refIsPointer
	PushLong #promptPtr
	pea refIsPointer
	pei wtptr+2
	pei wtptr
	pea 0	;Pointer to myReply.
	phx
	_SFPutFile2

	pei wthndl+2	;We are done with the window title.
	pei wthndl
	_DisposeHandle

	lda myReply+ogood	;See if the user clicked cancel.
	beq exit

	pha	;We may have a handle in the refCon.
	pha	;If we do, then we need to dispose it.
	pha
	pha
	_FrontWindow
	_GetWRefCon
	pla
	sta refCon
	pla
	sta refCon+2
	ora refCon
	beq ad
	pei refCon+2
	pei refCon
	_DisposeHandle

ad	pei myReply+opathRef+2 ;This is the new	handle for
	pei myReply+opathRef ;the refCon.
	pha
	pha
	_FrontWindow
	_SetWRefCon

	ldy #2	;We have a handle that is a
	lda [myReply+onameRef],y ;C1Output string.  We want this
	tax	;to be a pascal string.  This
	lda [myReply+onameRef] ;is accomplished	by moving byte
	sta pstr	;2 to byte 3, and then pointing
	stx pstr+2	;3 bytes into the handle.
	shortm
	lda [pstr],y	;2 in yreg.
	iny
	sta [pstr],y
	longm
	tya
	clc
	adc pstr	;3 in yreg.
	bcc ae
	inx
ae	phx
	pha
	pha
	pha
	_FrontWindow
	_SetWTitle

	pei myReply+onameRef+2 ;We are done with the name now.
	pei myReply+onameRef
	_DisposeHandle

	pei myReply+opathRef+2
	pei myReply+opathRef
	jsr putWindowIntoFile

exit	tsc	;Remove local space.
	clc
	adc #stkFrameSize
	tcs
	pld	;Restore directPage	register.
	rts

promptPtr	str 'Give it a name, any name.'

	ENDP

***********************************************************************
*
* doSave
*
* This routine either saves the file (unless it is new then	it does a save 
* as).
*
	EXPORT doSave
doSave	PROC

	DefineStack

wptr	long	;Must be at 1,s
refCon	long

saveDPage	word
returnAddr	word

******************

	phd	;Save directPage register.
	pha	;Make space for locals.
	pha
	pha
	pha
	tsc	;Set directPage register.
	tcd

	_FrontWindow	;Get the refCon.
	pha
	pha
	pei wptr+2
	pei wptr
	_GetWRefCon
	pla
	sta refCon
	pla
	sta refCon+2
	ora refCon	;If the refCon is not NULL, then
	bne aa	;we already have a name for this file.
	jsr doSaveAs	;We don't have a name yet, so do
	bra exit	;a save as.

aa	pei refCon+2	;We have a name, so	go for it.
	pei refCon
	jsr putWindowIntoFile

exit	plx
	pla	;Remove local space
	pla
	pla
	pla
	pld	;Restore directPage	register.
	phx
	rts

	ENDP

***********************************************************************
*
* NewWindow
*
* This routine opens a new untitled window.
*
	EXPORT doNewWindow
doNewWindow	PROC

	pha	;Result space
	pha
	PushLong #promptPtr	;Window title
	ldx #0
	phx	;NULL
	phx
	PushLong #drawThisWindow
	phx	;NULL
	phx
	pea refIsResource
	PushLong #MainWindowID
	pea rWindParam1
	_NewWindow2

	jsr placeAndShowWindow ;Uses above result space
	rts

promptPtr	str 'Untitled'

	ENDP

***********************************************************************
*
* SetUpWindows
*
* Sets up WindowList record for use through out the program.
*
	EXPORT setupWindows
setupWindows	PROC

	jsr doNewWindow
	rts

	ENDP

	END
