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
c     FORTRAN version of SURF routine for plotting XY mesh data in quasi-3D.
c
c     Note: calling interface is similar BUT NOT THE SAME
c     as the C SURF routine.
c
c     In particular:
c        1) FORTRAN logical variables are used on input
c        2) New input parameter to support un-scaling of data
c           (for plot of legend)
c
      subroutine surf_surf(id,
     +  title1, title2, title3, 
     +  labelx, labely, labelz,
     +  xvalues, yvalues, zvalues,
     +  nx_pts, ny_pts, isize, jsize,
     +  data_is_trigrid, nop, tri_clip,
     +  tri_npts, tri_ne,
     +  minimum_specified, minimum, maximum_specified, maximum,
     +  modify_eye,eye_radius,eye_psi,eye_theta,
     +  modify_axis,
     +  selected_axis, axis_log_flags, axis_omit_flags,
     +  axis_nonumbering_flags,
     +  axis_shortic_spacing,axis_longtic_frequency, axis_colors,
     +  hidden_line_method, data_exp)
c
      implicit none
c
      integer id, nx_pts, ny_pts, isize, jsize, hidden_line_method,
     1        data_exp
      integer tri_npts, tri_ne
      integer axis_colors(3), selected_axis(3)
      integer nop(3,tri_npts)
      character*(*) title1, title2, title3
      character*(*) labelx, labely, labelz
      real xvalues(*), yvalues(*), zvalues(*)
      real minimum(3), maximum(3)
      real axis_shortic_spacing(3), axis_longtic_frequency(3)
      real eye_radius, eye_psi, eye_theta
      logical minimum_specified(3), maximum_specified(3)
      logical axis_log_flags(3), axis_omit_flags(3),
     +        axis_nonumbering_flags(3)
      logical tri_clip(tri_ne)
      logical modify_eye, modify_axis, data_is_trigrid
c
      include 'const.h'
      include 'surf.cmn'
      include 'gksdefs.cmn'
      include 'sysdep.cmn'
c
      real req_win(4), cur_win(4), req_view(4), cur_view(4)
      integer ws_type, return_size, status, num_colors,
     +        color_or_mono, tpend
      integer i, j, n, tmpws, istat
      character*(132) ws_conid
c
c     values_type is not used, but is for compatibility with C SURF
c
c     Inquire about all the WS characteristics
c
      surf_ws%id = id
c
      call gks$inq_ws_type(surf_ws%id, status, ws_conid,
     +                      ws_type, return_size)
      call gks$inq_color_fac(ws_type, status, num_colors,
     +                       color_or_mono, surf_ws%ncolors)
      call gks$inq_ws_xform(surf_ws%id, status, tpend,
     +                      req_win, cur_win, req_view, cur_view)

      surf_ws%device_x = cur_view(2) - cur_view(1)
      surf_ws%device_y = cur_view(4) - cur_view(3)
      surf_ws%ratio = surf_ws%device_y / surf_ws%device_x

c     Mask out any bit masks in upper word of workstation type.
c     These control paper size, landscape/portrait, etc.
      tmpws =  IAND(ws_type,PM_HEX_FFFF)
      if( tmpws .eq. GKS$K_POSTSCRIPT .or.
     1    tmpws .eq. GKS$K_COLOR_POSTSCRIPT .or.
     2    tmpws .eq. GKS$K_EPSF .or.
     3    tmpws .eq. GKS$K_COLOR_EPSF ) then
c        Helvetica bold
         surf_ws%font = -107
         surf_ws%precision = GKS$K_TEXT_PRECISION_STRING
      else
         surf_ws%font = -9
         surf_ws%precision = GKS$K_TEXT_PRECISION_STROKE
      endif
