      SUBROUTINE STD.MENU(ELEMENTS, UPPER, LOWER, BS)
****
* STD.MENU
      LastUpdated... = "Rev: 11:45 30NOV88 MIS.ATM REP 34 Z UTILITIES>BP>STD.MENU.IBAS"
*
*     This program will free format build a menu screen from the data
* passed.  The argument list is defined as follows:
*
*     ELEMENTS      - A dynamic array of the menu elements that are to show
*        on the screen.
*     UPPER         - Last unavailable line from top of screen.
*     LOWER         - First unavailable line below available area in
*                     center of screen.
*     BS            - The background screen to build the menu into.
*
****
*                           R E V I S I O N   L O G
* PR#     WHEN     WHO        WHY
* ======= ======== ========== ==========================================
*         28AUG86  MCLAUGHLIN INITIAL CODING
* 001     07JAN87  MCLAUGHLIN Enhance to utilitize STD.SCREEN
* 002     25FEB87  J DIGNAN   Use standard inserts
* 003     30Nov88  ATM        Revise to allow use in any screen.
*
****
      TRUE$ = 1
      FALSE$ = 0
      OTHERS$ = 1

      ERROR = ''                        ;*[001]

      COUNT = COUNT(ELEMENTS,@FM) + (ELEMENTS NE '')

      MAX.ITEM.WIDTH = 0
      AVAILABLE = LOWER - (UPPER + 1)
      FOR I = 1 TO COUNT
         LEN = LEN(ELEMENTS<I>)
         IF LEN GT MAX.ITEM.WIDTH THEN
            MAX.ITEM.WIDTH = LEN
         END
      NEXT I

      TOTAL.ITEM.WIDTH = MAX.ITEM.WIDTH + 4
      SINGLE.COLUMN = TOTAL.ITEM.WIDTH GT 39
      SINGLE.SPACING = TRUE$

      BEGIN CASE
         CASE (COUNT LE (AVAILABLE/2))
            SINGLE.COLUMN = TRUE$
            SINGLE.SPACING = FALSE$
            START.LINE = ((AVAILABLE - ((2*COUNT) - 1)) / 2) + 1
            ALIGN = ((80 - TOTAL.ITEM.WIDTH) / 2)
         CASE (COUNT LE AVAILABLE)
            SINGLE.SPACING = SINGLE.COLUMN
            START.LINE = ((AVAILABLE - COUNT) / 2) + 1
            ALIGN = ((80 - TOTAL.ITEM.WIDTH) / 2)
         CASE (COUNT LE (AVAILABLE * 2))
            IF SINGLE.COLUMN THEN
               MAX.ITEM.WIDTH = 35
               TOTAL.ITEM.WIDTH = 39
               SINGLE.COLUMN = FALSE$
            END
            SINGLE.SPACING = TRUE$
            START.LINE = ((AVAILABLE - (COUNT / 2)) / 2) + 1
            DOUBLE.COLUMN = TRUE$
            ALIGN = ''
            LEAVE = (80 - (2 * TOTAL.ITEM.WIDTH)) / 3
            ALIGN<1> = LEAVE
            ALIGN<2> = LEAVE + TOTAL.ITEM.WIDTH + LEAVE
         CASE (COUNT LE (AVAILABLE * 3))
            MAX.ITEM.WIDTH = 70 / 3
            TOTAL.ITEM.WIDTH = 80 / 3
            SINGLE.COLUMN = FALSE$
            SINGLE.SPACING = TRUE$
            START.LINE = ((AVAILABLE - (COUNT / 3)) / 3) + 1
            TRIPLE.COLUMN = TRUE$
            ALIGN = ''
            LEAVE = (80 - (3 * TOTAL.ITEM.WIDTH)) / 4
            ALIGN<1> = LEAVE
            ALIGN<2> = LEAVE + TOTAL.ITEM.WIDTH + LEAVE
            ALIGN<3> = ALIGN<2> + ALIGN<2>
         CASE OTHERS$
      END CASE

      IF SINGLE.COLUMN THEN
      END

      LINE.NO = START.LINE
      ALIGN.NO = 1
      OFFSET = UPPER + 1
      SPLIT = COUNT / 2
      FOR ITEM.NO = 1 TO COUNT
         BS := @(ALIGN<ALIGN.NO>,LINE.NO + OFFSET):FMT(ITEM.NO,'R#2'):'. ':ELEMENTS<ITEM.NO>[1,MAX.ITEM.WIDTH]
         IF SINGLE.SPACING THEN
            LINE.NO += 1
         END ELSE
            LINE.NO += 2
         END
         IF NOT(SINGLE.COLUMN) THEN
            IF (ITEM.NO GE SPLIT) THEN
               ALIGN.NO += 1
               LINE.NO = START.LINE
               SINGLE.COLUMN = TRUE$
            END
         END
      NEXT ITEM.NO
      RETURN
   END
