/*===========================================================================
  Copyright (C) 1995-2010 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        infile.c
.LANGUAGE     C
.AUTHOR       K. Banse   ESO/IPG
.KEYWORDS     Data conversion, FITS
.PURPOSE      convert FITS data files to the internal MIDAS format.
.COMMENT      Formats supported are : FITS 8,16,32,-32,-64, tables
	      groups, etc. 
.VERSION      040108	creation

 100617		last modif
---------------------------------------------------------------------*/

#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 1
#endif

#include   <stdio.h>
#include   <stdlib.h>
#include   <string.h>
#include   <osfile.h>
#include   <osparms.h>
#include   <fitsfmt.h>
#include   <fitsdef.h>
#include   <midas_def.h>
#include   <fsydef.h>

#define RECMAX 256

int get_inname(), get_outname(), xoutname();


int main()
{
char  nameFITS[RECMAX+4];
char  root[24], tbuff[RECMAX+4];
char  hist, ffmt, resname[RECMAX+4];
char  suffix[12], opt[4];
char  *nampntr, datpath[192];
extern char DATA_PATH[328];		/* that's inside scs.c (SCSPRO) */

int   fmt, n, dsize, type, incount, ocount, nval;
int   mfd, mfdt, popt;
int   fid, fidcount, fout;		/* needed for data path business */
int   retstat, drop_empty, empty_header;
int   extcount, file_type, kinfo[4];
int   create_format, Midas_flag;

BFDEF   *bfdef;


void fillHISTORY(), resultname();



(void) SCSPRO("INFILE");                     /* get into MIDAS env. */
Midas_flag = 200;
extcount = file_type = 0;


/* get flag for dropping empty 1st header for following table extension */

(void) SCKGETC("DROP_EMPTY",1,2,&nval,tbuff);
if ((tbuff[0] == 'N') || (tbuff[0] == 'n'))
   drop_empty = 0;
else
   drop_empty = 1;

/* keyword ROOT holds 
  a) name of catalog with result names
  b) "*abcd" for result name creation via abcd0001, abcd0002, ...
  c) "$$" to use input names with relevant Midas file type        */
(void) SCKGETC("ROOT",1,20,&nval,root);

(void) SCKGETC("INTAPE_OPTIONS",1,3,&nval,opt);		/* read options */
switch (opt[0]) 
   {                          /* check print option    */
   case 'F' : 
   case 'f' : popt = 2; break;		/* Full print            */
   case 'N' : 
   case 'n' : popt = 0; break;		/* No print              */
   default  : popt = 1;			/* Short print - default */
   }
switch (opt[1]) 
   {                          /* check format option   */
   case 'F' :
   case 'f' : ffmt = 'F'; break;	/* FP format             */
   default  : ffmt = 'O';		/* Original - default    */
   }
switch (opt[2])
   {                     /* check keyword option       */
   case 'N' : 
   case 'n' : hist = 'N'; break;      /* No history                 */
   case 'C' : 
   case 'c' : hist = 'C'; break;      /* Code hierarch keyword      */
   case 'A' : 
   case 'a' : hist = 'A'; break;      /* Include hist in empty file */
   default  : hist = 'Y';             /* Yes-history - default      */
   }


/* open ASCII catalog with input FITS files */

incount = ocount = 0;
(void) get_inname("i__i.cat",0,nameFITS);

/* get output name specs and also 
   get type of new files (0/1 = Midas/FITS) */

create_format = get_outname(root,0,tbuff);
if (create_format == 1)		/* new files are FITS files - just copy */
   (void) SCKGETC("MID$TYPES",1,8,&nval,suffix);


/* create ASCII file for output names */

fout = osaopen("outnames.cat",WRITE);
if (fout < 0)
   SCETER(11,"Problems creating file with output names ...");



/* here we get each input FITS file from list */

read_loop:
/* ------ */

n = get_inname("i__i.cat",1,nameFITS);
if (n < 0) goto end_of_it;		/* we're done */
incount ++;

if (create_format == 1)
   {
   (void) get_outname(tbuff,1,resname);        /* get desired result name */
   n = (int) strlen(resname) - 3;
   if (strcmp(resname+n,"bdf") == 0)
      (void) strcpy(resname+n,suffix);
   if (strcmp(resname,nameFITS) != 0)
      {
      (void) sprintf(tbuff,"cp %s %s",nameFITS,resname);
      if (system(tbuff))
         (void) sprintf(tbuff,"copying fits file: %s to %s - failed...",
                        nameFITS,resname);
      else
         (void) sprintf(tbuff,"fits file: %s copied to %s",
                        nameFITS,resname);
      }
   else
      (void) sprintf(tbuff,"no action for fits file: %s",nameFITS);

   SCTPUT(tbuff);
   goto read_loop;
   }


(void) xoutname("x__x");		/* init root name for Midas files */
fidcount = 0;
extcount = 0;
nampntr = nameFITS;

open_file:
fid = dopen(nampntr,READ,'S',0);
if (fid < 0)
   {					/* open FITS file  */
   if (fidcount < 4)
      {
      n = fidcount*80;
      (void) strncpy(datpath,&DATA_PATH[n],80);
      if (datpath[0] != '^')
         {
         datpath[80] = ' ';
         n = CGN_INDEXC(datpath,' ');
         (void) strcpy(&datpath[n],nameFITS);          /* use new path */
         nampntr = datpath;
         fidcount ++;
         goto open_file;
         }
      }

   (void) sprintf(tbuff,"Warning: Cannot open file: %s",nameFITS);
   SCTPUT(tbuff);
   goto read_loop;		/* look for next FITS file */
   }
      

mfd = -1; mfdt = -1;

if ((fmt=drinit()) < 0) 
   {
   SCTPUT("Error: Unknown data format");
   goto read_loop;
   }


bfdef = hdr_init();                   /* decode primary header */
type = fitsrhd(&mfd,bfdef,&dsize,&mfdt,ffmt,hist,popt,Midas_flag);
if (type < BFITS)
   {
   SCTPUT("Warning: NOT supported FITS format!");
   dclose(fid); 
   goto read_loop;
   }
 
if (mfd > -1) fillHISTORY(mfd,nampntr,0); 	/* update HISTORY */

if ((bfdef->bitpix == -16) || (bfdef->bitpix == 16))
   retstat = fitsrdmUI2(mfd,bfdef,dsize,mfdt,ffmt,0);
else
   retstat = fitsrdm(mfd,bfdef,dsize,mfdt,ffmt,0);

if (retstat == NOFITS)
   {
   SCTPUT("Warning: Bad FITS image data - file skipped!");
   SCTPUT("corrupted Midas data file maybe there as: x__x0*.bdf");
   goto close_FITSfile;
   }

(void) SCKGETC("F$OUTNAM",1,40,&nval,resname);	/* get temp. name */

if (dsize > 0)
   {					/* real image is primary FITS header */
   empty_header = 0;
   resultname(nameFITS,resname,1,fout);	/* rename to final name */
   ocount ++;
   }
else					/* empty primary FITS header */
   empty_header = 1;

/* here we loop through any extensions of FITS file */

extcount = 0;
do 
   {
   mfd = -1; mfdt = -1;
   bfdef = hdr_init();			/* read extension header */
   type = fitsrhd(&mfd,bfdef,&dsize,&mfdt,ffmt,hist,popt,Midas_flag);
   extcount ++;

   switch (type)
      {
     case ATABLE :               /* ASCII tables         */
     case BTABLE :               /* BINARY tables        */
      if (empty_header == 1)
         {				/* check for drop_empty_header flag */
         if (drop_empty == 0)
            {				/* rename primary header file now */
            resultname(nameFITS,resname,1,fout);
            ocount ++;
            }
         empty_header = 0;
         }

      file_type = 3;
      fillHISTORY(mfd,nampntr,0); 		/* update HISTORY */;

      if (type == ATABLE)
         retstat = fitsrat(mfd,bfdef,dsize,0);
      else
         retstat = fitsrbt(mfd,bfdef,dsize,0);

      if (retstat == NOFITS)
         {
         SCTPUT("Warning: Bad FITS table data - file skipped!");
         SCTPUT("corrupted Midas data file maybe there as: x__x0*.bdf");
         goto close_FITSfile;
         }
      break;

     case IMAGE  :               /* IMAGE                */
      if (empty_header == 1)
         {				/* check for drop_empty_header flag */
         if (drop_empty == 0)
            {                           /* rename primary header file now */
            resultname(nameFITS,resname,1,fout);
            ocount ++;
            }
         empty_header = 0;
         }

      if (bfdef->cflag == 0) /* we didn't create the file before */
         {
         bfdef->cflag = 1;
         type = fitsrhd(&mfd,bfdef,&dsize,&mfdt,ffmt,hist,popt,Midas_flag);
         if (bfdef->cflag != -9)
            {
            (void) sprintf(tbuff,
                           "could not create Midas frame for extension [%d]",
                           extcount);
            SCTPUT(tbuff);
            break;
            }
         }
      file_type = 1;
      fillHISTORY(mfd,nampntr,0); 		/* update HISTORY */;
      if ((bfdef->bitpix == -16) || (bfdef->bitpix == 16))
         retstat = fitsrdmUI2(mfd,bfdef,dsize,mfdt,ffmt,0); 
      else
         retstat = fitsrdm(mfd,bfdef,dsize,mfdt,ffmt,0); 
      if (retstat == NOFITS)
         {
         SCTPUT("Warning: Bad FITS image data - file skipped!");
         SCTPUT("corrupted Midas data file maybe there as: x__x0*.bdf");
         goto close_FITSfile;
         }
      break;

     case UKNOWN :               /* skip unknown ext.    */
      SCTPUT("Warning: Unknown FITS extension skipped!");
      fitssxd(dsize,0); goto last_call;

     default :               /* finished with this FITS file */
      if (empty_header == 0) 
         goto close_FITSfile;
      else
         file_type = 4;		/* should be a fit file (just empty header) */
      }

   (void) SCKGETC("F$OUTNAM",1,40,&nval,resname);	/* get temp. name */
   resultname(nameFITS,resname,file_type,fout);
   ocount ++;

   last_call:
   ;
   } while (RGROUP<type);


close_FITSfile:
dclose(fid); 
goto read_loop;			/* look for next FITS file */


/* we're done with input list */

end_of_it:
(void) osaclose(fout);		/* close file with output names */

kinfo[0] = extcount;
kinfo[1] = file_type;
kinfo[2] = incount;
kinfo[3] = ocount;
(void) SCKWRI("MID$INFO",kinfo,4,4,&nval);	/* no. of valid exts */

if (ocount > 1)
   {
   (void) sprintf(tbuff,
          "%d FITS files converted to %d Midas files",incount,ocount);
   SCTPUT(tbuff);
   }

return SCSEPI();
}
/*

*/

