/*************************************************************************/
/*  name - rdsrbhdf                   type - program
 *  version - 1.0    date - 11/27/92   programmer - J. Travers,SAIC
 *
 *  Purpose - This program reads the SRB DAILY and MONTHLY HDF files
 *
 *  Input - HDF file named srb_monavgs_yymm or srb_dayavgs_yymm
 *  Output - Report file named srb_monagv_yymm.rpt or srb_dayavgs_yymm.rpt
 *
 *  Key Local Parameters - maxrank - max rank of HDF SDS
 *                         ddate - data date yymm
 *                         hdfname - name of HDF file
 *                         type - whether daily or monthly SRB files
 *                         areatyp - type of geographical subsetting
 *                         begin1 - beginning cell number
 *                         end1 - ending cell number
 *                         dataitems - data items to be read
 *                         status - input ok or not
 *
 * Functions Called -     Chkcode - checks for correct input
 *                        getinput - gets data date and file type
 *                        getfile - gets file names and opens output file
 *                        readhdf - reads file id and description, etc.
 *                        getarea - gets area to subset
 *                        getdata - gets parameters to subset
 *                        readdata - reads data, max, mins, etc
 *************************************************************************/

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "hdf.h"

#define MAXRANK    2
#define LISTSIZE   52
#define FIRST      1
#define MAXLEN     256
#define MAXLNG     21
#define STARTPOS   1

int main(argc,argv)

int argc;
char *argv[ ];

{

 int status, iret;
 char ddate[5], type[2], hdfname[36], outfile[50], areatyp[2], contkey[2];
 float begin1, end1;
 unsigned short int dataitems[LISTSIZE];
 FILE *out;

 /*  function prototypes */

 int Chkcode();
 char *getinput();
 void getfile();
 void readhdf();
 void getarea();
 void getdata();
 void readdata();

/* Try to extract date and file type from command line */
 status = FALSE;
 if (argc > 2){
   if (status = Chkcode(argv[1],argv[2]))
   {
     strncpy(ddate,argv[1],4);
     strncpy(type,argv[2],1);
   }
 }

/*  prompt for info if necessary */

 if (status == FALSE)
 {
   printf("This program reads SRB Daily and Monthly HDF files.  The input\n");
   printf("file name is built according to naming conventions formed at the\n");
   printf("Langley DAAC.  If you have changed the file name or need to\n");
   printf("specify a path, you need to modify this program.  Please enter\n");
   printf("Q to Quit or C to continue ");
   scanf("%s",contkey);
   printf("\n\n");
   if (contkey[0] =='Q' || contkey[0] =='q')
   {
     printf("\n\nExiting program ...\n\n");
     exit(1);
   }
   else
   {
     do{
       getinput(ddate,type);
       iret = Chkcode(ddate,type);
     }while(iret != TRUE);
   }
  }

/* get hdf filename and output file */


  getfile(ddate,type,hdfname,outfile);

/* open output file */

  if ((out=fopen(outfile,"wt")) == NULL)
  {
    printf("Cannot open output file\n\n");
    exit(1);
  }

/*  call function to read file id */

  readhdf(out,hdfname);

/*  call function to subset area */

  getarea(areatyp,&begin1,&end1);

/*  call function to get parameters */

  getdata(out,hdfname,dataitems);

/*  call function to read data */

  printf("\n\nGetting data, Please wait ...\n");
  readdata(out,hdfname,dataitems,areatyp,begin1,end1);
}

/************************************************************************/
/*  Name - Chkcode                           Type - function
 *  Version - 1.0       Date - 11/27/92      Programmer - J. Travers,SAIC
 *
 *  Purpose - This program checks the input parameters for the correct type
 *
 *  Input   - arg1,arg2 - representing data date and file type
 *
 ************************************************************************/

 int Chkcode(arg1,arg2)
 char *arg1, *arg2;

 {
  if ((!isdigit(arg1[0])) || (!isdigit(arg1[1])) || (!isdigit(arg1[2])) ||
  (!isdigit(arg1[3])) || (!isalpha(arg2[0]))){
     return FALSE;
  }
  else{
    return TRUE;
  }
 }

/***********************************************************************/
/*   name - getinput                      type - function
 *  version - 1.0      date - 11/27/92    programmer - J. Travers, SAIC
 *
 *   Purpose - This subroutine accepts user input for data date and type
 *             of SRB data to read
 *
 *   Input parameters -  none
 *   Output parameters - ddate - the data date (yymm) 
 *                       type - type of data to read (D-daily, M-monthly)
 *
 *  Key Local Parameters - NONE
 *  Functions Called - NONE
 ************************************************************************/
  
 char *getinput(ddate,type)
 char *ddate, *type;

 {
  printf("Enter data date of SRB data to read (yymm) ");
  scanf("%s",ddate);
  printf("\n\nEnter type of SRB data to read(D-Daily, M-Monthly) ");
  scanf("%s",type);
  printf("\n\n");
 }

