c
c     Copyright (c) 1999,2000, Compaq Computer Corporation
c
c     See the file "license.terms" for information on usage and redistribution
c     of this file, and for a DISCLAIMER OF ALL WARRANTIES.
c
      subroutine pmplot(fw, fposy, fposx,
     1                  inxm, inym, inptx, inpty,
     2                  ctitle, ctext, cunits,
     3                  llinea, nferrl, linter,
     4                  pmfile)
      implicit none
c
c     POSTMINI graphical postprocessor program
c
c     A utility for plotting, printing and othewise manipulating data
c     from device and process simulators and external files.
c
c     Programmer: John Faricelli
c     Callable interface
c     Date:     7-Dec-91
c     Revised: 30-Jan-92    Non-interactive mode, cleaned up calling interface
c
c     Input arguments:
c
c     FW     (real)   Data values to be plotted, arranged in FORTRAN
c                     two dimensional array format (column major order).
c                     Array FW is of declared size (INYM,INXM)
c                     Data occurs within the bounds (1:INPTY,1:INPTX)
c     FPOSY  (real)   Lateral  coordinates, in units of microns, 1:INPTY
c     FPOSX  (real)   Vertical coordinates, in units of microns, 1:INPTX
c     INYM  (integer) Size of 1st dimension of array fw as declared
c     INXM  (integer) Size of 2nd dimension of array fw as declared
c     INPTY (integer) Size of 1st dimension of array fw as used
c     INPTX (integer) Size of 2nd dimension of array fw as used
c     PMFILE (character) Name of Postmini command file (optional, see below)
c     CTITLE (character) Title for plot
c     CTEXT  (character) Name of plot quantity, e.g. 'POTENTIAL'
c     CUNITS (character) Units of plot quantity, e.g. 'cm^{-3}'
c     LLINEA (logical) If .TRUE. -> data varies on a linear scale
c                      Else      -> data varies on a log scale
c     NFERRL (integer) FORTRAN logical unit number to be used for all
c                      output messages if Postmini is run non-interactively
c     LINTER (logical) If .TRUE., Postmini is assumed to be called
c                      from an interactive program.
c                      If .FALSE., Postmini is assumed to be called from
c                      a program running without user intervention (batch)
c
c     Output parameters:
c
c     PMFILE (character) Name of the Postmini save file that was last explicitly
c                        written by the user with a "SAVE" command.
c                        If no file was explicitly saved, the default file
c                        POSTMINI.PMI is returned.
c
c     Interaction of PMFILE with LINTER:
c
c     If LINTER is .TRUE.
c        If PMFILE is all blanks, then Postmini runs in interactive mode.
c        Else, interpret PMFILE, execute plot to screen, and return.
c
c     If LINTER is .FALSE.
c        If PMFILE is all blanks, then output a quasi-3D plot
c           to a file given by parameter CTEXT (with extension .PS) and return.
c           The default 'hardcopy' device is used (hardcoded to PostScript)
c        Else, interpret PMFILE, output plot to a file given by parameter
c           CTEXT, and return. The 'hardcopy' device may be specified in
c           PMFILE. An appropriate extension is added depending on the hardcopy
c           device.
c
      integer inxm, inym, inptx, inpty, nferrl
      logical  linter, llinea
      character*(*) pmfile, ctitle, ctext, cunits
      real fposy(inym), fposx(inxm), fw(inym,inxm)
c
      include 'const.h'
      include 'sysdep.cmn'
      include 'mesh.cmn'
      include 'data.cmn'
      include 'io.cmn'
      include 'plot.cmn'
      include 'compare.cmn'
      include 'units.cmn'
      include 'annotations.cmn'
      include 'defaults.cmn'
      include 'save.cmn'
      include 'callable.cmn'
      include 'version.cmn'
c
c     local variables
c
      logical invalid, err, batchmode
      integer string_len
      character*1  ch
      character*10 answer, ext
c
c     init_common will only allow one intialization, so it's safe to
c     call anywhere.
      call init_common
c
c     init_defaults will only allow one initialization, so it's safe to
c     call anywhere.
      call init_defaults(luttyo, linter)
      call menu_set_logical_units(luttyi, luttyo)
c
      call date(date_string)
c
CC    NOT FOR CALLABLE INTERFACE
CC      call get_command_line_args
c
c     Set batch mode (non-interactive) if asked by calling procedure.
      lrestore = .FALSE.
      if( linter ) then
         lbatch = .FALSE.
c        If we are passed in a PMI file, then execute and return
         if( string_len(pmfile) .ne. 0 ) then
            lrestore = .TRUE.
         endif
      else
         lbatch = .TRUE.
         luttyo = nferrl
         call mathmode_set_lun(luttyo)
      endif
c
c     Load data passed in to private storage so we can re-load it later on
      err = .FALSE.
      callable_loaded = .FALSE.      
      call store_callable_data(fw,fposy,fposx,inym,inxm,inpty,inptx,
     1                         llinea,ctext,cunits,err)
c     Only error possible is that data was truncated to fit array size
      if( err ) then
         if( linter ) then
            call get_char(ch,'Enter any character to continue: ',0)
         endif
         err = .FALSE.
      endif
c     Load data passed in to Postmini arrays
      batchmode = .FALSE.
      call load_callable_data(batchmode,err)
      if( err ) return
