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

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.LANGUAGE   C
.IDENT      ltape.c
.AUTHOR     Preben J. Grosbol [ESO/IPG]
.KEYWORDS   tape, listing
.PURPOSE    list content of tape
.ENVIRON    UNIX, MIDAS
.VERSION    1.0  1991-Sep-09 : Creation,     PJG
.VERSION    1.1  1991-Sep-13 : Change print layout,     PJG
.VERSION    1.2  1991-Sep-17 : Minor layout changes,     PJG
.VERSION    1.3  1992-Mar-17 : Test for device type,     PJG
.VERSION    1.4  1994-Oct-09 : Write usage on wrong option,     PJG
.VERSION    1.5  1994-Nov-18 : Include c option for create,     PJG
.VERSION    1.6  1998-Jun-03 : Change of some dio function calls,     PJG
.VERSION    1.7  1998-Aug-26 : Include list of file-name option,     PJG

 090710		last modif
------------------------------------------------------------------------*/
#include    <stdio.h>                 /* Standard I/O definitions       */
#include    <time.h>                  /* Time library                   */
#include    <string.h>                /* String library                 */
#include    <osfile.h>                /* MIDAS OS file definitions      */
#include    <osparms.h>               /* MIDAS OS-definitions           */
#include    <midas_def.h> 
#include    <fitsfmt.h>               /* Data formats                   */
#include    <fitsdef.h>               /* FITS definitions               */
#include    <fitskwt.h>               /* FITS Table definitions         */

#define     MXPARM             10     /* Max. no. of parameters         */
#define     MXNAME            128     /* Max size of name string        */
#define     MXLINE            128     /* Max. size of print line        */

                                      /* Definition of parameter list   */
static char *plist[] = {"i+:Input file",
                        "o+:List file",
                        "l+:File no.",
                        "c+:Create file",
                        "d+:List of names of disk files",
                        "h-:Header list",
                        "n-:No questions",
                        "v-:Verbose", (char *) 0};

static char usage[] = 
"Usage: ltape [-i input] [-d filelist] [-o logfile] [-l file-no]\n"
"             [-c output-file] [-hnv]"; 


extern int dcparm();




int main(argc,argv)
int        argc;          /* parameter count                            */
char     **argv;          /* pointers to parameters                     */

