/*===========================================================================
  Copyright (C) 1986-2009 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

.TYPE		Module
.IDENTIFICATION edtime.c
.AUTHOR    	Francois Ochsenbein [ESO-IPG]
.LANGUAGE  	C
.KEYWORDS	Date & Time edition
.ENVIRONMENT	Any
.COMMENTS	The following conventions in pic:
\begin{TeX}
\begin{itemize}
\item	{\tt YY} or {\tt YYYY}: year
\item	{\tt MM}: month number
\item 	{\tt MMM}\dots: month name (alphabetic)
\item 	{\tt DD}: day of the month (number), edited with leading zeroes
\item 	{\tt dd}: day of the month (number), edited with leading blanks
\item 	{\tt DDD}: day of the year (number), edited with leading zeroes
\item 	{\tt ddd}: day of the year (number), edited with leading blanks
\item	{\tt WW\dots}: weekday name (alphabetic)
\item	{\tt ww\dots}: weekday name followed by a comma
\item	{\tt hh}: hour of the day (00\dots23)
\item 	{\tt mm}: minutes (00\dots59)
\item 	{\tt ss}: seconds (00\dots59)
\end{itemize}
The {\bf tm} structure is defined in {\tt time.h} and has the structure:
	 \begin{itemize} 
	 \item int tm\_year number
	 \item int tm\_mon number [0-11] \item int tm\_mday [1-31]
	 \item int tm\_yday [0-355]      \item int tm\_wday [0-6] (Sunday = 0)
	 \item int tm\_hour [0-23]	\item int tm\_min [0-59]
	 \item int tm\_sec  [0-59] 	\item int tm\_isdst
	 \end{itemize} 
\end{TeX}

.VERSION 1.0	31-Jul-1986: Creation.
.VERSION 1.1	04-Mar-1987: Usage of DCL_T structure; the
		date may be any valid Gregorian date.
.VERSION 1.2	21-Oct-1988: Use new include files

 090831		last modif
----------------------------------------------------------------------------*/

#include <midas_def.h>
#include <macrogen.h>
#include <trtime.h>	


extern int tr_tm(), tr_itm(), ed_pic();





#if SW_LEVEL
MID_RSTATIC char Month_list[] = 
"JanuaryFebruaryMarchAprilMayJuneJulyAugustSeptemberOctoberNovemberDecember\
 MarzM\\\"arzMaiJuniJuliOktoberDezember\
JanvierFevrierF\\\'evrierMarsAvrilJuinJuilletAoutAo\\^utSeptembreOctobre\
NovembreDecembreD\\\'ecembre";

MID_RSTATIC char Day_list[]= 
"SundayMondayTuesdayWednesdayThursdayFridaySaturday\
SonntagMontagDienstagMittwochDonnerstagFreitagSamstag\
DimancheLundiMardiMercrediJeudiVendrediSamedi";

MID_RSTATIC unsigned char Month_name[3][12][2] = {
  /* English */ { {7,0},  {8,7},  {5,15}, {5,20}, {3,25}, {4,28},
		  {4,32}, {6,36}, {9,42}, {7,51}, {8,58}, {8,66}},
  /* German  */ { {6,0},  {7,7},  {4,75}, {5,20}, {3,85}, {4,88},
		  {4,92}, {6,36}, {9,42}, {7,96}, {8,58}, {8,103}},
  /* French  */ { {7,111},{7,118},{4,134},{5,138},{3,85}, {4,143},
		  {7,147},{4,154},{9,164},{7,173},{8,180},{8,188}}
	};
MID_RSTATIC unsigned char Month_TeX[3][12][2] = {
  /* English */ { {7,0},  {8,7},  {5,15}, {5,20}, {3,25}, {4,28},
		  {4,32}, {6,36}, {9,42}, {7,51}, {8,58}, {8,66}},
  /* German  */ { {6,0},  {7,7},  {6,79}, {5,20}, {3,85}, {4,88},
		  {4,92}, {6,36}, {9,42}, {7,96}, {8,58}, {8,103}},
  /* French  */ { {7,111},{9,125},{4,134},{5,138},{3,85}, {4,143},
		  {7,147},{6,158},{9,164},{7,173},{8,180},{10,196}}
	};
MID_RSTATIC unsigned char Day_name[3][7][2] = {
  /* English */ { {6,0},  {6,6},  {7,12}, {9,19}, {8,28}, {6,36}, {8,42}},
  /* German  */ { {7,50}, {6,57}, {8,63}, {8,71}, {10,79},{7,89}, {7,96}},
  /* French  */ { {8,103},{5,111},{5,116},{8,121},{5,129},{8,134},{6,142}}
	};
MID_STATIC unsigned char language = 0;
MID_STATIC unsigned char TeX      = 0;

#else				/* Minimal Implementation */

MID_RSTATIC char Month_list[] = 
"JanuaryFebruaryMarchAprilMayJuneJulyAugustSeptemberOctoberNovemberDecember";
MID_RSTATIC char Day_list[]= "SundayMondayTuesdayWednesdayThursdayFridaySaturday";
MID_RSTATIC unsigned char Month_name[12][2] = {
  /* English */ {7,0},  {8,7},  {5,15}, {5,20}, {3,25}, {4,28},
		{4,32}, {6,36}, {9,42}, {7,51}, {8,58}, {8,66}
	};
