      SUBROUTINE grib_info(kunit, kinfo, kinfo_len, kret)

      implicit none

c-----------------------------------------------------------------------
      integer, intent(in)  :: kinfo_len     ! Length of the info vector
c***  Output variables
      integer, intent(out) :: kunit         ! PBIO file pointer
      integer, intent(out) :: kret          ! Return code
                                            !  0 = OK
                                            ! -1 = Couldn't open file
                                            ! -2 = Invalid file name
                                            ! -3 = Invalid open mode
                                            ! -4 = Invalid GRIB-file
      integer, intent(out) :: 
     $     kinfo(kinfo_len)     ! Information vector (if mode='r')
                                ! (1) = GRIB-file length in bytes
                                ! (2) = GRIB-edition number
                                ! (3) = grid type (left justified key 'SH','GG' or 'LL')
                                ! (4) = 0=Regular, 1=Quasi-regular grid
                                ! (5) = # of vertical coordinates (0=surface fields)
                                !
                                ! For 'GG' and 'LL' :
                                ! (6) =   NDGL i.e. number of latitudes
                                ! (7) = 2*NDGL = NDLON i.e. number of longitudes
                                ! (8) = Not used
                                !
                                ! For 'SH' :
                                ! (6) = J pentagonal resolution parameter
                                ! (7) = K pentagonal resolution parameter
                                ! (8) = M pentagonal resolution parameter
                                !
                                ! (9) = Number of fields in GRIB-file (an estimate)
                                !(10) = Version number of the code table 2
                                !(11) = Date (YYYYMMDD)
                                !(12) = Time (HHMM)
                                !(13) = Latitude of the first grid point
                                !(14) = Longitude of the first grid point
                                !(15) = Latitude of the last grid point
                                !(16) = Longitude of the last grid point
                                !
                                ! The following three only where applicable:
                                !(17) = Direction increment i
                                !(18) = Direction increment j
                                !(19) = Number of latitudes between pole and equator
                                !(20) = MARS class parameter (ECMWF local): Values
                                !       1 = Operations ("od")
                                !       2 = Research ("rd")
                                !       3 = ECMWF re-analysis
                                !(21) = MARS type parameter (ECMWF local): Values
                                !       1 = First Guess ("fg")
                                !       2 = Analysis ("an")
                                !       3 = Initialized analysis ("ia")
                                !       4 = OI analysis
                                !       5 = 3D-var analysis
                                !       6 = 4D-var analysis
                                !       7 = 3D-var gradients
                                !       8 = 4D-var gradients
                                !       9 = Forecast ("fc")
                                !       etc.
                                !(22) = Experiment id ("axyz" or "0001")
                                !(23) = No. of data values coded/encoded
                                !(24) = No. of bits used for packing
                                !(25) = Type of data
                                !         0 = Grid point
                                !       128 = Spherical harmonics
                                !(26) = Type of packing
                                !         0 = Simple
                                !        64 = Complex
                                !(27) = Data representation
                                !         0 = Floating point
                                !        32 = Integer
                                !(28) = For complex packing start offset (in bytes)
                                !       to the packed data
                                !(29) = Scaling factor (power) for complex packing
                                !(30) = Time unit indicator
                                !(31) = Time period P1
                                !(32) = Time period P2
                                !(33) = Time range indicator
                                !(34) = Field code
                                !(35) = GRIB-product length in bytes
                                !(36) = Level indicator
                                !(37) = Top level value
                                !(38) = Botton level value
                                !(39..n) = Reserved for future use
                                ! n = 255:
                                ! n   = # of points along each parallel (quasi-regular)
                                !(n + 1 ... n + NDGL) = NLOEN(NDGL)
