C$$$  SUBPROGRAM DOCUMENTATION BLOCK
C                .      .    .                                       .
C SUBPROGRAM:    MGETSFCC    GET SFC CHARACTER DATA FOR ONE VARIABLE
C   PRGMMR: M. BARTH         ORG: FSL        DATE: 99-09-29
C
C ABSTRACT: READ SFC CHARACTER DATA FOR ALL STATIONS FOR ONE VARIABLE
C   AND TIME.
C
C PROGRAM HISTORY LOG:
C   99-09-29  M. BARTH    ORIGINAL VERSION
C   00-03-22  M. BARTH    CHANGES TO ALLOW FOR UPPER-AIR-POINT DATA
C   01-05-03  M. BARTH    CHANGED MRDNUM/MRDCHR TO MGTNUM/MGTCHR
C   01-07-05  M. BARTH    - ADDED STALOC_VN_P SPECIAL-CASE
C                         - FIXED LOGIC ERROR THAT CAUSED FILES TO
C                           BE PROCESSED MULTIPLE TIMES GIVEN SOME
C                           TIME WINDOW CHOICES
C                         - CHANGE FROM CALLER-SPECIFIED VARIABLE CODE
C                           NUMBER TO VARIABLE CODE NAME
C   02-05-29  M. BARTH    RESTRUCTURED TEMPORARY MEMORY ARRAY USAGE
C   04-03-24  M. BARTH    ADDED COOP MAX/MIN TEMPERATURE TIME VARIABLES
C   04-06-21  M. BARTH    ADDED SUBPROVIDER VARIABLE FOR MESO & COOP.
C   05-04-12  L. BENJAMIN ADDED CHECK FOR VARIABLE NOT IN DATABASE.  
C                         CHANGED THIS TO NON-FATAL CASE IF ANY DATA
C                         IS FOUND.
C   06-09-25  L. BENJAMIN URBANET TIME VARIABLES.
C   07-06-15  L. BENJAMIN ADDED SKYCOVER FOR MESONET CASE.  WE WILL
C                         USE THE ROUTINE TO INIT THE RETURN DATA 
C                         FIELD AND FILL IN NON-MESONET DATA.  
C   07-07-24  L. BENJAMIN FIXED BUG WHEN SKY COVER VARIABLE
C                         DOES NOT EXIST IN NETCDF FILE
C   07-11-16  L. BENJAMIN CLEANED UP COMMENTED OUT CODE.
C   08-06-25  M. BARTH    ADDED HIGH FREQUENCY METAR DATASET - WHICH
C                         HAS A DIFFERENT MAX NUMBER OF SKY COVER
C                         LEVELS THAN THE OTHER DATASETS WITH THIS
C                         VARIABLE.
C   08-06-26  L. BENJAMIN UNUSED CODE
C
C USAGE:    CALL MGETSFCC (ATIME,VCODE,NSTA,CDATA,STATUS)
C
C   INPUT ARGUMENT LIST:
C     ATIME    - C       YYJJJHHMM OF THE DATA TO BE READ
C     VCODE    - C       VARIABLE CODE NAMES
C
C   OUTPUT ARGUMENT LIST:
C     NSTA     - I       NUMBER OF STATIONS RETURNED
C     CDATA    - CA      ARRAY OF RETURNED CHARACTER DATA
C     STATUS   - I       0 - SUCCESS, OR ERROR CODE
C
C   INPUT FILES:
C     MADIS SFC NETCDF FILES FOR ATIME
C
C SUBPROGRAMS CALLED:
C     UNIQUE:    MERROR, MGETVCN, MGTCHR, MRDDBL, M_MKFNAM
C
C REMARKS:
C   - THE CALLER MUST CALL MINIT AND MSFCSTA BEFORE CALLING THIS
C     ROUTINE.  MSFCSTA SHOULD BE CALLED FIRST WHENEVER ACCESS TO
C     A NEW TIME IS DESIRED.  IT STORES INFO IN THE STRCCOM COMMON
C     THAT IS USED BY THIS ROUTINE TO FIGURE OUT WHICH RECORDS ARE
C     NEEDED ON NETCDF FILES OPENED BY MSFCSTA.
C   - THE CALLER SHOULD DIMENSION ARRAYS TO MATCH MXSFC_P IN
C     madiscon.f, AND TO MATCH THE DIMENSIONS OF THE LARGEST VERSION
C     OF THE VARIABLE IN ANY DATASET.  SEE THE MADIS USER'S GUIDE
C     TO SEE WHAT DIMENSIONS SHOULD BE USED FOR THE CHARACTER
C     VARIABLES, OR SEE THE VALUES OF VCLEN FOR EACH CHARACTER
C     VARIABLE IN THE SFCTBL.TXT FILE.
C   - SEE madistmp.f FOR AN EXPLANATION OF HOW TEMPORARY STORAGE
C     IS HANDLED (ALL ARRAYS NAMED *TMP*).
C
C ATTRIBUTES:
C   LANGUAGE: FORTRAN-77 + EXTENSIONS
C   MACHINE:  UNIX
C$$$

      SUBROUTINE MGETSFCC(ATIME,VCODE,NSTA,CDATA,STATUS)