/**********************************************************************/
/*  name - getfile                            type - function
 *  version - 1.0        date - 11/27/92       programmer - J. Travers,SAIC
 *
 *  Purpose - This subroutine gets the files names and opens the
 *           output file
 *
 *  Input parameters - ddate - the data date
 *                     type  - whether daily or monthly SRB data
 *                 
 *  Output parameters - hdfname - name of HDF file
 *
 *  Key local parameters - outfile - name of output file
 *                         typename - dayavgs or monavgs
 ********************************************************************/

 void getfile(ddate,type,hdfname,outfile)

 char *ddate, *type, *hdfname, *outfile;
 {
  
  char typename[8];

  if (type[0] =='D' || type[0] =='d'){

    strcpy(typename,"dayavgs");
  }
  else if (type[0] == 'M' || type[0] == 'm'){
    strcpy(typename,"monavgs");
  }
  else{
    printf("Error on code for file type\n\n");
    exit(1);
  }

/*  hdf file name */

  strcpy(hdfname,"srb_");
  strncat(hdfname,typename,7);
  strcat(hdfname,"_");
  strncat(hdfname,ddate,4);
 /* strcat(hdfname,".hdf");*/

/* output file name */

  strncpy(outfile,hdfname,16);
  strcat(outfile,".rpt");

  printf("Input file is %s\n",hdfname);
  printf("Output file is %s\n\n",outfile);

}

/*******************************************************************/
/*  name - readhdf                               type - function
 *   version - 1.0          date - 11/27/92       programmer - J. Travers
 *
 * Purpose - This subroutine reads the file id and file description
 *
 * Input -   hdfname - the name of the HDF input file
 *
 * Key Local Parameters :  iret - return code from HDF routines
 *                         dfile - pointer to HDF file
 *                         id - file id
 *                         filedesc - file description
 *
 * Functions Called :  HDF functions to get file id, file description,
 *******************************************************************/

 void readhdf(out,hdfname)

 char *hdfname;
 FILE *out;

 {

  int iret,dfile;
  char fileid[255];

  dfile = Hopen(hdfname,DFACC_READ,0);
  if (dfile == NULL){
    fprintf(out,"%s %s\n\n","Error in opening HDF file",hdfname);
    exit(1);
  }

 /* get file id */

  iret = DFANgetfid(dfile,fileid,MAXLEN,FIRST);
  if (iret == -1){
    fprintf(out,"%s\n\n","Error in getting file id");
    exit(1);
  }
  else
    fprintf(out,"%s %s\n\n","File ID: ",fileid);

  iret = Hclose(dfile);

 }

/********************************************************************/
/*  Name - getarea                       type - function                    
 *  Version - 1.0     Date -11/27/92     Programmer - J. Travers,SAIC        
 *                                                                       
 * Purpose - This functions asks the user to enter the cell      
 *           numbers to subset data          
 *                                                                      
 * Input Parameters - NONE                                              
 * Output Parameters -areatyp - enter cell number(C) or none
 *                    begin1-beginning cell number               
 *                    end1 - ending cell number                       
 *                                                                      
 * Key Local Parameters -NONE
 *
 * Functions Called - NONE
 *****************************************************************/

 void getarea(areatyp,begin1,end1)

 char *areatyp;
 float *begin1, *end1;
 {
  char kind[2];

  printf("Enter whether you would like to further subset based on cell\n");
  printf("number (C) or no subsetting (N) ");
  scanf("%s",kind);
  *areatyp = toupper(kind[0]);
  
  if (areatyp[0] == 'N'){
    *begin1 = 0.0;
    *end1 = 0.0;
  }
  else if (areatyp[0] == 'C'){
     printf("\n\nEnter beginning and end cell number (1-6596) separated ");
     printf("by a space ");
     scanf("%f %f",begin1,end1);
  }
  else{
    printf("Error in entering subsetting requirements\n\n");
    exit(1);
  }
}

/*********************************************************************/
/*  Name - getdata                           Type - Function
 *  Version - 1.0         Date - 11/27/92    Programmer - J. Travers,SAIC
 *
 * Purpose - This subroutine allows the user to choose from the annotation
 *           labels, which data parameters to dump
 *
 * Input -   hdfname - the number of HDF file
 * Output -  dataitems - list of reference numbers of data to dump 
 *
 * Key Local Parameters - nlabels - number of reference labels
 *                        i,j - counters
 *                        k - index to dataitems
 *                        itemnum - number for user to choose
 *                        startpos - starting position in HDF file
 *                        reflist - list of reference numbers
 *                        labellist - list of annotation labels
 *            
 * Functions called - annotation label routines from HDF
 *********************************************************************/

