subroutine cnvwafs12(ifl1,ifl2,ipack,usemiss,imiss,uvvect,
     &                     table_ver)
C$$$  SUBPROGRAM DOCUMENTATION BLOCK
C                .      .    .                                       .
C SUBPROGRAM:    cnvwafs12 
C   PRGMMR: Gilbert        ORG: W/NP11    DATE: 2003-06-11
C
C ABSTRACT: This subroutine converts every GRIB1 field in a file
C   to a GRIB2 field.  U and V wind component fields are combined
C   into a single GRIB2 message.
C
C PROGRAM HISTORY LOG:
C 2003-06-11  Gilbert
C 2003-05-19  Gilbert  - Changed Master Table Version Number from 1 to 2.
C                      - Added check for grib1 table version with params 191
C                        and 192 for ensemble probs.
C 2007-03-26  Gordon   - Added check for ECMWF data to reference ECMWF
C                        Conversion tables.
C 2007-10-11  Vuong    - Added check for ensemble probs if the kpds > 28
C 2008-01-28  Vuong    - Fixed the V-GRD BY SETTING THE LPDS(22)=-1 and
C                        increase the array size MAXPTS
C 2008-05-14  Vuong    - Add option -m0 No explicit missing values included
C                        within data values
C 2010-12-02  Vuong    - Changed Master Table Version Number from 2 to 6.
C                      - Add option -mastertable_ver_x where x is mater table
C                        version 2 to 10
C
C USAGE:    CALL cnvwafs12(ifl1,ifl2,ipack)
C   INPUT ARGUMENT LIST:
C     ifl1   - Fortran unit number of input GRIB1 file
C     ifl2   - Fortran unit number of output GRIB2 file
C     ipack  - GRIB2 packing option:
C              0     = simple packing
C              2     = group packing
C              31    = group pack with 1st order differencing
C              32    = group pack with 2nd order differencing
C              40    = JPEG2000 encoding
C              40000 = JPEG2000 encoding (obsolete)
C              41    = PNG encoding
C              40010 = PNG encoding (obsolete)
C              if ipack .ne. one of the values above, 31 is used as a default.
C    usemiss - uses missing value management (instead of bitmaps), for use
C              ipack options 2, 31, and 32.
C    imiss   - Missing value management:
C              0     = No explicit missing values included within data values
C              1     = Primary missing values included within data values
C    uvvect  - .true. = combine U and V wind components into one GRIB2 msg.
C              .flase. = does not combine U and V wind components
C    mastertable_ver_x  -  Master Table version
C                          where x is number from 2 to 10
C
C   INPUT FILES:   See ifl1
C
C   OUTPUT FILES:  See ifl2
C
C REMARKS: None
C
C ATTRIBUTES:
C   LANGUAGE: Fortran 90
C   MACHINE:  IBM SP
C
C$$$

      use params
      use params_ecmwf
      integer,intent(in) :: ifl1,ifl2,ipack
      logical,intent(in) :: usemiss,uvvect

      PARAMETER (MAXPTS=40000000,msk1=32000)
      CHARACTER(len=1),allocatable,dimension(:) :: cgrib,cgribin
      integer KPDS(200),KGDS(200),KPTR(200)
      integer LPDS(200),LGDS(200),KENS(200),LENS(200)
      integer KPROB(2),KCLUST(16),KMEMBR(80)
      real XPROB(2)
      real,allocatable,dimension(:) :: FLD
      real,allocatable,dimension(:) :: FLDV
      real,allocatable,dimension(:) :: coordlist
      integer :: listsec0(2)=(/0,2/),imiss
      integer :: listsec1(13)=(/7,0,2,1,1,0,0,0,0,0,0,0,0/)
      integer :: ideflist(MAXPTS),idefnum
      integer :: igds(5)=(/0,0,0,0,0/),igdstmpl(200),ipdstmpl(200)
      integer :: ipdstmplv(200)
      integer :: idrstmpl(200),idrstmplv(200)
      integer :: currlen=0, table_ver
      integer,parameter :: mingrib=500
      logical :: ensemble,ecmwf
      Logical*1,allocatable,dimension(:) :: bmp,bmpv
