/* @(#)fitswkw.c	19.2 (ESO-DMD) 03/14/03 14:54:56 */
/*===========================================================================
  Copyright (C) 1998 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 Massachusetts Ave, Cambridge, 
  MA 02139, USA.
 
  Correspondence 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
===========================================================================*/

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.COPYRIGHT  (c)  1998   European Southern Observatory
.IDENT      fitswkw.c
.LAUGUAGE   C
.AUTHOR     P.Grosbol   ESO/IPG
.KEYWORDS   write FITS keyword, FITS header card
.COMMENT    format FITS header card of differebt types
.VERSION    1.0  1988-Nov-18 : Creation,   PJG 
.VERSION    1.1  1990-Feb-02 : Update for hierachical keywords, PJG 
.VERSION    1.2  1990-May-02 : Correct error in string/comment, PJG 
.VERSION    1.3  1991-Jan-25 : Change include file, PJG 
.VERSION    1.4  1991-Mar-03 : Add call for print-option, PJG 
.VERSION    1.5  1991-Mar-17 : Write all hierachical levels, PJG 
.VERSION    1.6  1993-Sep-03 : Use G format for reals, PJG 
.VERSION    1.7  1993-Oct-26 : Update to new SC + prototypes, PJG 
.VERSION    1.8  1994-Jun-29 : Add parm in fitswkd + chage G format, PJG
.VERSION    1.9  1996-Oct-22 : Align '=' for HIERARCH keywords, PJG
.VERSION    1.95 1998-Sep-16 : Correct compiler warnings, PJG

 030311		last modif

---------------------------------------------------------------------*/
#include   <stdlib.h>
#include   <stdio.h>
#include   <string.h>
#include   <fitsfmt.h>
#include   <fitsdef.h>
#include   <midas_def.h>

#define    MXFHC              80   /* characters in FITS header card */

static     char     fhc[MXFHC+1];  /* buffer for a FITS header card  */
static     int                 n;  /* character index in line buffer */
/*

*/

int fitswkl(kw,hkw,hkn,no,val,com)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE       create FITS header card with logical value
.RETURN        status 0: OK, else 1
---------------------------------------------------------------------*/
char          *kw;             /* IN: pointer to first keyword       */
char       *hkw[];             /* IN: array of pointer to kyywords   */
int           hkn;             /* IN: no. of hierachical keywords    */
int            no;             /* IN: sequence of keyword            */
int           val;             /* IN: integer value of keyword       */
char         *com;             /* IN: pointer to keyword comment     */
{
  kwput(kw,hkw,hkn,no);        /* write keyword labels to line       */

  fhc[n++] = '=';

  n = (n<29) ? 29 : n+1;              /* write integer value to line */
  fhc[n++] = (val) ? 'T' : 'F';

  kwcom(com); 

  return 0;
}

int fitswki(kw,hkw,hkn,no,val,com)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE       create FITS header card with integer value
.RETURN        status 0: OK, else 1
---------------------------------------------------------------------*/
char          *kw;             /* IN: pointer to first keyword       */
char       *hkw[];             /* IN: array of pointers to  keyword  */
int           hkn;             /* IN: no. of hierachical keywords    */
int            no;             /* IN: sequence of keyword            */
int           val;             /* IN: integer value of keyword       */
char         *com;             /* IN: pointer to keyword comment     */
{
  kwput(kw,hkw,hkn,no);        /* write keyword labels to line       */

  fhc[n++] = '=';

  n = (n<20) ? 20 : n+1;              /* write integer value to line */
  sprintf(&fhc[n],"%10d",val);
  n += 10; fhc[n] = ' ';

  kwcom(com); 

  return 0;
}
/*

*/

int fitswkd(kw,hkw,hkn,no,val,fmt,com)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE       create FITS header card with double value
.RETURN        status, 0: OK, else 1
---------------------------------------------------------------------*/
char          *kw;             /* IN: pointer to first keyword       */
char       *hkw[];             /* IN: array of pointers to keyword   */
int           hkn;             /* IN: no. of hierachical keywords    */
int            no;             /* IN: sequence no. of keyword        */
double        val;             /* IN: double  value of keyword       */
char         *fmt;             /* IN: pointer to print-format        */
char         *com;             /* IN: pointer to keyword comment     */