! === END OF INTERFACE BLOCK ===
      integer j ,iret_pbio, i_ngriblen
      integer ifile_size, iedition, igrid_type, iregular
      integer ivert, ifields, iversion
      integer idate, itime
      integer ilat_start, ilon_start
      integer ilat_end, ilon_end
      integer idir_inc_i, idir_inc_j
      integer ihalf_parallels
      integer idata_values, inum_bits, itype_data, itype_pack
      integer idata_rep, istart_offset, ipower
      integer itimex(4)
      integer iyycent, icentref, icode
      integer ilevind, itop, ibot

#include "grib_internal.h"

      integer iword, idgl, idlon, ilen, i_penta(3)
      integer iclass, itype, iexpid
      character*2, save :: CL_spherical = 'SH'
      character*2, save :: CL_gaussian  = 'GG'
      character*2, save :: CL_latlon    = 'LL'
      character*2, save :: CL_not_supported = '  '

      integer, parameter :: i_info_inc = 255
      integer i_info(i_info_inc + jpni)

c
c     2.1 Get initial information from the very first GRIB-product
c

      call UTIL_STAT(kunit, ifile_size)
      i_info(1) = ifile_size
      
      inquire(iolength=nobytes) ngrib(1)
      i_ngriblen = size(ngrib) * nobytes
      
      call PBGRIB(kunit, ngrib, i_ngriblen, ilen, iret_pbio)

      if (iret_pbio /= 0) goto 999

      allocate(rsec4(nsafety_factor * size(ngrib)))

      call GRIBEX(nsec0, nsec1, 
     $     nsec2, rsec2,
     $     nsec3, rsec3,
     $     nsec4, 
     $     rsec4, size(rsec4),
     $     ngrib, ilen, 
     $     iword, 'J', iret_pbio)
      
c      write(*,*)'nsec4='
c      write(*,'((1x,i10,3x,i10))') (j, nsec4(j), j=1,60)
c      write(*,*)'nsec4 (end)'
      
c---  
c      call GRPRS0(nsec0)
c      call GRPRS1(nsec0,nsec1)
c      call GRPRS2(nsec0,nsec2,rsec2)
c      call GRPRS4(nsec0,nsec4,rsec4)
c---  

      deallocate(rsec4)

      iedition  = nsec0(2)
      i_info(2) = iedition
      
      idgl = 0
      idlon = 0
      
      ilat_start = 0
      ilon_start = 0
      ilat_end   = 0
      ilon_end   = 0
      idir_inc_i = 0
      idir_inc_j = 0
      ihalf_parallels = 0
      
      idata_values = nsec4(1)
      inum_bits = nsec4(2)
      itype_data = nsec4(3)
      itype_pack = nsec4(4)
      idata_rep = nsec4(5)

      if (itype_pack == 64) then
         istart_offset = nsec4(16)
         ipower = nsec4(17)
      else
         istart_offset = 0
         ipower = 0
      endif
      
      itimex(1) = nsec1(15)
      itimex(2) = nsec1(16)
      itimex(3) = nsec1(17)
      itimex(4) = nsec1(18)
      
      iregular  = nsec2(17)
      i_info(4) = iregular
      
      igrid_type = nsec2(1)
      if ( igrid_type == 50 .or.
     $     igrid_type == 60 .or.
     $     igrid_type == 70 .or.
     $     igrid_type == 80 ) then
         read(CL_spherical,'(a2)') igrid_type
         i_penta(1:3) = nsec2(2:4)
         i_info(6:8)  = i_penta(1:3)
      else if ( igrid_type ==  4 .or.
     $        igrid_type == 14 .or.
     $        igrid_type == 24 .or.
     $        igrid_type == 34 ) then
         read(CL_gaussian,'(a2)') igrid_type
         idgl      = nsec2(3)
         idlon     = 2*idgl
         i_info(6) = idgl
         i_info(7) = idlon
         i_info(8) = 0
         ilat_start = nsec2(4)
         ilon_start = nsec2(5)
         ilat_end   = nsec2(7)
         ilon_end   = nsec2(8)
         if (nsec2(6) == 128) idir_inc_i = nsec2(9)
         ihalf_parallels = nsec2(10)
      else if ( igrid_type ==  0 .or.
     $        igrid_type == 10 .or.
     $        igrid_type == 20 .or.
     $        igrid_type == 30 ) then
         read(CL_latlon,'(a2)') igrid_type
         idgl      = nsec2(3)
         idlon     = 2*idgl
         i_info(6) = idgl
         i_info(7) = idlon
         i_info(8) = 0
         ilat_start = nsec2(4)
         ilon_start = nsec2(5)
         ilat_end   = nsec2(7)
         ilon_end   = nsec2(8)
         if (nsec2(6) == 128) then
            idir_inc_i = nsec2(9)
            idir_inc_j = nsec2(10)
         endif
      else
         read(CL_not_supported,'(a2)') igrid_type
         i_info(6) = 0
         i_info(7) = 0
         i_info(8) = 0
      endif
      i_info(3)  = igrid_type
      i_info(13) = ilat_start
      i_info(14) = ilon_start
      i_info(15) = ilat_end
      i_info(16) = ilon_end
      i_info(17) = idir_inc_i
      i_info(18) = idir_inc_j
      i_info(19) = ihalf_parallels
      
      ivert     = nsec2(12)
      i_info(5) = ivert
      
      if (nsec0(1) > 0) then
         ifields = ifile_size/nsec0(1)
      else
         ifields = 0
      endif
      i_info(9) = ifields
      
      iversion   = nsec1(1)
      i_info(10) = iversion
      
      if (iregular == 0) then
         do j=1,idgl
            i_info(i_info_inc + j) = idlon
         enddo
      else
         do j=1,idgl
            i_info(i_info_inc + j) = nsec2(22 + j)
         enddo
      endif
      
      icode = nsec1(6)

      ilevind = nsec1(7)
      itop = nsec1(8)
      ibot = nsec1(9)