MID_RSTATIC unsigned char Day_name[7][2] = {
  /* English */  {6,0},  {6,6},  {7,12}, {9,19}, {8,28}, {6,36}, {8,42}
	};
#endif

MID_STATIC struct tm TM;

/*==========================================================================
 *			ed
 *==========================================================================*/
static int ed(buffer, pic, T)
/*+++
.PURPOSE Edit the structure describing time & date (localtime)
	according to a picture.
.RETURNS Length of edited date / time
---------*/ 
	char *buffer;		/* OUT: Output buffer	*/
	char *pic;		/* IN: Used picture	*/
	struct tm *T;		/* IN: Decomposed time	*/
{
	char *q, *p;
	int i, l;
	unsigned char oc, lc;
	static char ypic[] = "--9999";
#define zpic	(ypic+2)
	static char dpic[] = "0009";

  p = buffer;
  while(*pic)
  {	l = 1;		/* Count identical characters	*/
	while (*(pic+l) == *pic)	l++;

	switch(*pic)	
	{ default: DEFAULT:	/* Simply copy characters to out	*/
		while (--l >= 0)	*(p++) = *(pic++);
		continue;

	  case 'Y': if (l < 2) 	goto DEFAULT;
		i = T->tm_year;
		if (l<=2)	i -= 1900;
		if (l<6)	ypic[l] = EOS;
		p += ed_pic(p, ypic, (long)i);
		if (l<6)	ypic[l] = '9';
		break;

	  case 'M':		/* Month number or name	*/
		i = T->tm_mon;
		if ((i < 0) || (i >= 12)) 
			{ p += oscfill(p, l, '~'); break; }
		if (l == 1) 	goto DEFAULT;
		if (l == 2)	{ p += ed_pic(p, "99", (long)(i+1)); break;}
#	if SW_LEVEL
		if (TeX)  
		{ 	oc = Month_TeX[language][i][1];
		   	lc = Month_TeX[language][i][0];
		} else	   
		{ 	oc = Month_name[language][i][1];
			lc = Month_name[language][i][0];
		}
#	else
		{ 	oc = Month_name[i][1];
			lc = Month_name[i][0];
		}
#	endif
		i = MIN(l,(int)lc);
		pic += i;
		l -= i;
		for (q = &Month_list[oc]; --i >= 0; )	*(p++) = *(q++);
		pic += l;
		while (--l >= 0) 			*(p++) = ' ';
		continue;

	  case 'D': case 'd':		/* Day number 	*/
		if (l == 1) 	goto DEFAULT;
		q = (*pic == 'D' ? zpic : dpic);
		if (l == 2)	{ p += ed_pic(p, q+2, (long)(T->tm_mday)); break;}
		l = 3;
		p += ed_pic(p, q+1, (long)((T->tm_yday%366) + 1));
		break;

	  case 'W': case 'w':		/* Weekday name		*/
		i = T->tm_wday;
		if ((i < 0) || (i >= 7)) 
			{ p += oscfill(p, l, '~'); break; }
		if (l == 1) 	goto DEFAULT;
#	if SW_LEVEL
		oc = Day_name[language][i][1];
		lc = Day_name[language][i][0];
#	else
		oc = Day_name[i][1];
		lc = Day_name[i][0];
#	endif
		i = MIN(l,(int)lc);
		l -= i;
		lc = (*pic == 'w');
		pic += i;
		for (q = &Day_list[oc]; --i >= 0; )	*(p++) = *(q++);
		pic += l;
		if ((lc) && (l > 0))	{ *(p++) = ',', l--;}
		while (--l >= 0) 			*(p++) = ' ';
		continue;

	  case 'h':		/* Hour, 00...23	*/
		i = T->tm_hour % 24;
	  ED2:
		if (l == 1) 	goto DEFAULT;
		p += ed_pic(p, zpic+2, (long)i);
		break;

	  case 'm':		/* Minutes, 00..59	*/
		i = T->tm_min % 60;
		goto ED2;

	  case 's':		/* Seconds, 00..59	*/
		i = T->tm_sec % 60;
		goto ED2;
	}
	pic += l;
  }

  *p = EOS;
  return(p-buffer);
}
	
/*==========================================================================
 *			Callable Routines
 *==========================================================================*/
int ed_tm(buffer, pic, T)
/*+++
.PURPOSE Edit the structure describing time & date (tm structure, see time1.h)
	according to a picture.
.RETURNS Length of characters edited in buffer
.REMARKS buffer is terminated with EOS.
---------*/ 
	char *buffer;		/* OUT: Output buffer	*/
	char *pic;		/* IN: Used picture	*/
	struct tm *T;		/* IN: Decomposed time	*/
{
#if SW_LEVEL
  TeX = 0;		/* No TeX option	*/
  language = 0;		/* Default is English	*/
#endif
  
  return(ed(buffer, pic, T));
}

