/* --------------------------------------------------------------- *
 *                                                                 *
 * time_igpp.c - This file contains functions to convert amongst   *
 *       various formats of the UCLA-IGPP time definition called   *
 *       "Cline time". This time is a double (real*8) value        *
 *       containing the number of seconds since January 1, 1966 at *
 *       00:00:00.000.  These functions convert to and from double *
 *       and integer arrays or character strings. They are callable*
 *       only from C.  See the file ctime.c for functions callable *
 *       by FORTRAN.                                               *
 *                                                                 *
 * Copyright (c) 1975-94 Regents of the University of California.  *
 * All Rights Reserved.                                            *
 *                                                                 *
 * Redistribution and use in source and binary forms are permitted *
 * provided that the above copyright notice and this paragraph are *
 * duplicated in all such forms and that any documentation,        *
 * advertising materials, and other materials related to such      *
 * distribution and use acknowledge that the software was developed*
 * by the University of California, Los Angeles.  The name of the  *
 * University may not be used to endorse or promote products       *
 * derived from this software without specific prior written       *
 * permission.  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY  *
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION,   *
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A     *
 * PARTICULAR PURPOSE.                                             *
 *                                                                 * 
 * For information about this software please contact:             *
 *                                                                 *
 *   Principal Investigator:                                       *
 *     Christopher Russell                                         *
 *     UCLA - Institute of Geophysics and Planetary Physics        *
 *     6871 Slichter Hall                                          *
 *     Los Angeles, Ca. 90024-1567                                 *
 *     INTERNET e-mail:    ctrussell@igpp.ucla.edu                 *
 *     NSI/DECnet e-mail:  BRUNET::CTRUSSELL                       *
 *     Telephone:          (310)825-3188                           *
 *                                                                 *
 *   Programmer:                                                   *
 *     Harry Herbert                                               *
 *     UCLA - Institute of Geophysics and Planetary Physics        *
 *     5833 Slichter Hall                                          *
 *     Los Angeles, Ca. 90024-1567                                 *
 *     INTERNET e-mail:    hherbert@igpp.ucla.edu                  *
 *     NSI/DECnet e-mail:  BRUNET::HARRY                           *
 *     Telephone:          (310)825-9030                           *
 *                                                                 *
 * --------------------------------------------------------------- */
/* Leel 03/02/00   N Supports pcs                                  */
/* Leel 03/02/00   N Supports AT2000 and Cline time                */
/*                 c Default to Cline time                         */
/* Leel 08/01/03   N Support JT2000 Time (Jan 01 2000 12:00:000)   */
/*******************************************************************/
#include <math.h>
#include <ctype.h>
#include <string.h>
#define PC  /* Added, jw, dec 2003 */
#ifndef PC
#include <sys/time.h>
#endif

#ifndef lint
static char sccsid[]="@(#)time_igpp.c	1.2 5/26/94";
#endif

#include "time_igpp.h"
#include "time_igppP.h"
int cc_num_str(),cc_mon_str();
void PrintArray(int i[8]);
#define INITDD 1e34
/* leel 06/19/00 added one day (seems off) */
static  int JulianDayOffset=(int)DN0;
static  int TimeEpoch      =Y1966;
static  char *Y1966Label="Y1966",*Y2000Label="Y2000",*J2000Label="J2000";
static  char *Y1958Label="Y1958";
static char *IGPPptr=NULL;
/* leel 09/10/02 dd is the number of days
                 if the current number of days does not differ
                 do not recalculate year,doy,month in t_con_i */
static float dd = (float)INITDD;
static char *months[]={"   ","JAN","FEB","MAR","APR","MAY","JUN",
           	             "JUL","AUG","SEP","OCT","NOV","DEC"};
