
	load 'macros.dump'
	include 'driver.equ'
	include 'pl.equ'

;-----------------------------------------------
;
;   Imported addresses
;
;-----------------------------------------------

	IMPORT	D_CloseDialog
	IMPORT	D_DigitsOnly
	IMPORT	D_FastMult
	IMPORT	D_GetNewModalDialog
	IMPORT	P_AllHGCount
	IMPORT	P_AllHGuides
	IMPORT	P_AllVGCount
	IMPORT	P_AllVGuides
	IMPORT	P_ContentRect
	IMPORT	P_CurrentWin
	IMPORT	P_DPageDlog
	IMPORT	P_DblPage
	IMPORT	P_DelObjList
	IMPORT	P_DeleteData
	IMPORT	P_DrawContent
	IMPORT	P_DrawObjList
	IMPORT	P_FirstPOff
	IMPORT	P_FixMenus
	IMPORT	P_FixSpecMenu
	IMPORT	P_GrewDoc
	IMPORT	P_HorizGCount
	IMPORT	P_HorizGuides
	IMPORT	P_InsertData
	IMPORT	P_KillUndo
	IMPORT	P_LastObj
	IMPORT	P_ListOp
	IMPORT	P_Merge
	IMPORT	P_ObjList
	IMPORT	P_PIconRect
	IMPORT	P_PInfoSize
	IMPORT	P_Page
	IMPORT	P_PageArray
	IMPORT	P_PageCount
	IMPORT	P_PageDlog
	IMPORT	P_PageIcons
	IMPORT	P_PageInfo
	IMPORT	P_PageStart
	IMPORT	P_PortRect
	IMPORT	P_ToolType
	IMPORT	P_UseTemplate
	IMPORT	P_VertGCount
	IMPORT	P_VertGuides
	IMPORT	T_ClipThread
	IMPORT	T_DotObj
	IMPORT	D_UseStdColors
	IMPORT	D_SetFileChanged
	IMPORT  T_Editing
	IMPORT	T_Deactivate
	
;-----------------------------------------------
;
;   Forward addresses and entries
;
;-----------------------------------------------

	ENTRY	P_CenterPage
	ENTRY	P_ChangePage
	ENTRY	P_FixTextObj
	ENTRY	P_InitPage
	ENTRY	P_KillPage
	ENTRY	P_LoadPage
	ENTRY	P_MergeGuides
	ENTRY	P_SavePage
	ENTRY	P_InsPgFilter

;		   ppage.s



;---------------------------------------------------------------------------
;
; P_InsertPages 
;
;
;			   OKBut	 1
;			   CancelBut 2
;			   Text1	 3	 ; Insert
;			   PgCnt	 4	 ; 1
;			   Text2	 5	 ; page(s)
;			   RCtl1	 6	 ; at the beginning.
;			   RCtl2	 7	 ; after the current page.
;			   RCtl3	 8	 ; at the end.
;
; invariants:   P_PageCount = # of user pages
;			   P_PageStart = 1st user page that is displayed as an icon
;			   P_Page	  = current page's index into page array
;						   = user page # + 1
;			   P_DblPage   = bool. F=1 template, T=L/R template


P_InsertPages	PROC		EXPORT
			;Using P_Data
			;Using P_AttrData
			;Using P_ICONDATA

