/*
 * readWSI.c
 *
 * Version 1.0 10/27/95
 *
 * Written by: Paul J. Meyer
 * NASA/MSFC:  10/26/95
 *
 * 02/20/97 - corrected error:  tag and ref were not set to 0 before calling
 *	      Hfind for the first time.  This error did not affect SGI, but
 *            caused code to fail on Sun Solaris 2.4 with cc and gcc.
 *            Evans A Criswell
 *
 * 02/06/97 - corrected line 164 (combined into one line) Judy Fennelly
 *
 * 10/27/95 - Added additional command line parameters
 *          - Accounted that pixelTotals, and echoes.echoes might be 0
 *          - Determined whether a gif image was available for the hdf file
 * 10/28/95 - Added additional error checks, comments
 *          - Bypassed status code check if status data not available
 *          - Corrected bug when no path component included in hdfName
 * 01/22/95 - Converted from meta file generation software to a simple
 *            data reader program.
 *
 *
 * The purpose of this program is to extract meta information from WSI nowrad
 * data files which have been translated into HDF file format.
 * It also shows how to read the HDF formatted data file.
 *
 */


#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "hdf.h"

enum boolean { False, True } ;

typedef struct {
    int present;                  /* # of radar sites included in composite */
    int absent;                   /* # of radar sites NOT included in composite
*/
    int offline;                  /* # of radar sites offline */
    int nodata;                   /* # of sites with no data received by vendor
*/
} SITES;

typedef struct {
    int echoes;                   /* # of echo pixels in image */
    int convEchoes;               /* # of echoes above 35 Dbz */
    long pixelTotal;              /* Total # of pixels in image */
} ECHOES;