void getdata(out,hdfname,dataitems)

char *hdfname;
unsigned short int dataitems[LISTSIZE];
FILE *out;

{
  int i,j,k,itemnum,nlabels,iret;
  char labellist[LISTSIZE*MAXLNG];
  unsigned short int reflist[LISTSIZE];

/*  initialize dataitems array */

  for (i=0; i<LISTSIZE; i++){
     dataitems[i] = 65535;
  }

/*  get annotation labels */

  nlabels  = DFANlablist(hdfname,DFTAG_NDG,reflist,labellist,LISTSIZE,
                         MAXLNG,STARTPOS);

  if (nlabels == -1){
    fprintf(out,"Error in getting annotation labels\n\n");
    exit(1);
  }
  
  printf("\n");

  j=1;
  k=0;
  for (i=0; i<nlabels; ++i){
    if (j == 1)
    {
      itemnum = 1;
      printf("      Item Number      Label\n\n");
    }
    printf("         %2d        %s\n",i+1,labellist+(i*MAXLNG));
    j++;
    if (j>26 || j>nlabels)
    {
      printf("\n");
      printf("Please choose the numbers of the data items to dump ");
      printf("separated by a space.\n");
      printf("Enter -1 to continue to the next list or 0 to quit ");
      printf("entering parameters\n\n");
      
      while (itemnum >0)
      {
         scanf("%d",&itemnum);
         if (itemnum == -1)
           break;
         if (itemnum == 0)
         {
           dataitems[k] = 0;
           return;
         }
         dataitems[k] = reflist[itemnum-1];
         k++;
       }
       j = 1; 
     }
   }
   dataitems[k] = 0;
}

