SUBROUTINE BT_DCOD ( curtim, bufrtb, nhours, iret )
C************************************************************************
C* BT_DCOD                                                              *
C*                                                                      *
C* This subroutine will read bathy, tesac, or trackob bulletins from    *
C* from standard input, decode the bulletin report data, and create     *
C* BUFR output.                                                         *
C*                                                                      *
C* BT_DCOD ( CURTIM, BUFRTB, NHOURS, IRET )                             *
C*                                                                      *
C* INPUT PARAMETERS:                                                    *
C*                                                                      *
C*      CURTIM		CHAR*		Date/time from command line	*
C*      BUFRTB		CHAR*		BUFR table file                 *
C*	NHOURS		INTEGER		Max number of hours before run  *
C*	                                time for creating BUFR output   *
C*                                                                      *
C* Output parameters:                                                   *
C*                                                                      *
C*      IRET            INTEGER		Return code			*
C*                                        0 = Normal return		*
C*                                                                      *
C**                                                                     *
C* Log:                                                                 *
C* R. Hollern/NCEP      11/98                                           *
C* R. Hollern/NCEP       1/99   Added code to decode TESAC reports and  *
C*                              added interface mnemonics to call       *
C*                              sequences                               *
C* R. Hollern/NCEP       1/99   Increased istrp array size to be able to*
C*                              decode up to 100 reports per bulletin.  *
C*                              Changed the value of nhours to be able  *
C*                              to decode reports up to 180 days old.   *
C* R. Hollern/NCEP       3/99   Added code to decode TRACKOB reports    *
C* R. Hollern/NCEP       4/00   Modified irptyp logic                   *
C* R. Hollern/NCEP       8/00   Modified the routine to make it conform *
C*                              to the NWS/IWT decoders standards.      *
C* C. Caruso Magee/NCEP 06/01   Replace calls to STATUS, WRITSA, and    *
C*                              DBN_BUFR with new s/r UT_WBFR.          *
C* J. Ator/NCEP		01/02	Remove iuwind initialization		*
C* C. Caruso Magee/NCEP 02/02   Rename orign to cborg; BT_BUFA to       *
C*                              BT_BUFR; replace btbufr.cmn with        *
C*                              btcmn_bufr.cmn; rename lunbfr to iunbfo.*
C* C. Caruso Magee/NCEP 01/03   Increased istrp array size to be able to*
C*                              decode up to 540 reports per bulletin   *
C*                              (roughly the number of obs in a trackob *
C*                              report for a ship that took obs every 4 *
C*                              min. for a day and a half). Note:  540  *
C*                              is set equal to MXRPT by a PARAMETER    *
C*                              statement in btcmn.cmn.                 *
C* R. Hollern/NCEP	03/04   Increased istgrp array size from 300 to	*
C*				1100. Increased MXDLYR from 255 to 1000.*
C*				Can now create BUFR messages up to 	*
C*				20000 bytes.				*
C* J. Ator/NCEP         08/04   SS_GTIM -> CSS_GTIM                     *
C* C. Caruso Magee/NCEP 01/06   Set irptdt(1) - report year here, using *
C*                              rivals (irydgt) decoded in btobst.f.    *
C* J. Ator/NCEP         02/06   Clean up                                *
C* J. Ator/NCEP         11/12   Increase istgrp size from 1100 to 3000  *
C************************************************************************
        INCLUDE 	'GEMPRM.PRM'
        INCLUDE 	'BRIDGE.PRM'
        INCLUDE 	'btcmn.cmn'
        INCLUDE 	'btcmn_bufr.cmn'
C* 
        CHARACTER*(*)   curtim,  bufrtb
C*
        INTEGER         istarr(5),   istrp(5,MXRPT),   istgrp(3000)
C*
        CHARACTER       bulltn*(DCMXBF), sysdt*12, dattmp*12, 
     +                  errstr*80, report*(DCMXBF),
     +                  cmdif*8, cdate*8, ctime*4, cdattm*15,
     +                  logrpt*55, rimnem(NRIMN)*8, cimnem(NCIMN)*8
C*
        LOGICAL		more, good, ibufr, last
C*
	DATA		last / .false. /
C-----------------------------------------------------------------------
        iret = 0
C
C*	Set the pointers for the interface arrays.
C
        CALL BT_IFSP  ( rimnem, cimnem, ier )
        IF ( ier .ne. 0 ) THEN
            CALL DC_WLOG ( 0, 'DCBTHY', -8, ' ', ierwlg )
            RETURN
        END IF
C
C*      Loop until a timeout occurs.
C
        ibufr = .false.
C
        DO WHILE ( .true. )
C
C*          Get the next bulletin.
C
            CALL DC_GBUL( bulltn, lenb, ifdtyp, iperr )
C
            IF ( iperr .ne. 0 ) THEN