main(int argc, char **argv)
{

    static SITES sites;           /* Radar site statistics */
    static ECHOES echoes;         /* Radar echo coverage statistics */

    struct stat statBuf;          /* Buffer for file status */

    long  hdfId;                  /* File identifier for the hdf file */

    uint16 tag;                   /* Tag for the Annotation */
    uint16 ref;                   /* Reference # for the annotation */
    int32 findOffset;             /* Offset into the file for the annotation */
    int32 findLength;             /* Length of the annotation block */

    short descBufSize;            /* Size of the description buffer */

    float echoCoverage;           /* Percent of composite covered with echoes
*/
    float echoConvCoverage;       /* Percent of echoes considered convective
 */

    int i;                        /* Loop variable */
    int level, pixcount;          /* Used for radar echo statistics */
    int width;                    /* width of the image (columns) */
    int height;                   /* height of image (rows) */
    int ispal;                    /* Is there a palette associated with the
image */

    int lastHdf_refI;             /* The most recently referenced HDF image */

    int expectedArgs;             /* expected # of command line arguments */

    int debug;                    /* Do we perform debug output lines */

    char *descBuf;                /* Pointer to the annotation buffer */

    char *labelBuf;               /* Hdf image annotation */
    int  labelBuf_sz;

    char *progName;               /* Handle to name of this program */
    char *hdfName;                /* Input file name */

    char *lastSlash;              /* Last / in a pathname */

    char *statPtr;                /* Useful pointer into description buffer */

    char metaDesc[83];            /* Output data line containing meta data */
    char hdfFile[256];            /* Base Name of the hdf File */
    char statusLine[256];         /* Radar site status line */
    char *inclusion;              /* Pointer to radar site inclusion token */

    unsigned char *inputImage;    /* Pointer to the Radar image data */


    /*****************************************************************************/

    progName = argv[0];

    expectedArgs = 2;
    if (argc < expectedArgs) {
	fprintf(stderr, "Usage: %s hdfName (debug)\n", progName);
	exit(1);
    }

    debug = (argc > expectedArgs) ? True : False;

    hdfName = argv[1];

    /* Obtain the location of the Base HDF file name */
    /* Of course the `basename()` routine works as well (hindsight 20-20) */
    lastSlash = strrchr(hdfName, '/');
    if (lastSlash) {          /* Was there a slash '/' in input name? */
        lastSlash++;          /* get to actual file name, next char after '/'
*/
    } else {
        lastSlash = hdfName;  /* no '/' in the input name */
    }

    /* Obtain the basename of the hdf files fully qualified path name */
    strcpy(hdfFile, lastSlash);

    /* Open the hdf file, and obtain the description buffer reference, tag #'s
*/

    hdfId = Hopen(hdfName, DFACC_READ, 0);

    printf ("hdfId = \"%d\"\n", hdfId);
    
    fflush (stdout);

    tag = 0;
    ref = 0;

    if (Hfind(hdfId, DFTAG_RIG, DFREF_WILDCARD, &tag, &ref, &findOffset,
	&findLength, DF_FORWARD) == FAIL) {
	fprintf(stderr, "Error finding a reference tag\n");
	exit(1);
    }


    /* Now determine the size of and obtain the description buffer */
    if ((descBufSize = DFANgetdesclen(hdfName, tag, ref)) == FAIL) {
	fprintf(stderr, "Error determining description buffer length\n");
	exit(1);
    }


    if((descBuf = (char *) calloc(descBufSize+1, sizeof(char))) == NULL) {
	fprintf(stderr, "Error obtaining memory for description buffer\n");
	exit(1);
    }

    fprintf(stderr, "Allocated space for Description buffer\n");

    if ((DFANgetdesc(hdfName, tag, ref, descBuf, descBufSize)) == FAIL) {
	fprintf(stderr, "Error obtaining description buffer\n");
	exit (1);
    }

    fprintf(stdout, "%s", descBuf);
    fprintf(stdout, "\n END OF DESCRIPTION BUFFER - Calculated values follow\n");

    /* Start of Raster 8 image block. Example of how to read the image data */

    if ( DFR8getdims(hdfName, (int32 *) &width, (int32 *) &height, &ispal) != 0 ) {
	fprintf(stderr,"Error reading dimensions of the RIS8 image \n");
	exit(1);
    }


    /* Allocate space for the input image */
    inputImage = (unsigned char *) calloc (width * height,
					   sizeof (unsigned char));
    if (!inputImage) {
	fprintf(stderr, "%s: Error allocating memory for input image\n",
		progName);
	exit (1);
    }

    /* Read the image data into memory, but we won't do anything with it */
    /* in this sample program */
    if(DFR8getimage(hdfName, inputImage, width, height, NULL) != 0 ) {
        fprintf(stderr,"%s: Error in reading the RIS8 image \n", progName);
        exit(1);
    }
    /* end of RIS8 image block */

    /* Obtain the annotation label */
    if ((lastHdf_refI = DFR8lastref() ) != -1 ) {
	if ((labelBuf_sz = DFANgetlablen(hdfName, DFTAG_RIG,
	    lastHdf_refI)) != -1 ) {
	    labelBuf = (char *) calloc(labelBuf_sz+1, sizeof(char));
	}

	if (DFANgetlabel(hdfName, DFTAG_RIG, lastHdf_refI,
	    labelBuf, labelBuf_sz) != -1 ) {
	    fprintf(stderr,"HDF Label: %s\n", labelBuf);
	}
    }



    /* Now lets collect some statistics from the data */
    /* You don't need to do this, it's just here for fun */

    echoes.pixelTotal = 0;
    echoes.echoes = 0;
    echoes.convEchoes = 0;

    /* Obtain the radar echo statistics */
    statPtr = strstr(descBuf, "Reflectivity(dbZ)");
    while (*statPtr != '\n') statPtr++;
    for (i = 0; i < 16; i++) {
        sscanf(statPtr, "%ld %ld", &level, &pixcount);

	statPtr++;
	while(*statPtr != '\n') {
	    statPtr++;
	}

	echoes.pixelTotal += pixcount;

        if (level > 0) echoes.echoes += pixcount;
	if (level > 6) echoes.convEchoes += pixcount;
    }

    /* Determine echo coverage in percent */
    echoCoverage = (echoes.pixelTotal > 0)
        ?  echoes.echoes/(float) echoes.pixelTotal * 100. : 0;
    echoConvCoverage = (echoes.echoes > 0)
        ? echoes.convEchoes/(float) echoes.echoes * 100. : 0;


    /* Search for the radar status information */

    statPtr = strstr(descBuf,
"*****************************************************");

    if (statPtr != NULL) {     /* Status information is present */
	while (*statPtr != '\n') statPtr++;
	statPtr++;

	while ( *statPtr != '\0') {
	    i = 0;
	    while ( *statPtr != '\n') {
		statusLine[i++] = *statPtr++;
	    }
	    statusLine[i] = '\0';

	    if (debug) fprintf(stderr, "%s\n", statusLine);

	    strtok(statusLine, "|");
	    strtok(NULL, "|");
	    strtok(NULL, "|");
	    inclusion = strtok(NULL, "|");

	    if (strstr(inclusion, "    included") != NULL) sites.present++;
	    else if (strstr(inclusion, "not included") != NULL) sites.absent++;
	    else if (strstr(inclusion, "offline") != NULL) sites.offline++;
	    else if (strstr(inclusion, "no data rcvd") != NULL) sites.nodata++;

	    statPtr++;
	}

    }

    sprintf(metaDesc, "%s %d %d %d %d %.1f %.1f\n",
	hdfFile, sites.present, sites.absent, sites.offline,
	sites.nodata, echoCoverage, echoConvCoverage);

    fprintf(stdout, "%s", metaDesc);

    free (inputImage);
    free (labelBuf);
    free (descBuf);

    Hclose (hdfId);

    exit(0);
}

