REPORT ZPOPUP NO STANDARD PAGE HEADING.
************************************************************************
* The programs ZPOPUP and ZPOPUPDE implement a talk utility -
* - similar to the UNIX talk or write commands. When zpopup is
* started via a transaction (i.e. ZPOP) it displays the active users.
* By double-clicking on the username the remote user will receive
* a popup window inviting him for a chat. The remote user starts ZPOP
* as well, and the two instances of zpops will negotiate the
* communication parameters and call zpopupde, the terminal module.
* The terminal module will enable them to send and receive the messages.
* To make these programs work, you have to assign zpopup to transaction
* code ZPOP and create status ZCLEAR for zpopupde with only the
* enter(AAAA), green arrow(BBBB), yellow arrow(CCCC) and red cross(DDDD)
************************************************************************
DATA: ESTABLISHED.
DATA: I_AM.
DATA: LINE(90).
DATA: A_NAME(22), B_NAME(22), AB_NAME(22), BA_NAME(22), MY_NAME(22).
DATA: INDXKEY LIKE INDX-SRTFD.
TABLES INDX.
DATA: CURR_TIM LIKE SY-UZEIT.
DATA: TEMP_TIM TYPE T.
DATA: MESSAGE(128).
DATA: OPCODE TYPE X VALUE 2.
DATA: BEGIN OF USR_TABL OCCURS 10.
        INCLUDE STRUCTURE UINFO.
DATA: END OF USR_TABL.
DATA: A(61).
DATA: TIM LIKE SY-UZEIT, N TYPE I VALUE 30, DTIM LIKE SY-UZEIT.

START-OF-SELECTION.
* Find out, if I am an initializator (A) or a responder (B)
  MY_NAME = SY-UNAME.
  INDXKEY = MY_NAME.
  IMPORT LINE FROM DATABASE INDX(ST) ID INDXKEY.
  IF SY-SUBRC <> 0.               "Nothing there: I am an initializator
    I_AM = 'I'.
    A_NAME = SY-UNAME.
* Get the list of logged on users
    CALL 'ThUsrInfo' ID 'OPCODE' FIELD OPCODE
        ID 'TAB' FIELD USR_TABL-*SYS*.
    WRITE: / 'Recently no one is waiting for you to connect.'.
    WRITE: / 'Doubleclick on a name of an active user, to establish'.
    WRITE: / 'a conversation or choose the green arrow to exit.'.
    SKIP.
    WRITE: /2(8)  'CLIENT',
           10(14) 'USER NAME',
           24(14) 'TRANSACTION',
           38(24) 'LAST DIALOG STEP(AGO)'.
    SKIP.
    SORT USR_TABL BY MANDT BNAME.
    LOOP AT USR_TABL.
      IF NOT USR_TABL-BNAME IS INITIAL AND USR_TABL-BNAME <> SY-UNAME
         AND USR_TABL-MANDT = SY-MANDT.
        TEMP_TIM = USR_TABL-ZEIT.
        CURR_TIM = SY-UZEIT - TEMP_TIM.
        WRITE: /2(8)  USR_TABL-MANDT,
               10(14) USR_TABL-BNAME,
               24(14) USR_TABL-TCODE,
               38(24) CURR_TIM.
        HIDE: USR_TABL-BNAME, USR_TABL-MANDT.
      ENDIF.
    ENDLOOP.
    CLEAR USR_TABL.
  ELSE.                                "I am a responder
    I_AM = 'R'.
    A_NAME = LINE.
    B_NAME = SY-UNAME.
    AB_NAME = A_NAME.
    AB_NAME+11 = B_NAME.
    CONDENSE AB_NAME NO-GAPS.
    BA_NAME = B_NAME.
    BA_NAME+11 = A_NAME.
    CONDENSE BA_NAME NO-GAPS.
* B sends an answer to A
    DELETE FROM INDX WHERE RELID = 'ST' AND
                           SRTFD = B_NAME.
    CLEAR LINE.
    EXPORT LINE TO DATABASE INDX(ST) ID AB_NAME.
    LINE = 'How are you?'.
    EXPORT LINE TO DATABASE INDX(ST) ID BA_NAME.
    COMMIT WORK AND WAIT.
