!filename    FOOTNOTE  11/06/93
VAR currentPageString
VAR footName
VAR footnoteNumber
VAR rightMargin
VAR leftMargin
VAR bottomMargin
VAR bottomStartPoint
VAR lineSpacing
VAR minFrameHeight
VAR footnoteBody
VAR startBlock
VAR endblock
VAR readCharAtCursor
VAR currentFrameName
VAR placeMarker
VAR beginMacroPoint
VAR frameHoldValue
VAR frameHoldName
VAR preserveSnapToGrid
VAR holdFrameName
VAR separatorLineStyle
VAR pageOver100Flag
VAR pageOver10Flag
VAR sepLineVisibleCheck
PROCEDURE DrawInitialFootnoteFrame
!This subroutine draws the initial oversized frame. It isn't critical where this gets placed really, as long as it is
!on the right page! Also it must not start below the bottom margin of the main text body's page definition, so I used "7"
!below as a place to start. I had some problems with incorrect units when I tried to calculate a safe number so...
!I punted on this one for now. Hopefully, no one will want to use a bottom margin greater than 4 inches!
        CancelDefinedBlock
        Set CursorPosition TO placeMarker
        EndnoteJump
        FrameCreateStart
        SET a TO 72.29pt
        SET DocPrefSnapToGrid TO FALSE
        CONVERT CursorPageNumber TOSTRING currentPageString
        CONVERT footnoteNumber TOSTRING footnoteNumber
        SET footName TO footnoteNumber
        SET footName TO footname+currentpagestring
        SET FrameName TO footName
        CreateLinkTag footName
        FrameTypeText
        FrameSkipSkip
        SET FrameAutomaticFlow TO FALSE
        SET FrameOpaque TO FALSE
        SET FrameStartingPage TO CursorPageNumber
        SET FrameRightPageMarginRight TO rightMargin
        SET FrameRightPageMarginLeft TO leftMargin 
        SET FrameRightPageMarginBottom TO bottomMargin
        SET b TO bottomStartPoint + a 
        SET FrameRightPageMarginTop TO 7
        FrameProcessChanges
        DefineToParagraphEnd
        DefineRight
        StyleCreateVariation
        StyleApplyNamed "Footnotes"
        StyleApplyVariation
        PasteFromClipboard
        ParagraphUp
        DefineToParagraphEnd
        DefineRight
        StyleCreateVariation
        PasteRulerStyle
        SET StyleLeading TO StyleLeading - Env0
        StyleApplyVariation
!       The following inserts the footnote separator line that was defined before starting the macro. It's still in the
!       experimental stage, but I think it works properly now.
        StyleCreateVariation
        CancelDefinedBlock
        CursorHome
        IF Env9 = "*" THEN
        ELSE
        PUT Env9
        DefineToLineBegin
        SET AttributeUnderline TO TRUE
        SET StylePointSize TO Env6
        SET UnderlineSize TO Env7
        SET sepLineVisibleCheck TO Env8
        SET sepLineVisibleCheck TO -sepLineVisibleCheck
        IF sepLineVisibleCheck > Env6 THEN
                SET Env8 TO Env6
                SET Env8 TO -Env8
        ELSE
        END IF
        SET UnderlinePosition TO Env8
        StyleApplyVariation
        CancelDefinedBlock
END IF  
        SET a TO "footnote" + footnoteNumber
        CreateLinkTag a                         !This creates a tag inside the footnote frame used in finding frames 
                                                        !and tags to delete during the execution of FOOTSTRT macro.
END PROCEDURE

PROCEDURE ResizeFootnoteFrame
!This subroutine resizes the footnote frame based on the final style and length of the
!footnote text block. The height of the frame is based on the number of lines in the 
!frame , multiplied by the number of points used for the leading of the text. 
!Then the Env5 variable is also read to add some (variable) 'padding' to the end of the frame.
!The Env5 variable was originally intended to allow the spacing to be decreased AND increased, but
!if the spacing is decreased more than what is already determined by minFrameHeight, the text in the footnote
!frame will be shoved down below where it is visible. To avoid this I disabled the option to allow the user to
!decrease the spacing. It was not useful, but increasing the spacing still is.
!The result is a frame that has an extra line at the beginning which, at this point, still has an underline
!attribute (if this option was used). The underline attribute gets turned off later, during the TestForExistingFootnote
!procedure, if, and only if, there is a footnote frame already placed before it. So, this line serves double-duty, both
!as a means to add some space between the footnotes, and also to provide the separator line if it is used.
        FrameModifyStart footName
        CursorHome
        SET f TO StylePointSize
        CursorDown
        SET a TO NumberFrameLines
        SET lineSpacing TO StyleLeading
        SET minFrameHeight TO a * lineSpacing
        SET f TO f - StyleLeading
!       The next three lines set the left, right and bottom margins
        SET FrameRightPageMarginLeft TO leftMargin 
        SET FrameRightPageMarginRight TO rightMargin
        SET FrameRightPageMarginBottom TO bottomMargin
!       The following lines actually define the height of the frame, indirectly, by basing
!       the margin setpoints on the "minFrameHeight" determined above.
        SET a TO bottomStartPoint
        SET b TO minFrameHeight
        SET b TO b + Env5
        SET b TO b + f
        SET c TO a - b
        SET FrameRightPageMarginTop TO c
        SET FrameRightPageMarginBottom TO  PageSizeHeight - a
        SET d TO NumberFrameChars
        SET e TO StylePointSize
        FrameProcessChanges
        SET holdFrameName TO FrameName
        SET SelectedFrame TO "footnote data"