C     ------------------------------------------------------------------
C     INCLUDES AND COMMONS
C     ------------------------------------------------------------------
      INCLUDE 'IMPLICIT'
      INCLUDE 'MADISCON'
      INCLUDE 'MADISCOM'
      INCLUDE 'STRCCOM'
      INCLUDE 'MADISTMP'

C     ------------------------------------------------------------------
C     ARGUMENTS
C     ------------------------------------------------------------------
      CHARACTER*9 ATIME
      CHARACTER*(*) VCODE
      INTEGER NSTA,STATUS
      CHARACTER*1 CDATA(*)

C     ------------------------------------------------------------------
C     LOCAL
C     ------------------------------------------------------------------
      INTEGER I,J,K,FNUM,DSN,LEN1REC,VCN,NCLEN,RTIME,IV
      LOGICAL HAVE_ANY,HAVE_DSN
      CHARACTER*1 CTMP(MAX_CHAR_VLEN_P*MXSFC_P),VCT
      LOGICAL PROC_FILE(SFC_MXSTRF),COOPTIME,SUBPVDR,ISSKYCOVER
      LOGICAL URBANETTIME,ISSET_LAST_BEST_STATUS
      CHARACTER*16 COOPVAR,URBANETVAR
      CHARACTER*9 CTMP1
      CHARACTER*1 IVC(6)
      DOUBLE PRECISION DTMP(MXSFC_P)
      INTEGER TOT,LAST_BEST_STATUS

C     ------------------------------------------------------------------
C     TEMPORARY STORAGE DEFINITIONS
C     ------------------------------------------------------------------
      EQUIVALENCE(CTMP,TMP_L1_C1)
      EQUIVALENCE(DTMP,TMP_L1_N1)


C     ------------------------------------------------------------------
C     DATA STATEMENTS
C     ------------------------------------------------------------------
      DATA IVC  /'1','2','3','4','5','6'/

C     ------------------------------------------------------------------
C     IF THE SFC SUBSYSTEM HASN'T BEEN INITIALIZED, OR IF THE REQUESTED
C     TIME DOESN'T MATCH THE TIME LAST PROCESSED BY MSFCSTA, OR IF THE
C     VCODE IS CLEARLY ILLEGAL, RETURN WITH ERROR.
C     ------------------------------------------------------------------
      IF(SFC_INIT.NE.INIT_P)THEN
         STATUS = SELSUB_NOTINIT_P
         CALL MERROR('MGETSFCC: SELECTED SUBSYSTEM NOT INITIALIZED - '//
     1               'SFC')
         GO TO 900
      ELSE IF(ATIME.NE.LAST_SFC_ATIME.OR.ATIME.EQ.'         ')THEN
         STATUS = TIME_NOTINIT_P
         CALL MERROR('MGETSFCC: TIME NOT INITIALIZED BY MSFCSTA')
         GO TO 900
      ELSE 
         CALL MGETVCN(VCODE,VCN,VCT,STATUS)
         IF(STATUS.NE.SUCCESS_P)GO TO 900
      ENDIF

