Module gui
 ! here are the shared data and methods (functions/subroutines)
 ! for the GUI for any application. Basically, drawing boxes,
 ! detecting clicks and returing action labels-- Siva. Oct 8,2000
Implicit None

Type :: guibutton  ! has size/co-ordinates, label, colour
  Real :: blx  ! x-cord of bottom left
  Real :: bly  ! y-cord of bottom left
  Real :: height
  Real :: width
  Logical :: editable  ! if .true. then button takes user input
  Character (len=20) :: name   !needed for all buttons
  Character (len=20) :: value  !needed for input buttons
  Integer :: fillstyle  ! 1 is solid, 2 is outline, 3 hatched
  Integer :: bcolour  ! colour of box
  Integer :: lcolour  ! colour of label
! 1-white, 2-red, 3-green, 4-blue, 5-cyan, 6-magenta, 7-yellow, 8-orange
End Type guibutton

contains

Subroutine init_buttons(buttons, n_buttons, filename)
  Implicit None
  Character (len=*) :: filename
  Integer, Intent(IN) :: n_buttons
  Type (guibutton), Dimension(n_buttons), Intent(INOUT) :: buttons
  Integer :: i  ! counter
!     must never put such things in the code file. -- flexibility.
!  buttons(1) = guibutton(0.1,0.89,0.1,0.15,'Button 1',1,1,3)
!  the above is done only by LAZY people.  change to gui.cfg file
  open(unit=9,file=filename,status='old')
! must handle errors gracefully like missing file...
  do i = 1, n_buttons
     !  must allow comments and not rigid format
     read(9,*) buttons(i)
  end do
End Subroutine init_buttons

Subroutine draw_button(button)
  Implicit None
  Type (guibutton), Intent(IN) :: button
  Character (Len=20) :: label
  ! first draw the button
  Call PGSFS(button%fillstyle) ! set fill style
  Call PGSCI(button%bcolour)   ! set colour and draw box
  Call PGRECT(button%blx, button%blx + button%width,  &
              button%bly, button%bly + button%height)
  ! then write the name or value inside
  Call PGSCI(button%lcolour)
  If (button%editable) Then
     label = button%value ! default value for this input
  Else
     label = button%name
  End If
    ! x, y, angle, justification, text
  Call PGPTXT(button%blx + 0.5 * button%width,  &
              button%bly + 0.5 * button%height, &
               0.0, 0.5, trim(label))
  If (button%editable) Then
      ! write name of editable button just outside on top
  Call PGPTXT(button%blx + 0.01,  &
              button%bly + button%height + 0.01, &
        0.0, 0.0, trim(button%name))
  End If
End Subroutine draw_button

Subroutine update_button_value(button, newval)
 !meant to be called when value of the button changes (user types)
  Implicit None
  Type (guibutton), Intent(IN) :: button
  Character (Len=*) :: newval
  ! we erase old value first (by rewriting with colour = box colour)
  Call PGSCI(button%bcolour)
  Call PGPTXT(button%blx + 0.5 * button%width,  &
              button%bly + 0.5 * button%height, &
               0.0, 0.5, trim(button%value))
  ! and show new value
  button%value = newval
  Call PGSCI(button%lcolour)
  Call PGPTXT(button%blx + 0.5 * button%width,  &
              button%bly + 0.5 * button%height, &
               0.0, 0.5, trim(button%value))
  ! move cursor also is a good idea, but ....
End Subroutine update_button_value

Logical Function within_button(button, x, y)
  Implicit None
  Type (guibutton), Intent(IN) :: button 
  Real, Intent(IN) :: x,y  !is this co-ordinate within button
  within_button = (button%blx <= x) .AND. &
                  (x <= button%blx + button%width) .AND. &
                  (button%bly <= y) .AND. &
                  (y <= button%bly + button%height)
End Function within_button

End Module gui

  