!       The next series of 'puts' writes data to the footnote data database
!       InsertMode is used to over-write the previous data
        SET InsertMode TO FALSE
        PUT footnotenumber              ! this is the 1st column in footnote data
        TableCellTab
        PUT currentPageString           !  this is the 2nd column
        TableCellTab
        PUT footname                    !  this is the 3rd column
        TableCellTab
        PUT d                           !  this is the 4th column and is a count of the characters in the footnote.
        TableCellTab
        PUT e                           !  this is the 5th column and is the last recorded Point size   
        TableCellTab
        SET SelectedFrame TO holdFrameName
        SET InsertMode TO TRUE
!       That's it, the footnote frame now has its final dimensions.
END PROCEDURE

PROCEDURE MoveFootnoteFrame
!This subroutine moves the footnote frame based on the dimension of the newly inserted footnote text block..
!This procedure is only used when more than one footnote frame is on a single page.
        FrameModifyStart  d
        SET FrameRightPageMarginBottom TO FrameRightPageMarginBottom + m
        SET FrameRightPageMarginTop TO FrameRightPageMarginTop - m
        FrameProcessChanges
END PROCEDURE

PROCEDURE TestForExistingFootnote
        REPEAT
                SET a TO FrameName
                SET SelectedFrame TO "footnote data"
                SET z TO CursorPosition         ! record where cursor was so I can return before  I leave
                CursorHome                                      ! move to beginning of footnote data table
                SearchClear
                SET SearchSearch1 TO a                  ! search for the frame currently being created
                SearchForward
                CancelDefinedBlock
                TableCellLeft                           ! move to the left to read page number of this frame
                DefineToWordEnd
                CopyToClipboard
                SET b TO PastedClipboard                ! save page number read above
                CancelDefinedBlock
                SET h TO TableCurrentRow
                IF h = 0 THEN                           ! if current row in table is 0 (the first row) then exit
                        SET SelectedFrame TO "footnote data"
                        SET CursorPosition TO z ! reset cursor position before exiting
                        EXIT
                ELSE
                END IF
                CursorWordLeft
                TableCellUp
                DefineToWordEnd
                CopyToClipBoard
                SET g TO PastedClipboard                ! read page number of preceding footnote recorded in the table
                CancelDefinedBlock
                IF b = g THEN                           !  if the page numbers read above are the same, then we need to move one
                        TableCellTab                    !  tab over to the linktag name for this footnote
                        DefineToWordEnd
                        CopyToClipboard
                        SET d TO PastedClipboard        !  and record it
                        CancelDefinedBlock 
                        SET SelectedFrame TO a          !  switch back to the frame that is being created first 
                        CursorHome
                        DefineToLineEnd
                        StyleCreateVariation
                        SET AttributeUnderline TO FALSE                 !  since this frame will not be the first on this page, turn off the separator line
                        StyleApplyVariation
                        CancelDefinedBlock
                        SET SelectedFrame TO "footnote data"            !  switch back to the database and move the cursor to where we started
                        SET CursorPosition TO z
                        SET SelectedFrame TO d                                  !  switch to the frame that needs to be moved
                        SET m TO bottomStartPoint - c                   !  pass the distance the frame needs to be moved to the next CALL
                        CALL  MoveFootnoteFrame                         !  call on this procedure to slide the frame up the page by distance 'm'
                ELSE
                        SET CursorPosition TO z                         !  if the page numbers aren't equal we still need to reset the curosr position
                        EXIT                                                            !  before exiting so the next series of data entries get properly placed.
                END IF
        END REPEAT
END PROCEDURE

MACRO DoFootnote
        SET preserveSnapToGrid TO DocPrefSnapToGrid
        CursorWordRight
        PUT " "
        CursorWordLeft
        CopyRulerStyle
        SET placeMarker TO CursorPosition
        DefineRight
        SET readCharAtCursor TO CursorCharacter
        REPEAT
                IF readCharAtCursor=" " THEN
                        EXIT
                ELSE
                        DefineRight
                        SET readCharAtCursor TO CursorCharacter
                END IF
        END REPEAT
        CopyToClipboard
        CancelDefinedBlock
        DeleteText
        SET footnoteNumber TO PastedClipboard
        SET CursorPosition TO placeMarker
        DefineToParagraphEnd
        DefineLeft
        SET currentFrameName TO SelectedFrame
        CopyToClipboard
        CancelDefinedBlock
        SET rightMargin TO FrameRightPageMarginRight
        SET leftMargin TO FrameRightPageMarginLeft
        SET bottomMargin TO FrameRightPageMarginBottom
        SET bottomStartPoint TO PageSizeHeight - FrameRightPageMarginBottom
!       Now that all the proper things have been read, the footnote frame can be created.
!       This Procedure draws an initial frame with no set of any significance) dimension yet.

CALL DrawInitialFootnoteFrame

!       This next step resizes the footnote frame that was just created so that it snugs up against the footnote text.
CALL ResizeFootnoteFrame

!       This next Procedure is the key to making footnoting work easily. It, and the MoveFootNoteFrame procedure that it calls
!       is responsible for getting the footnote frames placed in the right order on the page, and also for determing whether
!       or not to draw the 'separator' line. It was also the hardest part of the macro(s) to write. The lack of a direct way
!       to test to see if a specifc frame exists drove me nuts until I discovered I could get around it by using 'Tags' to echo the
!       footnote's framename. There IS a way to test for an existing Tag Name.!!!!
CALL TestForExistingFootnote

!       The next  step gets ready to end the macro by switching back to where it all started and resetting some of the
!       Preferences that were changed during the execution of the macro from what they were to begin with.
        SET SelectedFrame TO currentFrameName
        SET DocPrefSnapToGrid TO preserveSnapToGrid
END MACRO