/***********************************************************************/
/* Name - readdata                           type - function
 * Version - 1.0          Date-11/27/92      Programmer- J. Travers,SAIC  
 *                                                                         
 * Purpose - This function determines the data slice to retrieve and using
 *           the reference numbers gets the appropriate data, data        
 *           attributes, max, and min  and then prints the data.          
 *                                                                        
 * Input Parameters - hdfname - name of hdf file to read                  
 *                    dataitems- stores reference numbers of data chosen  
 *                    areatyp-type of subsetting (cell # or none) 
 *                    begin1- beginning cell number                   
 *                    end1- ending cell number                         
 *                                                                       
 *  Output Parameters - none                                               
 *                                                                         
 * Key Local Parameters - winst - stores starting dimensions of data slice
 *                        windims- stores length of slice                 
 *                        dims - stores dimension of data array
 *                        data - stores data gotten from HDF file               
 *                        datalabel - stores label for data               
 *                        dataunit- stores units for data
 *                        datafmt - stores format for data                
 *                        max,imax - stores maximum value                      
 *                        min,imin - stores minimum value                      
 *                        dataval,idataval - stores data values 
 *                        numdims - number of dimensions of SDS
 *                        dimsize - dimension sizes
 *                        listsize - the max number of parameters
 *                        numtype - HDF number type, 5 floating, 24 -
 *                                  32 bit integer  
 *                                                                        
 * Subroutines Called - HDF routines to read the SDS data slice, max,min  
 *                       data attributes, etc.
 **************************************************************************/          

 void readdata(out,hdfname,dataitems,areatyp,begin1,end1)

 char *hdfname, *areatyp;
 float begin1, end1;
 FILE *out;
 unsigned short int dataitems[LISTSIZE];

 {

 char datalabel[260], dataunt[25], datafmt[10], missingval[25];
 int32 iret, winst[MAXRANK], winend[MAXRANK], windims[MAXRANK];
 int32 dims[MAXRANK],dimsize[MAXRANK], numdims,numtype;
 int32 imax, imin, idatavals[204476];
 float max, min, datavals[204476];
 int k=0,i,j,iendvl1,iendvl2,index;


 /*  set up slice of data */

 if (areatyp[0] == 'C')
 {
  winst[1] = 1;
  winst[0] = (int) begin1;
  winend[1] = 1;
  winend[0] = (int) end1;
  windims[1] = 1;
  windims[0] = (int)(end1-begin1 + 1);
  dims[0] = windims[0];
  dims[1] = windims[1];
 }
 else{
   winst[0] = 1;
   winst[1] = 1;
   winend[0] = 6596;
   winend[1] = 1;
   windims[0] = 6596;
   windims[1] = 1;
   dims[0] = windims[0];
   dims[1] = windims[1];
 }



 /*  while we have data items to get */

 while (dataitems[k] != 0)
 {

 /*  go to desired data reference */

  iret = DFSDreadref(hdfname,dataitems[k]);
  if (iret == -1)
  {
   fprintf(out,"Error on going to specified reference number %d\n\n",
           dataitems[k]);
   exit(1);
  }

 /* get data dimensions */

  iret = DFSDgetdims(hdfname,&numdims,dimsize,MAXRANK);

  if (iret !=0)
  {
   fprintf(out,"Error on getting dimensions\n\n");
   exit(1);
  }
  else
  {
   fprintf(out,"Dimensions are %d by %d\n\n",dimsize[0],dimsize[1]);
  }

 /*  change slice info if daily i.e. dimsize[0] != 1 */

  if (dimsize[1] != 1)
  {
   windims[1] = dimsize[1];
   dims[1] = windims[1];
  }

 /*  get number type */

  iret = DFSDgetNT(&numtype);
  if (iret != 0)
  {
   fprintf(out,"Error on getting number type\n\n");
   exit(1);
  }

 /*  get data attributes */

  iret = DFSDgetdatastrs(datalabel,dataunt,datafmt,missingval);
  if (iret != 0)
  {
   fprintf(out,"Error on getting data attributes\n\n");
   exit(1);
  }
  else
  {
   fprintf(out,"Data attributes are as follows:\n\n");
   fprintf(out,"Label       :\n");
   for (i=0; i<260 && datalabel[i] != NULL; i++){
     fprintf(out,"%c",datalabel[i]);
     if (((i+1)%80) == 0) {
      fprintf(out,"\n");
     }
   }
   fprintf(out,"\n\n");
   fprintf(out,"Units        : %s\n",dataunt);
   fprintf(out,"Format       : %s\n",datafmt);
   fprintf(out,"Missing value: %s\n\n",missingval);
  }

  if (numtype == 5)
  {
   iret = DFSDgetrange(&max,&min);
   if (iret == -1)
   {
    fprintf(out,"Error on getting max and min\n\n");
    exit(1);
   }
   else
   {
    fprintf(out,"Data max: %f\n",max);
    fprintf(out,"Data min: %f\n\n",min);
   }

 /*  get data slice */

   iret = DFSDgetslice(hdfname,winst,windims,datavals,dims);
   if (iret == -1)
   {
    fprintf(out,"Error on getting data slice\n\n");
    exit(1);
   }
   else
   {
    fprintf(out,"Data values for cells %d to %d are as follows:\n\n",
            winst[0],winend[0]);

   if (dimsize[1] != 1)
   {
    iendvl1 = dims[0];
    iendvl2 = dims[1];
   }
   else
   {
    iendvl1 = dims[1];
    iendvl2 = dims[0];
   }

/* print data */

   for (i=0; i<iendvl1; i++){
     for (j=0; j<iendvl2; j++){
        index = i*iendvl2+j;
        fprintf(out,"%12.4f",datavals[index]);
        if (((j+1)%6) == 0){
         fprintf(out,"\n");
        }
     }
     fprintf(out,"\n\n");
    }
  }
  }

  else if (numtype == 24)
  {
   iret = DFSDgetrange(&imax,&imin);
   if (iret == -1)
   {
    fprintf(out,"Error on getting max and min\n\n");
    exit(1);
   }
   else
   {
    fprintf(out,"\n\nData max: %d\n",imax);
    fprintf(out,"Data min: %d\n\n",imin);
   }

 /*  get data slice */

   iret = DFSDgetslice(hdfname,winst,windims,idatavals,dims);
   if (iret == -1)
   {
    fprintf(out,"Error on getting data slice\n\n");
    exit(1);
   }
   else
   {
    fprintf(out,"Data values for cells %d to %d are as follows:\n\n",
            winst[0],winend[0]);

   if (dimsize[1] != 1)
   {
    iendvl1 = dims[0];
    iendvl2 = dims[1];
   }
   else
   {
    iendvl1 = dims[1];
    iendvl2 = dims[0];
   }

/* print data */

   for (i=0; i<iendvl1; i++){
     for (j=0; j<iendvl2; j++){
        index = i*iendvl2+j;
        fprintf(out,"%7d",idatavals[index]);
        if (((j+1)%11) == 0){
         fprintf(out,"\n");
        }
     }
     fprintf(out,"\n\n");
    }
  }
 }

  else
  {
   fprintf(out,"Invalid data type cannot get data\n\n");
   exit(1);
  }
  fprintf(out,"\n\n");
  k ++;
 }
}