Text1I	equ 3
PgCntI	equ 4
Text2I	equ 5
RCtl1	equ 6
RCtl2	equ 7
RCtl3	equ 8

		local TheDlog:l,result:w,NewPages:w,thepage:w
		local WhichCtl:w,offset:w,ptr:l,count:w,hdl:l,oldpage:w
		local Len:w,pagetext:r
		error err

		begin +b


		moveword #RCtl2,WhichCtl
		moveword P_Page,oldpage

		jsl	D_UseStdColors
		call D_GetNewModalDialog,in=(#P_PageDlog:l),out=(TheDlog:l)
		cmpw P_Page,#2
		bge DlogLoop


		moveword #RCtl1,WhichCtl
		tool _SetDItemValue,in=(#1:w,TheDlog:l,#RCtl1:w)

		pushword #255
		tool _GetControlDItem,in=(TheDlog:l,#RCtl2:w),out=(:l)
		tool _HiliteControl,in=(:w,:l)							; [sic]

DlogLoop
		tool _ModalDialog,in=(#P_InsPgFilter+$80000000:l),out=(result:w)
		cmp #OK
		jeq HitOK
		cmp #Cancel
		jeq DoCancel
		cmp #RCtl1
		blt DlogLoop
		cmp #RCtl3+1
		bge DlogLoop

		sta WhichCtl

		tool _SetDItemValue,in=(#1:w,TheDlog:l,WhichCtl:w)
		brl DlogLoop


DoCancel
		call D_CloseDialog,in=(TheDlog:l)
		brl Exit


HitOK	tool _GetIText,in=(TheDlog:l,#PgCntI:w,!pagetext:l)
		lda pagetext
		and #$00FF
		sta Len

		tool _Dec2Int,in=(!pagetext+1:l,Len:w,#0:w),out=(NewPages:w)

		lda NewPages
		beq DoCancel

		call D_CloseDialog,in=(TheDlog:l)



		call P_KillUndo
		call P_SavePage,in=(P_Page:w)


		cmpw WhichCtl,#RCtl1
		bne Ck2					 ; after the first page

		moveword #2,thepage
		bra DoneCk

Ck2	cmp #RCtl2
		bne Ck3					 ; after the current page

		lda P_Page
		ina
		sta thepage
		bra DoneCk

Ck3	; ; must be Ctl3:	 ; after the last page
		addword P_PageCount,#2,thepage

DoneCk	addword P_PageCount,#2,count
		rcall D_FastMult,in=(#P_PInfoSize:x,thepage:y),out=(offset:a)
		in P_PageArray:l,offset:w,NewPages:w,#P_PInfoSize:w,count:w
		xerr err
		xcall P_InsertData
		jcs whoops


		moveword NewPages,count
		moveword thepage,offset

ZilchLoop	call P_InitPage,in=(offset:w)

		inc offset
		dec count
		jne ZilchLoop

		lda offset							  ; Make P_Page correspond
		dec a								  ; to the page globals, so
		sta P_Page							  ; P_ChangePage is happy.

		addword P_PageCount,NewPages,P_PageCount

		call P_FixTextObj
		call P_GrewDoc,in=(P_CurrentWin:l)
		call P_ChangePage,in=(thepage:w,#1:w)
		tool _ValidRect,in=(#P_ContentRect:l)
		call D_SetFileChanged,in=(P_CurrentWin:l)
		bra exit


whoops	call P_ChangePage,in=(oldpage:w,#0:w)

Exit	return

		ENDP




;---------------------------------------------------------------------------
;
; P_InsPgFilter (don't activate OK until there is a number we can use.
;				 note that we're guaranteed we won't be called if the max.
;				 number of pages has already been reached.)
;

P_InsPgFilter	PROC EXPORT

		input	TheDlog:l,TheEvent:l,ItemHit:l
		local	Len:w,pagetext:r
		output	TheResult:w
		begin +b
		
PgCntI	equ 4

		tool _GetIText,in=(TheDlog:l,#PgCntI:w,!pagetext:l)
		lda pagetext
		and #$00FF
		sta Len
		beq NoOK

		tool _Dec2Int,in=(!pagetext+1:l,Len:w,#0:w),out=(a:w)
		bcs NoOK
		beq NoOK
		addword a,P_PageCount,a
		cmp #P_MaxPages+1
		blt DoOK


NoOK	pushword #255
		bra DoHilite
DoOK	pushword #0

DoHilite
		tool _GetControlDItem,in=(TheDlog:l,#1:w),out=(:l)
		tool _HiliteControl,in=(:w,:l)							; [sic]

		call D_DigitsOnly,in=(TheDlog:l,TheEvent:l,ItemHit:l),out=(TheResult:w)

exit	return
		ENDP




;---------------------------------------------------------------------------
;
; P_DeletePage
;
;		   Item#'s:
;
;		   1 = OK
;		   2 = Cancel
;		   3 = 'Delete pages'
;		   4 = FromPage
;		   5 = 'through'
;		   6 = ToPage
;

P_DeletePage	PROC		EXPORT
			;Using P_Data
			;Using P_AttrData

		local count:w,offset:w,TheDlog:l,result:w
		local first:w,last:w,oldpage:w,hdl:l,ptr:l,oldcount:w
		local tmp:l
		local pagetext:r

		error err

		begin +b

		call P_KillUndo
		call P_SavePage,in=(P_Page:w)
		moveword P_Page,oldpage
		jsl	D_UseStdColors
		call D_GetNewModalDialog,in=(#P_DPageDlog:l),out=(TheDlog:l)

DlogLoop
		tool _ModalDialog,in=(#D_DigitsOnly+$80000000:l),out=(a:w)
		cmp #Cancel
		jeq QuitDlog
		cmp #OK
		bne DlogLoop

		tool _GetIText,in=(TheDlog:l,#4:w,!pagetext:l)
		lda pagetext
		and #$00FF
		jeq QuitDlog

		tax
		tool _Dec2Int,in=(!pagetext+1:l,x:w,#0:w),out=(first:w)
		jcs QuitDlog

		tool _GetIText,in=(TheDlog:l,#6:w,!pagetext:l)
		lda pagetext
		and #$00FF
		bne GetLast

		moveword last,first
		bra GotLast

GetLast	tax
		tool _Dec2Int,in=(!pagetext+1:l,x:w,#0:w),out=(last:w)
		jcs QuitDlog

GotLast
		scmpw last,first
		bge GotOrder

		swap first,last

GotOrder	subword first,P_FirstPOff,first
		subword a,#2,tmp
		scmpw tmp,P_PageCount
		jge QuitDlog				; beyond page range.
		lda tmp
		bpl CkLast
		moveword #2,first		   ; don't delete before first

CkLast	subword last,P_FirstPOff,last
		jmi QuitDlog				;
		cmp #2					  ;
		jlt QuitDlog				; before page range.
		subword a,#2,a
		cmp P_PageCount
		blt StartDel

		addword P_PageCount,#1,last ; don't delete beyond last.

StartDel
		lda P_ToolType
		cmp #P_Alpha
		bne SkipIt
		call T_Deactivate,in=(#1:w,#1:w)
SkipIt
		moveword P_PageCount,oldcount
		moveword last,count
DeleteLoop	cmpw count,first
		blt DidDelete
Killit
		call P_KillPage,in=(count:w,#0:w)

		dec count
		dec P_PageCount
		bra DeleteLoop

DidDelete	pushlong P_PageArray
		tool _Multiply,in=(#P_PInfoSize:w,first:w),out=(a:w,x:w)
		phx
		subword last,first,a
		ina
		pha
		pushword #P_PInfoSize
		addword oldcount,#2,s
		call P_DeleteData,in=(:l,:w,:w,:w,:w)
;		  ;.. Hdl:l,offset:w,items:w,UnitSize:w,Count:w


		lda P_PageCount
		jne GotOne
		; make a D_New page.

		moveword #1,P_PageCount

		cmpw oldpage,#2
		blt DoInit
		moveword #2,oldpage
		stz T_Editing

DoInit	in P_PageArray:l,#2*P_PInfoSize:w,#1:w,#P_PInfoSize:w,#2:w
		xerr err
		xcall P_InsertData
		call P_InitPage,in=(#2:w)

		bra LoadIt

GotOne	cmpw first,oldpage		  ; Page was before deletion range
		bgt LoadIt				  ;

		cmpw oldpage,last
		ble InTheMiddle

		subword oldpage,last,a	  ; Page was after deletion range
		dec a					   ;
		addword a,first,oldpage	 ;
		stz T_Editing
		bra Loadit

InTheMiddle	
		stz T_Editing
		subword first,#1,oldpage	; Page was  in the deletion range.
		cmp #1					  ;
		bgt LoadIt				  ; Go to first page before deletion
		inc oldpage				 ; range if possible, or just 1st page.

LoadIt
		call D_CloseDialog,in=(TheDlog:l)
		call D_SetFileChanged,in=(P_CurrentWin:l)
		call P_FixTextObj
		call P_GrewDoc,in=(P_CurrentWin:l)
		call P_LoadPage,in=(oldpage:w)		  	; <- hacks to get the right
		call P_CenterPage,in=(#2:w)			 	; <- stuff for change page
		call P_ChangePage,in=(oldpage:w,#1:w)   ;	set up.
		tool _ValidRect,in=(#P_ContentRect:l)

		bra Exit

whoops
QuitDlog	call D_CloseDialog,in=(TheDlog:l)

Exit	RETURN
		ENDP




;---------------------------------------------------------------------------
;
; P_InitPage (PageNo:w)
;

P_InitPage	PROC		EXPORT
			;Using P_Data

		input PageNo:w
		begin

		stzl P_ObjList
		stzl P_LastObj
		stzl P_VertGuides
		stzl P_HorizGuides
		stz P_VertGCount
		stz P_HorizGCount

		cmpw PageNo,#2
		bge UseIt
		stz P_UseTemplate
		bra Done

UseIt	moveword #1,P_UseTemplate
Done	call P_SavePage,in=(PageNo:w)

		return
		ENDP



;-----------------------------------------------------------------------------
;
; P_SavePage (Page:w)
;

P_SavePage	PROC		EXPORT
			;Using P_Data
			;Using T_Data

		input Page:w
		local Hdl:l,Ptr:l,Size:l

		begin

		movelong P_PageArray,Hdl
		movelong [Hdl],Ptr

		tool _Multiply,in=(Page:w,#P_PINFOSIZE:w),out=(Size:l)

		pushlong #P_PageInfo
		addlong Size,Ptr,s
		tool _BlockMove,in=(:l,:l,#P_PINFOSIZE:l)

		return
		ENDP



;-----------------------------------------------------------------------------
;
; P_LoadPage (NewPage:w)
;
; Sets P_Page to NewPage, loads page data into globals.

P_LoadPage	PROC		EXPORT
			;Using P_Data

		input NewPage:w
		local Hdl:l,Ptr:l,Size:l

		begin

		movelong P_PageArray,Hdl
		movelong [Hdl],Ptr

		tool _Multiply,in=(NewPage:w,#P_PINFOSIZE:w),out=(Size:l)

		addlong Size,Ptr,s
		tool _BlockMove,in=(:l,#P_PageInfo:l,#P_PINFOSIZE:l)

		moveword NewPage,P_Page

		return
		ENDP




;------------------------------------------------------------------------------
;
; P_ChangePage (Page:w,Redraw:w)
;
; Changes the document to the given page, and changes the window to reflect
; this.  Any objects on the D_New page are deselected if the arrow tool is
; not in use.

P_ChangePage	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData
			;Using T_Data

		INPUT Page:w,Redraw:w
		BEGIN

		lda Redraw
		beq DidCenter
		call P_CenterPage,in=(page:w)
DidCenter

		tool _ClipRect,in=(#P_PortRect:l)

		call P_SavePage,in=(P_Page:w)
		tool _EraseRect,in=(#P_ContentRect:l)

		call P_LoadPage,in=(Page:w)			 ; Sets P_Page = page.
		call P_MergeGuides

		lda P_ToolType
		beq IsArrow
		call P_ListOp,in=(P_ObjList:l,#PL_DeselectAll:w,#0:w,#1:w,#0:l)
IsArrow

		lda Redraw
		beq DidDraw
		tool _EraseRect,in=(#P_PIconRect:l)
		call P_PageIcons
DidDraw

		tool _ClipRect,in=(#P_ContentRect:l)

		call T_ClipThread,in=(T_DotObj:l)
		call P_DrawContent,in=(#P_ContentRect:l,#0:w)
		call P_FixMenus
		call P_FixSpecMenu

		RETURN
		ENDP




;-----------------------------------------------------------------------------
;
; P_DrawTemplate (PageNo:w; RectPtr:l)
;

P_DrawTemplate	PROC		EXPORT
			;Using P_Data

		input PageNo:w,RectPtr:l
		local PHdl:l,PPtr:l,UseRight:w

		begin

; Use Right Template if not DoublePage.
; Otherwise Even Pages use Right Template (MPage = 1)
; and Odd Pages use Left Template (MPage = 0)

		moveword #1,UseRight

		lda P_DblPage
		beq DoIt
		addword PageNo,P_FirstPOff,a
		bit #1
		bne DoIt
		stz UseRight
DoIt

		movelong P_PageArray,PHdl
		movelong [PHdl],PPtr

		lda UseRight
		beq No
		addlong #P_PINFOSIZE,PPtr,PPtr
No

		call P_DrawObjList,in=([PPtr]:#4:l,RectPtr:l,#1:w)

		return
		ENDP




;------------------------------------------------------------------------------
;
; P_KillPage (PageNo:w,All:w)
;

P_KillPage	PROC		EXPORT
			;Using P_Data

		input PageNo:w,All:w

		begin

		call P_LoadPage,in=(PageNo:w)
		call P_DelObjList,in=(P_ObjList:l,#1:w,All:w)
		stzl P_ObjList
		stzl P_LastObj

		cpzl P_VertGuides
		beq DoHoriz
		tool _DisposeHandle,in=(P_VertGuides:l)
		stzl P_VertGuides

DoHoriz	cpzl P_HorizGuides
		beq Exit
		tool _DisposeHandle,in=(P_HorizGuides:l)
		stzl P_HorizGuides

Exit	call P_SavePage,in=(PageNo:w)
		return
		ENDP





;---------------------------------------------------------------------------
;
; P_MergeGuides   
;

P_MergeGuides	PROC		EXPORT
			;Using P_Data

		local UseRight:l,Ptr:l,Hdl:l
		local TemplV:l,TemplH:l,HCount:w,VCount:w
		begin

		stzl TemplV
		stzl TemplH
		stz HCount
		stz VCount

		lda P_UseTemplate
		beq DidSetup

		moveword #1,UseRight

		lda P_DblPage
		beq DoIt
		addword P_Page,P_FirstPOff,a
		bit #1
		bne DoIt
		stz UseRight
DoIt

		movelong P_PageArray,Hdl
		movelong [Hdl],Ptr

		lda UseRight
		beq No
		addlong #P_PINFOSIZE,Ptr,Ptr
No

		lda P_UseTemplate
		beq DidSetup

		movelong [Ptr]:#8,TemplV
		movelong [Ptr]:#12,TemplH

		moveword [Ptr]:#16,VCount
		moveword [Ptr]:#18,HCount

DidSetup

		in TemplV:l,P_VertGuides:l,P_AllVGuides:l
		in VCount:w,P_VertGCount:w
		out P_AllVGCount:w
		xcall P_Merge

		in TemplH:l,P_HorizGuides:l,P_AllHGuides:l
		in HCount:w,P_HorizGCount:w
		out P_AllHGCount:w
		xcall P_Merge

		return
		ENDP



;---------------------------------------------------------------------------
;
; P_CenterPage 
;
;		   given a page # (literal, not user) calculate P_PageStart
;		   so as to Q_center that page icon as well as possible.
;
;		   only side effect is the modification of P_PageStart

P_CenterPage	PROC		EXPORT
			;Using P_Data

		input page:w
		local newfirst:w,userpage:w
		begin

		cmpw page,#2						; Don't Q_center master pages.
		blt exit							;

		cmpw P_PageCount,#6				 ; No scroll arrows.
		blt UseFirst						;

		addword page,P_FirstPOff,userpage
		subword a,P_PageStart,a
		bmi DoSet
		cmp #5
		blt exit							; It's already visible

DoSet	cmpw page,#4
		blt UseFirst						; Too D_Close to the left

		cmp P_PageCount					 ; Obscure hack.
		blt GotIt

		subword P_PageCount,#3,a			; Too D_Close to the right,
		addword a,P_FirstPOff,P_PageStart   ; so get (last page - 4)
		bra exit							; to display the last 5 pp.

GotIt	subword userpage,#2,P_PageStart
		bra exit
UseFirst	addword P_FirstPOff,#2,P_PageStart
exit	return
		ENDP





;-------------------------------------------------------------------------------
;
; P_FixTextObj ()
;
; This routine is called after pages have been inserted or deleted.
; It D_Update the PageNo field in Q_Text objects.


P_FixTextObj	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData

		local PageHdl:l,PagePtr:l,PageCount:w,CurPage:w

		begin

		movelong P_PageArray,PageHdl
		movelong [PageHdl],PagePtr
		addwl #P_PINFOSIZE*2,PagePtr		 ;Skip master pages

		stz PageCount
		moveword #2,CurPage

PLoop

		call P_ListOp,in=([PagePtr]:l,#PL_FixTObj:w,#0:w,CurPage:w,#0:l)

		addwl #P_PINFOSIZE,PagePtr
		inc CurPage
		inc PageCount
		cmpw PageCount,P_PageCount
		blt PLoop

		return
		ENDP
		END