C     ------------------------------------------------------------------
C     SET UP STRUCTURES TO ALLOW US TO POINT TO PROCESS EITHER A
C     REGULAR CHARACTER VARIABLE, DEFINED IN THE VARIABLE DATA 
C     STRUCTURES, OR TO PROCESS MAX/MIN TEMPERATURE TIMES, WHICH WILL
C     BE READ IN AS NUMBERS THEN CONVERTED TO CHARACTER STRINGS.
C     ------------------------------------------------------------------
      URBANETTIME = .FALSE.
      COOPTIME = .FALSE.
      SUBPVDR = .FALSE.
      ISSKYCOVER = .FALSE.
      ISSET_LAST_BEST_STATUS = .FALSE.
      IF(VCN.EQ.TMXTIME_VN_P)THEN

         COOPVAR = 'maxDailyTempTime'
         NCLEN = 9
         COOPTIME = .TRUE.

      ELSE IF(VCN.EQ.TMNTIME_VN_P)THEN

         COOPVAR = 'minDailyTempTime'
         NCLEN = 9
         COOPTIME = .TRUE.

      ELSE IF(VCN.EQ.TMFOT15M_VN_P)THEN

         URBANETVAR = 'obStartTime15m'
         NCLEN = 9
         URBANETTIME = .TRUE.
         
      ELSE IF(VCN.EQ.TMLOT15M_VN_P)THEN

         URBANETVAR = 'obEndTime15m'
         NCLEN = 9
         URBANETTIME = .TRUE.

      ELSE IF(VCN.EQ.SUBPVDR_VN_P)THEN

         SUBPVDR = .TRUE.
         NCLEN = 11

      ELSE IF(VCN.EQ.SKYCOV_VN_P)THEN

         ISSKYCOVER = .TRUE.
         NCLEN = 6 * 8

      ENDIF

      NSTA = SFC_LNUM
      IF(NSTA.EQ.0)THEN
         STATUS = NO_DATA_P
         GO TO 900
      ENDIF

      FNUM = 0
      HAVE_ANY = .FALSE.
      HAVE_DSN = .FALSE.

      DO 2 I = 1, SFC_MXSTRF
         PROC_FILE(I) = .FALSE.
 2    CONTINUE
      TOT = 0
C     ------------------------------------------------------------------
C     NOTE THAT WE LOOP THROUGH SFC_FNUM TO SEE WHICH FILES ARE NEEDED
C     AND NOT THROUGH SFC_NFILES.  THIS IS DONE AS JUST BECAUSE A FILE
C     GOT READ DOESN'T MEAN ANY OF ITS RECORDS ACTUALLY WERE EXTRACTED
C     WHEN ALL THE FILTERING WAS DONE IN MSFCSTA.  THEREFORE, WE'LL
C     ONLY PROCESS EACH FILE WITH RECORDS IN USE.
C     ------------------------------------------------------------------
      DO 100 I = 1, NSTA

C     ------------------------------------------------------------------
C     ALREADY HANDLED THIS FILE.
C     ------------------------------------------------------------------
         IF(PROC_FILE(SFC_FNUM(I)))GO TO 100

         FNUM = SFC_FNUM(I)
         PROC_FILE(FNUM) = .TRUE.
         DSN = SFC_SOURCE(FNUM)

