/*
 * filter the result of ncdump to output time information - RD February 2004
 *
 * Use the output of ncdump as the input to this program.  For example, this perl script 
 * could be used on multiple netCDF files to replace dates with something more readable:
 *
 *  #!/usr/bin/perl -w
 *  for ($a = 0; $a < scalar(@ARGV); $a++) {
 *    $command = "ncdump -c $ARGV[$a] | read.ncdump\n";
 *    system($command);
 *  }
 *
 */

#include <stdio.h>
#include <math.h>
#include "/opt/netcdf/include/udunits.h"

#define LEN     99
/*
 * Please note that a "segmentation error" may occur owing to a
 * liberal use of memory here.  If this occurs, a reduction of
 * LOTS(=3333 or so) may be in order.
 */
#define LOTS    99999
#define DIMS    0
#define VARS    1
#define DATA    2

void datestr(char date[], int yr, int mo, int dy, int hr, int mn, int sc);

int main(int argc, char *argv[])
{
    FILE *fpa, *fpb, *fopen();
    int a, b, c, d, year, month, day, hour, minute, section;
    char line[LOTS], date[LEN], times[LOTS][LEN], valstr[LEN];
    float second;

    char udunita[LEN], udunitb[LEN];                                          /* udunits declarations */
    utUnit utunita, utunitb;
    float value;

    if (argc != 1) {
      printf("Usage: %s\n",argv[0]);
      exit(1);
    }

    if (utInit("") != 0) {
      printf("couldn't initialize Unidata units library\n");
      exit(2);
    }

    while (gets(line) != NULL) {                                              /* for each ncdump output line */
      if (strstr(line,"dimensions:") != NULL) section = DIMS;                 /* note the section being printed */
      if (strstr(line,"variables:")  != NULL) section = VARS;
      if (strstr(line,"data:")       != NULL) section = DATA;

      if (section == VARS && strstr(line,"time:units") != NULL) {
        printf("%s\n",line);
        strtok(line,"\"");
        strcpy(udunita,strtok(NULL,"\""));
        utScan(udunita,&utunita);
      }
      else if (section == VARS && strstr(line,"time:actual_range") != NULL) {
        strtok(line,"=,;");
        strcpy(valstr,strtok(NULL,"=,;"));
        sscanf(valstr,"%f",&value);
        utCalendar(value,&utunita,&year,&month,&day,&hour,&minute,&second);
        datestr(date,year,month,day,hour,minute,second);
        printf("%s= \"%s, ",line,date);
        strcpy(valstr,strtok(NULL,"=,;"));
        sscanf(valstr,"%f",&value);
        utCalendar(value,&utunita,&year,&month,&day,&hour,&minute,&second);
        datestr(date,year,month,day,hour,minute,second);
        printf("%s\"\n",date);
      }
      else if (section == VARS && strstr(line,"time:ltm_range") != NULL) {
        strtok(line,"=,;");
        strcpy(valstr,strtok(NULL,"=,;"));
        sscanf(valstr,"%f",&value);
        utCalendar(value,&utunita,&year,&month,&day,&hour,&minute,&second);
        datestr(date,year,month,day,hour,minute,second);
        printf("%s= \"%s, ",line,date);
        strcpy(valstr,strtok(NULL,"=,;"));
        sscanf(valstr,"%f",&value);
        utCalendar(value,&utunita,&year,&month,&day,&hour,&minute,&second);
        datestr(date,year,month,day,hour,minute,second);
        printf("%s\"\n",date);
      }
      else if (section == DATA && strstr(line,"time =") != NULL) {
        while (strstr(line,";") == NULL) {
          gets(valstr);
          strcat(line,valstr);
        }
        strcpy(valstr,strtok(line,"=,"));
        a = 0;
        while (strstr(valstr,";") == NULL) {
          strcpy(valstr,strtok(NULL,"=,"));
          sscanf(valstr,"%f",&value);
          utCalendar(value,&utunita,&year,&month,&day,&hour,&minute,&second);
          datestr(date,year,month,day,hour,minute,second);
          strcpy(times[a],date);
          a++;
        }
        printf(" time = ");
        b = c = 0;
        while (b < a) {
          printf("%s",times[b]);
          if (b == a-1)
            printf(" ;\n");
          else if (c == 2) {
            printf(",\n        ");
            c = -1;
          }
          else
            printf(", ");
          b++; c++;
        }
      }
      else {
        printf("%s\n",line);
      }
    }
    fclose(fpa);
    return(0);
}

void datestr(char date[], int yr, int mo, int dy, int hr, int mn, int sc)
{
    char num[LEN];

    sprintf(num,"%d",yr);
    if (yr < 10)        strcpy(date,"000");
    else if (yr < 100)  strcpy(date,"00");
    else if (yr < 1000) strcpy(date,"0");
    else                strcpy(date,"");
    strcat(date,num);
    strcat(date,"-");

    sprintf(num,"%d",mo);
    if (mo < 10)        strcat(date,"0");
    strcat(date,num);
    strcat(date,"-");

    sprintf(num,"%d",dy);
    if (dy < 10)        strcat(date,"0");
    strcat(date,num);
    strcat(date," ");

    sprintf(num,"%d",hr);
    if (hr < 10)        strcat(date,"0");
    strcat(date,num);
    strcat(date,":");

    sprintf(num,"%d",mn);
    if (mn < 10)        strcat(date,"0");
    strcat(date,num);
    strcat(date,":");

    sprintf(num,"%d",sc);
    if (sc < 10)        strcat(date,"0");
    strcat(date,num);
}