void resultname(inname,resname,ftype,fid)
char  *inname, *resname;
int   ftype, fid;

{
char  dummy[4], outname[RECMAX+4], txt[RECMAX+4];

int  unit = 0;


(void) get_outname(dummy,ftype,outname);        /* get desired result name */

(void) osawrite(fid,outname,(int)strlen(outname));
if (osfrename(resname,outname) != 0) SCETER(7,"osfrename failed...");

(void) sprintf(txt,"FITS file: %s converted to: %s",inname,outname);
(void) SCKWRC("OUT_A",1,outname,1,116,&unit);
SCTPUT(txt);
}
/*

*/

int get_inname(infile,flag,name)
char *infile;	/* IN: name of ASCII catalog */
int  flag;	/* IN: 0 = startup, 1 = read next record */
char *name;	/* OUT: next name in ASCII file i__i.cat */

/* return -1 for end-of-file; 0 for o.k. */


{
int reclen;
static int fid;

char  tmpname[RECMAX];




if (flag == 0)
   {
   fid = osaopen(infile,READ);
   if (fid < 0)
      {
      char  errmess[80];
   
      (void) sprintf(errmess,"Problems opening data file %s",infile);
      SCETER(1,errmess);
      }
   return 0;
   }

/* here we read line by line of `infile' */

read_rec:
reclen = osaread(fid,tmpname,RECMAX);
if (reclen > 0) 
   {
   CGN_LOGNAM(tmpname,name,RECMAX);
   return 0;		/* success, we have a file name */
   }

if (reclen < 0) 
   {
   osaclose(fid);
   return (-1);				/* EOF encountered */
   }

if (reclen == 0) goto read_rec;		/* skip empty records */

return 0;
}
/*

*/

