#define MAX_WINDOWS 4
#define ACTIVEGETS 1
#define READSAVE 2
#define WAITING 3
#define NORMAL 4

#define NO_EVENT -1
#define KEYBD_EVENT 1
#define MENU_EVENT 2
#define SELECTWINDOW_EVENT 3
#define CLOSEWINDOW_EVENT 5
#define BUTTON_EVENT 6

#define OPENWINDOW_MENU 1
#define ABOUT_MENU 2

set eventmsk to 159

set procedure to first

set window title to 'First'
public WinCount, state, done, AboutOpen

declare winarray[MAX_WINDOWS]

*Initialize window array
x = 1
do while x <= MAX_WINDOWS
  winarray[x] = .f.
  inc x
enddo
WinCount = 0
done = .f.
AboutOpen = .f.

create popup menu 'Window' from "Open" at 1,1
create popup menu 'Help' from "About" at 1,1
create pulldown menu "mainmenu" from 'Window', 'Help'
set menu to "mainmenu"
create button '   Quit   ' at 20,43
create window 'Event Info' from 19, 2 to 21, 40



*Here is our event loop
myevent = -1

do while myevent <> 0
  myevent = GetEvent(NORMAL,0)
  me = myevent
  myevent = TranslateEvent(myevent)

  if myevent <> -1 
	  actwind = window ()
	  select window 'Event Info'
	  @ 0,1 say "Event      = "
	  @ 1,1 say "Translated = "
	  @ 0,13 say me
	  @ 1,13 say myevent
	  select window actwind
      noev = 0
  endif

  do ProcessEvent with myevent
enddo
return


**********************************
function TranslateEvent(ievent)
**********************************
parameter ievent

  if done
    return(0)
  endif
  do case
    case ievent = CLOSEWINDOW_EVENT .and. window() = 'CONSOLE'
      return(0)
    case ievent = BUTTON_EVENT
      return(0)
    otherwise
      return(ievent)
  endcase


**********************************
function GetEvent
**********************************
parameter emode, getstart

  do case
    case emode = ACTIVEGETS
      if getstart > 0
        read starting with getstart
      else
        read
      endif
    case emode = READSAVE
      read save
    case emode = WAITING
      @ 0,0 say
      wait ""
    otherwise
      return(chkevent())
  endcase
return(event())


**********************************
procedure ProcessEvent
**********************************
parameter ievent

do case
  case ievent = NO_EVENT
    return
  case ievent = MENU_EVENT
    if hmenu() = OPENWINDOW_MENU
      do OpenAWindow
    else
      do About
    endif
  case ievent = CLOSEWINDOW_EVENT
    do CloseAWindow
  case ievent = SELECTWINDOW_EVENT
    do SelectAWindow
  otherwise
    return
endcase
return


**********************************
procedure OpenAWindow
**********************************

x = FindWindowSlot()
offset = 1 + x * 2
winarray[x] = .t.
do UpdateAbout with WinCount + 1
set window type to 33
create window 'Window '+str(x,1) from offset, offset + 2;
                 to offset + 8, offset + 52
inc WinCount
if WinCount > 3
  disable menu 1,1
endif
return


**********************************
procedure CloseAWindow
**********************************
private w

w = window()
if w = 'CONSOLE'
  done = .t.
  return
endif
if w = 'About'
  AboutOpen = .f.
  close window 'About'
  enable menu 2,1
  return
endif
if WinCount > 3
  enable  menu 1,1
endif
do UpdateAbout with wincount - 1
x = val(substr(w,8,1))
winarray[x] = .f.
close window w
dec WinCount
return


**********************************
procedure SelectAWindow
**********************************

select window window()
return


**********************************
function FindWindowSlot
**********************************

x = 1
do while x <= MAX_WINDOWS
  if winarray[x] = .f.
    return(x)
  endif
  inc x
enddo


***********************
procedure About
***********************

set window type to 33
create window 'About' from 19,59 to 22,77
AboutOpen = .t.
**center("Example",0,0,18,9)
center("Open Windows:",1,0,18,0)
do UpdateAbout with wincount
disable menu 2,1
return


**********************************
procedure UpdateAbout
**********************************
parameter count

if .not. AboutOpen
  return
endif
select window 'About'
@ 2,0 say space (18) 
center(str(count,1),2,0,18,0)
return
