/*===========================================================================
  Copyright (C) 1988-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 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        intape.c
.LANGUAGE     C
.AUTHOR       P.Grosbol   ESO/IPG
.KEYWORDS     Data conversion, FITS
.PURPOSE      Read data file either from tape unit or disk and
              convert it to the internal MIDAS format.
.COMMENT      Formats supported are : FITS 8,16,32,-32,-64, tables
	      groups, etc. and IHAP code(1,14) with 16 or 32 data.
.VERSION      1.0  1988-Nov-17 : Creation,   PJG 
.VERSION      1.1  1989-Jan-25 : Force lower case names,   PJG 
.VERSION      1.2  1989-Jun-12 : Change def. of unit+kunit,   PJG 
.VERSION      1.3  1989-Sep-07 : Remore dskip call,   PJG 
.VERSION      1.4  1989-Oct-08 : Add mfdt for groups format,   PJG 
.VERSION      1.5  1990-Feb-19 : Include explicit input file name, PJG 
.VERSION      1.55 1990-Mar-21 : Change default options, PJG 
.VERSION      1.58 1990-Jun-19 : Insert 'break' in option check, PJG 
.VERSION      1.6  1990-Aug-08 : Enable U/L-case in file names, PJG 
.VERSION      1.62 1990-Sep-14 : Correct list no., PJG 
.VERSION      1.65 1990-Oct-23 : Disable SC-errors, PJG 
.VERSION      2.0  1991-Feb-24 : Change structures, PJG 
.VERSION      2.1  1991-Mar-24 : initiate file no. at each ext., PJG 
.VERSION      2.2  1992-Mar-17 : Accepting physical device-names. CG
.VERSION      2.3  1992-Aug-13 : Add IMAGE extension. PJG
.VERSION      2.4  1992-Dec-02 : Translating environment variables, CG
.VERSION      2.5  1993-Oct-29 : Update to new SC/TC + prototypes, CG
.VERSION      2.7  1993-Dec-13 : Enable SC/TC standard error check, PJG
.VERSION      2.8  1994-Jun-09 : Check if file-name or prefix, PJG
.VERSION      2.85 1994-Jun-29 : Check if file exist, PJG
.VERSION      2.9  1994-Dec-08 : Terminate after tape-position error, PJG
.VERSION      2.95 1995-Jan-23 : No 'cannot open' warning for '*', PJG
.VERSION      3.0  1996-Oct-22 : Add code 'C' option for keywords, PJG
.VERSION      3.05 1996-Nov-12 : Clean error-exits, increase buffers, PJG
.VERSION      3.10 1997-Jan-22 : Change test on input file/dev name, PJG
.VERSION      3.15 1997-Jul-29 : Add comment on 'No files created', PJG
.VERSION      3.20 1997-Oct-15 : use also Midas data path, KB  980527
.VERSION      3.25 1999-Mar-30 : Add history option 'A', PJG 

 090710		last modif
---------------------------------------------------------------------*/

#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>