int get_outname(root,flag,name)
char *root;	/* IN: root, name of ASCII catalog, or "$$" */
int  flag;	/* IN: 0 = startup, 
		       > 0 = read next record and flag also serves as type
			     1 = image, 2 = fit file, 3 = table           */
char *name;	/* OUT: next name in ASCII file i__i.cat */

/* for flag = 0, return 0 or 1, if we create Midas or FITS files 
            > 0, always return 0                                 */


{
int reclen, n1, n2, ival, nval;
static int fid, mycount=0;

static char  myroot[32];
static char  bad_guys[16] = " @+-,^!#$%()| ?";
register char cc;



if (flag == 0)
   {
   int  baddy;
   register int  nr, mr;
   register char cc;

   if (*root == '*')
      {				/* we have a root string */
      bad_guys[0] = '\\';	/* put backslash char. into first element */
      fid = -99;
      baddy = mr = 0;

      /* copy + check root string for bad chars (for a file name) */
      for (nr=1; nr<=30; nr++)
         {					/* bad chars => '_' */
         cc = root[nr];
         if (CGN_INDEXC(bad_guys,cc) > 0) 
            {
            baddy ++;
            myroot[mr++] = '_';
            }
         else if (cc == '\0')
            break;
         else
            myroot[mr++] = cc;
         }
      myroot[mr] = '\0';
      if (baddy > 0) SCTPUT("bad chars. in root_name replaced by `_'");
      }
   else
      {
      if ((*root == '$') && (*(root+1) == '$'))
         {
         myroot[0] = '$';	/* so we'll remember to use input names */
         myroot[1] = '\0';
         fid = osaopen("i__i.cat",READ);	 /* use input catalog */
         }
      else
         fid = osaopen(root,READ);
      if (fid < 0)
         {
         char  errmess[80];
   
         (void) sprintf(errmess,"Problems opening data file %s",root);
         SCETER(1,errmess);
         }
      }

   n2 = -1;				/* no check for NULL */
   (void) SCKRDI("AUX_MODE",13,1,&nval,&ival,&n1,&n2);

   return ival;
   }

norm_mode:
if (fid < 0) 				/* root business */
   {
   if (flag == 1)
      (void) sprintf(name,"%s%4.4d.bdf",myroot,++mycount);
   else
      (void) sprintf(name,"%s%4.4d.tbl",myroot,++mycount);
   }
else
   {
   /* here we read line by line of output names file */
  read_rec:
   reclen = osaread(fid,name,RECMAX);
   if (reclen < 0) 
      {
      osaclose(fid);
      (void) strcpy(myroot,"toto");	/* switch to root business */
      fid = -99;
      goto norm_mode;
      }
   else if (reclen == 0) 
      goto read_rec;				/* skip empty records */

   cc = name[0];
   if ((cc == '&') || (cc == '#'))
      {					/* check + complete explicit name */
      char  clean_name[RECMAX+4];

      n1 = CGN_singleframe(name,flag,clean_name);
      if (n1 != 0) (void) strcpy(name,clean_name);
      }
   else
      {				/* check, if we have to add type to name */
      n1 = CGN_JNDEXC(name,FSY_TYPMARK);	/* look for '.' */
      if (n1 > 1)
         {
         if (myroot[0] == '$') 
            name[n1] = '\0';		/* cut off file type */
         else
            {
            n2 = CGN_JNDEXC(name,FSY_DIREND);	/* look for '/' or ']' */
            if (n2 < n1)		/* so `.' comes after a directory */
               return 0;		/* and we already have a type */
            }
         }
      if (flag == 1)
         (void) strcat(name,".bdf");
      else if (flag == 3)
         (void) strcat(name,".tbl");
      else
         (void) strcat(name,".fit");
      }
   }

return 0;
}




