/*===========================================================================
  Copyright (C) 2000-2011 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        indisk.c
.LANGUAGE     C
.AUTHOR       K. Banse		ESO - Garching
.KEYWORDS     Data conversion, FITS, IHAP
.PURPOSE      Read data file from disk and
              convert it to the internal MIDAS format.
.COMMENT      Formats supported are : FITS 8,16,32,-32,-64, tables
	      groups, etc. 
.VERSION      1.0  000728	KB

 111012		last modification
---------------------------------------------------------------------*/

#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 1
#endif

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

/*

*/

int main()
{
char  extensio[60], *extlabel[10], pfix[100], name[132], text[164];
char  hist, ffmt, *pc, *nfn, catfile[88], resname[48];
char  opt[4], backwflag[2], typbuf[80], styp;
char  *nampntr, datpath[192];
char  exxtc[80], labels[160];
extern char DATA_PATH[328];		/* that's inside scs.c (SCSPRO) */

int   fmt, n, dsize, type, nval, istat;
int   mfd, mfdt, popt, fcopt;
int   fid, fidcount, retstat;
int   extcount, Midas_flag, extno, catopt, totext;
int   mark, scount, firstext, lastext, mm, single, mshift, labelcount;
int   xoutname();

BFDEF        *bfdef;

void fillHISTORY();




nfn = (char *) 0;
mark = lastext = extno = retstat = 0;
extcount = 0;			/* counts the extensions visited */
totext = 0;			/* no. of extens wanted: 0, 1, 2 (= many) */ 
scount = labelcount = 0;
Midas_flag = 200;		/* to write stuff independent of `popt' */
memset((void *)typbuf,32,(size_t)80);
mshift = 0;
memset((void *)exxtc,0,(size_t)80); 	/* non-selected extensions */
firstext = -1;
extlabel[0] = &labels[0];	/* labels = space for max. 10 labels */

(void) SCSPRO("INDISK");			/* get into MIDAS env. */
(void) SCKGETC("P1",1,100,&nval,name);		/* read FITS file name */


/* check, if specific extensions should be extracted */

single = 0;					/* means full FITS file */
if (name[nval-1] == ']')			/* looks like extension */
   {
   n = CGN_JNDEXC(name,'[');
   if (n > 0)				/* Yes - we have extensions */
      {
      int    ia, ib;
      int    idum[2];
      float  rdum;
      double ddum;
      char   tmpbuf[60];


      totext = single = 1;
      name[nval-1] = '\0';		/* separate file name + extension */
      (void) strcpy(extensio,&name[n+1]);	/* get extstring without [] */
      name[n] = '\0';

     ext_string:
      if (extensio[0] == '\0') goto after_ext_string;

      /* here we process more extensions */

      mm = CGN_INDEXC(extensio,',');	/* look for ',' separator */
      if (mm > 0)
         {
         totext = 2;			/* more than 1 extens required */
         (void) strncpy(tmpbuf,extensio,mm);
         tmpbuf[mm] = '\0';
         (void) strcpy(pfix,&extensio[mm+1]);   /* move rest of string*/
         (void) strcpy(extensio,pfix); 
         }
      else
         {
         (void) strcpy(tmpbuf,extensio);
         extensio[0] = '\0';
         }

      /* check for the 3 options: interval, number, label */

      if ((tmpbuf[0] >= '0') && (tmpbuf[0] <= '9'))
         {					/* no label */
         n = CGN_INDEXC(tmpbuf,'-');		/* look for interval a-b */
         if (n > 0)
            {
            tmpbuf[n] = ',';			/* a-b  =>  a,b */
            mm = CGN_CNVT(tmpbuf,1,2,idum,&rdum,&ddum);
            if ((mm < 2) || (idum[0] > idum[1]))
               SCETER(8,"invalid syntax for extension no. interval...");

            ia = idum[0];
            ib = idum[1]; 
            if ((ia < 0) || (ib > 79))
               SCETER(8,"invalid syntax for extension no. interval...");
            for (n=ia; n<=ib; n++) exxtc[n] = '1';
            totext = 2;			/* more than 1 extens required */
            }
         else
            {					/* single no. */
            mm = CGN_CNVT(tmpbuf,1,1,idum,&rdum,&ddum);
            if ((mm < 1) ||			/* invalid extension no. */
                ((idum[0] < 0) || (idum[0] > 79)))
               SCETER(8,"invalid extension no ...");
            exxtc[idum[0]] = '1';
            }
         }
      else
         {				/* we have a string */
         char  *ptr;

         ptr = extlabel[labelcount++];
         
         if (tmpbuf[0] == '"')		/* "abc"  =>  abc */
            {
            mm = CGN_INDEXC(&tmpbuf[1],'"');
            if (mm > 0)
               {
               (void) strncpy(ptr,&tmpbuf[1],mm);
               *(ptr+mm) = '\0';
               }
            else
               (void) strcpy(ptr,tmpbuf);
            }
         else
            (void) strcpy(ptr,tmpbuf);

         CGN_UPSTR(ptr);

         if (labelcount > 9)		/* max. 10 labels ... */
            labelcount = 9;
         else
            extlabel[labelcount] = ptr + (int) strlen(ptr) + 1; 
         }
      goto ext_string;
      }
   }



after_ext_string:
(void) SCKGETC("INPUTC",1,100,&nval,pfix);	/* read newfile prefix */
(void) SCKGETC("P3",1,3,&nval,opt);		/* read options */
(void) SCKGETC("P4",1,1,&nval,backwflag);	/* read backwards comp. flag */
(void) SCKGETC("P5",1,80,&nval,catfile);	/* read optional catalog name */
catopt = 0;
if (catfile[0] != '+') catopt = 1;


pc = opt; 
while (*pc) 				/* use capital letters for option */
   {
   if (('a'<=*pc) && (*pc<='z')) *pc += 'A' - 'a';
   pc++;
   }
     

switch (opt[0])
   {				/* check print option    */
   case 'F' : 
    popt = 2; 
    break; 				/* Full print */

   case 'H' : 
    popt = 3; 
    opt[1] = 'N';
    opt[2] = 'N';
    break; 				/* Full print */

   case 'N' : 
    popt = 0; 
    break; 				/* No print */

   case 'S' :				/* Short print */
   default  : 
    popt = 1; 
    opt[0] = 'S';			/* Short print - default */
   }

switch (opt[1]) 
   {				/* check format option */
   case 'N' : 
    fcopt = 0; 
    ffmt = 'N';				/* No creation */
    break;
   case 'F' : 
    fcopt = 1; 
    ffmt = 'F';				/* FP format */
    break;
   case 'O' :				/* Original format */
   default  : 
    fcopt = 1; 
    ffmt = 'O';				/* Original - default */
   }

switch (opt[2]) 
   {				/* check keyword option */
   case 'N' : 
    hist = 'N'; 
    break;				/* No history */
   case 'C' : 
    hist = 'C'; 
    break;				/* Code hierarch keyword */
   case 'A' : 
    hist = 'A'; 
    break;				/* Include hist in empty file */
   case 'Y' :				/* Yes - full history */
   default  : 
    hist = 'Y';				/* Yes-history - default */
   }

fidcount = 0;	/* take also the Midas DATA_PATH into account */
nampntr = name;

open_file:
fid = dopen(nampntr,READ,'S',0);
if (fid < 0)
   {					/* try to 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],name);          /* use new path */
         nampntr = datpath;
         fidcount ++;
         goto open_file;
         }
      }
   SCETER(11,"Cannot find FITS file ...");
   }

