/*===========================================================================
  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
===========================================================================*/

/*+++++++++++++++++++++++ SC interface module SCFE +++++++++++++++++++++++
.LANGUAGE C
.IDENTIFICATION Module scfe.c
.AUTHOR         K. Banse 		ESO - Garching
.KEYWORDS       standard interfaces, bulk data files
.ENVIRONMENT    VMS and UNIX
.COMMENTS 
holds SCFINF, SCFNAME, SCFXMP,SCFYMP
.REMARKS
opening modes are: F_I_MODE, F_O_MODE, F_IO_MODE, F_X_MODE.                
data types are: D_R4_FORMAT, D_I2_FORMAT, D_I1_FORMAT, D_OLD_FORMAT.         
filetype no's are: F_IMA_TYPE, F_TBL_TYPE, F_FIT_TYPE.              

.VERSION  [1.00] 920211: pulled over from scf.c

 100816		last modif
----------------------------------------------------------------------------*/

#include <fileexts.h>

#include <stdio.h>


static int   virt_count = -1;

/*

*/

int SCFINF(name,flag,ibuf)

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
open a frame + return the file info in buffer of 5 integers
.ALGORITHM
use CGN_CLEANF + MID_ACCFRM to do the job
for 'flag' = 0, we do not pass via MID_ERROR !
.RETURNS
return status ( 0 = o.k)
-----------------------------------------------------------------------*/

char *name;	/* IN: name of data frame */
int flag;     	/* IN: specify desired info, 
		       0 = FCT_number (= `imno' of SCFOPN)  (1 val)
		       1 = version_no, file_type (Ima/Tab/Fits), FCB.SWPSHORT, 
		           FCB.SWPINT, FCB.FLOTFMT  (5 vals)
		       2 = nobytes, data_format, pixpbl, stblok, lastblk
                           (5 vals)
		       3 = file_type(Ima/Tab/Fits), data_format, file_protect,
			   file_compress (4 vals)
		       4 = nobytes, data_format, 
                           file_format (FITS/Midas), FCB.NDVAL,
                           file_type (Ima/Tab/Fits) (5 vals)
		       5 = part_no, namtyp (info via CGN_CLEANF, no FCT access)
                           (2 vals)
		       6 = version_no, file_type (Ima/Tab/Fits), FCB.DSCFLAG,
			   file_format (FITS/Midas), file_protect, 
                           file_compress (6 vals)
		       7 = nobytes, data_format, 
                           file_format (FITS/Midas), FCB.NDVAL,
                           file_type (Ima/Tab/Fits), FCB.DSCFLAG (6 vals)
		       9 = file_format (FITS/Midas), file_type (Ima/Tab/Fits)
			   (2 vals)

		       -1,-2,-3,-4,-6 as 1,2,3,4,6 above but with FCT_number
		       also passed in ibuf[0] (will be overwritten)

		       99 = just check, if frame already in FCT       */

int  *ibuf;	/* IN/OUT: buffer with desired info;
			   if flag < 0 then ibuf[0] already holds the 
			   FCT_number (so we have faster access) */


