
		LOAD		'Macros.dump'

		INCLUDE	'SS.equ'

		INCLUDE	'Driver.equ'
		INCLUDE	'Heap.aii.i'
		INCLUDE	'Eval.aii.i'

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

		IMPORT	D_AlertBox
		IMPORT	D_BeachBall
		IMPORT	D_DisableMItems
		IMPORT	D_EnableMItems
		IMPORT	D_FastMult
		IMPORT	D_GetRefCon
		IMPORT	D_GrowHandle
		IMPORT	D_NeedHandle
		IMPORT	D_NewCtl
		IMPORT	D_SetCursor
		IMPORT	D_SetFileChanged

		IMPORT	X_FormatValue

		IMPORT	S_ActivateScrlBars
		IMPORT	S_ActiveWindow
		IMPORT	S_AdjustTitleOffset
		IMPORT	S_AworksMemError
		IMPORT	S_BSRect
		IMPORT	S_BScrollTemp
		IMPORT	S_BuildColWdUndo
		IMPORT	S_CalcAutoStr
		IMPORT	S_ColLabRect
		IMPORT	S_CurBRMost
		IMPORT	S_CurBRSelect
		IMPORT	S_CurBRTitle
		IMPORT	S_CurBScrl
		IMPORT	S_CurChangedList
		IMPORT	S_CurChartCount
		IMPORT	S_CurChartList
		IMPORT	S_CurColumnWds
		IMPORT	S_CurContHt
		IMPORT	S_CurContRect
		IMPORT	S_CurContWd
		IMPORT	S_CurContXpt
		IMPORT	S_CurContYpt
		IMPORT	S_CurCopySize
		IMPORT	S_CurDefColWd
		IMPORT	S_CurDefFormat
		IMPORT	S_CurEditFlag
		IMPORT	S_CurFormat
		IMPORT	S_CurGrow
		IMPORT	S_CurHeap
		IMPORT	S_CurLEHandle
		IMPORT	S_CurMaxTLCell
		IMPORT	S_CurRScrl
		IMPORT	S_CurRowBlock
		IMPORT	S_CurSheet
		IMPORT	S_CurSheetInfo
		IMPORT	S_CurTLCell
		IMPORT	S_CurTLSelect
		IMPORT	S_CurTLTitle
		IMPORT	S_CurTwiceVertLines
		IMPORT	S_CurVPageSize
		IMPORT	S_CurVertLineHandSize
		IMPORT	S_CurVertLines
		IMPORT	S_CurWindow
		IMPORT	S_GetCellPtr
		IMPORT	S_GetCellTableEntry
		IMPORT	S_GrowRect
		IMPORT	S_GrowTemp
		IMPORT	S_InsertLeftPadCells
		IMPORT	S_InsertRightPadCells
		IMPORT	S_LEDestRect
		IMPORT	S_LEViewRect
		IMPORT	S_NormalizeRange
		IMPORT	S_RSRect
		IMPORT	S_RSViewSize
		IMPORT	S_RScrollTemp
		IMPORT	S_RemovePadCells
		IMPORT	S_ResetCircularBits
		IMPORT	S_RowLabRect
		IMPORT	S_ScrlUpdate
		IMPORT	S_SetUndoOff
		IMPORT	S_SheetSize
		IMPORT	S_ViewDataStr

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

		ENTRY	S_FixPadCells
		ENTRY	S_QTraverse
		ENTRY	S_SetCellWidth
		ENTRY	S_SwapOut
		ENTRY	S_WhereCell

;---------------------------------------------------------------------------
;	S_CellWidth( Col:w ): Width:w
;
;	This routine gets the width of a given cell in the current sheet.

S_CellWidth	PROC		EXPORT
			;Using	S_CurrentData

			input	Col:w
			output	Width:w
			local	WdArray:l
			error	DefaultFlag
			BEGIN

			stz		DefaultFlag

			lda		S_CurColumnWds
			ora		S_CurColumnWds+2
			beq		getDefault

			H_GetBlockPtr	S_CurColumnWds,WdArray

			ldy		Col
			lda		[WdArray],y
			and		#$00FF
			beq		getDefault

			asl		a
			asl		a
			sta		Width
			bra		Exit

getDefault
			MoveWord	S_CurDefColWd,Width
			inc		DefaultFlag

Exit
			RETURN
			ENDP

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

S_ChangeColWidth	PROC		EXPORT

			input	Col:w,NewWidth:w
			local	OldWidth:w
			error	ErrFlag
			BEGIN

			stz		ErrFlag

			Call		S_BuildColWdUndo,in=(Col:w),err=ErrFlag
			bcs		Exit

			Call		S_CellWidth,in=(Col:w),out=(OldWidth:w)
			Call		S_SetCellWidth,in=(Col:w,NewWidth:w),err=ErrFlag
			bcs		Exit

			CmpWord	OldWidth,NewWidth
			beq		Exit

			Call		S_AdjustTitleOffset

			in		Col:w,#1:w,Col:w,#9999:w,#S_FixPadCells:l
			XCall	S_QTraverse,err=ErrFlag

Exit
			RETURN
			ENDP

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

S_ChangeDef	PROC		EXPORT

			input	Cell:l
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

			Call		S_CellWidth,in=(Cell+2:w),out=(a:w)
			bcc		Exit

			in		Cell+2:w,#1:w,Cell+2:w,#9999:w,#S_FixPadCells:l
			XCall	S_QTraverse,err=ErrorFlag

Exit
			RETURN
			ENDP

;-----------------------------------------------------------------------------
;	S_ColLab2Text ( Cell:a ) Text:a
;
;	Input, an internal column number, is passed in the a-register,
;	and output, a text form of the corsponding column, is returned in
;	the a-register.