{
  char              *pc, *name, *cname, *list, *dname;
  char              fform, dtype, ffmt;
  char              tpname[MXNAME], dev[MXNAME], devn[MXNAME];
  char 		    rem[MXLINE], vol[MXLINE], fname[MXNAME];
  char              own[MXLINE], date[30];
  char              *pval[MXPARM], line[MXLINE];
  char              *gvparm(), *getenv();
  int               n, vmode, vlist, popt, quest, no, fmt;
  int               type, size, mfd, mfdt, fid;
  double            mb;
  struct tm         tmstr;
  struct filestatus status;
  FILE              *ofp, *ofd;
  BFDEF             *bfdef, *hdr_init();
  TXDEF             *txdef;  

  SCSPRO("-1");                           /* initiate MIDAS environment */

  if (dcparm(argc,argv,plist,pval)) {       /* decode parameter list    */
     fprintf(stdout,"%s\n",usage); SCSEPI();
   }

  size = 0;
  fid = -1;
  ofd = (FILE *) 0;
  name = (char *) 0;
  dname = (pc=gvparm('d',plist,pval)) ? pc : (char *) 0;
  if (dname) {
    if (!(ofd=fopen(dname,"r"))) {
      fprintf(stderr,"Error: cannot open file >%s<\n",dname);
      SCSEPI();
    }
    dtype = 'S';
  }
  else {
    if (!(name=gvparm('i',plist,pval))) {     /* Get device name and type */
      fprintf(stdout,"Tape device  : ");
      fgets(dev,MXNAME-1,stdin);
      pc = dev; while (*pc && *pc!='\n') pc++; *pc = '\0';
      name = dev;
    }

    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)) {
      for (pc = name; (*pc) && (*pc != '!') && (*pc != ':'); pc++);
                                    /* Check for '[' after ':' for VMS */
      if (*pc == '!' || *pc == ':' )
	dtype = (*(pc+1) == '[' ) ? 'S' : 'B';
      else {
        if ( osfinfo(name,&status) == 0)             /* if name exists */
                                     /* is it a device? block : stream */
          dtype = (S_ISCHR(status.protection)) ? 'B' : 'S';
        else dtype = '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)) {
	  fprintf(stderr,
		  "Error: environment variable >%s< not defined!\n",name);
	  SCSEPI();
	}
      }
      dtype = 'B';                             /* block type device  */
      strcpy(name,tpname);                     /* copy actual name   */
    }
  }

  ofp = (pc=gvparm('o',plist,pval)) ? fopen(pc,"w") : stdout;
  if (!ofp) SCSEPI();

  list = (pc=gvparm('l',plist,pval)) ? pc : "*";
  if (deflist(list)) {
     fprintf(stderr,"Error: wrong syntax in file list\n");
     SCSEPI();
   }

  popt = (gvparm('h',plist,pval) != (char *) 0) ? 2 : 0;
  quest = (gvparm('n',plist,pval) == (char *) 0);

  cname = (pc=gvparm('c',plist,pval)) ? pc : (char *) 0;
  if (cname) {
     quest = 0;
     ffmt = 'O';
   }
  else  ffmt = 'N';

  if (quest) {
     fprintf(stdout,"Name         : ");
     fgets(own,MXLINE-1,stdin);
     fprintf(stdout,"Volume/format: ");
     fgets(vol,MXLINE-1,stdin);
     fprintf(stdout,"Comments     : ");
     fgets(rem,MXLINE-1,stdin);
   }

  vlist = 0;
  vmode = (gvparm('v',plist,pval) != (char *) 0);
  if (vmode) vlist = (ofp != stdout) || cname;

  if (!dname && (fid=dopen(name,READ,dtype,6250))<0) {  /* Open device */
     fprintf(stderr,"Error: cannot open device >%s<\n",name);
     SCSEPI();
   }

  if (quest) {
     sprintf(line,"                          Tape Directory Listing\n\n\n");
     fputs(line,ofp); if (vlist) fputs(line,stdout);
     oshdate(date,&tmstr);
     sprintf(line,"%72.72s\n\n",date);
     fputs(line,ofp); if (vlist) fputs(line,stdout);
     sprintf(line,"Name    : %s",own);
     fputs(line,ofp); if (vlist) fputs(line,stdout);
     sprintf(line,"Volume  : %s",vol);
     fputs(line,ofp); if (vlist) fputs(line,stdout);
     sprintf(line,"Comments: %s\n",rem);
     fputs(line,ofp); if (vlist) fputs(line,stdout);
     sprintf(line,"  Name/no         Identifier        "
	       "    Format   Mb  Axes  Nx    Ny  Remarks\n");
     fputs(line,ofp); if (vlist) fputs(line,stdout);
     sprintf(line,"--------------------------------"
	     "-----------------------------------------------\n");
     fputs(line,ofp); if (vlist) fputs(line,stdout);
   }

  while ((!dname && getlist(&no)) ||   /* Read files in list       */
	 (dname && fgets(fname,MXNAME,ofd))) {
    if (dtype=='B') {
      if (no<1) continue;
      if (dapos(no-1)) break;
      sprintf(fname,"%5d          ",no);
      pc = fname;
    }
    else {
      pc = strchr(fname, '\n');
      if (pc) *pc = '\0';
      if (dname) {
	if ((fid=dopen(fname,READ,dtype,6250))<0) continue;
      }
      else
	strcpy(fname,name);
      pc = strrchr(fname, '/');
      pc = (!pc) ? fname : pc+1;
    }
    fmt = drinit();                       /* Check format of file     */
    if (fmt<0) break;                     /* End of Information, exit */

     mfd = -1; mfdt = -1; *line = '\0';
     bfdef = hdr_init();
     if (cname) outname(cname,-1,'o');
     switch (fmt) {
	case  FITS :
	  type = fitsrhd(&mfd,bfdef,&size,&mfdt,ffmt,'N',popt,0);
	  mb = size / 1048576.0;
	  if (size || !bfdef->xflag) {
	     fform = (type < BFITS) ? 'U' : 'F';
	     sprintf(line,"%-16.16s >%-20.20s< %c(%3d)%5.1f, %2d: %5d %5d\n",
		     pc,bfdef->ident,fform,bfdef->bitpix,mb,bfdef->naxis,
		     bfdef->data[0].naxis,bfdef->data[1].naxis);
	     if (!cname) fputs(line,ofp);
	     if (vlist) fputs(line,stdout);
	   }
	  if (cname) fitsrdm(mfd,bfdef,size,mfdt,ffmt,0);  /* data matrix  */
	  else fitssxd(size,0);

	  do {
	     mfd = -1; mfdt = -1; *line = '\0';
	     bfdef = hdr_init();
	     mb = size / 1048576.0;
	     type = fitsrhd(&mfd,bfdef,&size,&mfdt,ffmt,'N',popt,0);
	     switch (type) {
		case ATABLE : 
		  txdef = (TXDEF *) bfdef->extd;
		  sprintf(line,"%-16.16s >%-20.20s<"
			  " F(ATx)%5.1f,r,c: %5d %5d\n",
			  pc,bfdef->ident,mb,
			  bfdef->data[1].naxis,txdef->tfields);
		  if (cname) fitsrat(mfd,bfdef,size,0);
		  break;
                case BTABLE : 
		  txdef = (TXDEF *) bfdef->extd;
		  sprintf(line,"%-16.16s >%-20.20s<"
			  " F(BTx)%5.1f,r,c: %5d %5d\n",
			  pc,bfdef->ident,mb,
			  bfdef->data[1].naxis,txdef->tfields);
                  if (cname) fitsrbt(mfd,bfdef,size,0);
		  break;
                case IMAGE  :
		  sprintf(line,"%-16.16s >%-20.20s<"
			  " F(ITx)%5.1f, %5d,%2d: %5d %5d\n",
			  pc,bfdef->ident,mb,bfdef->bitpix,bfdef->naxis,
			  bfdef->data[0].naxis,bfdef->data[1].naxis);
		  if (cname) fitsrdm(mfd,bfdef,size,mfdt,ffmt,0);
		  break;
                case UKNOWN : 
		  sprintf(line,"%-16.16s5d >%-20.20s< F(--x)%5.1f\n",
			  pc,bfdef->ident,mb);
		  if (cname) fitssxd(size,0);
		  break;
	      }
	     if (!cname) fitssxd(size,0);
	     if (*line) {
		if (!cname) fputs(line,ofp);
		if (vlist) fputs(line,stdout);
	      }
	   } while (RGROUP<type);
	  break;
	case  IHAP :
          (void)printf("IHAP files are not supported anymore in Midas\n");
          (void)printf
("the 96NOV release is the last version with which IHAP files can be\n");
          (void) printf("converted to the Midas format\n");
	  break;
	default    :
	  sprintf(line,"%-16.16s > UNKNOWN FILE FORMAT\n",pc);
	  if (!cname) fputs(line,ofp);
	  if (vlist) fputs(line,stdout);
	}
     if (dtype=='S') {
       dclose(fid);
       if (!dname || cname) break;
     }
   }
  if (dtype!='S') dclose(fid);
  if (dname) fclose(ofd);
  SCSEPI();

return 0;
}