static int verbose=0;
static int first = 1;
double c_con_t (at)
char *at;
{
  int it[8];
  c_con_i(at,it);
  return (i_con_t(it));
}
void c_con_i(at,it)
  char *at;
  int it[8];
{
  int k=0;


  it[0] = cc_num_str(&at,4,&k);   /* try for year, up to 4 digits */
  it[1] = it[2] = it[3] = 0;
  /* try for character month */
  if ((it[2] = cc_mon_str(&at,&k)) != 0) goto dom;  
  /* no month, try for 3 digit day of year */
  it[1] = cc_num_str(&at,3,&k);    
  /* try for character month */
  if ((it[2] = cc_mon_str(&at,&k)) == 0) goto hour;  
dom:
    it[3] = cc_num_str(&at,2,&k);    /* day of month */
hour:
  it[4] = cc_num_str(&at,2,&k);
  it[5] = cc_num_str(&at,2,&k);
  it[6] = cc_num_str(&at,2,&k);
  it[7] = cc_num_str(&at,3,&k);
  return;
}
int cc_num_str(a,w,k)
char **a;		/* character time string */
int w;		/* maximum number of digits to scan */
int *k;		/* Number of digits scanned. */
{
  int d;                /* number of digits scanned */
  int n;                /* decimal value of characters, returned */
  char p,*s,x;
  int nc= *k;
                   
  for (s= *a,n=0,x= *s,d=0; (d<w) & (nc < 28) ; x= *++s,nc++) {
    if (isdigit(x)) {
      n *= 10;
      n += x - '0';
      d++;
    }
    else {
      if (x == '\0') break;/* end of string */
      if (d != 0) break;   /* previous digits found */
      p = x;          /* save character before digits, might be d.p. */
    }
  }

  if (p == '.') while (d < w) { d++; n *= 10; }
  *a = s;
  *k = nc;
  return n;
}
int cc_mon_str(a,k)
  char **a;			/* character time string */
  int *k;
{
  char month[4],*s;
  int n = 0,nc= *k;
  int i;

  s = *a;
/* search for non blank */
  while ( isspace (*s) && nc < 28) { nc++; s++; }

/* Assume ucb toupper, where one has to check islower first */
  for (i = 0; i < 3 && (month[i] = *s) !='\0'; i++,s++,nc++) 
    if (islower(month[i])) month[i] = toupper(month[i]);
  month[i] = '\0';

  for (n=12; n > 0 && strcmp (month,months[n]); n--);
  if (n) { *k = nc; *a = s; }
  return n;
}
void t_con_c(t,at)
  double t;
  char *at;
{
  extern int TimeEpoch;
  int it[8];
  t_con_i(t,it);
  i_con_c(it,at);
  return;
}
double i_con_t(it)
int it[8];
{
  extern int JulianDayOffset;
  extern int TimeEpoch;
  int yr;
  double dn=0; /* leel 05/07/00 initialize to zero always */
  double time;
  if(JulianDayOffset==0)JulianDayOffset=(int)DN0;
  yr = it[0];
  if (yr < 100) yr += 1900;
  if (it[1] == 0) dn = gregorian_day(it[3],it[2],yr);
  else dn = gregorian_day(1,1,yr) + it[1] - 1;
  time= 86400.    *(dn-JulianDayOffset)+
         3600.    * it[4] + 
           60.    * it[5] + 
                    it[6] +
             .001 * it[7];
  if(TimeEpoch==J2000){time=time-HalfDaySecs;}
  return(time);
}
void t_con_i(t,it)
double t;
int it[8];
{
  extern int JulianDayOffset;
  extern int TimeEpoch;
  extern float dd;
  static int ss=0;
  static int jt[8]={66,1,1,1,0,0,0,0};
  extern int first ;

  float d;
  int i,s;
  if(JulianDayOffset==0)JulianDayOffset=(int)DN0;
  if(first){ /* initialize */
    jt[0]=(JulianDayOffset==(int)DN0)?66:2000;
    first=0;
  }

  if(TimeEpoch==J2000){t=t+HalfDaySecs;}
  t = floor (t*1000. + .5);  /* round time to nearest millisecond */
  d = (float)floor (t/86400000.);
  if (fabs(d-dd) > .1 ) { /* if day don't differ, 
                              don't cal year,doy,mon*/
    jt[0]=(JulianDayOffset==(int)DN0)?66:2000; /* reset */
    jt[1]=jt[2]=jt[3]=1;
    dd = (float)(d + JulianDayOffset);
    gregorian_date (dd, &jt[3],&jt[2],&jt[0]);
    jt[1] = (int)(gregorian_day(jt[3],jt[2],jt[0]) - 
	    gregorian_day(1,1,jt[0]) + 1.);
    if (1899 < jt[0] && jt[0] < 2000) jt[0] = jt[0] - 1900;
    dd = d;
  } /* end fabs(d-dd) > .1 ) */
  s = (int)(t - 86400000. * d);   /* milliseconds of day */
  if (s != ss) {
    ss = s;
    jt[7] = s % 1000;
    s /= 1000;
    jt[6] = s % 60;
    s /= 60;
    jt[5] = s % 60;
    jt[4] = s / 60;
  }
  for (i = 0; i < 8; i++) it[i] = jt[i];
  return;
}
/*
************************************************************
NAME
  gregorian_day - convert date to number of days since 
                  13th Sept, 1752.
SYNOPSIS
  C
    double gregorian_day(dy,month,year)
    int dy, month, year;

DESCRIPTION

RETURN VALUE

ERRORS

AUTHOR/DATE
  Neal Cline UCLA Inst. of Geophysics   01/24/80
UPDATES
  Converted to C:  Gordon Maclean   02/89
*************************************************************/
double gregorian_day(dy,month,year)
int dy, month, year;
{
  double d;
  int k,m;

  m = month -3;
  if (m < 0) {
    m += 12;
    year--;
  }
  k = year / 100 - 16;
  year %= 100;
  d = 36524.0 * k + 365.0 * year +
       k / 4 + year / 4 + (153 * m + 2) / 5 + dy - 55714.0;
  return d;
}