!
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
!
      ICND=0
      IFLI1=0
      allocate(fld(maxpts))
      allocate(coordlist(maxpts))
      allocate(bmp(maxpts))
      listsec1(3) = table_ver
!      
      iseek=0
      do 
        call skgb(ifl1,iseek,msk1,lskip,lgrib)
        if (lgrib.eq.0) exit                ! end loop at EOF or problem
         if (lgrib.gt.currlen) then
            if (allocated(cgribin)) deallocate(cgribin)
            allocate(cgribin(lgrib),stat=is)
            currlen=lgrib
            lcgrib=lgrib*2
            if (lcgrib .lt. mingrib) lcgrib=mingrib
            if (allocated(cgrib)) deallocate(cgrib)
            allocate(cgrib(lcgrib),stat=is)
         endif
        call baread(ifl1,lskip,lgrib,lengrib,cgribin)
        if (lgrib.eq.lengrib) then
           call w3fi63(cgribin,KPDS,KGDS,BMP,FLD,KPTR,IRET)
           numpts=KPTR(10)
           if (iret.ne.0) then
              print *,' cnvgrib: Error unpacking GRIB field.',iret
              iseek=lskip+lgrib
              cycle
           endif
        else
           print *,' cnvgrib: IO Error on input GRIB file.'
           cycle
        endif
        iseek=lskip+lgrib
        !print *,'kpds:',kpds(1:28)
        !print *,'kpds:',kpds(1:45)
        if ((kpds(5).eq.34).AND.uvvect) cycle ! V-comp already processed with U
        listsec1(1)=kpds(1)
        listsec1(2)=kpds(23)
        listsec1(5)=1
        if (kpds(16).eq.1) listsec1(5)=0
        listsec1(6)=((kpds(21)-1)*100)+kpds(8)
        listsec1(7)=kpds(9)
        listsec1(8)=kpds(10)
        listsec1(9)=kpds(11)
        listsec1(10)=kpds(12)
        listsec1(13)=1
        if (kpds(16).eq.1) listsec1(13)=0
        ensemble=.false.
        if ( (kpds(23).eq.2) .or.
     &       (kptr(3).gt.28 .and. kpds(19).eq.2 .and. 
     &       (kpds(5).eq.191.or.kpds(5).eq.192) ) ) then        ! ensemble forecast
           ensemble=.true.
        endif
        if (ensemble) then    ! ensemble forecast
           call gbyte(cgribin(9),ilast,0,24)
           call pdseup(kens,kprob,xprob,kclust,kmembr,ilast,cgribin(9))
           if (kens(2).eq.1) listsec1(13)=3
           if (kens(2).eq.2.OR.kens(2).eq.3) listsec1(13)=4
           if (kens(2).eq.5) listsec1(13)=5
        endif
        ecmwf=.false.
        if (kpds(1).eq.98) ecmwf=.true.
        if (ecmwf) then         ! treat ecmwf data conversion seperately
           call param_ecmwf_g1_to_g2(kpds(5),kpds(19),listsec0(1),idum,
     &          jdum)           ! set discipline
        else
           if (ensemble.and.(kpds(5).eq.191.or.kpds(5).eq.192)) then
              !kprob(1)=61
              call param_g1_to_g2(kprob(1),kpds(19),listsec0(1),idum,
     &             jdum)        ! set discipline
           else
              call param_g1_to_g2(kpds(5),kpds(19),listsec0(1),idum,
     &             jdum)        ! set discipline
           endif
        endif
        call gribcreate(cgrib,lcgrib,listsec0,listsec1,ierr)
        if (ierr.ne.0) then
          write(6,*) ' ERROR creating new GRIB2 field = ',ierr
          cycle
        endif
! 
!-----------------------------------------------------------------------
! convert grid info
        call gds2gdt(kgds,igds,igdstmpl,idefnum,ideflist,ierr)
        if (ierr.ne.0) then
          cycle
        endif
        if (listsec1(1) .eq. 7 ) igdstmpl(1)=6    ! FOR NWS/NCEP
        call addgrid(cgrib,lcgrib,igds,igdstmpl,200,ideflist,
     &               idefnum,ierr)
        if (ierr.ne.0) then
          write(6,*) ' ERROR adding GRIB2 grid = ',ierr
          cycle
        endif