c
c     Allocate arrays
      if( data_is_trigrid ) then
         n = tri_npts
      else
         n = nx_pts*ny_pts
      endif
      if( .NOT. associated(surf_curve%xposition) ) then
         allocate(surf_curve%xposition(1:n), stat=istat)
         allocate(surf_curve%yposition(1:n), stat=istat)
         allocate(surf_curve%zposition(1:n), stat=istat)
         allocate(surf_curve%scaled_xposition(1:n), stat=istat)
         allocate(surf_curve%scaled_yposition(1:n), stat=istat)
         allocate(surf_curve%scaled_zposition(1:n), stat=istat)
         allocate(surf_curve%nop(3,1:2*n), stat=istat)
         allocate(surf_curve%tri_clip(1:2*n), stat=istat)
         if( istat .ne. 0 ) then
            call display_message(
     1           'Postmini internal error: could not allocate arrays')
            return
         endif
      else if ( n .gt. surf_curve%npoints ) then
c        Reallocate arrays
         deallocate(surf_curve%xposition, stat=istat)
         deallocate(surf_curve%yposition, stat=istat)
         deallocate(surf_curve%zposition, stat=istat)
         deallocate(surf_curve%scaled_xposition, stat=istat)
         deallocate(surf_curve%scaled_yposition, stat=istat)
         deallocate(surf_curve%scaled_zposition, stat=istat)
         deallocate(surf_curve%nop, stat=istat)
         deallocate(surf_curve%tri_clip, stat=istat)
c
         allocate(surf_curve%xposition(1:n), stat=istat)
         allocate(surf_curve%yposition(1:n), stat=istat)
         allocate(surf_curve%zposition(1:n), stat=istat)
         allocate(surf_curve%scaled_xposition(1:n), stat=istat)
         allocate(surf_curve%scaled_yposition(1:n), stat=istat)
         allocate(surf_curve%scaled_zposition(1:n), stat=istat)
         allocate(surf_curve%nop(3,1:2*n), stat=istat)
         allocate(surf_curve%tri_clip(1:2*n), stat=istat)
         if( istat .ne. 0 ) then
            call display_message(
     1           'Postmini internal error: could not allocate arrays')
            return
         endif
      endif
c
c     Assign default values
      call surf_set_default
c
c     Store title lines in common
      surf_title(1) = title1
      surf_title(2) = title2
      surf_title(3) = title3
c
      surf_xaxis%label = labelx
      surf_yaxis%label = labely
      surf_zaxis%label = labelz
c

      if( modify_eye ) then
         if( eye_radius .le. 0.0 ) then
            surf_eye%radius = 1.0
         else
            surf_eye%radius = eye_radius
         endif
         surf_eye%psi    = eye_psi
         surf_eye%theta  = eye_theta
 

c        Define the new viewing transformation...
         call surf_spherical_to_cartesian(surf_eye%xposition,
     +          surf_eye%yposition, surf_eye%zposition,
     +          surf_eye%radius, surf_eye%psi, surf_eye%theta)
         surf_view%xnormal = 0.5 - surf_eye%xposition
         surf_view%ynormal = 0.5 - surf_eye%yposition
         surf_view%znormal = 0.5 - surf_eye%zposition
c        Scale u-v plane by eye radius to effect zoom */
c        Magic number 8.66 is radius of default position (5,5,5)
c        used in perspective transformation. In parallel transform,
c        we scale by 8.66 to normalize radius and keep it compatible
c        with previous versions of SURF.
         surf_view%umin = surf_view%umin*surf_eye%radius/8.66
         surf_view%umax = surf_view%umax*surf_eye%radius/8.66
         surf_view%vmin = surf_view%vmin*surf_eye%radius/8.66
         surf_view%vmax = surf_view%vmax*surf_eye%radius/8.66
      endif

      if( hidden_line_method .eq. HIDDEN_LINES_WITH_FILL_AREA .or.
     +    hidden_line_method .eq. HIDDEN_LINES_WITH_HORIZON_FCN .or.
     +    hidden_line_method .eq. HIDDEN_LINES_HISTOGRAM )
     +    surf_hidden_line_method = hidden_line_method