{
char   temp[200];

int   mm, namtyp, part_no;
int   ista, jkno, tmpno;

struct FCT_STRUCT  *fctpntr;

struct FCB_STRUCT  *fcbp;




/*
printf("entering SCFINF(%s,%d) \n",name,flag);
*/


if (flag < 0) 				/* ibuf[0] = tmpno from last call */
   {
   flag = -flag;
   tmpno = jkno = *ibuf;
   ista = ERR_NORMAL;
   if (flag != 5) goto do_it;
   }


/*  check file name */
 
CGN_CLEANF(name,F_IMA_TYPE,temp,FCT_NAME_LEN,&namtyp,&part_no);
if (flag == 5)
   {
   *ibuf++ = part_no;
   *ibuf = namtyp;
   return ERR_NORMAL; 
   }


jkno = MID_FINDFR(temp);		/* to know if it was already opened */

if (flag == 0)
   {
   if (jkno < 0)			/* do not use MID_ERROR stuff ... */
      return ERR_FRMNAC;
   else
      {
      *ibuf = jkno;
      return ERR_NORMAL; 
      }
   }

 
/*  for flag = 1,2,3,4,6,7,9 and 99 access data frame + get FCB in  */

if (jkno < 0)
   {
   tmpno = 0;
   ista = MID_ACCFRM(temp,0,&tmpno,&mm);	/* get file into FCT  */
   }
else
   {
   tmpno = jkno;
   ista = ERR_NORMAL;
   }

if (ista == ERR_VERNOR)			/* if Version problem, try FITS */
   {
   char  bname[200], dummy[8];
   int  iext;
   float rbuf;
   double  dbuf;

   if (part_no < 0)				/* we have a FITS extension */
      {
      int i;

      mm = - part_no;
      i = CGN_CNVT(&name[mm+1],1,1,&iext,&rbuf,&dbuf);
      if (i != 1) return ERR_FITEXT;
      } 
   else
      iext = -1;

   if (flag == 9)			/* just test type of FITS file */
      {					/* do not create internal FITS file */
      (void) sprintf(dummy,"%3.3d",iext);
      (void) strcpy(bname,"FITZ");
      (void) strcat(bname,temp);
      (void) strcat(bname,dummy);

      ista = MID_fitsin(0,temp,iext,bname,dummy,&jkno,&mm);
      if (ista == 0)
         {
         *ibuf++ = 1;				/* = 1 for FITS file */
         if (mm != 1)			/* file_type (Ima/Tab) */
            *ibuf = F_TBL_TYPE;
         else
            *ibuf = F_IMA_TYPE;

         MID_POPERR();
         return (ERR_NORMAL);
         }
      else
         return (ERR_INPINV);
      }
   else
      {
      ista = MID_ACCFITS(temp,0,iext,&tmpno);
      if (ista != ERR_NORMAL) 
         return (ista);
      else
         MID_POPERR();
      }
   }

if ((flag == 99) ||	  	/* we just want to see, if it's there */
    (ista != ERR_NORMAL))	/* error... */
   return (ista);	   


do_it:				/* store required info in return buffer  */
fctpntr = FCT.ENTRIES + tmpno;
fcbp = fctpntr->FZP;

switch (flag)
   {
  case 1:				/* 5 return values */
   if (fcbp->VERSION[5] == '1')		/* version no. */
      *ibuf++ = 100;				/* 100 (new) as of 010301 */
   else if (fcbp->VERSION[6] == '1')
      *ibuf++ = 10;				/* 010 (old) */
   else
      *ibuf++ = 8;				/* 008 (very old) */

   if (fcbp->BDTYPE[0] == 'T')		/* file_type (Ima/Tab/Fits) */
      *ibuf++ = F_TBL_TYPE;
   else if (fcbp->BDTYPE[0] == 'F')
      *ibuf++ = F_FIT_TYPE;
   else
      *ibuf++ = F_IMA_TYPE;

   if (fcbp->SWPSHORT == '=')		/* FCB.SWPSHORT */
      *ibuf++ = 12;
   else 
      *ibuf++ = 21;

   if (fcbp->SWPINT == '=')		/* FCB.SWPINT */
      *ibuf++ = 1234;
   else if (fcbp->SWPINT == 's')
      *ibuf++ = 4321;
   else if (fcbp->SWPINT == 'h')
      *ibuf++ = 2143;
   else 
      *ibuf++ = 3412;

   if (fcbp->FLOTFMT == '=')		/* FCB.FLOTFMT */
      *ibuf = 11;
   else if (fcbp->FLOTFMT == 'V')
      *ibuf = 12;
   else if (fcbp->FLOTFMT == 'G')
      *ibuf = 13;
   else 
      *ibuf = 14;
   break;


  case 2:		/* return 
			   nobytes, data_format, pixpbl, stblok, lastblk */
   *ibuf++ = fcbp->NOBYT;
   *ibuf++ = fcbp->DFORMAT;
   *ibuf++ = fcbp->PIXPBL;
   *ibuf++ = fcbp->D1BLOCK;
   *ibuf = fcbp->DLBLOCK;
   break;


  case 3:				/* 3 return values */
   if (fcbp->BDTYPE[0] == 'T')		/* file_type(Ima/Tab/Fits) */
      *ibuf++ = F_TBL_TYPE;
   else if (fcbp->BDTYPE[0] == 'F')
      *ibuf++ = F_FIT_TYPE;
   else
      *ibuf++ = F_IMA_TYPE;

   *ibuf++ = fcbp->DFORMAT;		/*  data format */

   *ibuf++ = fctpntr->PROT;		/* file protection */ 
   *ibuf = fctpntr->COMPRESS;		/* compression flag */ 
   break;


  case 4:				/* 5 return values */
  case 7:				/* 6 return values */
   *ibuf++ = fcbp->NOBYT;		/* nobytes */
   *ibuf++ = fcbp->DFORMAT;		/* data_format */
   *ibuf++ = fctpntr->FILTYP;		/* = 1 for FITS file */
   *ibuf++ = fcbp->NDVAL;		/* FCB.NDVAL */
   if (fcbp->BDTYPE[0] == 'T')		/* file_type (Ima/Tab/Fits) */
      *ibuf = F_TBL_TYPE;
   else if (fcbp->BDTYPE[0] == 'F')
      *ibuf = F_FIT_TYPE;
   else
      *ibuf = F_IMA_TYPE;
   if (flag == 4) break;

   ibuf ++;
   if (fcbp->DSCFLAG == 'Y')
      *ibuf = 2;			/* 2 for descr flag = 'Y' */
   else if (fcbp->DSCFLAG == 'Z')
      *ibuf = 1;			/* 1 for descr flag = 'Z' */
   else
      *ibuf = 0;
   break;


  case 6:				/* 6 return values */
   if (fcbp->VERSION[5] == '1')              /* version no. */
      *ibuf++ = 100;                         /* 100 (new) as of 010301 */
   else if (fcbp->VERSION[6] == '1') 
      *ibuf++ = 10;                          /* 010 (old) */
   else
      *ibuf++ = 8;                           /* 008 (very old) */

   if (fcbp->BDTYPE[0] == 'T')		/* file_type (Ima/Tab/Fits) */
      *ibuf++ = F_TBL_TYPE;
   else if (fcbp->BDTYPE[0] == 'F')
      *ibuf++ = F_FIT_TYPE;
   else
      *ibuf++ = F_IMA_TYPE;

   if (fcbp->DSCFLAG == 'Y')
      *ibuf++ = 2;			/* 2 for descr flag = 'Y' */
   else if (fcbp->DSCFLAG == 'Z')
      *ibuf++ = 1;			/* 1 for descr flag = 'Z' */
   else
      *ibuf++ = 0;

   *ibuf++ = fctpntr->FILTYP;		/* = 1 for FITS file */
   *ibuf++ = fctpntr->PROT;		/* file protection */
   *ibuf = fctpntr->COMPRESS;		/* compression flag */
   break;


  case 9:				/* 2 return values */
   *ibuf++ = fctpntr->FILTYP;		/* = 1 for FITS file */
   if (fcbp->BDTYPE[0] == 'T')		/* file_type (Ima/Tab/Fits) */
      *ibuf = F_TBL_TYPE;
   else if (fcbp->BDTYPE[0] == 'F')
      *ibuf = F_FIT_TYPE;
   else
      *ibuf = F_IMA_TYPE;

   if (jkno < 0) 			/* was not open before, so */
      (void) SCFCLO(tmpno);		/* get rid of it again */
   break;


  default:
   ista = ERR_INPINV;
   }


return (ista);
}