C     ------------------------------------------------------------------
C     THE VARIABLE'S NOT ASSOCIATED WITH THIS SOURCE DATASET.
C     ------------------------------------------------------------------
         IF(COOPTIME)THEN

            IF(DSN.NE.COOP_DS_P)GO TO 100

         ELSE IF(URBANETTIME)THEN

            IF(DSN.NE.URBANET_DS_P)GO TO 100

         ELSE IF(SUBPVDR)THEN

            IF(DSN.NE.MESONET_DS_P.AND.DSN.NE.COOP_DS_P)GO TO 100

         ELSE 

            IF(VLEN(VCN,DSN).EQ.0.OR.(VCN.EQ.STALOC_VN_P.AND.
     1         CDBTYPE.EQ.AWIPS_DB_P.AND.DSN.NE.MESONET_DS_P))GO TO 100

C     ------------------------------------------------------------------
C     THE VARIABLE'S NOT CHARACTER DATA TYPE:  THIS WILL BE
C     TRUE FOR ANY DATASET FOR WHICH THIS VARIABLE APPLIES, AND IS
C     AN ILLEGAL OPTION.
C     ------------------------------------------------------------------
            IF(VDTYPE(VCN,DSN).NE.'c')THEN
               STATUS = INV_DTYPE_P
               CALL MERROR('MGETSFCC: INVALID VARIABLE DATA TYPE')
               GO TO 900
            ENDIF

         ENDIF

         IF(.NOT.HAVE_DSN)THEN
C     ------------------------------------------------------------------
C     NOW THAT WE HAVE A VALID (VCN,DSN), WE NOW KNOW THE LENGTH OF
C     THE CHARACTER RECORDS TO BE RETURNED TO THE CALLER, AND CAN FILL
C     BLANKS INTO THE CALLER'S ARRAY.  (NOTE THAT THERE ARE NO MISSING
C     DATA FLAGS FOR CHARACTER VARIABLES.)
C     ------------------------------------------------------------------

C     ------------------------------------------------------------------
C     ALSO NOTE THAT IF THIS IS SKY COVER FOR HFMETAR, WE ONLY HAVE 
C     3 LEVELS, THE OTHER 6 LEVELS WILL BE SET TO BLANK TO KEEP ALL THE
C     INDEXES STRAIGHT.
C     ------------------------------------------------------------------



            HAVE_DSN = .TRUE.
            IF(.NOT.URBANETTIME.AND..NOT.COOPTIME.AND..NOT.SUBPVDR
     1           .AND..NOT.ISSKYCOVER)THEN
               NCLEN = VCLEN(VCN,DSN)
            ENDIF
            
            DO 118 J = 1, NSTA

               DO 119 K = 1, NCLEN

                  CDATA((J-1)*NCLEN+K) = ' '

 119           CONTINUE

 118        CONTINUE

         ENDIF


C     ------------------------------------------------------------------
C     READ THE VARIABLE.  IF THERE'S AN ERROR, THE SUBROUTINE WILL HAVE
C     SET STATUS & CALLED MERROR.  IF THERE ISN'T AN ERROR, INDICATE
C     THAT WE ACTUALLY READ SOMETHING.
C     ------------------------------------------------------------------
         IF(COOPTIME)THEN

            CALL MRDDBL(COOPVAR,SFC_NCID(FNUM),SFC_RECDIM(FNUM),
     1                  1,SFC_NRECS(FNUM),MISS_P,DTMP,STATUS)

         ELSE IF(URBANETTIME)THEN

            CALL MRDDBL(URBANETVAR,SFC_NCID(FNUM),SFC_RECDIM(FNUM),
     1                  1,SFC_NRECS(FNUM),MISS_P,DTMP,STATUS)

         ELSE IF(SUBPVDR.AND.DSN.EQ.MESONET_DS_P)THEN

            CALL MGTCHR('stationName',SFC_NCID(FNUM),SFC_RECDIM(FNUM),
     1                  1,SFC_NRECS(FNUM),CTMP,LEN1REC,STATUS)
            
         ELSE 

            CALL MGTCHR(VNAME(VCN,DSN)(1:VLEN(VCN,DSN)),SFC_NCID(FNUM),
     1                  SFC_RECDIM(FNUM),1,SFC_NRECS(FNUM),CTMP,LEN1REC,
     2                  STATUS)
            
         ENDIF

         IF(I.EQ.1)THEN
            LAST_BEST_STATUS = STATUS
         ENDIF
         IF(STATUS.EQ.VAR_NOTINDB_P)THEN
            GO TO 100
         ELSE IF(STATUS.NE.SUCCESS_P)THEN
            GO TO 900
         ELSE
            LAST_BEST_STATUS = STATUS
         ENDIF
         ISSET_LAST_BEST_STATUS = .TRUE.

         HAVE_ANY = .TRUE.