!-----------------------------------------------------------------------
! set PDS Template
        if (ensemble) then    ! ensemble forecast
           call pds2pdtens(kpds,kens,kprob,xprob,kclust,kmembr,
     &                     ipdsnum,ipdstmpl,numcoord,coordlist,ierr)
        else
           call pds2pdt(kpds,ipdsnum,ipdstmpl,numcoord,coordlist,ierr)
        endif
        if (ierr.ne.0) then
          cycle
        endif
!-----------------------------------------------------------------------
! set bitmap flag
        idrstmpl=0
        if (btest(kpds(4),6)) then
          ibmap=0
          !fld=pack(fld,mask=bmp(1:numpts))
          !itemp=count(bmp(1:numpts))
          !numpts=itemp
          !
          !   convert bitmap to "missing" values, if requested.
          !
          if ( (usemiss) .AND. (ipack.eq.2 .OR. ipack.eq.31 .OR.
     &                          ipack.eq.32) ) then
             ibmap=255
             rmiss=minval(fld(1:numpts))
             if ( rmiss .lt. -9999.0 ) then
                rmiss=rmiss*10.0
             else
                rmiss=-9999.0
             endif
             do i=1,numpts
                if ( .NOT. bmp(i) ) then
                   fld(i)=rmiss
                   bmp(i)=.true.
                endif
             enddo
             idrstmpl(7)=imiss                   ! Missing value management 
             call mkieee(rmiss,idrstmpl(8),1)
          endif
        else
          ibmap=255
          idrstmpl(7)=0                   ! No missing values
        endif

!-----------------------------------------------------------------------
!   Set DRT info  ( packing info )
        if ( ipack.eq.0 ) then
           idrsnum=0
        elseif ( ipack.eq.2 ) then
           idrsnum=2
           idrstmpl(6)=1                   ! general group split
        elseif ( ipack.eq.31.OR.ipack.eq.32 ) then
           idrsnum=ipack/10
           idrstmpl(6)=1                   ! general group split
           idrstmpl(17)=mod(ipack,10)      ! order of s.d.
        elseif ( ipack.eq.40 .OR. ipack.eq.41 .OR.
     &           ipack.eq.40000 .OR. ipack.eq.40010 ) then
           idrsnum=ipack
           idrstmpl(6)=0
           idrstmpl(7)=255
           !idrstmpl(6)=1
           !idrstmpl(7)=15
        else
           idrsnum=3
           idrstmpl(17)=1                  ! order of s.d.
           idrstmpl(6)=1                   ! general group split
           if (kpds(5).eq.61) idrsnum=2
        endif
        idrstmpl(2)=KPTR(19)       ! binary scale
        idrstmpl(3)=kpds(22)       ! decimal scale
        !idrstmpl(2)=-4       ! binary scale
        !idrstmpl(3)=0       ! decimal scale
        call addfield(cgrib,lcgrib,ipdsnum,ipdstmpl,200,
     &                coordlist,numcoord,idrsnum,idrstmpl,200,
     &                fld,numpts,ibmap,bmp,ierr)
c       print *,'done with addfield'
        if (ierr.ne.0) then
          write(6,*) ' ERROR adding GRIB2 field = ',ierr
          cycle
        endif

        if ((kpds(5).eq.33) .AND. uvvect) then
          if (.not.allocated(fldv)) allocate(fldv(maxpts))
          if (.not.allocated(bmpv)) allocate(bmpv(maxpts))
          LGDS=KGDS
          LENS=KENS
          LPDS=KPDS
          LPDS(22)=-1
          LPDS(5)=34
          jsrch=0
          CALL GETGBE(IFL1,IFLI1,MAXPTS,jsrch,LPDS,LGDS,LENS,NUMPTSO,
     *         jsrch,KPDS,KGDS,KENS,BMPV,FLDV,ICND)
          if (icnd.ne.0) then
            write(6,*) ' ERROR READING/UNPACKING GRIB1 V = ',icnd
            exit
          endif
          ipdstmplv=ipdstmpl
          if (ecmwf) then       ! treat ecmwf data conversion seperately