c     Set filename for use with making hardcopy files
      binfilestem = ctext
c
c     Reset autoscaling flags (callable only)
      oned_lfirst   = .TRUE.
      twod_lfirst   = .TRUE.
      threed_lfirst = .TRUE.
      comp_lfirst   = .TRUE.
      lfirst_read   = .TRUE.
c     Set title
      plot_title    = ctitle
c
c     If non-interactive run, call restore and then return
c
      if( lbatch ) then
         lplotfile = .TRUE.
         call get_plotfile_extension(default_hc_name,ext)
         call make_plotfile_name(given_plotfilename,ctext,ext)
         if( string_len(pmfile) .eq. 0) then
c           Perform default plot (quasi-3D)
            call ship_surface(arrdat(arrind(1)), ni, nj,
     1                        data_name(1), data_units(1),
     2                        data_nickname(1), is_data_log(1),
     3                        .FALSE.)
         else
            call do_restore_plot(pmfile,err)
         endif
         return
      else
         lplotfile = .FALSE.
      endif
c
c     If 'lrestore' mode run, call restore and then return
c
      if( lrestore ) then
         call do_restore_plot(pmfile,err)
         return
      endif
c
c     Else it's full interative. Put up main menu...
c
400   call clear_screen
      write(luttyo,300) version_string
300   format(' ','POSTMINI graphical postprocessor (',a,')'//
     1    ' ','1d        - Plot data along a 1D cut line'/
     1    ' ','2d        - Plot contours in 2D'/
     1    ' ','3d        - Plot surface in 3D perspective'/
     1    ' ','Compare   - Plot several 1D plots together '/
     1    ' ','            (also plot integrated quantities and ',
     1        'ASCII files)'/
     1    ' ','Exit      - Exit'/
     1    ' ','Find      - Find where value occurs along a 1D cut line'/
     1    ' ','Integrate - Integrate quantity in a region of device'/
     1    ' ','Line      - Print internal quantity along a 1D cut',
     1        ' line to a file'/
     1    ' ','Minmax    - Find min/max of quantity; derivatives'/
     1    ' ','Print     - Print internal quantity in formatted array',
     1        ' to a file'/
     1    ' ','Quit      - Quit (same as exit)'/
     1    ' ','Read      - Read a new data file'/
     1    ' ','Show      - List infomation about the simulation run'//
     1    ' ','Default      - Modify default plot characteristics'/
     1    ' ','Save         - Save plot information in a file '/
     1    ' ','Shell        - Run operating system commands'/
     1    ' ','Restore      - Restore plot from file'/
     1    ' ','Window       - Manage windows on workstation')
410   write(luttyo,305)
305   format(/' ','Request? ',$)
      read(luttyi,310,end=10100) answer
310   format(a)
      call upcase(answer)
c
c     switch on answer
c
      invalid = .FALSE.
      if( answer(1:1) .eq. '1' ) then
          call plot1d
      else if( answer(1:1) .eq. '2' ) then
          call plot2d
      else if( answer(1:1) .eq. '3' ) then
          call plot3d
      else if( answer(1:1) .eq. 'C' ) then
          call compare
      else if( answer(1:1) .eq. 'D' ) then
          call change_defaults
      else if( answer(1:1) .eq. 'E' ) then
         goto 10100
      else if( answer(1:1) .eq. 'F' ) then
          call find_value
      else if( answer(1:1) .eq. 'I' ) then
          call integrate
      else if( answer(1:1) .eq. 'L' ) then
         call print_line
      else if( answer(1:1) .eq. 'M' ) then
          call pm_minmax
      else if( answer(1:1) .eq. 'P' ) then
         call print_array
      else if( answer(1:1) .eq. 'Q' ) then
         goto 10100
      else if( answer(1:1) .eq. 'R' ) then
         if( answer(1:3) .eq. 'RES' ) then
            call restore_plot
         else
            call readbinfile
         endif
      else if( answer(1:1) .eq. 'S' ) then
         if( answer(1:2) .eq. 'SH' ) then
            if( answer(3:3) .eq. 'O' ) then
               call runinfo
            elseif ( answer(3:3) .eq. 'E' ) then
               call spawn_subprocess('POSTMINI', 'Postmini> ')
            else
               invalid = .TRUE.
            endif
         else
            call save_plot
         endif
      else if( answer(1:1) .eq. 'W' ) then
          call vs_window_manager
c     The following is a 'user defined' function for special hacking
c     SHHH! It's a secret!
      else if( answer(1:1) .eq. 'U' ) then
          call user_function
      else
         invalid = .TRUE.
      endif
c
      if( invalid ) then
         write(luttyo,390) answer
390      format(' ','Invaid request: ''',a,'''')
         goto 410
      else
         goto 400
      endif
c
c     the end of the road...
c
10100 continue
c
c     Write save file
      if( save_plot_type .ne. PLOT_NULL_COMMAND .and.
     1    gks_is_open ) then
c        Third argument says to create a new file (VMS only)
         call write_savefile('POSTMINI.PMI',current_window_id,
     1                       .FALSE.,err)
         pmfile = savefilename
      else
         pmfile = ' '
      endif
c
CC      if( gks_is_open ) call close_gks
c
      return
      end