mfd = -1; mfdt = -1;			/* init FITS business */
fmt = drinit();
if (fmt != FITS) 
   SCETER(9,"Unknown data format of input file...");
    


/* ------------------------------------------------------------------- */
/* for extension name, we first have to find the corresponding ext no. */
/* ------------------------------------------------------------------- */

if (single == 1) 
   {		
   if (labelcount > 0)
      {
      int  savpopt;


      savpopt = popt;
      popt = 0;
      (void) xoutname("midd");
      bfdef = hdr_init();			/* decode header */
      mark = labelcount;

      type = fitsrhd(&mfd,bfdef,&dsize,&mfdt,ffmt,hist,popt,-1);
      if (type < BFITS) SCETER(10,"bad FITS header...");

      extcount ++;
      (void) fitssxd(dsize,1);		/* skip data matrix */

      for(;;)			/* loop over all extensions */
         {				/* to get extension no. */
         if (mark == 0) break;

         bfdef = hdr_init();			/* decode header */
         type = fitsrhd(&mfd,bfdef,&dsize,&mfdt,ffmt,hist,popt,-1);
         if (type == EOFITS) goto after_loop;

         CGN_UPSTR(bfdef->extname);
         for (n=0; n<labelcount; n++)
            {
            if (strcmp(extlabel[n],bfdef->extname) == 0) 
               {
               if (type < BFITS) SCTPUT("bad FITS header...");
               (void) strcpy(extlabel[n],"---");
               mark--;
               exxtc[extcount] = '1';
               break;
               }
            }

         extcount ++;
         (void) fitssxd(dsize,1);		/* skip data matrix */
         }

     after_loop:
      if (mark != 0)
         {
         if (mark > 1)
            (void) sprintf(name,"%d extensions not found in FITS file...",mark);
         else
            {
            mm = 0;
            for (n=0; n<labelcount; n++)
               {
               if (*extlabel[n] != '-')
                  {
                  mm = n;
                  break;
                  }
               } 
            (void) sprintf
            (name,"extension: %s not found in FITS file...",extlabel[mm]);
            }
         SCETER(8,name);
         }

      dclose(fid);			/* rewind the file the "hard" way */
      extcount = 0;
      labelcount = 0;
      popt = savpopt;
      goto open_file;		/* now we continue only with numbers */
      }

   else
      {				/* find first + last index */
      for (n=0; n<80; n++)
         {
         if (exxtc[n] == '1')
            {
            firstext = n;
            lastext = n;
            break;
            }
         }
      if (firstext == -1)
         SCETER(8,"invalid syntax for extension no.s ...");

      for (n=79; n>firstext; n--)
         {
         if (exxtc[n] == '1')
            {
            lastext = n;
            break;
            }
         }

      backwflag[0] = 'N';		/* keep ext. no.'s */
      mark = 0;

      extno = firstext++;
      exxtc[extno] = '0';
      }
   }