C
C*              A time-out occurred while waiting for a new bulletin
C*              on the input pipe.  Shut down the decoder and exit.
C
                CALL DC_WLOG ( 0, 'DC', iperr, ' ' , ierwlg )
C
C*              Close BUFR files.
C
                IF ( ibufr ) THEN
                    last = .true.  
                    CALL  BT_BUFR( bufrtb, last, report, mszrpt, ierr3)
                END IF
C
                RETURN
            END IF
C
            more = .true.
C
            IF ( ifdtyp .eq. 0 ) THEN
C
C*              Parse the header information from the bulletin.
C
                CALL DC_GHDR ( bulltn, lenb, seqnum, buhd, cborg,
     +                         btime, bbb, nchrd, ierr )
                IF ( ierr .ne. 0 ) THEN
                    CALL DC_WLOG ( 2, 'DC', ierr, ' ', ierwlg )
                    CALL ST_UNPR ( bulltn(:72), 72, errstr, len1, ier )
                    CALL DC_WLOG ( 2, 'DCBTHY', 2, errstr, ierwlg )
                    more = .false.
                END IF
            END IF
C
            IF ( more ) THEN
C
C*		Get the system time and make a standard GEMPAK time
C*		from the "current" time.
C
		itype = 1
                CALL CSS_GTIM ( itype, sysdt, ier )
                IF ( curtim .eq. 'SYSTEM' ) THEN
                    dattmp = sysdt
                  ELSE
                    CALL TI_STAN ( curtim, sysdt, dattmp, ier )
                END IF
C
                CALL TI_CTOI ( dattmp, istarr, ier )
C
C*		Set receipt time significance to 0.
C
                rctim (1) = 0.0 
C
C*		Save receipt time and pass via btcmn.cmn.
C
                DO i = 1, 5
                    rctim ( i+1 ) = FLOAT ( istarr ( i ) )
                END DO
C
C*		Remove control characters from bulletin.
C
                CALL ST_UNPR ( bulltn, lenb, bulltn, lennew, ier )
                lenb = lennew
C
                IF ( lenb .ge. 40 ) THEN
C
C*                   Write bulletin header data to decoder log.
C
                     logmsg = seqnum // buhd // cborg // btime // bbb
                     CALL DC_WLOG (2, 'BT', 1, logmsg(1:36),ierwlg)
                  ELSE
C
C*                  Reject bulletins less than 60 characters long.
C
                    more = .false.
                END IF
            END IF
C
C*          Check if this bulletin contains TRACKOB reports and that
C*          they are correctly formatted for the decoding routines.
C
            CALL BT_BLNX ( report, lenb, bulltn, ier )
            IF ( ier .ne. 0 ) THEN
                more = .false.
            END IF
C
C*          Get the report types and their starting locations
C*          in bulltin.
C
            IF ( more ) THEN
                CALL BT_RPTY ( lenb, bulltn, numrpt, istrp, iret )
              ELSE
                numrpt = 0
            END IF
C
C*          Loop through reports.
C
            DO jrpt = 1, numrpt
C
                good = .true.
                irptyp = 0         
C
C*              Initialize report interface variables to missing.
C
                CALL BT_IFIV ( kret )
C
C*              Get next report from bulletin.
C
                CALL BT_GRPT ( lenb, bulltn, jrpt, istrp, mszrpt,
     +                         report, ngrps, istgrp, jret)
C
                IF ( jret .ne. 0 ) THEN
                    good = .false.
                  ELSE
C
C*                  Write raw report to LOG file.        
C
                    loglvl = 2
                    mm = istrp(3,jrpt)
                    mmm = MIN ( mm+49, lenb )
                    IF ( mm .gt. 0 ) THEN
                        isz = mmm - mm + 1
                        logrpt(1:isz) = bulltn(mm:mmm)
                        CALL DC_WLOG ( loglvl, 'BT', 1,
     +                                 logrpt (1:isz), ierwlg )
                    END IF
C*
                    IF ( irptyp .eq. 1 .or. irptyp .eq. 4 ) THEN
C
C*                      Decode bathy report.             
C
                        CALL BT_BSEC ( mszrpt, report, ierr1 )
                        IF ( ierr1 .ne. 0 ) THEN
                            good = .false.
                        ELSE 
C
C*                        Create report year by comparing units digit
C*                        of year read in via btobst.f to receipt year.
C
                          iyrdif = NINT ( rivals ( irydgt ) ) -
     *                             MOD ( NINT ( rctim (2) ), 10 )
                          IF ( iyrdif .gt. 1 ) THEN
                             irptdt (1) = rctim (2) - 10 + iyrdif
                          ELSE IF ( iyrdif .eq. -9 ) THEN
                             irptdt (1) = rctim (2) + 10 + iyrdif
                          ELSE
                             irptdt (1) = rctim (2) + iyrdif
                          END IF
                        END IF
                      ELSE IF ( irptyp .eq. 2 .or. irptyp .eq. 5 ) THEN