c     Set up colormap, if needed
      if( (surf_hidden_line_method .eq. HIDDEN_LINES_WITH_FILL_AREA
     +    .or. surf_hidden_line_method .eq. HIDDEN_LINES_HISTOGRAM)
     +    .and. surf_ws%ncolors .gt. 2 )
     +    call set_color_contour_colormap
c
c      Convert from XY mesh to vector values
       surf_curve%data_is_trigrid = data_is_trigrid
       if( data_is_trigrid ) then
          surf_curve%nx = 0
          surf_curve%ny = 0
          surf_curve%npoints = tri_npts
          surf_curve%nelem   = tri_ne
          do i=1,tri_npts
             surf_curve%xposition(i) = xvalues(i)
             surf_curve%yposition(i) = yvalues(i)
             surf_curve%zposition(i) = zvalues(i)
          end do
          do i=1,tri_ne
             surf_curve%tri_clip(i) = tri_clip(i)
             do j=1,3
                surf_curve%nop(j,i) = nop(j,i)
             end do
          end do
       else
          n = 1
          surf_curve%nx = nx_pts
          surf_curve%ny = ny_pts
          surf_curve%npoints = (nx_pts)*(ny_pts)
          do i=1,nx_pts
             do j=1,ny_pts
               surf_curve%xposition(n) = xvalues(i)
               surf_curve%yposition(n) = yvalues(j)
               surf_curve%zposition(n) = zvalues(i+(j-1)*nx_pts)
               n = n + 1
            end do
         end do
      endif

      if ( modify_axis ) then
         surf_curve%xaxis   = selected_axis(1)
         surf_curve%yaxis   = selected_axis(2)
         surf_curve%zaxis   = selected_axis(3)

         surf_xaxis%log     = axis_log_flags(1)
         surf_yaxis%log     = axis_log_flags(2)
         surf_zaxis%log     = axis_log_flags(3)

         surf_xaxis%nonumbering = axis_nonumbering_flags(1)
         surf_yaxis%nonumbering = axis_nonumbering_flags(2)
         surf_zaxis%nonumbering = axis_nonumbering_flags(3)

         surf_xaxis%tic_spacing = axis_shortic_spacing(1)
         surf_yaxis%tic_spacing = axis_shortic_spacing(2)
         surf_zaxis%tic_spacing = axis_shortic_spacing(3)

         surf_xaxis%longtic_frequency = axis_longtic_frequency(1)
         surf_yaxis%longtic_frequency = axis_longtic_frequency(2)
         surf_zaxis%longtic_frequency = axis_longtic_frequency(3)

         surf_xaxis%color  = axis_colors(1)
         surf_yaxis%color  = axis_colors(2)
         surf_zaxis%color  = axis_colors(3)
      endif


c     Set the values of the minimum and maximum.
      if( minimum_specified(1) ) then
          surf_xaxis%min_flag = .TRUE.
          surf_xaxis%min = minimum(1)
      endif
      if (minimum_specified(2)) then
         surf_yaxis%min_flag = .TRUE.
         surf_yaxis%min = minimum(2)
      endif
      if (minimum_specified(3)) then
         surf_zaxis%min_flag = .TRUE.
         surf_zaxis%min = minimum(3)
      endif

      if (maximum_specified(1)) then
          surf_xaxis%max_flag = .TRUE.
          surf_xaxis%max = maximum(1)
      endif
      if (maximum_specified(2)) then
          surf_yaxis%max_flag = .TRUE.
          surf_yaxis%max = maximum(2)
      endif
      if (maximum_specified(3)) then
          surf_zaxis%max_flag = .TRUE.
          surf_zaxis%max = maximum(3)
      endif
c
      surf_data_exp = data_exp
c
c     set_limits sets the values of minimum and maximum for the specified 
c     curves axis. And scale everything from -1. to 1.
      call surf_set_limits
c
      call surf_plot(SURF_WITH_TITLE)
      call gks$update_ws(surf_ws%id, 0)
c
      return
      end
