/*===========================================================================
  Copyright (C) 1995-2006 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
===========================================================================*/

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.IDENT      fitsrmd.c
.LAUGUAGE   C
.AUTHOR     P.Grosbol   ESO/IPG
.KEYWORDS   FITS, decode MIDAS descriptor cards
.COMMENT    decodes a FITS HISTORY card in MIDAS format
.VERSION    1.0  1990-Feb-26 : Creation,   PJG 
.VERSION    2.0  1991-Feb-15 : Change structures,   PJG 
.VERSION    2.1  1993-Nov-25 : Update to new SC + prototypes,   PJG 
.VERSION    2.2  1996-Oct-22 : Update to length of descriptor name, PJG 
.VERSION    2.3  2002-Jan-11 : Add logical format, PJG 
 
 060111		last modif
---------------------------------------------------------------------*/

#include   <fitsfmt.h>
#include   <fitsdef.h>
#include   <midas_def.h>

#include   <stdio.h>
#include   <stdlib.h>
#include   <string.h>


static     int          mdcc;    /* MIDAS descriptor char. count     */
static     int          mdsc;    /* MIDAS descriptor special char.   */
static     int          mdfe;    /* MIDAS descriptor first element   */
static     int          mdle;    /* MIDAS descriptor last element    */
static     int          mdfw;    /* MIDAS descriptor field width     */
static     int          mdcw;    /* MIDAS descriptor character width */
static     int         mdvpl;    /* MIDAS descriptor values per line */
static     int     mdunit[4];    /* MIDAS descriptor unit            */
static     char          mdt;    /* MIDAS descriptor type            */
static     char   mdn[MXMDN];    /* MIDAS descriptor name            */
static     char      buf[81];    /* buffer for MIDAS C*n descriptor  */

static int selidx_flag = 0;
/*

*/

#ifdef __STDC__
void fitsrmdbad(char *name)
#else
void fitsrmdbad(name)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE       return descr. name after an error
---------------------------------------------------------------------*/
char    *name;
#endif

{
(void) strcpy(name,mdn);
}
/*

*/

#ifdef __STDC__
int fitsrmd(int mfd, KWORD *kw,int *pmdc)
#else
int fitsrmd(mfd,kw,pmdc)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE       decode FITS HISTORY card in MIDAS format
.RETURN        status - 0:OK, -1:error
---------------------------------------------------------------------*/
int          mfd;                 /* IN:     MIDAS file descriptor   */
KWORD        *kw;                 /* IN:     keyword structure       */
int          *pmdc;               /* IN/OUT: MIDAS desc. count       */
#endif