void gregorian_date (float d, int *dy, int *month, int *year)
/*
void gregorian_date (d,dy,month,year)
float d;
int *dy, *month, *year;
*/
{
  double dd;
  int i,k,m;

  dd = d + 445711.0 / 8. ;
  k  = (int)((4. * dd) / 146097.);
  dd += -36524. * k - k / 4 ;
  i = (int)((4. * dd) / 1461.) ;
  dd += -365. * i - i / 4 ;
  i += 100 * (k + 16);
  k = (int)(5. * dd - 1.875);
  m = (int)(k / 153);
  k = (int)((k - 153 * m + 5) / 5);
  if (m > 9) {
    *month = m - 9;
    i++;
  }
  else *month = m + 3;
  *year = i;
  *dy = k;
  return;
}
double t_now()
{ 
  int it[8];
#ifdef MACOS
#include <time.h>
  struct timeval now;
  struct timezone tzp;
  struct tm *ptr;
  if (gettimeofday(&now,&tzp) < 0) perror ("Gettimeofday error");
  ptr = localtime((const time_t *)&now.tv_sec);
  it[7] = now.tv_usec / 1000; 
  it[0] = ptr->tm_year+(ptr->tm_year>=100?1900:0);
  it[1] = ptr->tm_yday + 1;
  it[2] = ptr->tm_mon+1;
  it[3] = ptr->tm_mday;
  it[4] = ptr->tm_hour;
  it[5] = ptr->tm_min;
  it[6] = ptr->tm_sec;
#endif
#ifdef LINUX
#include <time.h>
#define TNOW
  struct timeval now;
  struct timezone tzp;
  struct tm *localtime(),*ptr;
  if (gettimeofday(&now,&tzp) < 0) perror ("Gettimeofday error");
  ptr = localtime(&now.tv_sec);
  it[7] = now.tv_usec / 1000;
  it[0] = ptr->tm_year+(ptr->tm_year>=100?1900:0);
  it[1] = ptr->tm_yday + 1;
  it[2] = 0;
  it[3] = 0;
  it[4] = ptr->tm_hour;
  it[5] = ptr->tm_min;
  it[6] = ptr->tm_sec;
#endif
#ifdef SUN
/* leel check if tm_mon is correct */
  struct timeval now;
  struct timezone tzp;
  struct tm *localtime(),*ptr;
  if (gettimeofday(&now,&tzp) < 0) perror ("Gettimeofday error");
  ptr = localtime(&now.tv_sec);
  it[7] = now.tv_usec / 1000;
  it[0] = ptr->tm_year+(ptr->tm_year>=100?1900:0);
  it[1] = ptr->tm_yday + 1;
  it[2] = ptr->tm_mon;
  it[3] = ptr->tm_mday;
  it[4] = ptr->tm_hour;
  it[5] = ptr->tm_min;
  it[6] = ptr->tm_sec;
#endif
#ifdef PC
#include <stdio.h>
#include <string.h>
#include <time.h>
  struct tm *newtime;
  time_t long_time;
  time(&long_time);
/* leel check if tm_mon is correct */
  newtime=localtime(&long_time);
  it[0]=newtime->tm_year+(newtime->tm_year>=100?1900:0);
  it[1]=newtime->tm_yday;
  it[2]=newtime->tm_mon;
  it[3]=newtime->tm_mday;
  it[4]=newtime->tm_hour;
  it[5]=newtime->tm_min;
  it[6]=newtime->tm_sec;
  it[7]=0;
#endif
  return i_con_t(it);
}
void i_con_c(it,at)
int it[8];
char *at;
{
 int mon,fdy;
 static int jt[8]={66,1,1,1,0,0,0,0};
 static char a[2][29]={" 66 001 JAN  1  00:00:00.000",
	                     "1966 001 JAN  1 00:00:00.000"};
 static ix1[2][8]={ 1, 4, 8,12,16,19,22,25, 0, 5, 9,13,16,19,22,25};
 static ix2[2][8]={ 2, 6,10,13,17,20,23,27, 3, 7,11,14,17,20,23,27};
 static int lf=0;
 int i,k,k1,k2;
 unsigned int n;
/*
   The following code is an attempt to optimize iconc when it is
   being repeatedly passed similar times.  Rather than call sprintf,
   on the whole time string, it only formats the string
   starting a the first portion which needs changing.
      I tested three codes.  The first simply called sprintf
   to format the entire string for each time.  The next code
   only called sprintf to format the string starting at the
   first time field which was different than the last.  Then 
   this code was tested which uses its own formatting instead
   of sprintf.
      Two tests were run for each code.  Test1 consists of
   processing a series of times, each differing by 333.33 seconds
   spanning 5 years (a total of 475000 calls).  The times in test2
   were 1 second apart for 4 days.
		 
      Full sprintf  Optimized sprintfs    Own formatting
test1    6:03.54       4:55.84               3:50.99
test2    4:19.33       3:04.25               2.26.33

if (fdy)
   sprintf(a,"%4.4ld%4.3ld%4.3s%3.1l d%2.2ld:%2.2ld:%2.2ld.%3.3ld",
   it[0],it[1],months[mon],it[3],it[4],it[5],it[6],it[7]);
else
   sprintf(a,"%3.2ld%4.3ld%4.3s%3.1ld  %2.2ld:%2.2ld:%2.2ld.%2.3ld",
   it[0],it[1],months[mon],it[3],it[4],it[5],it[6],it[7]);
*/

  fdy = (it[0] > 99);	/* four digit year */
  mon = it[2];
  if (mon < 0 || mon > 12 ) mon = 0;

  for (i=0; i < 8; i++) {
    n = it[i];
    if (n != (unsigned int)jt[i] || fdy != lf) {
      jt[i] = n;
      k1 = ix1[fdy][i];
      if (i != 2) {
        k2 = ix2[fdy][i];
	k = k2;
	while (k > k1) {
	  a[fdy][k--] = n % 10 + '0';
	  n /= 10;
	}
	if (n > 9) for (k=k1; k<=k2; k++) a[fdy][k] = '*';
	else {
	  a[fdy][k] = n + '0'; 
	  if (i == 3 && n == 0) a[fdy][k] = ' ';
	}
      }
      else for (k=0; k < 3; k++) a[fdy][k1+k] = months[mon][k];
    }
  }
  lf = fdy;
  strcpy (at,a[fdy]);
  return;
}
/*
SOME CHARACTER TIME STRINGS RETURNED BY OLD IBM TCONA HAVE .*** 
AS THE DECIMAL PART OF SECONDS, CAUSED BY TRYING TO CONVERT THE    
NUMBER 1000 WITH AN I3 FORMAT.  WHEN ACONT IS CALLED THE .***  
IS IGNORED, AND T IS ONE SECOND LESS THAN IT SHOULD BE.       
SO THE FIX HERE IS TO ADD ONE SECOND TO T.                   
*/
double c_fix_t(at)
  char *at;
{
  double t;
  int l;
//  c_con_t(at,&t);
  if ((l=strlen(at)) == 28 && !strncmp(at+24,".***",4)) t += 1.;
  return t;
}