/*

*/

int SCFNAME(fno,fname,fnamlen)

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
  get the FCT name of a file id
.ALGORITHM
  return the name in given FCT_entry
.RETURNS
  if wrong fno return -2, if empty slot return -1, else 0
-----------------------------------------------------------------------*/

int   fno; 		/* IN: file no. */
char  *fname;     	/* OUT: name of data frame */
int   fnamlen;		/* IN: max. length of `fname' */

{
return (MID_RETNAM(fno,fname,fnamlen));
}

/*

*/

int SCFYMP(nopix,datform,imno,pntr)
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
use SCFCRE + SCFMAP to get virtual memory
.ALGORITHM
straight forward
.RETURNS
return status ( 0 = o.k )
-----------------------------------------------------------------------*/

int nopix;		/* IN: size in pixels */
int datform;		/* IN: data format of pixels */
int *imno;		/* OUT: file id (entry in FCT) */
char   **pntr;		/* OUT: pointer to data */

{
int  status, iav;

char  dumnam[20], *mypntr;



/* check, if creation or deletion */

if (nopix < 1)                          /* get rid of allocated space */
   {
   struct FCT_STRUCT  *fctpntr;


   status = ERR_INPINV;

   fctpntr = FCT.ENTRIES;
   for (iav=0; iav<FCT.MAXENT; iav++)
      {
      if ((iav == *imno) && (fctpntr->ACCESS == 'X'))
         {
         status = SCFCLO(iav);
         break;
         }
      fctpntr ++;
      }
   return status;
   }



/* allocate space - build up unique name */

virt_count++ ;
(void) snprintf(dumnam,(size_t)20,"virtual%d",virt_count);


/*  create + map X-MODE frame  */

status = SCFCRE(dumnam,datform,F_X_MODE,F_IMA_TYPE,nopix,imno);
if (status == ERR_NORMAL)
   status = SCFMAP(*imno,F_X_MODE,1,nopix,&iav,&mypntr);

if (status != ERR_NORMAL)
   {
   *pntr = 0;
   (void) snprintf(dumnam,(size_t)20,"nopix = %d",nopix);
   MID_E1(13,dumnam,status,1);
   }
else
   *pntr = mypntr;

return status;
}

/*

*/

int SCFXMP(nopix,datform,pntr)

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
use SCFCRE + SCFMAP to get virtual memory
.ALGORITHM
straight forward
.RETURNS
return status ( 0 = o.k )
-----------------------------------------------------------------------*/

int nopix;     	/* IN: size in pixels */
int datform;	/* IN: data format of pixels */
char   **pntr;		/* OUT: pointer to data */

{
int  status, imno, iav;

char  dumnam[20], *mypntr;



/* allocate space - build up unique name */

virt_count++ ;
(void) snprintf(dumnam,(size_t)20,"virtual%d",virt_count);


/*  create + map X-MODE frame  */

status = SCFCRE(dumnam,datform,F_X_MODE,F_IMA_TYPE,nopix,&imno);
if (status == ERR_NORMAL)
   status = SCFMAP(imno,F_X_MODE,1,nopix,&iav,&mypntr);

if (status != ERR_NORMAL)
   {
   *pntr = 0;
   (void) snprintf(dumnam,(size_t)20,"nopix = %d",nopix);
   MID_E1(13,dumnam,status,1);
   }
else
   *pntr = mypntr;

return status;
}

