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

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

	IMPORT	X_CopyOneHandle
	IMPORT	D_Deref
	IMPORT	X_DisposeThread
	IMPORT	P_AddObjRgn
	IMPORT	P_AddThreadRgn
	IMPORT	P_ChangePage
	IMPORT	P_ContentRect
	IMPORT	P_CopyObjList
	IMPORT	P_CurrentWin
	IMPORT	P_DelMarkObj
	IMPORT	P_DelObjList
	IMPORT	P_DeselectAll
	IMPORT	P_DrawContent
	IMPORT	P_DrawRgn
	IMPORT	P_FixMenus
	IMPORT	P_HorizGCount
	IMPORT	P_HorizGuides
	IMPORT	P_ListOp
	IMPORT	P_LoadPage
	IMPORT	P_MergeGuides
	IMPORT	P_NewTool
	IMPORT	P_NotActive
	IMPORT	P_ObjList
	IMPORT	P_Page
	IMPORT	P_SavePage
	IMPORT	P_SetDelFlag
	IMPORT	P_VertGCount
	IMPORT	P_VertGuides
	IMPORT	D_SetFileChanged
	IMPORT	D_SetUndoStr
	IMPORT	T_Clear
	IMPORT	T_ClearPrim
	IMPORT	T_Copy
	IMPORT	T_CopyPrim
	IMPORT	T_CurParHdl
	IMPORT	T_DotLine
	IMPORT	T_DotOffset
	IMPORT	T_DotParag
	IMPORT	T_FixParag
	IMPORT	T_InvSelect
	IMPORT	T_MarkOffset
	IMPORT	T_MarkParag
	IMPORT	T_Paste
	IMPORT	T_ReThread
	IMPORT	T_TextSelect
	IMPORT	T_JunkRight
	IMPORT	T_JunkLeft
	IMPORT	T_MakeParStyle



;-----------------------------------------------
;
;   Forward addresses and entries
;
;-----------------------------------------------

	ENTRY	P_ClearStr
	ENTRY	P_ColorStr
	ENTRY	P_CropStr
	ENTRY	P_CutStr
	ENTRY	P_FillStr
	ENTRY	P_FontStr
	ENTRY	P_GuideStr
	ENTRY	P_KillBuild
	ENTRY	P_MoveStr
	ENTRY	P_PenSizeStr
	ENTRY	P_SizeStr
	ENTRY	P_StretchStr
	ENTRY	P_StyleStr
	ENTRY	P_TypeStr
	ENTRY	P_UndoAux1
	ENTRY	P_UndoAux2
	ENTRY	P_UndoAux3
	ENTRY	P_UndoAux4
	ENTRY	P_UndoAuxHdl
	ENTRY	P_UndoHdl
	ENTRY	P_UndoPage
	ENTRY	P_UndoStrings
	ENTRY	P_UndoType
	ENTRY	P_RedoFlag



;-----------------------------------------------------------------------------
;
; P_SetUndoStr ()
;
; Sets the undo string according to whats in P_UndoType

P_SetUndoStr	PROC		EXPORT
			;Using P_Data
			;Using P_UndoDataSeg

		begin

		lda P_UndoType
		asl a
		asl a
		tax

		pushlong P_UndoStrings:x

		lda P_UndoType
		bpl NotRedo
		lda 3,s
		ora #$8000
		sta 3,s
NotRedo


		call D_SetUndoStr,in=(:l,P_CurrentWin:l)

Exit	return
		ENDP





;-------------------------------------------------------------------------------
;
; P_KillUndo ()
;
; Kills the undo by throwing away the undo and setting the menu.

P_KillUndo	PROC		EXPORT
			;Using P_UndoDataSeg

		begin

		call P_KillBuild
		call P_SetUndoStr

Exit	return
		ENDP




;------------------------------------------------------------------------------
;
; P_KillBuild ()
;
; Kills whatever has been stored for the undo.

P_KillBuild	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData
			;Using P_UndoDataSeg

		local CurPage:w

		begin


		lda P_UndoType
		asl a
		tax
		jmp (KillTable,x)