/* these set which epoch to use AT or Cline Time */
int IGPPSetEpoch(int epoch){
  switch(epoch){
    case(Y1966): SetEpoch2CT();break;
    case(Y2000): SetEpoch2AT();break;
    case(J2000): SetEpoch2JT();break;
    case(Y1958): SetEpoch2SC();break;
    default    : return(0); /* not good */
  }
  return(epoch);
}
int IGPPSetEpochf(int *epoch){
   int i;
   i= IGPPSetEpoch(*epoch);
   return(i);
}
void SetEpoch2AT(){
  extern float dd;
  extern int JulianDayOffset;
  extern int TimeEpoch;
  extern int verbose;
  extern int first;
  extern char *IGPPptr;
  first = 1;
  if(verbose)printf("C:EPOCH set to at 2000 Jan 01 00:00:000\n");
  JulianDayOffset = (int)DN2;
  TimeEpoch = Y2000;
  IGPPptr=Y2000Label;
  dd=(float)INITDD;
}
void SetEpoch2JT(){
  extern float dd;
  extern int JulianDayOffset;
  extern int TimeEpoch;
  extern int verbose;
  extern int first;
  extern char *IGPPptr;
  first = 1;
  if(verbose)printf("C:EPOCH set to jt 2000 Jan 01 12:00:000\n");
  JulianDayOffset = (int)DNJ;
  TimeEpoch = J2000;
  IGPPptr=J2000Label;
  dd=(float)INITDD;
}