/* ----------------------------------------------------------- */
/* here we move through complete FITS file with all extensions */
/* ----------------------------------------------------------- */

if (xoutname(pfix) != 0) SCETER(6,"Invalid prefix...");

bfdef = hdr_init();			/* decode primary header */
type = fitsrhd(&mfd,bfdef,&dsize,&mfdt,ffmt,hist,popt,Midas_flag);
if (type < BFITS)
   SCETER(10,"bad primary FITS header...");

if ((single == 1) && (extno > 0))
   {
   fitssxd(dsize,0);			/* skip FITS data section */

   mark = 1;				/* set delete mark */
   extcount ++;
   goto extens_loop;
   }

scount ++;
styp = 'I';
if (mfd > -1)
   {
   if (catopt == 1)
      {
      (void) SCKGETC("F$OUTNAM",1,40,&nval,resname);	/* get result name */
      (void) SCCADD(catfile,resname," ");
      }

   if (dsize > 0)
      {			/* update HISTORY if image */
      nval = sprintf(text,"Extracted from: %s",nampntr);
      fillHISTORY(mfd,text,nval);

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

      if (retstat == NOFITS)
         {
         retstat = -999;
         goto close_file;
         }
      retstat = 0;
      }

   else		/* empty primary FITS header */
      {
      styp = 'E';

      nval = sprintf(text,"Empty primary header of: %s",nampntr);
      fillHISTORY(mfd,text,nval);
      (void) SCFCLO(mfd);		/* close empty primary header file */ 
      }
   }