{
char       c, *ps, *pc;

int        i, k, status;
int        ista, icou, iarr[36];	/* max. ints' on card */
int   SCDWRL();

float      farr[36];

double     darr[36];





status = ERR_NORMAL;

if (*pmdc) 
   {
   pc = kw->buf + 1;		/* skip leading "'" */

   ista = mdfe;			/* used always except in case 'S' */
   icou = 0;

   switch (mdt) 
      {
     case 'S' :
      i = mdvpl * mdfw;
      while (i--) 
         {
         c = *pc++;
         if (mdsc) 
            {
            if (c=='n') 
               buf[mdcc++] = '\n';
            else if (c=='\\') 
               buf[mdcc++] = '\\';
            else 
               buf[mdcc++] = ' ';
            mdsc = 0;
	    }
         else if (c=='\\') 
            {
            mdsc = 1; continue;
            }
         else
            buf[mdcc++] = c;

         if (1<mdcw && mdcw<=mdcc) 
            {
            buf[mdcc] = '\0';
            status = SCDWRC(mfd,mdn,mdcw,buf,mdfe,1,mdunit);
            mdcc = 0; mdfe++;
            if (mdle<mdfe) break;
	    }
	 }

      if (mdcw==1)
         {
         i = (mdle-mdfe+1<mdcc) ? mdle-mdfe+1 : mdcc;
         buf[mdcc] = '\0';
	 status = SCDWRC(mfd,mdn,mdcw,buf,mdfe,i,mdunit);
         mdcc = 0; mdfe += i;
	 }
      *pmdc = (mdle<mdfe) ? 0 : 1;
      break;

     case 'L' :
      for (i=0; i<mdvpl && mdfe<=mdle; i++, mdfe++) 
         {
         getint(pc,mdfw,&k,iarr+icou);
         pc += mdfw;
         icou++;
         }
      status = SCDWRL(mfd,mdn,iarr,ista,icou,mdunit);
      (*pmdc)--; break;

     case 'I' :
      if (selidx_flag != 99)
         {
         for (i=0; i<mdvpl && mdfe<=mdle; i++, mdfe++) 
            {
	    getint(pc,mdfw,&k,iarr+icou);
            pc += mdfw;
            icou++;
            }

         if ((selidx_flag == 1) && (ista == 1))
            {				/* check 1st elem of SELIDX */
            if (iarr[0] < 1)
               {
               selidx_flag = 99;
               goto end_I;
               }
            else
               {			/* valid SELIDX => Midas descr */
               selidx_flag = 0;
               i = 0;			/* initial SCDWRI not done before */
               status = SCDWRI(mfd,mdn,&i,mdle,1,mdunit);
               if (status != ERR_NORMAL) goto end_I;
               }
            }

         status = SCDWRI(mfd,mdn,iarr,ista,icou,mdunit);
         }

      end_I:
      (*pmdc)--; break;

     case 'R' :
      for (i=0; i<mdvpl && mdfe<=mdle; i++, mdfe++) 
         {
	 getval(pc,mdfw,&k,darr+icou); 
         pc += mdfw; 
         icou++;
         }
      for (i=0; i<icou; i++) farr[i] = (float) darr[i];
      status = SCDWRR(mfd,mdn,farr,ista,icou,mdunit);
      (*pmdc)--; break;

     case 'D' :
      for (i=0; i<mdvpl && mdfe<=mdle; i++, mdfe++)
         {
	 getval(pc,mdfw,&k,darr+icou); 
         pc += mdfw; 
         icou++;
         }
      status = SCDWRD(mfd,mdn,darr,ista,icou,mdunit);
      (*pmdc)--; break;
      }
   }


else 		/* first time here */
   {
   float f;
   double d;

   pc = kw->val.pc;
   i = 0;
   if (!fldis(&pc,&ps))
      while (*ps && i<MXMDN-1) mdn[i++] = *ps++;
   mdn[i] = '\0';
   fldis(&pc,&ps);
   c = *ps; ps += 2; mdt = '\0';
   getint(ps,72,&i,&mdcw);
   mdfe = (fldiv(&pc,&d)) ? 0 : d;
   mdle = (fldiv(&pc,&d)) ? 0 : d;
   for (i=0; i<4; i++) mdunit[i] = 0;


   switch (c) 			/* write last elem. to reserve full space */
      {
     case 'C' : mdt = 'S'; mdcc = 0; mdsc = 0;
	     status =  SCDWRC(mfd,mdn,mdcw,"",mdle,1,mdunit);
             break;
     case 'L' : mdt = 'L'; i = 0;
             status = SCDWRL(mfd,mdn,&i,mdle,1,mdunit);
             break;
     case 'I' :
             mdt = 'I'; 
             if (strcmp(mdn,"SELIDX") == 0) 	/* for selection table we'll */
                selidx_flag = 1;		/* check 1st elem later */
             else
                {
                i = 0;
                selidx_flag = 0;
                status = SCDWRI(mfd,mdn,&i,mdle,1,mdunit);
                }
             break;
     case 'R' :
             if (mdcw==4) 
                {
	        mdt = 'R'; f = 0.0;
	        status = SCDWRR(mfd,mdn,&f,mdle,1,mdunit);
                }
             else if (mdcw==8) 
                {
	        mdt = 'D'; d = 0.0;
	        status = SCDWRD(mfd,mdn,&d,mdle,1,mdunit);
                }
             break;
     default  : mdt = '\0'; break;
      }
   
   i = fldis(&pc,&ps);
   if (dcffmt(ps,&mdvpl,&c,&mdfw,&i))
      SCTMES(M_BLUE_COLOR,"Error: invalid FORTRAN format");
   *pmdc = (c!='A') ? (mdle-mdfe)/mdvpl + 1 : 1;
   }

if (status != ERR_NORMAL) 
   return 888;
else
   return status;
}