c            print *,' param_ecmwf call 2'
             call param_ecmwf_g1_to_g2(kpds(5),kpds(19),idum,
     &            ipdstmplv(1),ipdstmplv(2))
c            print *,' done with call 2'
          else
             call param_g1_to_g2(kpds(5),kpds(19),idum,ipdstmplv(1),
     &            ipdstmplv(2))
          endif
! set bitmap flag
          idrstmplv=0
          if (btest(kpds(4),6)) then
            !fldv=pack(fldv,mask=bmpv(1:numpts))
            if ( ANY(bmp(1:igds(2)) .NEQV. bmpv(1:igds(2))) ) then
               !print *,'SAGT: BITMAP different'
               ibmap=0
               !   convert bitmap to "missing" values, if requested.
               if ( (usemiss) .AND. (ipack.eq.2 .OR. ipack.eq.31 .OR.
     &                               ipack.eq.32) ) then
                  ibmap=255
                  rmiss=minval(fldv(1:numpts))
                  if ( rmiss .lt. -9999.0 ) then
                     rmiss=rmiss*10.0
                  else
                     rmiss=-9999.0
                  endif
                  do i=1,numpts
                     if ( .NOT. bmpv(i) ) then
                        fldv(i)=rmiss
                        bmpv(i)=.true.
                     endif
                  enddo
                  idrstmplv(7)=imiss                   ! Missing values management
                  call mkieee(rmiss,idrstmplv(8),1)
               endif
            else
               !print *,'SAGT: BITMAP SAME'
               ibmap=254
            endif
          else
            ibmap=255
            idrstmplv(7)=0                   ! No missing values
          endif
          !   Set DRT info  ( packing info )
          if ( ipack.eq.0 ) then
             idrsnum=0
          elseif ( ipack.eq.2 ) then
             idrsnum=2
             idrstmplv(6)=1                   ! general group split
          elseif ( ipack.eq.31.OR.ipack.eq.32 ) then
             idrsnum=ipack/10
             idrstmplv(6)=1                   ! general group split
             idrstmplv(17)=mod(ipack,10)      ! order of s.d.
          elseif ( ipack.eq.40 .OR. ipack.eq.41 .OR.
     &             ipack.eq.40000 .OR. ipack.eq.40010 ) then
             idrsnum=ipack
             idrstmplv(6)=0
             idrstmplv(7)=255
             !idrstmplv(6)=1
             !idrstmplv(7)=15
          else
             idrsnum=3
             idrstmplv(17)=1                  ! order of s.d.
             idrstmplv(6)=1                   ! general group split
             if (kpds(5).eq.61) idrsnum=2
          endif
          idrstmplv(2)=KPTR(19)       ! binary scale
          idrstmplv(3)=kpds(22)       ! decimal scale
          !idrstmplv(2)=-4       ! binary scale
          !idrstmplv(3)=0       ! decimal scale
          call addfield(cgrib,lcgrib,ipdsnum,ipdstmplv,200,
     &                coordlist,numcoord,idrsnum,idrstmplv,200,
     &                fldv,numpts,ibmap,bmpv,ierr)
          if (ierr.ne.0) then
            write(6,*) ' ERROR adding second GRIB2 field = ',ierr
            cycle
          endif
        endif
! End GRIB2 field
        call gribend(cgrib,lcgrib,lengrib,ierr)
        if (ierr.ne.0) then
          write(6,*) ' ERROR ending new GRIB2 message = ',ierr
          cycle
        endif
!        print *,' writing ',lengrib,' bytes...'
        call wryte(ifl2,lengrib,cgrib)

      enddo

      if (allocated(cgribin)) deallocate(cgribin)
      if (allocated(cgrib)) deallocate(cgrib)
      if (allocated(fld)) deallocate(fld)
      if (allocated(fldv)) deallocate(fldv)
      if (allocated(coordlist)) deallocate(coordlist)
      if (allocated(bmp)) deallocate(bmp)
      if (allocated(bmpv)) deallocate(bmpv)

      return
      end