else
   {
   if (dsize < 1) styp = 'E';

   fitssxd(dsize,0);
   }

typbuf[mshift++] = styp;
extcount ++;			/* count extensions */


extens_loop:				/* go through all extensions */
if (popt == 3) 
   {
   if (extcount == 1)
      (void) sprintf(text,"------------  end of primary header  ------------");
   else
      (void) sprintf(text,"-----------   end of extension # %d   -----------",
                          extcount-1);
   SCTPUT(text);
   SCTPUT(" ");
   }


/* if we work on single extensions, get next extno to work on */

if (single == 1)
   {		
   if (mark == 1)		/* last extension was not extracted */
      {
      if (mfd > -1) 
         { 		/* delete previously created Midas frame */ 
         /*
         printf("delete last Midas file [%d] ...\n",extcount-1);
         */
         (void) SCFXDEL(mfd);
         }
      mark = 0;
      }
   else
      {
      extno = -1;			/* get next extno */
      for (n=firstext; n<=lastext; n++)
         {
         if (exxtc[n] == '1')
            {
            extno = n;
            firstext = n+1;
            exxtc[n] = '0';
            break;
            }
         }
      if (extno == -1) goto close_file;		/* all extensions done */
      }
   }


/* read next FITS extension */

mfd = -1; mfdt = -1;
bfdef = hdr_init();
type = fitsrhd(&mfd,bfdef,&dsize,&mfdt,ffmt,hist,popt,Midas_flag);
if (type == EOFITS) goto close_file;
if (type < BFITS) 
   {
   (void) sprintf(text,"bad FITS extension[%d] ...",extcount);
   SCTPUT(text);
   extcount ++;
   if (dsize > 0) fitssxd(dsize,0);
   goto extens_loop;
   }

if ((single == 1) && (extno != extcount))
   {
   if (dsize > 0) fitssxd(dsize,0);
   mark = 1;
   extcount ++;
   goto extens_loop;
   }


/* for images, check if we really created the file */

if (bfdef->cflag == 0)
   {
   bfdef->cflag = 1;
   type = fitsrhd(&mfd,bfdef,&dsize,&mfdt,ffmt,hist,popt,Midas_flag);

   if (bfdef->cflag != -9)
      {
      extcount ++;
      (void) sprintf
      (text,"could not create Midas frame for extension [%d]",extcount);
      SCTPUT(text);
      goto extens_loop;
      }
   }

if (catopt == 1)
   {
   (void) SCKGETC("F$OUTNAM",1,40,&nval,resname);	/* get result name */
   (void) SCCADD(catfile,resname," ");
   }

scount ++;
if ( (dsize < 1) &&
     ((type == IMAGE) || (type == BFITS) || (type == BFITSE)) )
   {					/* empty header */
   styp = 'E';
       
   if (fcopt && (mfd > -1))
      {
      nval = sprintf(text,
                     "Empty header extracted from: %s[%d]",nampntr,extcount);
      fillHISTORY(mfd,text,nval);
      (void) SCFCLO(mfd);               /* close empty header file */
      }
   }

else
   {
   if (fcopt && (mfd > -1))
      {
      nval = sprintf(text,"Extracted from: %s[%d]",nampntr,extcount);
      fillHISTORY(mfd,text,nval);

      switch (type)
         {
         case ATABLE :				/* ASCII tables */
          retstat = fitsrat(mfd,bfdef,dsize,0);
          styp = 'A';
          break;

         case BTABLE :				/* BINARY tables */
          retstat = fitsrbt(mfd,bfdef,dsize,0);
          styp = 'B';
          break;

         case IMAGE  :				/* IMAGE */
          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)
             {
             styp = 'X';
             retstat = -999;
             goto close_file;
             }
          styp = 'I';
          retstat = 0; 
          break;

         default :				/* skip unknown ext. */
          styp = 'U';
          (void) sprintf
          (text,"Warning: Unknown type (%d) in FITS extension [%d] - skipped",
           type,extcount);
          SCTPUT(text);
          fitssxd(dsize,0);
          retstat = -888;
         }
      }
   else
      {
      switch (type)
         {
         case ATABLE :                          /* ASCII tables */
          styp = 'A';
          break;

         case BTABLE :                          /* BINARY tables */
          styp = 'B';
          break;

         case IMAGE  :                          /* IMAGE */
          styp = 'I';
          break;

         default :                              /* skip unknown ext. */
          styp = 'U';
         }

      fitssxd(dsize,0);			/* skip data section */
      }
   }