S_ColLab2Text	PROC		EXPORT

			BEGIN

			dec		a
			Tool		_UDivide,in=(a:w,#26:w),out=(:w,:w)

			pla								; quotient
			beq		OneChar

			xba
			ora		1,s						; remainder
			inc		a
			xba
			ora		#$4040

			plx								; remainder
			bra		Exit

OneChar
			pla								; remainder
			inc		a
			xba
			ora		#$4020

Exit
			RETURN
			ENDP

;-------------------------------------------------------------------------
;	S_CopyIn
;

S_CopyIn		PROC		EXPORT
			;Using	S_CurrentData

			input	DestPtr:l
			BEGIN

			in		#S_CurWindow:l,DestPtr:l,#S_CurCopySize:l
			XTool	_BlockMove

			RETURN
			ENDP

;-------------------------------------------------------------------------
;	S_CopyOut
;

S_CopyOut		PROC		EXPORT
			;Using	S_CurrentData

			input	SrcPtr:l
			BEGIN

			in		SrcPtr:l,#S_CurWindow:l,#S_CurCopySize:l
			XTool	_BlockMove

			RETURN
			ENDP

;-------------------------------------------------------------------------
;	S_FindRect
;

S_FindRect	PROC		EXPORT
			;Using	S_CurrentData

			output	TLCell:l,BRCell:l,Rect:r
			BEGIN

			PushLong	TLCell
			PushLong	BRCell
			Call		S_NormalizeRange
			PullLong	BRCell
			PullLong	TLCell

			in		TLCell:l
			out		:w,:w,:w,:w
			XCall	S_WhereCell

			pla
			bne		OK1

			lda		S_CurContYpt

OK1
			sta		Rect

chk2	pla
			bne		OK2

			lda		S_CurContXpt

OK2
			sta		Rect+2

cont	pla
			pla

			in		BRCell:l
			out		Rect+4:l,a:w,a:w
			XCall	S_WhereCell

			RETURN
			ENDP

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

S_FixPadCells	PROC		EXPORT

			input	Cell:l,CellIndex:l
			error	ErrFlag
			BEGIN

			stz		ErrFlag

	;	I believe we could do some checks to see if all this is
	;	necessary.

			in		Cell:l
			out		ax:l,ax:l
			XCall	S_RemovePadCells,err=ErrFlag
			bcs		Exit

			in		Cell:l
			out		ax:l
			XCall	S_InsertLeftPadCells,err=ErrFlag
			bcs		Exit

			in		Cell:l
			out		ax:l
			XCall	S_InsertRightPadCells,err=ErrFlag

Exit
			RETURN
			ENDP

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

S_InitState	PROC		EXPORT
			;Using	S_CurrentData

			error	ErrorFlag
			BEGIN

			H_NewHeap	S_CurHeap,err=ErrorFlag
			jcs		Exit

	;	Initialize all of the sheet fields	;

			MoveWord	#1,S_CurTLCell
			MoveWord	a,S_CurTLSelect
			MoveWord	a,S_CurBRSelect
			MoveWord	a,S_CurBRMost

			MoveWord	a,S_CurTLCell+2
			MoveWord	a,S_CurTLSelect+2
			MoveWord	a,S_CurBRSelect+2
			MoveWord	a,S_CurBRMost+2

			MoveWord	#9988,S_CurMaxTLCell	; TLRow = 9989
			MoveWord	#$2B9,S_CurMaxTLCell+2	; TLCol = ZU

			MoveWord	#S_EditHeight+S_ColLabelHeight,S_CurContYPt
			MoveWord	#S_NumLabelWidth,S_CurContXPt

			lda		#0
			MoveWord	a,S_CurTLTitle
			MoveWord	a,S_CurTLTitle+2
			MoveWord	a,S_CurBRTitle
			MoveWord	a,S_CurBRTitle+2

			MoveWord	a,S_CurRowBlock
			MoveWord	a,S_CurRowBlock+2

			MoveWord	a,S_CurChartCount
			MoveWord	a,S_CurChartList
			MoveWord	a,S_CurChartList+2

			MoveWord	a,S_CurChangedList
			MoveWord	a,S_CurChangedList+2

			MoveWord	a,S_CurColumnWds
			MoveWord	a,S_CurColumnWds+2

			MoveWord	a,S_CurEditFlag


			MoveWord	#S_DefaultColWd,S_CurDefColWd

			MoveLong	#S_DefDefFormat,S_CurDefFormat
;			MoveWord	#S_DefDefFormat,S_CurDefFormat
;			MoveWord	#^S_DefDefFormat,S_CurDefFormat+2

			MoveWord	S_CurContYpt,S_RowLabRect
			MoveWord	S_CurContXpt,S_ColLabRect+2

Exit
			RETURN
			ENDP

;----------------------------------------------------------------------------
;	S_InsertControls
;
;	This routine calculates the size of the scroll bars to be made and inserts
;	them into the window.	This routine also set the sheet's content sizes.

S_InsertControls	PROC		EXPORT
				;Using	S_CurrentData
				;Using	S_WindowData

			local	Rect:r
			error	ErrFlag
			BEGIN

			stz		ErrFlag

	;	Set the control rects to the appropriate values
	;	also set the sheet's content sizes.

			Tool		_GetPortRect,in=(!Rect:l)

			MoveWord	#S_EditHeight+1,S_RSRect
			MoveWord	#-2,S_BSRect+2

			lda		Rect+4
			inc		a
			sta		S_BSRect+4
			sta		S_GrowRect+4

			SubWord	a,#S_GrowHeight+1,S_BSRect
			sta		S_GrowRect
			sta		S_CurContHt

			inc		a
			sta		S_RSRect+4



			lda		Rect+6
			inc		a
			inc		a
			sta		S_RSRect+6
			sta		S_GrowRect+6

			SubWord	a,#S_GrowWidth+1,S_RSRect+2
			sta		S_GrowRect+2
			sta		S_CurContWd

			inc		a
			inc		a
			sta		S_BSRect+6

	;	Determine the ViewSizes of the right scroll bar

			SpaceWord
			SpaceWord
			SubWord	S_GrowRect,S_CurContYpt,s
			PushWord	#S_RowHeight
			Tool		_UDivide
			pla

			sta		S_CurVPageSize

			inc		a
			sta		S_RSViewSize

			pla


	;	Create the controls
 
			in		#S_RScrollTemp:l,S_CurWindow:l
			out		S_CurRScrl:l
			XCall	D_NewCtl

			in		#S_BScrollTemp:l,S_CurWindow:l
			out		S_CurBScrl:l
			XCall	D_NewCtl

			in		#S_GrowTemp:l,S_CurWindow:l
			out		S_CurGrow:l
			XCall	D_NewCtl

			MoveWord	S_CurContHt,S_RowLabRect+4
			MoveWord	S_CurContWd,S_ColLabRect+6

			RETURN
			ENDP

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

S_IsCellCircular	PROC		EXPORT

			input	Cell:l
			local	CellPtr:l
			error	ErrFlag
			BEGIN

			stz		ErrFlag

			in		Cell:l
			out		CellPtr:l
			XCall	S_GetCellPtr

			ora		CellPtr
			beq		Exit

			MoveWord	[CellPtr]:#S_CellFormat+2,a
			and		#S_CellCircular

			sta		ErrFlag

Exit
			RETURN
			ENDP

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

S_LoadAWorksInfo	PROC		EXPORT
				;Using	S_CurrentData
				;Using	S_AttrData
				;Using	S_ErrorData

			input	MesgHdl:l
			local	Message:l,Pos:w,Col:w,UpdateRgn:l
			error	ErrFlag
			BEGIN

			stz		ErrFlag

			MoveLong	[MesgHdl],Message

			MoveWord	[Message]:#16,a
			bne		recalcSet

			lda		S_CurEditFlag
			ora		#S_ManCalcBit
			sta		S_CurEditFlag

			Tool		_SetMItemName,in=(#S_CalcAutoStr:l,#S_CalculateItem:w)
			Call		D_EnableMItems,in=(#S_RecalcMI:w,#5:w)
recalcSet

			MoveWord	[Message]:#18,a
			beq		showSet

			lda		S_CurEditFlag
			ora		#S_ViewFormulaBit
			sta		S_CurEditFlag

			Tool		_SetMItemName,in=(#S_ViewDataStr:l,#S_ViewItem:w)
showSet

			MoveLong	[Message]:#20,S_CurDefFormat

	;	Set the column widths	;

			MoveWord	#24-2,Pos
			MoveWord	#1-1,Col

loop
			MoveLong	[MesgHdl],Message

			inc		Pos
			inc		Pos

			lda		Col
			inc		a
			cmp		#128
			bge		done

			sta		Col

			MoveWord	[Message]:Pos,a
			cmp		#S_MinCellWidth
			blt		setMin

			cmp		#S_MaxCellWidth
			blt		setWidth

			lda		#S_MaxCellWidth
			bra		setWidth

setMin
			lda		#S_MinCellWidth

setWidth
			tax

			Call		S_ChangeColWidth,in=(Col:w,x:w),err=ErrFlag
			bcs		memError

			Call		D_BeachBall
			bra		loop

memError
			Call		D_SetCursor,in=(#ArrowCursor:w)
			Call		D_AlertBox,in=(#OKBox:w,#S_AworksMemError:l),out=(a:w)

done

			MoveLong	[MesgHdl],Message
			MoveWord	[Message]:#8,S_CurTLTitle
			MoveWord	[Message]:#10,S_CurBRTitle
			MoveWord	[Message]:#12,S_CurTLTitle+2
			MoveWord	[Message]:#14,S_CurBRTitle+2

			Call		S_AdjustTitleOffset
			Call		S_ActivateScrlBars

			Tool		_NewRgn,out=(UpdateRgn:l)
			Tool		_RectRgn,in=(UpdateRgn:l,#S_CurContRect:l)
			Tool		_EraseRect,in=(#S_CurContRect:l)
			Call		S_ScrlUpdate,in=(UpdateRgn:l)
			Tool		_DisposeRgn,in=(UpdateRgn:l)

;			MoveLong	[MesgHdl],Message
;			MoveLong	[Message],S_CurTLCell

			Call		D_SetFileChanged,in=(S_CurWindow:l)

			RETURN
			ENDP


;-----------------------------------------------------------------------------
;	S_NewSheet()
;
;	At the moment this routine does nothing more than allocate the required
;	space for a New spreadsheet, and then lock it down.

S_NewSheet	PROC		EXPORT
			;Using	S_CurrentData

			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

			in		#S_SheetSize:l,#0:w
			out		S_CurSheet:l
			XCall	D_NeedHandle,err=ErrorFlag
			jcs		Exit

			in		#S_LEDestRect:l,#S_LEViewRect:l,#255:w
			out		S_CurLEHandle:l
			XTool	_LENew,err=ErrorFlag
			bcc		Exit

Exit2
			Tool		_DisposeHandle,in=(S_CurSheet:l)

Exit
			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_QRTraverseTable (TLCell:l,BRCell:l,Routine:l)
;
;	This routine traverses the range in the reverse order of QTraverseTable.
; The last cell of the last row is operated on first, and so on.  The TraverseTable
; routines will invoke calls on any entry in the CellTable, while the QTraverse
; routine only calls real cells.  TraverseRange invokes calls on all cells in the
; range.

S_QRTraverseTable	PROC		EXPORT
				;Using	S_CurrentData

			input	FCol:w,FRow:w,LCol:w,LRow:w,Routine:l
			local	CurCol:w,RowIndex:l,RowPtr:l
			local	ColOffset:w,ColIndex:l
			local	RowBlock:l,RowBlockPtr:l,RowOffset:w
			error	ErrorFlag
			BEGIN	+b

			stz		ErrorFlag

			lda		#<S_NotACell
			cmp		FCol
			beq		badRange

			cmp		FRow
			beq		badRange

			cmp		LCol
			beq		badRange

			cmp		LRow
			bne		start

badRange
			brl		Exit

start
			MoveWord	LCol,CurCol
			bra		startRow

	;	Outer loop, for each row in the range, ....	;

nextRow
			dec		LRow
			MoveWord	LCol,CurCol
			bra		startRow

	;	Inner loop, for each cell in the current row, ....	;

nextCol
			dec		CurCol

startRow
			MoveLong	S_CurRowBlock,RowBlock

			ora		RowBlock
			jeq		Exit

			MoveLong	[RowBlock],RowBlockPtr

			CmpWord	LRow,[RowBlockPtr]:#S_KeyMax
			bge		RowTooBig

			SubWord	a,[RowBlockPtr]:#S_KeyMin,a
			bge		RowInRange

			brl		Exit

RowTooBig
			MoveWord	[RowBlockPtr]:y,LRow
			SubWord	a,[RowBlockPtr]:#S_KeyMin,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,RowOffset
			bra		startRowLoop

RowInRange
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,RowOffset

			tay
			MoveLong	[RowBlockPtr]:y,RowIndex
			ora		RowIndex
			bne		gotRow
			bra		startRowLoop

findRowLoop
			MoveLong	[RowBlockPtr]:RowOffset,RowIndex
			ora		RowIndex
			bne		gotRow2

startRowLoop
			dec		LRow

			SubWord	RowOffset,#4,RowOffset
			cmp		#S_KeyArray
			blt		rowQuit

			CmpWord	LRow,FRow
			bge		findRowLoop

rowQuit
			brl		Exit

gotRow2
			MoveWord	LCol,CurCol

gotRow
			MoveLong	[RowIndex],RowPtr

			CmpWord	CurCol,[RowPtr]:#S_KeyMax
			bge		ColTooBig

			SubWord	a,[RowPtr]:#S_KeyMin,a
			bge		ColInRange

			brl		cmpRow

ColTooBig
			MoveWord	[RowPtr]:y,CurCol
			SubWord	a,[RowPtr]:#S_KeyMin,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,ColOffset
			bra		startColLoop

ColInRange
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,ColOffset

			tay
			MoveLong	[RowPtr]:y,ColIndex
			ora		ColIndex
			bne		gotCol

			bra		startColLoop

findColLoop
			MoveLong	[RowPtr]:ColOffset,ColIndex
			ora		ColIndex
			bne		gotCol

startColLoop
			dec		CurCol

			SubWord	ColOffset,#4,ColOffset
			cmp		#S_KeyArray
			blt		colQuit

			CmpWord	CurCol,FCol
			bge		findColLoop

colQuit
			brl		cmpRow

gotCol
			MoveWord	Routine,Callit+1
			MoveWord	Routine+1,Callit+2

			PushWord	CurCol
			PushWord	LRow
			PushLong	ColIndex

			Call		D_BeachBall

Callit		jsl		*
			sta		ErrorFlag
			bcs		Exit

cmpCol
			CmpWord	FCol,CurCol
			jlt		nextCol

cmpRow
			CmpWord	FRow,LRow
			jlt		nextRow

Exit
			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_QTraverseTable (TLCell:l,BRCell:l,Routine:l)
;

S_QTraverseTable	PROC		EXPORT
				;Using	S_CurrentData

			input	FCol:w,FRow:w,LCol:w,LRow:w,Routine:l
			local	CurCol:w,RowIndex:l,RowPtr:l
			local	ColOffset:w,ColIndex:l
			local	RowBlock:l,RowBlockPtr:l,RowOffset:w
			local	MaxCol:w,MaxRow:w
			error	ErrorFlag
			BEGIN	+b

			stz		ErrorFlag

			lda		#<S_NotACell
			cmp		FCol
			beq		badRange

			cmp		FRow
			beq		badRange

			cmp		LCol
			beq		badRange

			cmp		LRow
			bne		start

badRange
			brl		Exit

start
			MoveWord	FCol,CurCol
			bra		startRow

	;	Outer loop, for each row in the range, ....	;

nextRow
			inc		FRow
			MoveWord	FCol,CurCol
			bra		startRow

	;	Inner loop, for each cell in the current row, ....	;

nextCol
			inc		CurCol

startRow
			MoveLong	S_CurRowBlock,RowBlock

			ora		RowBlock
			jeq		Exit

			MoveLong	[RowBlock],RowBlockPtr
			MoveWord	[RowBlockPtr]:#S_KeyMax,MaxRow

			CmpWord	FRow,[RowBlockPtr]:#S_KeyMin
			blt		rowTooSmall

			CmpWord	a,MaxRow
			blt		rowInRange

			brl		Exit

rowTooSmall
			lda		[RowBlockPtr],y
			dec		a
			sta		FRow
			MoveWord	#S_KeyArray-4,RowOffset
			bra		startRowLoop

RowInRange
			SubWord	a,[RowBlockPtr]:y,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,RowOffset

			tay
			MoveLong	[RowBlockPtr]:y,RowIndex
			ora		RowIndex
			bne		gotRow
			bra		startRowLoop

findRowLoop
			MoveLong	[RowBlockPtr]:RowOffset,RowIndex
			ora		RowIndex
			bne		gotRow2

startRowLoop
			inc		FRow
			AddWord	RowOffset,#4,RowOffset

			CmpWord	FRow,MaxRow
			bge		rowQuit

			CmpWord	LRow,FRow
			bge		findRowLoop

rowQuit
			brl		Exit

gotRow2
			MoveWord	FCol,CurCol

gotRow
			MoveLong	[RowIndex],RowPtr
			MoveWord	[RowPtr]:#S_KeyMax,MaxCol

			CmpWord	CurCol,[RowPtr]:#S_KeyMin
			blt		colTooSmall

			CmpWord	a,MaxCol
			blt		colInRange

			brl		cmpRow

colTooSmall
			lda		[RowPtr],y
			dec		a
			sta		CurCol
			MoveWord	#S_KeyArray-4,ColOffset
			bra		startColLoop

ColInRange
			SubWord	a,[RowPtr]:y,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,ColOffset

			tay
			MoveLong	[RowPtr]:y,ColIndex
			ora		ColIndex
			bne		gotCol

			bra		startColLoop

findColLoop
			MoveLong	[RowPtr]:ColOffset,ColIndex
			ora		ColIndex
			bne		gotCol

startColLoop
			inc		CurCol
			AddWord	ColOffset,#4,ColOffset

			CmpWord	CurCol,MaxCol
			bge		colQuit

			CmpWord	LCol,CurCol
			bge		findColLoop

colQuit
			brl		cmpRow

gotCol
			MoveWord	Routine,Callit+1
			MoveWord	Routine+1,Callit+2

			PushWord	CurCol
			PushWord	FRow
			PushLong	ColIndex

			Call		D_BeachBall

Callit		jsl		*
			sta		ErrorFlag
			bcs		Exit

cmpCol
			CmpWord	CurCol,LCol
			jlt		nextCol

cmpRow
			CmpWord	FRow,LRow
			jlt		nextRow

Exit
			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_QTraverse (TLCell:l,BRCell:l,Routine:l)
;

S_QTraverse	PROC		EXPORT
			;Using	S_CurrentData

			input	FCol:w,FRow:w,LCol:w,LRow:w,Routine:l
			local	CurCol:w,RowIndex:l,RowPtr:l
			local	ColOffset:w,ColIndex:l
			local	RowBlock:l,RowBlockPtr:l,RowOffset:w
			local	MaxCol:w,MaxRow:w
			error	ErrorFlag
			BEGIN	+b

			stz		ErrorFlag

			lda		#<S_NotACell
			cmp		FCol
			beq		badRange

			cmp		FRow
			beq		badRange

			cmp		LCol
			beq		badRange

			cmp		LRow
			bne		start

badRange
			brl		Exit

start
			MoveWord	FCol,CurCol
			bra		startRow

	;	Outer loop, for each row in the range, ....	;

nextRow
			inc		FRow
			MoveWord	FCol,CurCol
			bra		startRow

	;	Inner loop, for each cell in the current row, ....	;

nextCol
			inc		CurCol

startRow
			MoveLong	S_CurRowBlock,RowBlock

			ora		RowBlock
			jeq		Exit

			MoveLong	[RowBlock],RowBlockPtr
			MoveWord	[RowBlockPtr]:#S_KeyMax,MaxRow

			CmpWord	FRow,[RowBlockPtr]:#S_KeyMin
			blt		rowTooSmall

			CmpWord	a,MaxRow
			blt		rowInRange

			brl		Exit

rowTooSmall
			lda		[RowBlockPtr],y
			dec		a
			sta		FRow
			MoveWord	#S_KeyArray-4,RowOffset
			bra		startRowLoop

RowInRange
			SubWord	a,[RowBlockPtr]:y,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,RowOffset

			tay
			MoveLong	[RowBlockPtr]:y,RowIndex
			ora		RowIndex
			bne		gotRow
			bra		startRowLoop

findRowLoop
			MoveLong	[RowBlockPtr]:RowOffset,RowIndex
			ora		RowIndex
			bne		gotRow2

startRowLoop
			inc		FRow
			AddWord	RowOffset,#4,RowOffset

			CmpWord	FRow,MaxRow
			bge		rowQuit

			CmpWord	LRow,FRow
			bge		findRowLoop

rowQuit
			brl		Exit

gotRow2
			MoveWord	FCol,CurCol

gotRow
			MoveLong	[RowIndex],RowPtr
			MoveWord	[RowPtr]:#S_KeyMax,MaxCol

			CmpWord	CurCol,[RowPtr]:#S_KeyMin
			blt		colTooSmall

			CmpWord	a,MaxCol
			blt		colInRange

			brl		cmpRow

colTooSmall
			lda		[RowPtr],y
			dec		a
			sta		CurCol
			MoveWord	#S_KeyArray-4,ColOffset
			bra		startColLoop

ColInRange
			SubWord	a,[RowPtr]:y,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,ColOffset

			tay
			MoveWord	[RowPtr]:y,ColIndex
			iny
			iny
			MoveWord	[RowPtr]:y,ColIndex+2

			ora		ColIndex
			beq		startColLoop

			lda		ColIndex+2
			and		#S_CellTableFlags
			beq		gotCol

			bra		startColLoop

findColLoop
			MoveLong	[RowPtr]:ColOffset,ColIndex
			ora		ColIndex
			beq		startColLoop

			lda		ColIndex+2
			and		#S_CellTableFlags
			beq		gotCol

startColLoop
			inc		CurCol
			AddWord	ColOffset,#4,ColOffset

			CmpWord	CurCol,MaxCol
			bge		colQuit

			CmpWord	LCol,CurCol
			bge		findColLoop

colQuit
			brl		cmpRow

gotCol
			MoveWord	Routine,Callit+1
			MoveWord	Routine+1,Callit+2

			PushWord	CurCol
			PushWord	FRow
			PushLong	ColIndex

			Call		D_BeachBall

Callit		jsl		*
			sta		ErrorFlag
			bcs		Exit

cmpCol
			CmpWord	CurCol,LCol
			jlt		nextCol

cmpRow
			CmpWord	FRow,LRow
			jlt		nextRow

Exit
			RETURN
			ENDP

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

S_ResetCircularity	PROC		EXPORT
				;Using	S_CurrentData

			input	Cell:l
			local	CellTableEntry:l,CellPtr:l,DependPtr:l,NextCell:l
			local	DLimit:l,DNext:l,DependIndex:l,DependList:l
			BEGIN

			Call		S_GetCellTableEntry,in=(Cell:l),out=(CellTableEntry:l)

			ora		CellTableEntry
			jeq		Exit

			lda		CellTableEntry+2
			and		#S_CellTableFlags
			beq		realCell

			MoveLong	CellTableEntry,DependList
			bra		gotDepList

realCell
			H_GetBlockPtr	CellTableEntry,CellPtr

			MoveWord	[CellPtr]:#S_CellFormat+2,a
			and		#-1-S_CellCircular
			MoveWord	a,[CellPtr]:y

			MoveLong	[CellPtr]:#S_CellDependOnMe,DependList

gotDepList
			MoveWord	DependList,DependIndex
			lda		DependList+2
			and		#$FFFF-S_CellTableFlags
			sta		DependIndex+2

			ora		DependIndex
			beq		Exit

			lda		DependList+2
			bpl		fullList

			Call		S_ResetCircularBits,in=(DependIndex:l)
			bra		Exit

fullList
			H_GetBlockPtr	DependIndex,DependPtr

			lda		DependPtr+2
			ora		DependPtr
			beq		Exit

			MoveLong	#S_DependList,DNext
			MoveLong	[DependPtr],DLimit

circularLoop
			AddLong	DependPtr,DNext,NextCell
			Call		S_ResetCircularBits,in=([NextCell]:l)

			AddLong	DNext,#S_DependInc,DNext

			CmpLong	DNext,DLimit
			blt		circularLoop

Exit
			RETURN
			ENDP

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

S_RestoreWidth	PROC		EXPORT

			input	Cell:l
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

			Call		S_CellWidth,in=(Cell+2:w),out=(a:w)
			bcs		Exit

			Call		S_ChangeColWidth,in=(Cell+2:w,#0:w),err=ErrorFlag

Exit
			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_SetBRMostCell
;

S_SetBRMostCell	PROC		EXPORT
				;Using	S_CurrentData

			input	VisibleFlag:w
			local	RowBlockPtr:l,Col:w,Row:w,RowIndex:l
			local	CellIndex:l,RowFlag:w,CellPtr:l,TableEntry:l
			local	BRMost:l,RowPtr:l,RowBlock:l,RowStruct:l
			BEGIN

			stz		RowFlag
			stz		BRMost
			stz		BRMost+2

			MoveLong	S_CurRowBlock,RowBlock
			ora		RowBlock
			jeq		setBRMost

			MoveLong	[RowBlock],RowBlockPtr

			MoveWord	[RowBlockPtr]:#S_KeyMax,Row
			SubWord	a,[RowBlockPtr]:#S_KeyMin,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,RowIndex

BRLoop
			dec		Row
			SubWord	RowIndex,#4,RowIndex
			cmp		#S_KeyArray
			jlt		setBRMost

			tay
			MoveLong	[RowBlockPtr]:y,RowStruct
			ora		RowStruct
			beq		BRLoop

			MoveLong	[RowStruct],RowPtr
			MoveWord	[RowPtr]:#S_KeyMax,Col
			SubWord	a,[RowPtr]:#S_KeyMin,a
			asl		a
			asl		a
			AddWord	a,#S_KeyArray,CellIndex

contentLoop
			dec		Col
			SubWord	CellIndex,#4,CellIndex
			cmp		#S_KeyArray
			blt		BRLoop

			CmpWord	BRMost+2,Col
			bge		BRLoop

			MoveLong	[RowPtr]:CellIndex,TableEntry

	;	Make sure the Entry is not zero.

			lda		TableEntry+2
			ora		TableEntry
			beq		contentLoop

	;	Make sure the Entry is a real cell.

			lda		TableEntry+2
			and		#S_CellTableFlags
			bne		contentLoop

			H_GetBlockPtr	TableEntry,CellPtr

			lda		VisibleFlag
			beq		contentOnly

			MoveWord	[CellPtr]:#S_CellFormat,a	; this allows this
			bpl		setCol					; routine to select

			and		#S_CellType				; pad cells too.
			cmp		#S_CellTypeEmpty
			beq		contentLoop
			bra		setCol

contentOnly
			MoveWord	[CellPtr]:#S_CellFormat,a
			bmi		contentLoop

setCol
			MoveWord	Col,BRMost+2

			lda		RowFlag
			bne		over

			MoveWord	Row,BRMost
			inc		RowFlag

over
			brl		BRLoop

setBRMost
			lda		BRMost
			ora		BRMost+2
			bne		doOK

			MoveWord	#0001,BRMost
			sta		BRMost+2

doOK
			MoveLong	BRMost,S_CurBRMost

Exit
			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_SetCellWidth( Col:w,Width:w )
;
;	This routine sets the width of a given cell in the current sheet.

S_SetCellWidth	PROC		EXPORT
			;Using	S_CurrentData

			input	Col:w,Width:w
			local	WdArray:l
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

			lda		S_CurColumnWds
			ora		S_CurColumnWds+2
			bne		structExists

			H_NewBlock	#S_ColWdStructSize,S_CurColumnWds,WdArray,err=ErrorFlag
			bcc			initStruct

			stz		S_CurColumnWds
			stz		S_CurColumnWds+2
			bra		Exit

;S_MaxCellWidth gequ	500

initStruct
			lda		#S_MaxCellWidth
			lsr		a
			lsr		a
			xba

			ldy		#S_ColWdStructSize-2
			sta		[WdArray],y
			lda		#0

loop
			dey
			dey
			sta		[WdArray],y
			bne		loop

			bra		pokeWd

structExists
			H_GetBlockPtr	S_CurColumnWds,WdArray

pokeWd
			lda		Width
			lsr		a
			lsr		a

			shortm
			ldy		Col
			sta		[WdArray],y
			longm

Exit
			RETURN
			ENDP

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

S_SetCurFormat	PROC		EXPORT
			;Using	S_CurrentData

			input	Cell:l
			local	CellPtr:l
			BEGIN

			in		Cell:l
			out		CellPtr:l
			XCall	S_GetCellPtr

			ora		CellPtr
			beq		setDef

			MoveWord	[CellPtr]:#S_CellFormat,a
			bmi		setDef

			MoveWord	[CellPtr]:y,S_CurFormat
			MoveWord	[CellPtr]:#S_CellFormat+2,S_CurFormat+2
			bra		Exit

setDef
			MoveLong	S_CurDefFormat,S_CurFormat

Exit
			RETURN
			ENDP

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

S_SetEdittingMenus	PROC		EXPORT
				;Using	S_AttrData

			BEGIN

			Call		S_SetUndoOff

			Call		D_DisableMItems,in=(#S_GotoMI:w,#6:w)
			Call		D_DisableMItems,in=(#S_DeleteMI:w,#3:w)
			Call		D_DisableMItems,in=(#S_InsertMI:w,#3:w)
			Call		D_DisableMItems,in=(#S_MoveMI:w,#3:w)

			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_SetMaxTLCell
;
;	This routine determines the maximum cell that can be in the top left.
;	It also sets the data size of the horizontal scroll bar.

S_SetMaxTLCell	PROC		EXPORT
			;Using	S_CurrentData

			local	Width:w,RSViewSize:w
			BEGIN

			MoveWord	S_CurContXpt,Width
			MoveWord	#$02BE,S_CurMaxTLCell+2
			bra		startloop

	;	Determine what the maximum column is	;

loop
			dec		S_CurMaxTLCell+2

startloop
			Call		S_CellWidth,in=(S_CurMaxTLCell+2:w),out=(a:w)
			AddWord	a,Width,Width
			cmp		S_CurContWd
			blt		loop

			CmpWord	S_CurMaxTLCell+2,#$02BE
			beq		doRow

			inc		S_CurMaxTLCell+2

	;	Determine what the maximum row is	;
	;	Determine the ViewSizes of the right scroll bar

doRow
			SpaceWord
			SpaceWord
			SubWord	S_CurContHt,S_CurContYpt,s
			PushWord	#S_RowHeight
			Tool		_UDivide
			pla
			sta		S_CurVPageSize

			inc		a
			sta		RSViewSize

			pla

			SubWord	#10001,RSViewSize,S_CurMaxTLCell

			RETURN
			ENDP

;---------------------------------------------------------------------------
;	S_SetVertLines
;

S_SetVertLines	PROC		EXPORT
			;Using	S_CurrentData

StartSize	equ	16

			local	VertLineHandle:l,VertLinePtr:l,Column:w,Width:w
			BEGIN

			MoveLong	S_CurVertLines,VertLineHandle
			MoveLong	[VertLineHandle],VertLinePtr

			MoveWord	S_CurContXpt,Width
			stz		S_CurTwiceVertLines
			MoveWord	S_CurTLCell+2,Column

loop
			Call		S_CellWidth,in=(Column:w),out=(:w)
			AddWord	s,Width,Width

			cmp		S_CurContWd
			bge		Exit

			MoveWord	a,[VertLinePtr]:S_CurTwiceVertLines
			iny
			iny
			sty		S_CurTwiceVertLines

			inc		Column

			cpy		S_CurVertLineHandSize
			blt		loop

resizeHand
			AddLong	S_CurVertLineHandSize,#StartSize,S_CurVertLineHandSize

			in		S_CurVertLineHandSize:l,VertLineHandle:l
			XCall	D_GrowHandle
			bcs		Exit

			MoveLong	[VertLineHandle],VertLinePtr
			bra		loop
			
Exit
			RETURN
			ENDP

;--------------------------------------------------------------------------
; S_SwapIn( Window:l )
;
;	Call this routine with Zero's in the inputs to clear out current data.

S_SwapIn		PROC		EXPORT
			;Using	S_CurrentData

			input	Window:l
			local	Sheet:l
			BEGIN

			CmpLong	Window,S_CurWindow			; everything is right
			beq		chkPort

			CmpLong	S_CurWindow,S_ActiveWindow	; do I need to Save data
			bne		bringIn

			Call		S_SwapOut

bringIn
			MoveWord	Window,S_CurWindow
			MoveWord	Window+2,S_CurWindow+2

			ora		Window					; Zero input clears
			beq		Exit						; current data

			Call		D_GetRefCon,in=(Window:l),out=(ax:l)

			MoveLong	ax,S_CurSheet
			MoveLong	ax,Sheet

			in		[Sheet]:l,#S_CurSheetInfo:l,#S_SheetSize:l
			XTool	_BlockMove

			MoveWord	S_CurContYpt,S_RowLabRect
			MoveWord	S_CurContHt,S_RowLabRect+4

			MoveWord	S_CurContXpt,S_ColLabRect+2
			MoveWord	S_CurContWd,S_ColLabRect+6

chkPort
			lda		Window
			ora		Window+2
			beq		Exit

			Tool		_SetPort,in=(Window:l)
			H_SetHeap	S_CurHeap

Exit
			RETURN
			ENDP

;--------------------------------------------------------------------------
; S_SwapOut
;

S_SwapOut		PROC		EXPORT
			;Using	S_CurrentData

			local	Sheet:l
			BEGIN	+b

			lda		S_CurWindow				; in case window is 0
			ora		S_CurWindow+2
			beq		Exit

			MoveLong	S_CurSheet,Sheet

			in		#S_CurSheetInfo:l,[Sheet]:l,#S_SheetSize:l
			XTool	_BlockMove

Exit
			RETURN
			ENDP

;--------------------------------------------------------------------------
; S_TraverseRange ( TLCell:l,BRCell:l,RoutinePtr:l )
;
;	RoutinePtr is a routine that takes 1 long (the cell) as input.

S_TraverseRange	PROC		EXPORT

			input	FCol:w,FRow:w,LCol:w,LRow:w,RoutinePtr:l
			local	CurCol:w
			error	ErrorFlag
			BEGIN

			stz		ErrorFlag

			lda		#<S_NotACell
			cmp		FCol
			beq		Exit

			cmp		FRow
			beq		Exit

			cmp		LCol
			beq		Exit

			cmp		LRow
			beq		Exit

			MoveWord	FCol,CurCol
			bra		skip1

	;	Outer loop, for each row in the range, ....

loop2
			inc		FRow
			MoveWord	CurCol,FCol
			bra		skip1

	;	Inner loop, for each cell in the current row, ....

loop1
			inc		FCol

skip1
			MoveWord	RoutinePtr,>Callit+1
			MoveWord	RoutinePtr+1,>Callit+2

			Call		D_BeachBall

			PushWord	FCol
			PushWord	FRow
Callit		jsl		*
			sta		ErrorFlag
			bcs		Exit

			CmpWord	FCol,LCol
			blt		loop1

			CmpWord	FRow,LRow
			blt		loop2

Exit
			RETURN
			ENDP

;-----------------------------------------------------------------------------
;	S_WhereCell
;

S_WhereCell	PROC		EXPORT
			;Using	S_CurrentData

			input	Cell:l
			output	Rect:r
			local	Temp:l
			BEGIN

			stz		Rect
			stz		Rect+2
			stz		Rect+4
			stz		Rect+6

			MoveLong	S_CurTLCell,Temp

			CmpWord	Cell+2,S_CurTLCell+2	; compare the columns
			blt		CalcY

			MoveWord	S_CurContXpt,Rect+2

loop
			CmpWord	Temp+2,Cell+2
			beq		gotX

			Call		S_CellWidth,in=(Temp+2:w),out=(a:w)
			inc		Temp+2

			AddWord	a,Rect+2,Rect+2
			cmp		S_CurContWd
			bge		OffRight

			bra		loop

gotX
			Call		S_CellWidth,in=(Cell+2:w),out=(a:w)
			AddWord	a,Rect+2,Rect+6
			bra		CalcY

OffRight
			MoveWord	S_CurContWd,Rect+2
			sta		Rect+6

CalcY
			SubWord	Cell,Temp,a				; compare the rows
			blt		Exit

			tax
			ldy		#S_RowHeight
			Call		D_FastMult
			sta		Temp

			AddWord	a,S_CurContYpt,Rect
			AddWord	a,#S_RowHeight,Rect+4

			CmpWord	S_CurContHt,Rect
			bge		Exit

OffBottom
			sta		Rect
			sta		Rect+4

Exit			RETURN
			ENDP

;-----------------------------------------------------------------------------
;	S_WhichCell(Xin:w,Yin:w): Cell:l,Xout:w,Yout:w
;
;	This routine determines which cell a given point is in.	It also returns
;	the point found in the upper left corner of the cell.

S_WhichCell	PROC		EXPORT
			;Using	S_CurrentData

			input	Xin:w,Yin:w
			output	Cell:l,Xout:w,Yout:w
			BEGIN

	;	Start with the TLCell	;

			MoveWord	S_CurContXpt,Xout
			MoveWord	S_CurContYpt,Yout
			MoveLong	S_CurTLCell,Cell

	;	Determine which column the point is in.	;

			bra		start1

loop1
			sta		Xout
			inc		Cell+2

start1
			Call		S_CellWidth,in=(Cell+2:w),out=(a:w)
			AddWord	a,Xout,a

			cmp		Xin
			bge		done1

			ldy		Cell+2
			cpy		#$02BF
			blt		loop1
done1

	;	Determine which row the point is in.	;

			ldy		Cell
			bra		start2

loop2
			sta		Yout
			iny

start2
			AddWord	#S_RowHeight,Yout,a

			cmp		Yin
			bge		done2

			cpy		#10000
			blt		loop2

done2
			sty		Cell

			RETURN
			ENDP
			END