* B calls the display program
    EXPORT I_AM A_NAME B_NAME AB_NAME BA_NAME TO MEMORY ID 'AAA'.
    SUBMIT ZPOPUPDE VIA SELECTION-SCREEN.
  ENDIF.                               "responder/initializator

* When a user is selected:
AT LINE-SELECTION.
* Double click
  IF NOT USR_TABL-BNAME IS INITIAL.    " When a partner is selected
* Set up my variables
    B_NAME = USR_TABL-BNAME.
    AB_NAME = A_NAME.
    AB_NAME+11 = B_NAME.
    CONDENSE AB_NAME NO-GAPS.
    BA_NAME = B_NAME.
    BA_NAME+11 = A_NAME.
    CONDENSE BA_NAME NO-GAPS.
* Construct the popup message
    MESSAGE = 'User'.
    MESSAGE+5(12) = SY-UNAME.
    MESSAGE+18(44) = 'would like to start a conversation with you.'.
    MESSAGE+63(34) = 'Please run transaction ZPOP. Time:'.
    MESSAGE+98(2) = SY-UZEIT.
    MESSAGE+100(1) = ':'.
    MESSAGE+101(2) = SY-UZEIT+2(2).
    MESSAGE+103(1) = ':'.
    MESSAGE+104(2) = SY-UZEIT+4(2).
    MESSAGE+106(10) = ' (Pacific)'.
* A sends the popup window to B
    CALL FUNCTION 'TH_POPUP'
         EXPORTING
              CLIENT         = USR_TABL-MANDT
              USER           = USR_TABL-BNAME
              MESSAGE        = MESSAGE
         EXCEPTIONS
              USER_NOT_FOUND = 1.
* A initializes the comunication: write to B, AB, BA.
    LINE = A_NAME.
    EXPORT LINE TO DATABASE INDX(ST) ID B_NAME.
    LINE = 'HELLO'.
    EXPORT LINE TO DATABASE INDX(ST) ID AB_NAME.
    CLEAR LINE.
    EXPORT LINE TO DATABASE INDX(ST) ID BA_NAME.
    COMMIT WORK AND WAIT.
* Wait for the reply for 60 seconds, display a status and check INDX
    TIM = SY-UZEIT.
    TIM = TIM + 60.
    DO.
      GET TIME.
      DTIM = TIM - SY-UZEIT.
      IF TIM < SY-UZEIT.
* No answer from B: clean INDX
        DELETE FROM INDX WHERE RELID = 'ST' AND
                               SRTFD = B_NAME.
        DELETE FROM INDX WHERE RELID = 'ST' AND
                               SRTFD = AB_NAME.
        DELETE FROM INDX WHERE RELID = 'ST' AND
                               SRTFD = BA_NAME.
        COMMIT WORK AND WAIT.
        EXIT.
      ENDIF.
* A displays a progress indicator while waiting
      A = 'Waiting for'.
      A+12(12) = USR_TABL-BNAME.
      A+25(27) = 'to respond. Remaining time:'.
      A+53(8) = DTIM.
      CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
           EXPORTING
                PERCENTAGE = ''
                TEXT       = A.
* A waits for the answer of B: reading BA
      IMPORT LINE FROM DATABASE INDX(ST) ID BA_NAME.
* An answer has come from B
      IF NOT LINE IS INITIAL.
        CLEAR LINE.
        EXPORT LINE TO DATABASE INDX(ST) ID BA_NAME.
        EXPORT LINE TO DATABASE INDX(ST) ID BA_NAME.
        COMMIT WORK AND WAIT.
        ESTABLISHED = '1'.
        EXIT.
      ENDIF.
    ENDDO.
* Answer has come: wait for 4 seconds, the start the terminal module
    IF ESTABLISHED = '1'.
      TIM = SY-UZEIT.
      TIM = TIM + 4.
      DO.
        GET TIME.
        DTIM = TIM - SY-UZEIT.
        IF TIM < SY-UZEIT.
          EXIT.
        ENDIF.
      ENDDO.
      EXPORT I_AM A_NAME B_NAME AB_NAME BA_NAME TO MEMORY ID 'AAA'.
      SUBMIT ZPOPUPDE VIA SELECTION-SCREEN.
* No answer has come
    ELSE.
      WRITE: / 'Partner does not answer.'.
    ENDIF.
  ENDIF.
  CLEAR USR_TABL.