typbuf[mshift++] = styp;
if (mshift > 79) mshift = 79;

extcount ++;
goto extens_loop;


close_file:
dclose(fid); 



if (fcopt == 0) 
   {
   if (popt > 0)
      SCTPUT("Warning: No Midas file(s) created");
   else if (extno == -999)		/* all extensions used */
      {
      (void) sprintf(text,
             "No. of extensions = %d in FITS file: %s",extcount,name);
      SCTPUT(text);
      }
   }
else
   {
   if (single == 1) 
      {
      if (retstat != 0)
         {
         extcount = 0;
         SCTPUT("Warning: No Midas file created");
         goto save_info;
         }

      if (totext == 1) goto save_info;
      }

   if ((backwflag[0] == 'Y') || (backwflag[0] == 'y'))
      {
      char   namea[132], nameb[132];

      if (extcount == 1)			/* we have single image */
         {
         nfn = newfn('X',(char *)0);               /* get name again */
         (void) strcpy(namea,nfn);
         (void) strcat(namea,".bdf");
         (void) strcpy(nameb,namea);

         n = CGN_INDEXS(namea,"0000");
         nameb[n+3] = '1';                    /* xxxx0000.yyy => xxxx0001.yyy */
         istat = osfrename(namea,nameb);
         if (istat != 0)
            SCETER(7,"osfrename failed...");

         (void) sprintf(text,"Single image is renamed to %s",nameb);
         SCTPUT(text);
         SCTPUT("(to obtain same name as with `intape/fits')");
         }
      }
   }

if (single == 1) extcount = scount;

save_info:
(void) SCKWRI("MID$INFO",&extcount,4,1,&nval);	/* no. of valid exts */
(void) SCKWRI("OUTPUTI",&retstat,15,1,&nval);
(void) SCKWRC("OUTPUTC",1,typbuf,1,80,&nval);

if (extcount > 1)
   {
   (void) sprintf(name,"%d extensions read in ...",extcount);
   SCTPUT(name);
   }

return SCSEPI();
}

/*

*/

void addHISTORY(imno,text,tl)
int  imno;	/* IN: frame no. */
char *text;	/* IN: HISTORY text */
int  tl;	/* IN: length of text */

{
int  hsize, n, m, iav, klen;

char  *mypntr, work[82];





/* ensure, that HISTORY is multiple of 80 chars */

(void) SCDFND(imno,"HISTORY",work,&n,&m);
if (work[0] == 'C')
   {
   hsize = n*m;                         /* curent size */
   m = hsize / 80;
   iav = m * 80;
   if (iav < hsize)                         /* force multiple of 80 chars. */
      {
      iav += 80;
      klen = iav - hsize;
      memset((void *)work,32,(size_t)klen);
      (void) SCDWRC(imno,"HISTORY",1,work,-1,klen,&m);
      hsize = iav;
      }
   }
else
   hsize = 0;


n = tl;
m = n / 80;
iav = m * 80;
if (iav < n)
   {
   iav += 80;
   klen = iav - n;
   }
else
   klen = 0;

mypntr = (char *) malloc((size_t)iav);
if (mypntr == (char *) 0)
   {
   SCETER(33,"Could not allocate memory...!");
   SCSEPI();
   }
(void) strcpy(mypntr,text);

if (klen > 0)                           /* clean end of string */
   memset((void *)(mypntr+n),32,(size_t)klen);

*(mypntr+iav-1) = '\0';
(void) SCDWRC(imno,"HISTORY",1,mypntr,hsize+1,iav,&m);

free((void *) mypntr);
}