C     ------------------------------------------------------------------
C     EXTRACT DESIRED RECORDS INTO CALLER'S ARRAY.  NOTE THAT THE
C     RETURNED SIZE (NCLEN) WILL BE .GE. THE ACTUAL SIZE (LEN1REC).
C     THIS ALLOWS SLIGHTLY DIFFERENT SIZES IN DIFFERENT DATASETS TO
C     BE TRANSPARENT TO THE CALLER.  ALSO, REPLACE NULLS WITH BLANKS
C     (FOR FORTRAN USERS).
C     ------------------------------------------------------------------

         IF(.NOT.URBANETTIME.AND..NOT.COOPTIME.AND..NOT.
     1      (SUBPVDR.AND.DSN.EQ.MESONET_DS_P))THEN

            IF(ISSKYCOVER)THEN
               DO 130 J = I, NSTA

                  IF(SFC_FNUM(J).NE.FNUM)GO TO 130

                  DO 131 K = 1, LEN1REC

                     IF(ICHAR(CTMP((SFC_RNUM(J)-1)*LEN1REC+K)).NE.0)THEN
                        CDATA((J-1)*NCLEN+K) =
     1                       CTMP((SFC_RNUM(J)-1)*LEN1REC+K)
                     ELSE
                        CDATA((J-1)*NCLEN+K) = ' '
                     ENDIF

 131              CONTINUE               
                  TOT = TOT + 1
 130           CONTINUE

            ELSE
               DO 120 J = I, NSTA

                  IF(SFC_FNUM(J).NE.FNUM)GO TO 120
                  
                  DO 121 K = 1, LEN1REC
                     
                     IF(ICHAR(CTMP((SFC_RNUM(J)-1)*LEN1REC+K)).NE.0)THEN
                        CDATA((J-1)*NCLEN+K) =
     1                       CTMP((SFC_RNUM(J)-1)*LEN1REC+K)
                     ELSE
                        CDATA((J-1)*NCLEN+K) = ' '
                     ENDIF
                     
 121              CONTINUE               
                  TOT = TOT + 1
 120           CONTINUE
            ENDIF

         ELSE IF(SUBPVDR.AND.DSN.EQ.MESONET_DS_P)THEN

C     ------------------------------------------------------------------
C     THE SUBPROVIDER FIELD IS IN COLUMNS 40-50 OF THE stationName
C     VARIABLE.
C     ------------------------------------------------------------------
            DO 122 J = I, NSTA

               IF(SFC_FNUM(J).NE.FNUM)GO TO 122

               DO K = 1, NCLEN

                  IF(ICHAR(CTMP((SFC_RNUM(J)-1)*LEN1REC+K+39)).NE.0)THEN
                     CDATA((J-1)*NCLEN+K) =
     1                    CTMP((SFC_RNUM(J)-1)*LEN1REC+K+39)
                  ELSE
                     CDATA((J-1)*NCLEN+K) = ' '
                  ENDIF

               ENDDO
               TOT = TOT + 1

 122        CONTINUE

         ELSE

            DO 220 J = I, NSTA

               IF(SFC_FNUM(J).NE.FNUM)GO TO 220

               IF(DTMP(SFC_RNUM(J)).NE.MISS_P)THEN

                  RTIME = DTMP(SFC_RNUM(J))