void SetEpoch2SC(){
  extern float dd;
  extern int JulianDayOffset;
  extern int TimeEpoch;
  extern int verbose;
  extern int first;
  extern char *IGPPptr;
  first = 1;
  if(verbose)printf("C:EPOCH set to sc 1958 Jan 01 00:00:000\n");
  JulianDayOffset = (int)DNS;
  TimeEpoch = Y1958;
  IGPPptr=Y1958Label;
  dd=(float)INITDD;
}

void SetEpoch2CT(){
  extern float dd;
  extern int JulianDayOffset;
  extern int TimeEpoch;
  extern int verbose;
  extern int first;
  extern char *IGPPptr;
  first = 1;
  if(verbose)printf("C:EPOCH set to ct 1966 Jan 01 00:00:000\n");
  JulianDayOffset = (int)DN0;
  TimeEpoch = Y1966;
  IGPPptr=Y1966Label;
  dd=(float)INITDD;
}

int WhichEpoch(){
  extern int TimeEpoch;
  char *CLINE="ct 1966 Jan 01 00:00:000";
  char *MATOM="at 2000 Jan 01 00:00:000";
  char *JATOM="jt 2000 Jan 01 12:00:000";
  char *SATOM="sc 1958 Jan 01 00:00:000";
  char *cptr;
  if(verbose){
     switch(TimeEpoch){
       case(Y1966):cptr=CLINE;break;
       case(Y2000):cptr=MATOM;break;
       case(J2000):cptr=JATOM;break;
       case(Y1958):cptr=SATOM;break;
     }
     printf("Current Epoch :%s.\n",cptr);
  }
  return(TimeEpoch);
}
char *FF_EpochLabel(){
  extern int TimeEpoch;
  extern char *IGPPptr;
  if(IGPPptr==NULL)
     switch(TimeEpoch){
       case(Y1966):IGPPptr=Y1966Label;
       case(Y2000):IGPPptr=Y2000Label;
       case(J2000):IGPPptr=J2000Label;
       case(Y1958):IGPPptr=Y1958Label;
     }
  return(IGPPptr);
}

void setepoch2at(){
  extern float dd;
  extern int JulianDayOffset;
  extern int TimeEpoch;
  extern int verbose;
  extern int first;
  extern char *IGPPptr;
  first = 1;
  if(verbose)printf("c:EPOCH set to at 2000 Jan 01 00:00:000\n");
  JulianDayOffset = (int)DN2;
  TimeEpoch = Y2000;
  IGPPptr=Y2000Label;
  dd=(float)INITDD; /* force reset to recalcuate year,doy,mon*/
}
void setepoch2jt(){
  extern float dd;
  extern int JulianDayOffset;
  extern int TimeEpoch;
  extern int verbose;
  extern int first;
  extern char *IGPPptr;
  first = 1;
  if(verbose)printf("c:EPOCH set to at 2000 Jan 01 12:00:000\n");
  JulianDayOffset = (int)DN2;
  TimeEpoch = J2000;
  IGPPptr=J2000Label;
  dd=(float)INITDD; /* force reset to recalcuate year,doy,mon*/
}