KillTable
	DC.W	Exit	;Can't Undo
	DC.W	PartDelete	;Move
	DC.W	PartDelete	;Stretch
	DC.W	PartDelete	;Crop
	DC.W	PartDelete	;Fill
	DC.W	PartDelete	;Q_PenSize
	DC.W	PartDelete	;ObjFontID
	DC.W	PartDelete	;ObjFont
	DC.W	PartDelete	;ObjStyle
	DC.W	PartDelete	;ObjSize
	DC.W	PartDelete	;ObjColor
	DC.W	FullDelete	;ObjClear
	DC.W	FullDelete	;ObjCut
	DC.W	GuideDispose	;Guide
	DC.W	TextDelete	;TextClear
	DC.W	TextDelete	;TextCut
	DC.W	Typing	;Typing


PartDelete
		call P_DelObjList,in=(P_UndoHdl:l,#0:w,#1:w)
		brl Exit


FullDelete
		moveword P_Page,CurPage
		cmp P_UndoPage
		beq PageOkay
		call P_SavePage,in=(CurPage:w)
		call P_LoadPage,in=(P_UndoPage:w)
PageOkay

		lda P_UndoType
		bmi Redo
		call P_DelMarkObj
		bra CkReset
Redo	call P_ListOp,in=(P_ObjList:l,#PL_ClrUndoData:w,#0:l,#0:l)

CkReset
		cmpw CurPage,P_UndoPage
		beq Exit
		call P_SavePage,in=(P_UndoPage:w)
		call P_LoadPage,in=(CurPage:w)
		bra Exit


GuideDispose
		cpzl P_UndoHdl
		beq NotMe
		tool _DisposeHandle,in=(P_UndoHdl:l)
NotMe

		cpzl P_UndoAuxHdl
		beq NotMe2
		tool _DisposeHandle,in=(P_UndoAuxHdl:l)
NotMe2	bra Exit


TextDelete
		lda P_UndoType
		bmi Exit
TextDispose	call X_DisposeThread,in=(P_UndoHdl:l,#1:w)
		bra Exit


Typing
		lda P_UndoType
		bmi TextDispose



Exit	stzl P_UndoHdl
		stz P_UndoType

		return
		ENDP




;--------------------------------------------------------------------------------
;
; P_BuildUndo (UndoType:w)
;

P_BuildUndo	PROC		EXPORT
			;Using P_Data
			;Using T_Data
			;Using P_UndoDataSeg

		input UndoType:w

		begin

		call D_SetFileChanged,in=(P_CurrentWin:l)

		lda P_NotActive
		jne Exit

		call P_KillBuild

		moveword P_Page,P_UndoPage
		moveword UndoType,P_UndoType
		asl a
		tax
		jmp (BuildTable,x)

BuildTable
	DC.W	Done	;Can't Undo
	DC.W	PartCopy	;Move
	DC.W	PartCopy	;Stretch
	DC.W	PartCopy	;Crop
	DC.W	PartCopy	;Fill
	DC.W	PartCopy	;Q_PenSize
	DC.W	PartCopy	;ObjFontID
	DC.W	PartCopy	;ObjFont
	DC.W	PartCopy	;ObjStyle
	DC.W	PartCopy	;ObjSize
	DC.W	PartCopy	;ObjColor
	DC.W	SetDelete	;ObjClear
	DC.W	SetDelete	;ObjCut
	DC.W	GuideCopy	;Guide
	DC.W	TextCopy	;TextClear
	DC.W	TextCopy	;TextCut
	DC.W	BuildType	;Typing


PartCopy
		call P_CopyObjList,in=(P_ObjList:l,#0:w),out=(P_UndoHdl:l)
		jcs DoErr
		brl Done



SetDelete
		brl Done


GuideCopy
		stzl P_UndoAuxHdl
		moveword P_HorizGCount,P_UndoAux2
		beq NoHoriz
		call X_CopyOneHandle,in=(P_HorizGuides:l),out=(P_UndoAuxHdl:l)
		jcs DoErr
NoHoriz

		stzl P_UndoHdl
		moveword P_VertGCount,P_UndoAux1
		beq Done
		call X_CopyOneHandle,in=(P_VertGuides:l),out=(P_UndoHdl:l)
		bcc Done
		tool _DisposeHandle,in=(P_UndoAuxHdl:l)
		bra DoErr


TextCopy
		moveword T_DotParag,P_UndoAux1
		moveword T_DotOffset,P_UndoAux2
		call T_Copy,out=(P_UndoHdl:l)
		bcs DoErr
		bra Done


BuildType
		moveword T_DotParag,P_UndoAux1
		moveword T_DotOffset,P_UndoAux2
		moveword T_MarkParag,P_UndoAux3
		moveword T_MarkOffset,P_UndoAux4

		stzl P_UndoHdl
		lda T_TextSelect
		beq @NoSelect
		call T_Copy,out=(P_UndoHdl:l)
@NoSelect
		bra Done



DoErr	stz P_UndoType
Done	jsl P_SetUndoStr

Exit	return
		ENDP





;-------------------------------------------------------------------------------
;
; P_BuildType ()
;
;

P_BuildType	PROC		EXPORT
			;Using P_Data
			;Using P_UndoDataSeg


		begin

		cmpw P_UndoType,#P_TypeUndo
		beq Exit

		call P_BuildUndo,in=(#P_TypeUndo:w)

Exit	return
		ENDP




;-------------------------------------------------------------------------------
;
; P_ListUndo ()
;
; Does all object list undos.
;
; Use PlaceHdl for undoing object changes.


P_ListUndo	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData
			;Using P_UndoDataSeg


		local RgnHdl:l,ObjHdl:l,ObjPtr:l,NextObj:l,PlaceNo:w
		local DataPtr1:l,DataPtr2:l,ObjSize:l
		local PlaceHdl:l,PlacePtr:l,Counter:w


		begin


		tool _NewRgn,out=(RgnHdl:l)
		movelong P_UndoHdl,ObjHdl

Loop	cpzl ObjHdl
		jeq Done

		rcall D_Deref,in=(ObjHdl:ax),out=(ObjPtr:ax)
		call P_AddObjRgn,in=(ObjPtr:l,RgnHdl:l)

		moveword [ObjPtr]:#P_UndoData,PlaceNo
		jsr GetPlace


		rcall D_Deref,in=(PlaceHdl:ax),out=(PlacePtr:ax)
		call P_AddObjRgn,in=(PlacePtr:l,RgnHdl:l)


; Set the place so redo works

		moveword PlaceNo,[PlacePtr]:#P_UndoData


; Don't copy the first 16 bytes of the object

		tool _GetHandleSize,in=(ObjHdl:l),out=(ObjSize:l)
		subword ObjSize,#16,ObjSize
		addlong #16,ObjPtr,DataPtr1
		addlong #16,PlacePtr,DataPtr2

		tool _BlockMove,in=(DataPtr2:l,#Temp:l,ObjSize:l)
		tool _BlockMove,in=(DataPtr1:l,DataPtr2:l,ObjSize:l)
		tool _BlockMove,in=(#Temp:l,DataPtr1:l,ObjSize:l)

		movelong [ObjPtr],NextObj
		tool _HUnlock,in=(PlaceHdl:l)
		tool _HUnlock,in=(ObjHdl:l)

		cmpw [PlacePtr]:#P_Type,#P_Alpha
		bne NotText
		call P_AddThreadRgn,in=(PlaceHdl:l,RgnHdl:l)
		call T_ReThread,in=(PlaceHdl:l)
NotText

		movelong NextObj,ObjHdl
		brl Loop


Done
		call P_DrawRgn,in=(RgnHdl:l)


Exit	return


; PlaceNo	 --   0 - (ObjCount-1)
; PlaceHdl	--   Points to the object in PlaceNo, if it exists.


GetPlace
		movelong P_ObjList,PlaceHdl
		stz Counter

PlaceLoop	cpzl PlaceHdl
		beq FoundIt

		cmpw Counter,PlaceNo
		beq FoundIt

		inc Counter
		movelong [PlaceHdl],PlacePtr
		movelong [PlacePtr],PlaceHdl
		bra PlaceLoop


FoundIt
		rts

Temp		DS.B 40				   ;P_TextObjSize-16

		ENDP




;------------------------------------------------------------------------------
;
; P_Undo()
;

P_Undo	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData
			;Using P_UndoDataSeg
			;Using T_Data

		local RgnHdl:l,CharCount:w,TempHdl:l

		begin +b

		cmpw P_Page,P_UndoPage
		beq Okay
		call P_ChangePage,in=(P_UndoPage:w,#1:w)
Okay


		lda P_UndoType
		asl a
		tax
		jmp (UndoTable,x)

UndoTable
	DC.W	Exit	;None
	DC.W	UndoList	;Move
	DC.W	UndoList	;Stretch
	DC.W	UndoList	;Crop
	DC.W	UndoList	;Fill
	DC.W	UndoList	;Q_PenSize
	DC.W	UndoList	;ObjFontId
	DC.W	UndoList	;ObjFont
	DC.W	UndoList	;ObjStyle
	DC.W	UndoList	;ObjSize
	DC.W	UndoList	;ObjColor
	DC.W	DeleteObj	;ObjClear
	DC.W	DeleteObj	;ObjCut
	DC.W	GuideChange	;Guide
	DC.W	TextPaste	;TextClear
	DC.W	TextPaste	;TextCut
	DC.W	Typing	;Typing


UndoList
		jsl P_ListUndo
		brl Done


DeleteObj
		call P_NewTool,in=(#P_ARROW:w,#1:w)
		jsl P_DeselectAll
		tool _NewRgn,out=(RgnHdl:l)

		lda P_UndoType
		bmi RedoDel

		call P_SetDelFlag,in=(#0:w)
		call P_ListOp,in=(P_ObjList:l,#PL_SetUndoData:w,#0:w,#1:w,#0:l)
		call P_ListOp,in=(P_ObjList:l,#PL_AddUpdate:w,RgnHdl:l,#0:l)
		bra DrawThem

RedoDel
		call P_ListOp,in=(P_ObjList:l,#PL_CpyUndoData:w,#0:l,#0:l)
		call P_ListOp,in=(P_ObjList:l,#PL_AddUpdate:w,RgnHdl:l,#0:l)
		call P_SetDelFlag,in=(#1:w)


DrawThem
		call P_DrawRgn,in=(RgnHdl:l)
		brl Done



GuideChange
		pushlong P_UndoHdl
		pushlong P_UndoAuxHdl
		pushword P_UndoAux1
		pushword P_UndoAux2

		movelong P_VertGuides,P_UndoHdl
		movelong P_HorizGuides,P_UndoAuxHdl
		moveword P_VertGCount,P_UndoAux1
		moveword P_HorizGCount,P_UndoAux2

		pullword P_HorizGCount
		pullword P_VertGCount
		pulllong P_HorizGuides
		pulllong P_VertGuides

		call P_MergeGuides
		tool _EraseRect,in=(#P_ContentRect:l)
		call P_DrawContent,in=(#P_ContentRect:l,#0:w)
		brl Done


TextPaste
		lda P_UndoType
		bmi TextDel

* I save T_DotOffSet because T_Paste screws it up and we know that it should
* never change


		pushword T_DotOffset
		call T_Paste,in=(P_UndoHdl:l,#0:w)
		inc T_TextSelect
		pullword T_DotOffSet
		
 		rcall T_JunkLeft,in=(T_MarkParag:a,T_MarkOffset:x)
   		sta T_MarkOffset


		jsl T_InvSelect
		brl Done

TextDel
* This is so that the second undo doesn't bleed style changes to adjacent text.
   		rcall T_JunkLeft,in=(T_MarkParag:a,T_MarkOffset:x)
   		sta T_MarkOffset

		call T_Copy,out=(P_UndoHdl:l)
		jsl T_Clear

		brl Done


Typing
		jsl T_InvSelect
		lda P_UndoType
		jmi RedoType

   		rcall T_JunkLeft,in=(P_UndoAux1:a,P_UndoAux2:x)
   		sta P_UndoAux2

   		rcall T_JunkLeft,in=(T_DotParag:a,T_DotOffset:x)
   		sta T_DotOffset

		in T_CurParHdl:l,P_UndoAux1:w,P_UndoAux2:w
		in T_DotParag:w,T_DotOffset:w
		out TempHdl:l
		xcall T_CopyPrim


		moveword T_DotParag,T_MarkParag
		moveword T_DotOffset,T_MarkOffset
		moveword P_UndoAux1,T_DotParag
		moveword P_UndoAux2,T_DotOffset

		jsl T_MakeParStyle
		
		in P_UndoAux1:w,P_UndoAux2:w,T_MarkParag:w,T_MarkOffset:w
		out CharCount:w
		xcall T_ClearPrim
				
		moveword P_UndoAux1,T_DotParag
		moveword P_UndoAux2,T_DotOffset
		stz T_TextSelect
		moveword P_UndoAux3,T_MarkParag

		cpzl P_UndoHdl
		beq NoPaste
  		pushword T_DotOffSet
		call T_Paste,in=(P_UndoHdl:l,#0:w)
  		pullword T_DotOffSet
		inc T_TextSelect
		jsl T_InvSelect
  		bra DidType

NoPaste
		call T_FixParag,in=(T_DotParag:w,T_DotLine:w,CharCount:w)

DidType
		movelong TempHdl,P_UndoHdl
		bra Done



RedoType
		 
		stzl TempHdl

 		lda T_TextSelect
 		beq @NoSelect
		inc P_RedoFlag

   		rcall T_JunkLeft,in=(T_DotParag:a,T_DotOffset:x)
   		sta T_DotOffset

		in T_CurParHdl:l,T_DotParag:w,T_DotOffset:w
		in T_MarkParag:w,T_MarkOffset:w
		out TempHdl:l
		xcall T_CopyPrim
				

@NoSelect
		call T_Paste,in=(P_UndoHdl:l,#1:w)			 
		movelong TempHdl,P_UndoHdl

Done
		lda P_UndoType
		eor #$8000
		sta P_UndoType

		jsl P_SetUndoStr
		jsl P_FixMenus


Exit	return
		ENDP





;-----------------------------------------------------------------------------
;
;

P_UndoDataSeg	PROC		EXPORT
		EXPORT	P_UndoType
		EXPORT	P_UndoHdl
		EXPORT	P_UndoAuxHdl
		EXPORT	P_UndoAux1
		EXPORT	P_UndoAux2
		EXPORT	P_UndoAux3
		EXPORT	P_UndoAux4
		EXPORT	P_UndoPage
		EXPORT	P_MoveStr
		EXPORT	P_StretchStr
		EXPORT	P_CropStr
		EXPORT	P_FillStr
		EXPORT	P_PenSizeStr
		EXPORT	P_FontStr
		EXPORT	P_StyleStr
		EXPORT	P_SizeStr
		EXPORT	P_ColorStr
		EXPORT	P_ClearStr
		EXPORT	P_CutStr
		EXPORT	P_GuideStr
		EXPORT	P_TypeStr
		EXPORT	P_UndoStrings
		EXPORT	P_RedoFlag
		
P_RedoFlag		DC.W 0	;special case flag

P_UndoType		DS.B 2	; Type of undo.  0 for none.
P_UndoHdl		DS.B 4	; Hdl to undo data

P_UndoAuxHdl		DS.B 4	; Aux data for certain undos
P_UndoAux1		DS.B 2
P_UndoAux2		DS.B 2
P_UndoAux3		DS.B 2
P_UndoAux4		DS.B 2

P_UndoPage		DS.B 2	; Page to undo on.

; Undo types
;			 --- located in P_Data



; Undo strings

P_MoveStr	str 'Move'
P_StretchStr	str 'Stretch'
P_CropStr	str 'Crop'
P_FillStr	str 'Fill Change'
P_PenSizeStr	str 'Pen Change'
P_FontStr	str 'Font Change'
P_StyleStr	str 'Style Change'
P_SizeStr	str 'Size Change'
P_ColorStr	str 'Color Change'
P_ClearStr	str 'Clear'
P_CutStr	str 'Cut'
P_GuideStr	str 'Guide Change'
P_TypeStr	str 'Typing'





P_UndoStrings

	DC.L	0
	DC.L	P_MoveStr
	DC.L	P_StretchStr
	DC.L	P_CropStr
	DC.L	P_FillStr
	DC.L	P_PenSizeStr
	DC.L	P_FontStr
	DC.L	P_FontStr
	DC.L	P_StyleStr
	DC.L	P_SizeStr
	DC.L	P_ColorStr

	DC.L	P_ClearStr
	DC.L	P_CutStr

	DC.L	P_GuideStr

	DC.L	P_ClearStr
	DC.L	P_CutStr
	DC.L	P_TypeStr

		ENDP
		END