/*==========================================================================*/
int ed_t(buffer, pic, t)
/*+++
.PURPOSE Edit the time (is in since Jan. 1, 1970)
	according to a picture.
.RETURNS Length of characters edited in buffer / -1 if error
.REMARKS buffer is terminated with EOS.
---------*/ 
	char *buffer;		/* OUT: Output buffer	*/
	char *pic;		/* IN: Used picture	*/
	long int t;		/* IN: Time (s)	*/
{
  	register int ret;
  
#if SW_LEVEL
  TeX = 0;		/* No TeX option	*/
  language = 0;		/* French		*/
#endif
  
  if ((ret = tr_itm(t,&TM)) < 0)	goto FIN;
  if ((ret = tr_tm(&TM)) < 0)		goto FIN;
  ret = ed(buffer, pic, &TM);
  FIN:
  return(ret);
}

	/* Other Functions Only Defined for Large SW_LEVEL	*/
#if SW_LEVEL
/*==========================================================================*/
int ed_tm_F(buffer, pic, T)
/*+++
.PURPOSE Edit the structure describing time & date (tm structure, see time1.h)
	according to a picture, in French
.RETURNS Length of characters edited in buffer
.REMARKS buffer is terminated with EOS.
---------*/ 
	char *buffer;		/* OUT: Output buffer	*/
	char *pic;		/* IN: Used picture	*/
	struct tm *T;		/* IN: Decomposed time	*/
{
  TeX = 0;		/* No TeX option	*/
  language = 2;		/* French		*/
  
  return(ed(buffer, pic, T));
}

/*==========================================================================*/
int ed_tm_G(buffer, pic, T)
/*+++
.PURPOSE Edit the structure describing time & date (tm structure, see time1.h)
	according to a picture, in German.
.RETURNS Length of characters edited in buffer
.REMARKS buffer is terminated with EOS.
---------*/ 
	char *buffer;		/* OUT: Output buffer	*/
	char *pic;		/* IN: Used picture	*/
	struct tm *T;		/* IN: Decomposed time	*/
{
  TeX = 0;		/* No TeX option	*/
  language = 1;		/* German		*/
  
  return(ed(buffer, pic, T));
}

/*==========================================================================*/
int ed_t_F(buffer, pic, t)
/*+++
.PURPOSE Edit the time (is in since Jan. 1, 1970)
	according to a picture, in French
.RETURNS Length of characters edited in buffer / -1 if error
.REMARKS buffer is terminated with EOS.
---------*/ 
	char *buffer;		/* OUT: Output buffer	*/
	char *pic;		/* IN: Used picture	*/
	long int t;		/* IN: Time (s)	*/
{
  	register int ret;
  
  TeX = 0;		/* No TeX option	*/
  language = 2;		/* French		*/
  
  if ((ret = tr_itm(t,&TM)) < 0)	goto FIN;
  if ((ret = tr_tm(&TM)) < 0)		goto FIN;
  ret = ed(buffer, pic, &TM);
  FIN:
  return(ret);
}

/*==========================================================================*/
int ed_t_G(buffer, pic, t)
/*+++
.PURPOSE Edit the time (is in since Jan. 1, 1970)
	according to a picture, in German
.RETURNS Length of characters edited in buffer / -1 if error
.REMARKS buffer is terminated with EOS.
---------*/ 
	char *buffer;		/* OUT: Output buffer	*/
	char *pic;		/* IN: Used picture	*/
	long int t;		/* IN: Time (s)	*/
{
  	register int ret;
  
  TeX = 0;		/* No TeX option	*/
  language = 1;		/* German		*/
  
  if ((ret = tr_itm(t,&TM)) < 0)	goto FIN;
  if ((ret = tr_tm(&TM)) < 0)		goto FIN;
  ret = ed(buffer, pic, &TM);
  FIN:
  return(ret);
}

/*==========================================================================*/
int TeX_tm_F(buffer, pic, T)
/*+++
.PURPOSE Edit the structure describing time & date (tm structure, see time1.h)
	according to a picture, in French and for TeX
.RETURNS Length of characters edited in buffer
.REMARKS buffer is terminated with EOS.
---------*/ 
	char *buffer;		/* OUT: Output buffer	*/
	char *pic;		/* IN: Used picture	*/
	struct tm *T;		/* IN: Decomposed time	*/
{
  TeX = 1;		/* No TeX option	*/
  language = 2;		/* French		*/
  
  return(ed(buffer, pic, T));
}

/*==========================================================================*/
int TeX_tm_G(buffer, pic, T)
/*+++
.PURPOSE Edit the structure describing time & date (tm structure, see time1.h)
	according to a picture, in German.
.RETURNS Length of characters edited in buffer
.REMARKS buffer is terminated with EOS.
---------*/ 
	char *buffer;		/* OUT: Output buffer	*/
	char *pic;		/* IN: Used picture	*/
	struct tm *T;		/* IN: Decomposed time	*/
{
  TeX = 1;		/* No TeX option	*/
  language = 1;		/* German		*/
  
  return(ed(buffer, pic, T));
}

#endif
