      $set preprocess(window1)
      *
      * @(#)mfwnote.cbl	1.0
      ************************************************************************
      * Copyright (C) 1994-1999 Micro Focus International Ltd.
      * All rights reserved.
      *  
      * This demonstration program is provided for use by users of 
      * Micro Focus products (the "Software") and may be used, 
      * modified and distributed as part of your application provided 
      * that you properly acknowledge the copyright of Micro Focus in this
      * material.
      *     
      * All conditions, warranties and undertakings, express or implied, 
      * statutory or otherwise, on the part of Micro Focus are excluded, 
      * including without limitation those of merchantability or fitness  
      * for purpose. This shall not, however, purport to exclude or 
      * restrict the liability of Micro Focus to any extent not 
      * permitted by law.
      *
      * IN NO EVENT WILL MICRO FOCUS BE LIABLE FOR ANY INDIRECT, 
      * INCIDENTAL, SPECIAL, CONSEQUENTIAL OR OTHER DAMAGES ARISING OUT 
      * OF THE USE OF THE DEMONSTRATION PROGRAM DISTRIBUTED WITH THE 
      * SOFTWARE, WHETHER OR NOT INFORMED OF THE POSSIBILITIES OF 
      * DAMAGES IN ADVANCE.  THESE LIMITATIONS APPLY TO ALL CAUSES OF 
      * ACTION, INCLUDING BREACH OF CONTRACT, BREACH OF WARRANTY, STRICT
      * LIABILITY, AND ANY ACTIONS IN TORTS.
      ************************************************************************

       identification division.
       program-id. mfwnote.

      ******************************************************************
      *                                                                *
      * This simple notepad example program allows the user to  easily *
      * jot  down notes and comments at any time.  It is  designed  to *
      * suitable  for calling from an application program in  response *
      * to the user hitting a "hot" key.  The contents of the  notepad *
      * are held between calls until the application ends with a  STOP *
      * RUN.                                                           *
      *                                                                *
      * This  program  has been produced purely to  highlight  various *
      * programming techniques that may be used with Micro Focus COBOL *
      * such as:                                                       *
      *                                                                *
      *   1 Windowing syntax                                           *
      *   2 Screen Section syntax                                      *
      *   3 Setting Escape and data keys as function keys              *
      *   4 Reading a character from the keyboard                      *
      *   5 Figurative constants to give easier maintenance            *
      *   6 Reading and setting the cursor position                    *
      *                                                                *
      *                                                                *
      ******************************************************************
       special-names.
           cursor     is cursor-position
           crt status is crt-status.

       select note-file assign filename
           organization line sequential
           file status is file-status.
       fd  note-file.
       01  note-record                  pic x(80).

       working-storage section.

      ******************************************************************
      *                                                                *
      * Note  how  the notepad and menu function keys are  set  up  as *
      * figurative constants by using level 78.  This enables the  key *
      * characters to be specified in one place only so that  changing *
      * one  of them to a different value during  maintenance  becomes *
      * trivial.   The  figurative constant is used in  the  level  88 *
      * value  for  the status key, the value to be displayed  in  the *
      * screen section display item and also in the procedure division *
      * when evaluating which key has been pressed.                    *
      *                                                                *
      * Note how the window height and width are specified as  figura- *
      * tive  constants  so  that the size of the field  to  hold  the *
      * result  can be calculated by multiplying together, the  OCCURS *
      * can be set to the correct value and the DISPLAY WINDOW in  the *
      * procedure  division specifies the same height and width.   The *
      * use of figurative constants makes maintenance much easier.     *
      *                                                                *
      ******************************************************************
       78  screen-handling		value x"af".
       78  enable-data-key		value 1.
       78  normal-data-key		value 2.
       78  key-exit                     value x"00".
       78  key-f1                       value x"01".
       78  key-enter                    value 0.
       78  key-enter2                   value x"00".
       78  key-cursor-l                 value x"03".
       78  key-cursor-r                 value x"04".
       78  key-cursor-u                 value x"05".
       78  key-cursor-d                 value x"06".
       78  key-load                     value "L".
       78  key-load2                    value "l".
       78  key-save                     value "S".
       78  key-save2                    value "s".
       78  key-calc                     value "C".
       78  key-calc2                    value "c".
       78  val-note-height              value 16.
       78  val-note-width               value 41.
       78  val-note-size                value val-note-height *
                                              val-note-width.
       77  note-window                  pic x(10).
       77  menu-window                  pic x(10).
       77  error-window                 pic x(10).
       77  current-function             pic x           value space.
           88  exit-pressed             value key-exit.
           88  f1-pressed               value key-f1.
       77  dummy-param                  pic 9(4) comp.
       78  val-result-size              value 17.
       01  calc-result                  pic -(9)9.9(6).
       01  calc-result-r redefines calc-result.
        03 result-char                  pic x occurs val-result-size.
       77  sub1                         pic 9(4) comp-x.
       77  sub2                         pic 9(4) comp-x.
       77  sub3                         pic 9(4) comp-x.
       78  val-filename-size            value 30.
       77  filename            pic x(val-filename-size) value spaces.
       77  error-message                pic x(80).

       78  selected-control             value "REVERSE".
       78  unselected-control           value " ".
       78  menu-field-max               value 4.
       01  menu-field-data.
        03 menu-field-active            pic 9(2) comp-x value 1.
        03 menu-field-control           pic x(20) occurs menu-field-max.

      ******************************************************************
      *                                                                *
      * Note  that the note-data needs to be held between  invocations *
      * of this program so we initialize with a VALUE clause at start- *
      * up rather than during the b000-initialize routine.             *
      *                                                                *
      ******************************************************************
       01  note-data value spaces.
        03 note-char                    pic x occurs val-note-size.
       01  note-data-r redefines note-data.
        03 note-line   pic x(val-note-width)  occurs val-note-height.

       01  file-status.
       88  file-ok                      value "00" thru "09".
       88  file-not-found               value "35".
       88  end-of-file                  value "10" thru "19".
        03 file-stat1                   pic x.
        03 file-stat2                   pic 9(2) comp-x.
       77  file-stat3                   pic 9(3).

       01  crt-status.
        03 crt-stat1                    pic x.
        03 crt-stat2			pic x.
        03 filler                       pic x.

       01  cursor-position.
        03 cursor-line                  pic 99 value 1.
        03 cursor-column                pic 99 value 1.
       77  saved-cursor-position        pic x(4).

       01  set-data-keys		pic 9(2) comp-x value 1.
       01  data-key-control.
        03 data-key-setting		pic 9(2) comp-x.
        03 data-or-function-key		pic x.
        78 function-selected		value "1".
        78 data-selected		value "3".
        03 data-key-value		pic x.
        03 filler                       pic 9(2) comp-x value 1.

       01  get-a-char                   pic 9(2) comp-x value 26.

       screen section.
      ******************************************************************
      *                                                                *
      * We define the note as one long field for convenience,  knowing *
      * that it will be automatically wrapped from line to line within *
      * the window.  By having this as one field then the handling  of *
      * cursor keys, character insert/delete keys, home, erase to  end *
      * of line/filed keys, etc. will all work automatically, wrapping *
      * from line to line with no explicit coding.                     *
      *                                                                *
      * BEWARE  of  keys such as delete which are configured  as  Unix *
      * kill or interrupt keys.  When running the application use  the *
      * -i run time flag to disable Unix interrupts.                   *
      *                                                                *
      ******************************************************************
       01  note-screen                  pic x(val-note-size)
                       using note-data prompt " " reverse-video.
       01  menu-screen.
        03 menu-field0         blank screen.
        03 menu-field1 control menu-field-control(1).
           05 line 1 column 3  value "Esc" highlight.
           05                  value "ape ".
        03 menu-field2 control menu-field-control(2).
           05                  value key-load highlight.
           05                  value "oad ".
        03 menu-field3 control menu-field-control(3).
           05                  value key-save highlight.
           05                  value "ave ".
        03 menu-field4 control menu-field-control(4).
           05                  value key-calc highlight.
           05                  value "alculator".

       01  menu-screen2.
        03 menu2-field1 control menu-field-control(1).
           05 line 1 column 3  value "Esc".
        03 menu2-field2 control menu-field-control(2).
           05        column 10 value key-load.
        03 menu2-field3 control menu-field-control(3).
           05        column 15 value key-save.
        03 menu2-field4 control menu-field-control(4).
           05        column 20 value key-calc.

       01  filename-screen.
        03 line 2 column 3 value "Enter filename: ".
        03        pic x(val-filename-size) using filename highlight.

       01  error-screen.
        03 line 2 column 3 pic x(80) from error-message blink highlight.
        03 line 4 column 3 value "(Press any key to exit)".

       procedure division.
       declaratives.
       x000-file-error section.
           use after standard error procedure on note-file.
       x100.
           evaluate file-stat1
           when 9
               move file-stat2 to file-stat3
               string "Error on file " delimited by size
                      filename         delimited by space
                      ", status 9/" file-stat3 delimited by size
                                                   into error-message
           when other
               if file-not-found
                   string "File "    delimited by size
                        filename     delimited by space
                        " not found" delimited by size
                                                   into error-message
               else
               if end-of-file
                   continue
               else
                   string "Error on file " delimited by size
                        filename     delimited by space
                        ", status " file-status delimited by size
                                                   into error-message
               end-if
               end-if
           end-evaluate
           if error-message not = spaces
               perform p000-error-routine
           end-if
       end declaratives.

       a000-control section.
           perform b000-initialize
           perform c000-do-note until exit-pressed
           perform d000-tidy-up.
       a999.
           exit program
           stop run.


       b000-initialize section.

           display window, line 2, column 38, lines val-note-height,
                   size val-note-width, boxed, erase, reverse
                   pop-up area is note-window,
                   bottom right title "Press Esc to exit, F1 for menu"

           move space to current-function

           move enable-data-key to data-key-setting
           perform e000-note-function-keys.
           

       c000-do-note section.
           display note-screen
           accept note-screen
           move space to current-function
           evaluate crt-stat1
           when "0"
                evaluate crt-stat2
      ******************************************************************
      *                                                                *
      * The note is one long field that automatically wraps from  line *
      * to  line.  The enter key will always position at the start  of *
      * the  field  which does not feel right, so here  we  explicitly *
      * code to make it move from line to line by using the CURSOR  IS *
      * cursor-position feature of SPECIAL-NAMES.                      *
      *                                                                *
      ******************************************************************
                when key-enter
                   if cursor-line < val-note-height
                       add 1 to cursor-line
                       move 1 to cursor-column
                   end-if
                end-evaluate
           when "1"
                evaluate crt-stat2
                when key-exit
                    move crt-stat2 to current-function
                when key-f1
                    move cursor-position to saved-cursor-position
                    perform h000-menu-initialize
                    perform g000-do-menu until exit-pressed
                    perform i000-menu-tidy
                    move space to current-function
                    move saved-cursor-position to cursor-position
                end-evaluate
           end-evaluate.

       d000-tidy-up section.
      ******************************************************************
      *                                                                *
      * The  calling program will need to enable any special  function *
      * keys that it may require after this program has returned.  All *
      * we can do here is to disable any keys enabled in this  program *
      * to keep things tidy.                                           *
      *                                                                *
      ******************************************************************
           move normal-data-key to data-key-setting
           perform e000-note-function-keys
           close window note-window.


       e000-note-function-keys section.
           move function-selected to data-or-function-key
           move key-exit to data-key-value
           perform f000-one-data-key
           move key-f1   to data-key-value
           perform f000-one-data-key.


       f000-one-data-key section.
      ******************************************************************
      *                                                                *
      * This routine enables or disables function keys.  Actual  func- *
      * tion  keys  (including  the Escape key) can  be  specified  or *
      * ordinary  data keys can be used as function keys  that  return *
      * control  to  the  program from an active  full  screen  ACCEPT *
      * statement.                                                     *
      *                                                                *
      ******************************************************************
           call screen-handling using set-data-keys data-key-control.

       g000-do-menu section.
       g100.
           perform varying sub1 from 1 by 1 until sub1 > menu-field-max
               if sub1 = menu-field-active
                   move selected-control to menu-field-control(sub1)
               else
                   move unselected-control to menu-field-control(sub1)
               end-if
           end-perform
           display menu-screen.
       g200.
           move saved-cursor-position to cursor-position
           perform m000-get-character
           move space to current-function
           evaluate crt-stat1
           when "2"
                evaluate crt-stat2
                when key-cursor-l
                   if menu-field-active <= 1
                       move menu-field-max to menu-field-active
                   else
                       subtract 1 from menu-field-active
                   end-if
                when key-cursor-r
                   if menu-field-active >= menu-field-max
                       move 1 to menu-field-active
                   else
                       add 1 to menu-field-active
                   end-if
                when key-enter2
                   evaluate menu-field-active
                   when 1      move key-exit to crt-stat2
                               move "1" to crt-stat1
                   when 2      move key-load to crt-stat2
                               move "3" to crt-stat1
                   when 3      move key-save to crt-stat2
                               move "3" to crt-stat1
                   when 4      move key-calc to crt-stat2
                               move "3" to crt-stat1
                   end-evaluate
                end-evaluate
           end-evaluate
           evaluate crt-stat1
           when "1"
                evaluate crt-stat2
                when key-exit
                    move crt-stat2 to current-function
                end-evaluate
           when "3"
                evaluate crt-stat2
                when key-load
                when key-load2
                    move 2 to menu-field-active
                    perform g100
                    display menu-screen2
                    perform q000-get-filename
                    if not exit-pressed
                        perform k000-load
                    end-if
                    set exit-pressed to true
                when key-save
                when key-save2
                    move 3 to menu-field-active
                    perform g100
                    display menu-screen2
                    perform q000-get-filename
                    if not exit-pressed
                        perform l000-save
                    end-if
                    set exit-pressed to true
                when key-calc
                when key-calc2
                    move 4 to menu-field-active
                    perform g100
                    display menu-screen2
                    call "mfwcalc" using dummy-param calc-result
                      on exception
                      move "Calculator program missing" to error-message
                      perform p000-error-routine
                    end-call
                    move enable-data-key to data-key-setting
                    perform j000-menu-function-keys
                    move saved-cursor-position to cursor-position
                    perform n000-set-result-into-note
                    set exit-pressed to true
                end-evaluate
           end-evaluate.

       h000-menu-initialize section.
           display window, line 2, column 38, lines 2, size 41,
                   erase pop-up area is menu-window
           move 1 to menu-field-active
           move normal-data-key to data-key-setting
           perform e000-note-function-keys
           move enable-data-key to data-key-setting
           perform j000-menu-function-keys.

       i000-menu-tidy section.
           close window menu-window
           move normal-data-key to data-key-setting
           perform j000-menu-function-keys
           move enable-data-key to data-key-setting
           perform e000-note-function-keys.

       j000-menu-function-keys section.
           move function-selected to data-or-function-key
           move key-exit to data-key-value
           perform f000-one-data-key
           move data-selected to data-or-function-key
           move key-load to data-key-value
           perform f000-one-data-key
           move key-load2 to data-key-value
           perform f000-one-data-key
           move key-save to data-key-value
           perform f000-one-data-key
           move key-save2 to data-key-value
           perform f000-one-data-key
           move key-calc to data-key-value
           perform f000-one-data-key
           move key-calc2 to data-key-value
           perform f000-one-data-key.

       k000-load section.
           open input note-file
           if file-ok
               read note-file
               perform varying sub1 from 1 by 1 until
                                               sub1 >= val-note-width
                   if note-char(sub1) < space or > "z"
                       close note-file
                       move "File to load is not text" to error-message
                       perform p000-error-routine
                       go to k999
                   end-if
               end-perform
               perform with test before varying sub1 from 1 by 1 until
                               sub1 > val-note-height or end-of-file
                   move note-record to note-line(sub1)
                   read note-file
               end-perform
               close note-file
           end-if
           display note-screen.
       k999.
           exit.

       l000-save section.
           open output note-file
           if file-ok
               perform varying sub1 from 1 by 1 until
                                               sub1 > val-note-height
                   write note-record from note-line(sub1)
               end-perform
               close note-file
           end-if.


       m000-get-character section.
      ******************************************************************
      *                                                                *
      * This  routine reads a character from the keyboard without  the *
      * need  to  ACCEPT a data item and without the  character  being *
      * echoed to the screen.  The same function keys are detected  as *
      * during an ACCEPT and returned in a crt-status format.          *
      *                                                                *
      ******************************************************************
           call screen-handling using get-a-char crt-status.

       n000-set-result-into-note section.
           move 1 to sub1
           inspect calc-result tallying sub1 for leading space
           move val-result-size to sub2
           perform with test before
                       until result-char(sub2) not = zero
               subtract 1 from sub2
           end-perform
           if result-char(sub2) = "."
               subtract 1 from sub2
           end-if
      ******************************************************************
      *                                                                *
      * When  a  full  screen ACCEPT is used it will  set  the  cursor *
      * position  in cursor-position if the CURSOR IS clause has  been *
      * used in SPECIAL-NAMES.  Similarly, the cursor will be moved to *
      * the  position in cursor-position when a full screen ACCEPT  or *
      * DISPLAY is used.                                               *
      *                                                                *
      * We  use the facility here to place the number returned by  the *
      * calculator  program  at the current cursor  position  held  in *
      * cursor-line and cursor-column.                                 *
      *                                                                *
      ******************************************************************
           compute sub3 =
                   ((cursor-line - 1) * val-note-width) + cursor-column
           perform with test before varying sub1 from sub1 by 1 until
                           sub1 > sub2 or sub3 > val-note-size
               move result-char(sub1) to note-char(sub3)
               add 1 to sub3
           end-perform
           display note-screen.

       p000-error-routine section.
           display window line 9 column 20 lines 5 size 40
                   boxed erase pop-up area is error-window
                   title is "File Error!"
           display error-screen
           perform m000-get-character
           move spaces to error-message
           close window error-window.

       q000-get-filename section.
           move normal-data-key to data-key-setting
           perform j000-menu-function-keys
           move function-selected to data-or-function-key
           move key-exit to data-key-value
           perform f000-one-data-key
           display filename-screen
           accept filename-screen
           if crt-stat1 = "1" and crt-stat2 = key-exit
               set exit-pressed to true
           end-if
           if filename = spaces
               set exit-pressed to true
           end-if
           move enable-data-key to data-key-setting
           perform j000-menu-function-keys.

      *******************   End of Source  *********************