C     ------------------------------------------------------------------
C     FIX AN LDAD INGEST PROBLEM WHERE MISSING TIMES GET TRANSLATED
C     INTO UNIX TIMES OF 0 OR 18000...
C     ------------------------------------------------------------------
                  IF(RTIME.LE.18000)THEN
                     CTMP1 = '         '
                  ELSE
                     RTIME = RTIME - 1325376000
                     CALL M_MKFNAM(RTIME,CTMP1,K)
                     IF(K.NE.SUCCESS_P)CTMP1 = '         '
                  ENDIF


                  DO K = 1, 9
                     CDATA((J-1)*NCLEN+K) = CTMP1(K:K)
                  ENDDO
                  TOT = TOT + 1
                  
               ENDIF

 220        CONTINUE

         ENDIF

 100  CONTINUE

      IF(TOT.EQ.0)THEN
         HAVE_ANY = .FALSE.
      ELSE
         STATUS = LAST_BEST_STATUS
      ENDIF

 900  IF(STATUS.NE.SUCCESS_P)THEN

         NSTA = 0

      ELSE IF(.NOT.HAVE_ANY)THEN

         STATUS = NO_DATA_P
         NSTA = 0

      ENDIF

      RETURN
      END

C**---------------------------------------------------------------------
C**REQUIRED STANDARD FSL DISCLAIMER (NOVEMBER 2000)
C**---------------------------------------------------------------------
C**  OPEN SOURCE LICENSE/DISCLAIMER,  FORECAST SYSTEMS LABORATORY
C**  NOAA/OAR/FSL, 325 BROADWAY BOULDER, CO 80305
C**
C**  THIS SOFTWARE IS DISTRIBUTED UNDER THE OPEN SOURCE DEFINITION, 
C**  WHICH MAY BE FOUND AT http://www.opensource.org/osd.html.
C**
C**  IN PARTICULAR, REDISTRIBUTION AND USE IN SOURCE AND BINARY FORMS,
C**  WITH OR WITHOUT MODIFICATION, ARE PERMITTED PROVIDED THAT THE 
C**  FOLLOWING CONDITIONS ARE MET:
C**
C**  - REDISTRIBUTIONS OF SOURCE CODE MUST RETAIN THIS NOTICE, THIS LIST
C**    OF CONDITIONS AND THE FOLLOWING DISCLAIMER.
C**
C**  - REDISTRIBUTIONS IN BINARY FORM MUST PROVIDE ACCESS TO THIS 
C**    NOTICE, THIS LIST OF CONDITIONS AND THE FOLLOWING DISCLAIMER, AND
C**    THE UNDERLYING SOURCE CODE.
C**
C**  - ALL MODIFICATIONS TO THIS SOFTWARE MUST BE CLEARLY DOCUMENTED, 
C**    AND ARE SOLELY THE RESPONSIBILITY OF THE AGENT MAKING THE 
C**    MODIFICATIONS.
C**
C**  - IF SIGNIFICANT MODIFICATIONS OR ENHANCEMENTS ARE MADE TO THIS
C**    SOFTWARE, THE FSL SOFTWARE POLICY MANAGER 
C**    (softwaremgr.fsl@noaa.gov) BE NOTIFIED.
C**
C**  THIS SOFTWARE AND ITS DOCUMENTATION ARE IN THE PUBLIC DOMAIN AND 
C**  ARE FURNISHED "AS IS."  THE AUTHORS, THE UNITED STATES GOVERNMENT,
C**  ITS INSTRUMENTALITIES, OFFICERS, EMPLOYEES, AND AGENTS MAKE NO 
C**  WARRANTY, EXPRESS OR IMPLIED, AS TO THE USEFULNESS OF THE SOFTWARE
C**  AND DOCUMENTATION FOR ANY PURPOSE.  THEY ASSUME NO RESPONSIBILITY 
C**  (1) FOR THE USE OF THE SOFTWARE AND DOCUMENTATION; OR (2) TO 
C**  PROVIDE TECHNICAL SUPPORT TO USERS.
C**---------------------------------------------------------------------