c--   Y2K fix for date done
c     13/5/98: note there was an error in GRIB doc, where
c     ksec1(10) and ksec1(21) indices where accidentally swapped
c     in the footnote comment. Reported to John Chambers, ECMWF.

c      nsec1(21) = 20; nsec1(10)=100 ! Year 2000 --> OK
c      nsec1(21) = 21; nsec1(10)=1   ! Year 2001 --> OK

      iyycent = nsec1(10)
      icentref = nsec1(21)
c      print *,'==> iyycent=nsec1(10)=',nsec1(10)
c      print *,'==> icentref=nsec1(21)=',nsec1(21)
      if (icentref == 100) then
c--   Years 1900, 2000, 2100, ...
         icentref = 0
      else
c--   Any other year
         icentref = icentref - 1
      endif
      
      idate = 
     $  icentref*1000000 + iyycent*10000 + nsec1(11)*100 + nsec1(12)
      itime = nsec1(13)*100 + nsec1(14)
      
      i_info(11) = idate
      i_info(12) = itime
      
      iclass = nsec1(38)
      itype  = nsec1(39)
      iexpid = nsec1(41)
      
      i_info(20) = iclass
      i_info(21) = itype
      i_info(22) = iexpid
      
      i_info(23) = idata_values
      i_info(24) = inum_bits
      i_info(25) = itype_data
      i_info(26) = itype_pack
      i_info(27) = idata_rep
      i_info(28) = istart_offset
      i_info(29) = ipower
      
      i_info(30) = itimex(1)
      i_info(31) = itimex(2)
      i_info(32) = itimex(3)
      i_info(33) = itimex(4)
      i_info(34) = icode
      i_info(35) = ilen
      i_info(36) = ilevind
      i_info(37) = itop
      i_info(38) = ibot
      
      do j=1,min(size(i_info),kinfo_len)
         kinfo(j) = i_info(j)
      enddo

 999  continue
      kret = iret_pbio
      END