/*

*/
int main()
{
  char         list[129], pfix[129], name[129], tpname[162], devn[5];
  char         hist, ffmt, devt, *pc, *nfn;
  char         opt[4];
  char  *nampntr, datpath[192];
  extern char DATA_PATH[328];		/* that's inside scs.c (SCSPRO) */

  int          fmt, no, n, dsize, type, nval, wcf, ntf;
  int          mfd, mfdt, popt, fcopt, pfx;
  int   fid, fidcount;		/* needed for data path business */
  int   history_flag, retstat, maxno;
  int   extcount=0, file_type=-1, kinfo[2];

  BFDEF        *bfdef;

  struct filestatus status;

  void fillHISTORY();




  (void) SCSPRO("INTAPE");                     /* get into MIDAS env. */
  nfn = (char *) 0;
  pfx = 0;
  retstat = 0;
  fid = -1;

  (void) SCKGETC("P1",1,128,&nval,list);               /* read file list */
  wcf = (*list != '*');                         /* wildcard flag  */
  if (deflist(list))                            /* initialize file list */
    SCETER(1,"Error: Wrong syntax in file list");

  (void) SCKGETC("P2",1,128,&nval,pfix);               /* read file prefix */

  (void) SCKGETC("P3",1,128,&nval,name);               /* read device/file */
  for (n=0; n<4; n++)
      devn[n] = (('A'<=name[n]) && (name[n]<='Z')) ? name[n]+'a'-'A' : name[n];
  devn[n] = '\0';

  if (strncmp(devn,"tape",4)) {
     CGN_LOGNAM(name,tpname,128);
     strcpy(name,tpname);                        /* copy actual name */
     if (osfinfo(name,&status) == 0)             /* if name exists */
       devt = (S_ISCHR(status.protection)) ? 'B' : 'S';	/* block:stream */
     else 
       devt = (((pc=strchr(name,':')) || (pc=strchr(name,'!'))) &&
	       (*(pc+1)=='/')) ? 'B' : 'S';
  }	
  else {
     pc = name; 
     while (*pc) { if (('A'<=*pc) && (*pc<='Z')) *pc += 'a'-'A'; pc++; }
     if (osfphname(name,tpname)) {  /* get physical name of device */
	pc = name; 
	while (*pc) { if (('a'<=*pc) && (*pc<='z')) *pc += 'A'-'a'; pc++; }
	if (osfphname(name,tpname))
	   SCETER(2,"Error: device not defined");
      }
     devt = 'B';                             /* block type device  */
     strcpy(name,tpname);                    /* copy actual name   */
   }

  if (devt == 'B') {
     fid = dopen(name,READ,devt,6250);
     if (fid<0) SCETER(3,osmsg());		/* open block device  */
   }
  else {
     pc = name; pfx = 1;                     /* check for extension   */
     while (*pc) {
	pfx = pfx && (*pc != '.');
	if (*pc == ']' || *pc == '/') pfx = 1;  /* only after ] and / */
	pc++;
      }
     if (osfinfo(name,&status) == 0) pfx = 0;     /* if name exists */
     nfn = name;
   }

  (void) SCKGETC("P4",1,3,&nval,opt);               /* read options          */
  pc = opt; 
  while (*pc) 
     {
     if (('a'<=*pc) && (*pc<='z')) *pc += 'A' - 'a';
     pc++;
     }

  /* get max. no of extensions to extract/convert  from single file */

  (void) SCKGETC("P5",1,6,&nval,tpname);
  if (tpname[0] == '?') 		/* all extensions by default */
     maxno = 9999;
  else
     maxno = atoi(tpname);		/* bad string => maxno = 0 */
  if (maxno < 1) maxno = 1;

     
  switch (opt[0]) {                          /* check print option    */
     case 'F' : popt = 2; 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      */
  }

  ntf = 0;
  while (getlist(&no)) 
    {		                  /* go through list of files */
    if (no<1) continue;
    if (devt=='S') {
       if (pfx) {
          outname(name,no,'o');		/* 'o' like 'original version' */
          nfn = newfn('I',".mt");
       }

       /* KB. 971015   Take also the Midas DATA_PATH into account */

       fidcount = 0;
       extcount = 0;
       nampntr = nfn;

    open_file:
       fid = dopen(nampntr,READ,devt,0);
       if (fid < 0)
          {					/* try to open 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],nfn);          /* use new path */
                nampntr = datpath;
                fidcount ++;
                goto open_file;
                }
             }

	  if (wcf) 
             {
	     (void) sprintf(list,"Warning: Cannot open file: %s",nfn);
	     SCTPUT(list);
	     }
          continue;                              /* cannot open - continue */
	  }
      }
    else
      {
      if (dapos(no-1))
         {
         (void) sprintf(list,"Error: Cannot position tape on file no %d",no);
         SCTPUT(list);
         break;
        }
     nampntr = name;
     (void) sprintf(name,"tape file no. %d",no);
     }

    history_flag = 1;
    mfd = -1; mfdt = -1;
    if ((fmt=drinit()) < 0) 
       {
       if (devt=='S') 
          continue; 
       else
          break;
       }
    outname(pfix,no,'o');

    switch (fmt) {                          /* check which format     */
       case FITS :                          /* file is in FITS format */
	    ntf++;
            bfdef = hdr_init();                   /* decode header    */
            type = fitsrhd(&mfd,bfdef,&dsize,&mfdt,ffmt,hist,popt,0);
            if (type < BFITS)
               {
               SCTPUT("Warning: NOT supported FITS format!");
	       break;
               }
            else
               {                                    /* data matrix  */
               if ((0 < type) && (mfd > -1))
                  {			/* update HISTORY if image */
                  fillHISTORY(mfd,nampntr,0);
	          history_flag = 0;
                  }

	       if (fcopt) 
                  {
                  if ((bfdef->bitpix == -16) || (bfdef->bitpix == 16))
                     retstat = fitsrdmUI2(mfd,bfdef,dsize,mfdt,ffmt,0);
                  else
                     retstat = fitsrdm(mfd,bfdef,dsize,mfdt,ffmt,0);
                  file_type = 1;		/* image */
                  if (retstat == NOFITS)
                     {
                     retstat = -999;
                     goto close_file;
                     }
                  retstat = 0;
                  }
	       else
                  fitssxd(dsize,0);
	       }
               if (dsize > 0) extcount ++;	/* count, if no empty header */
               if (extcount >= maxno)  goto close_file;


            do 
               {                             /* go through extensions */
	       mfd = -1; mfdt = -1;
	       bfdef = hdr_init();
	       type = fitsrhd(&mfd,bfdef,&dsize,&mfdt,ffmt,hist,popt,0);

               if ((history_flag == 1) &&  (mfd > -1))
                  {			/* update HISTORY for table */
                  fillHISTORY(mfd,nampntr,0);
	          history_flag = 0;
	          }

               if (fcopt)
		 switch (type)
                    {
                    case ATABLE :               /* ASCII tables         */
                       file_type = 2;
                       fitsrat(mfd,bfdef,dsize,0);
                       extcount ++;
                       break;
                    case BTABLE :               /* BINARY tables        */
                       file_type = 2;
                       fitsrbt(mfd,bfdef,dsize,0);
                       extcount ++;
                       break;
                    case IMAGE  :               /* IMAGE                */

                       if (bfdef->cflag == 0) /* we didn't create the file */
                          {
                          bfdef->cflag = 1;
                          type = fitsrhd(&mfd,bfdef,&dsize,&mfdt,ffmt,
                                         hist,popt,0);
                          if (bfdef->cflag != -9)
                             {
                             char  text[80];

                             extcount ++;
                             (void) sprintf(text,
                             "could not create Midas frame for extension [%d]",
                             extcount);
                             SCTPUT(text);
                             break;
                             }
                          }
                       file_type = 1;
                       retstat = fitsrdm(mfd,bfdef,dsize,mfdt,ffmt,0); 
                       if (retstat == NOFITS)
                          {
                          retstat = -999;
                          goto close_file;
                          }
                       extcount ++;
                       retstat = 0;
                       break;
                    case UKNOWN :               /* skip unknown ext.    */
		       SCTPUT("Warning: Unknown FITS extension skipped!");
                       fitssxd(dsize,0); break;
		    }
	       else
                  fitssxd(dsize,0);

               if (extcount >= maxno)  goto close_file;

	       } while (RGROUP<type);

            break;
       default   : SCTPUT("Error: Unknown data format");
    }

close_file:
    if (devt=='S') {                              /* close disk file  */
        dclose(fid); if (!pfx) break;
    }
  }

  if (fcopt==0) SCTPUT("Warning: No file(s) created");
  if (devt!='S') dclose(fid);
  if (!ntf) SCETER(4,"Error: No files found");

   kinfo[0] = extcount;
   kinfo[1] = file_type;
  (void) SCKWRI("MID$INFO",kinfo,4,2,&nval);	/* no. of valid exts */
  (void) SCKWRI("OUTPUTI",&retstat,15,1,&nval);
  return SCSEPI();
}