C
C*                      Decode tesac report.             
C
                        CALL BT_TSEC ( mszrpt, report, ierr1 )
                        IF ( ierr1 .ne. 0 ) THEN
                            good = .false.
                        ELSE 
C
C*                        Create report year by comparing units digit
C*                        of year read in via btobst.f to receipt year.
C
                          iyrdif = NINT ( rivals ( irydgt ) ) -
     *                             MOD ( NINT ( rctim (2) ), 10 )
                          IF ( iyrdif .gt. 1 ) THEN
                             irptdt (1) = rctim (2) - 10 + iyrdif
                          ELSE IF ( iyrdif .eq. -9 ) THEN
                             irptdt (1) = rctim (2) + 10 + iyrdif
                          ELSE
                             irptdt (1) = rctim (2) + iyrdif
                          END IF
                        END IF
                      ELSE IF ( irptyp .eq. 3 ) THEN
C
C*                      Decode trackob report.             
C
                        CALL BT_KSEC ( mszrpt, report, ngrps, istgrp,
     +                                 ierr1 )
                        IF ( ierr1 .ne. 0 ) THEN
                            good = .false.
                        ELSE 
C
C*                        Create report year by comparing units digit
C*                        of year read in via btobst.f to receipt year.
C
                          iyrdif = NINT ( rivals ( irydgt ) ) -
     *                             MOD ( NINT ( rctim (2) ), 10 )
                          IF ( iyrdif .gt. 1 ) THEN
                             irptdt (1) = rctim (2) - 10 + iyrdif
                          ELSE IF ( iyrdif .eq. -9 ) THEN
                             irptdt (1) = rctim (2) + 10 + iyrdif
                          ELSE
                             irptdt (1) = rctim (2) + iyrdif
                          END IF
                        END IF
                      ELSE 
                        good = .false.
                    END IF
C
                END IF
C 
                IF ( good ) THEN
C
C*		    Compute difference between observation
C*		    and system times.
C
                    CALL  TI_MDIF ( irptdt, istarr, imdif, ier1)
C
C*		    Check that the time is within NHOURS before the
C*		    system time.
C
C*		    Report time for BUFR must not be more than nhours
C*		    before the system time, and not more than
C*		    60 minutes after.
C
                    IF ( ( ier1 .ne. 0 ) .or. ( imdif .gt. 60 ) .or.
     +			 ( imdif .lt. -60 * nhours ) ) THEN
C
                        good = .false.
                        errstr = buhd // cborg // btime
                        CALL DC_WLOG ( 2, 'DCBTHY', 3, errstr, ierwlg )
         		CALL ST_INCH ( imdif, cmdif, ier )
                        idate = irptdt(1) * 10000 + irptdt(2) * 100 +
     +				irptdt(3)
                        itime = irptdt(4)*100 + irptdt(5)
                        CALL ST_INCH ( idate, cdate, ier )
                        CALL ST_INCH ( itime, ctime, ier )
                        cdattm = cdate(3:) // '/' // ctime
                        errstr = cdattm // dattmp // cmdif
                        CALL DC_WLOG ( 2, 'DCBTHY', 4, errstr, ierwlg )
C
                    END IF
C
                    IF ( good ) THEN
C
C*                      Output decoded report to LOG file
C
                        loglvl = 3
                        logmsg ='<-----BEGIN INTERFACE OUTPUT----->'
                        CALL DC_WLOG ( loglvl, 'DC', 2,
     +                                 logmsg (1:50), ierwlg )
C
C*                      Print the raw report.
C
                        CALL DC_WLOG ( loglvl, 'DC', 2,
     +                                 'RAW REPORT:', ierwlg )
                        CALL DC_WLOG ( loglvl, ' ',1, report(1:mszrpt),
     +                                 ierwlg )
C
                        CALL  BT_IFPT ( rimnem, cimnem, ierr2 )
C
                        logmsg = '<-----END INTERFACE OUTPUT----->'
                        CALL DC_WLOG ( loglvl, 'DC', 2,
     +                                 logmsg (1:50), ierwlg )
C
C*                      Convert current report data to BUFR format.
C
                        CALL  BT_BUFR( bufrtb, last, report, mszrpt,
     +                                 ierr2 )
                        ibufr = .true.
                    END IF
                END IF
C
            END DO
C
C*          Make sure that all BUFR output for this bulletin
C*          has been written out before going back to DC_GBUL
C*          and waiting for a new bulletin on the input pipe.
C
            IF ( ibufr ) THEN
                CALL UT_WBFR ( iunbfo, 'bathy', 1, ierwbf )
            END IF
C
        END DO
C*
        RETURN
        END