{
char   *pfmt, *pc, vbuf[MXFHC+1];

int    i, nc, ndp;



kwput(kw,hkw,hkn,no);			/* write keyword labels to line */

fhc[n++] = '=';
n = (n<10) ? 10 : n+1;			/* write double value to line */

if (*fmt == '%')
   pfmt = fmt;
else
   pfmt = "%20.12G";

/* use that format for conversion */

i = sprintf(vbuf,pfmt,val);

pc = vbuf;
while (*pc == ' ')
   {
   pc ++;
   i --;
   }

nc = (hkn) ? 10 : 20;

ndp = !strchr(pc,'.');             /* no decimal point in number */
if (ndp)
   {
   if (i<nc) n += (nc-i-1);
   if ((n+i) >= MXFHC) return (1);

   while (i--) 
      {					/* copy value over to card    */
      if ((*pc=='E' || *pc=='e')) 
         {
         fhc[n++] = '.';
         ndp = 0;
         }
      fhc[n++] = *pc++;
      }
   
   if (ndp) fhc[n++] = '.';
   }
else
   {
   if (i<nc) n += (nc-i);
   if ((n+i) > MXFHC) return (1);

   while (i--) fhc[n++] = *pc++;
   }

kwcom(com); 				/* append comment */

return 0;
}
/*

*/

int fitswks(kw,hkw,hkn,no,val,com)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE       create FITS header card with string
.RETURN        status, 0:OK, else 1:Error
---------------------------------------------------------------------*/
char          *kw;             /* IN: pointer to first keyword       */
char       *hkw[];             /* IN: array of pointers to keyword   */
int           hkn;             /* IN: no. of hierachical keywords    */
int            no;             /* IN: sequence no. of keyword        */
char         *val;             /* IN: pointer to string of keyword   */
char         *com;             /* IN: pointer to keyword comment     */
{
  int        i,nspc;
  char       *pc;

  kwput(kw,hkw,hkn,no);        /* write keyword labels to line       */

  fhc[n++] = '='; n++;
  fhc[n++] = '\'';

  if (!val) val = "";
  i = 1; nspc = 0; pc = val;
  while (*pc) {
     if (*pc<' ' || *pc>'~') *pc = ' ';
     if (*pc!=' ') nspc = i;
     pc++; i++;
  }

  i = (nspc<8) ? 8 : nspc;
  while (n<MXFHC-1 && (0<i-- || *val))
     fhc[n++] = (*val) ? *val++ : ' ';
  fhc[n++] = '\'';

  kwcom(com); 

  return 0;
}

int fitswkc(kw,com)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE       create FITS header card with comment
.RETURN        status, 0:OK, else 1:Error
---------------------------------------------------------------------*/
char          *kw;             /* IN: pointer to first keyword       */
char         *com;             /* IN: pointer to keyword comment     */
{
  if (!kw) kw = "";
  for (n=0; n<8; n++) fhc[n] = (*kw) ? *kw++ : ' ';

  if (!com) com = "";
  while (n<MXFHC) fhc[n++] = (*com) ? *com++ : ' ';
  fhc[n] = '\0';

  dwrite(fhc,MXFHC);
  return 0;
}

int kwput(kw,hkw,hkn,no)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE       initiate keyword card buffer and put keyword labels
.RETURN        index number in buffer, if error 0
---------------------------------------------------------------------*/
char          *kw;             /* IN: pointer to first keyword       */
char       *hkw[];             /* IN: array of pointers to keywords  */
int           hkn;             /* IN: no. of hierachical keywords    */
int            no;             /* IN: sequence no. of keyword        */
{
  char       *pc, cn[9];
  int        k;

  if (0<no && no<1000000) sprintf(cn,"%d",no);  /* encode seq. no.   */
   else cn[0] = '\0';

  for (n=0; n<MXFHC;) fhc[n++] = ' ';       /* init. line with blank */
  fhc[n] = '\0';

  if (!kw) return 0;

  k = 0;
  for (n=0; n<8; n++)
      if (*kw) fhc[n] = *kw++;
       else fhc[n] = (!cn[k]) ? ' ' : cn[k++];

  if (0<hkn) {                              /* hierachical keywords  */
    for (k=0; k<hkn; k++) {
      n++;
      if (!(pc=hkw[k])) break;
      while (*pc) fhc[n++] = *pc++;
    }
    n += (7 - n%8);                                    /* align '='  */
  }       
  
  return n;
}
/*

*/

int kwcom(com)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE       insert comment in FITS keyword line
.RETURN        status, 0:OK, 1:no space for comment 
---------------------------------------------------------------------*/
char         *com;             /* IN: pointer to keyword comment     */

{

if (*com)
   {
   if (n<30) 
      {
      n = 31;            /* comment in column 32 if possible   */
      fhc[n++] = '/';
      n++;
      while (n<MXFHC && *com) fhc[n++] = *com++;
      }
   else if ((n+3) < MXFHC) 
      {
      n++; 
      fhc[n++] = '/';
      n++;
      while (n<MXFHC && *com) fhc[n++] = *com++;
      }
   }

dwrite(fhc,MXFHC);
return 0;
}