void setepoch2sc(){
  extern float dd;
  extern int JulianDayOffset;
  extern int TimeEpoch;
  extern int verbose;
  extern int first;
  extern char *IGPPptr;
  first = 1;
  if(verbose)printf("c:EPOCH set to at 1958 Jan 01 00:00:000\n");
  JulianDayOffset = (int)DNS;
  TimeEpoch = Y1958;
  IGPPptr=Y1958Label;
  dd=(float)INITDD; /* force reset to recalcuate year,doy,mon*/
}

void setepoch2ct(){
  extern float dd;
  extern int JulianDayOffset;
  extern int TimeEpoch;
  extern int verbose;
  extern int first;
  extern char *IGPPptr;
  first = 1;
  if(verbose)printf("c:EPOCH set to ct 1966 Jan 01 00:00:000\n");
  JulianDayOffset = (int)DN0;
  TimeEpoch = Y1966;
  IGPPptr=Y1966Label;
  dd=(float)INITDD; /* force reset to recalcuate year,doy,mon*/
}

/* Used for debugging only */
void SetIGPPTimeVerbose(){extern int verbose; verbose= !verbose;}

/* BEGIN FORTRAN WRAPPERS */
/* signiture list for FORTRAN wrappers
void acont(int *l,char *at,double *t);
void tcona(double *t,char *at);
void aconi(int *l,char *at,int it[8]);
void icona(int it[8],char at);
void tconi(double *t,int it[8]);
void icont(int it[8],double *t);
void ccont(char *ct,double *t,int len);
void cconi(char *ct,int it[8],int len);
void tconc(double *t,char *ct,int len);
double  tnow();
void set2at();
void set2ct();
void whichepoch();
void FF_VERBOSE()
*/
   

#if FORTRAN | GNUFORTRAN
#define acont acont_
#define tcona tcona_
#define aconi aconi_
#define icona icona_
#define tconi tconi_
#define icont icont_
#define ccont ccont_
#define tconc tconc_
#define cconi cconi_
#define iconc iconc_
#define tnow tnow_
#define set2at set2at_
#define set2ct set2ct_
#define set2jt set2jt_
#define set2sc set2sc_
#define whichepoch  whichepoch_
#define silence  silence_
#define ff_verbose     ffverbose_
#define ff_epochlabel  ffepochlabel_
#define IGPPSetEpochf  IGPPSetEpoch_
#endif
/******************************************************************/
/* leel 08/06/03 Warning! Even though the signiture list expects
                 an integer, the FORTRAN call should omit this
                 This was an error in the original ctime.c code.
                 the parameter len or l is not used.
*/


void acont(int *l,char *at,double *t){
  *t=c_con_t(at);
}
void tcona(double *t,char *at){
  t_con_c(*t,at);
}
void aconi(int *l,char *at,int it[8]){
  c_con_i(at,it);
}

void icona (int it[8], char *at){
//jw void icona(int it[8],char at){
  i_con_c(it,at);
}
void tconi(double *t,int it[8]){
  t_con_i(*t,it);
}
void icont(int it[8],double *t){
  *t=i_con_t(it);
}
void ccont(char *ct,double *t,int len){
  *t=c_con_t(ct);
}
void cconi(char *ct,int it[8],int len){
  c_con_i(ct,it);
}
void tconc(double *t,char *ct,int len){
  t_con_c(*t,ct);
}
void iconc(int it[8],char *ct,int len){
  i_con_c(it,ct);
}
double  tnow(){
  return(t_now());
}
void set2at(){
  SetEpoch2AT();
}
void set2ct(){
  SetEpoch2CT();
}
void set2jt(){
  SetEpoch2JT();
}

void set2sc(){
  SetEpoch2SC();
}

int whichepoch(){
  return(WhichEpoch());
}


void ff_verbose(){
     SetIGPPTimeVerbose();
}
void silence(){
     SetIGPPTimeVerbose();
}

void  ff_epochlabel(char *label){
  extern char *IGPPptr;
  if(IGPPptr==NULL)
    switch(TimeEpoch){
      case(Y1966):IGPPptr=Y1966Label;break;
      case(Y2000):IGPPptr=Y2000Label;break;
      case(J2000):IGPPptr=J2000Label;break;
      case(Y1958):IGPPptr=Y1958Label;break;
    }
  sprintf(label,"%s",IGPPptr);
}
