/*===========================================================================
  Copyright (C) 1995,2004 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  SCI +++++++++++++++++++++++
.LANGUAGE C
.IDENTIFICATION Module SCI
.AUTHOR         K. Banse  	ESO - Garching
.KEYWORDS       standard interfaces, data frames, descriptors
.ENVIRONMENT    VMS and UNIX
.COMMENTS
holds SCIGET, SCIPUT
.VERSION [1.20]	861220:	creation
 040604		last modif

-----------------------------------------------------------------------------*/

#include <string.h>

#include <fileexts.h>


/*

*/

int SCIGET(name,dattype,iomode,filtype,maxdim,naxis,npix,start,step,ident,
       cunit,pntr,imno)

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
map complete data frame for reading or updating and read
the standard descriptors.
.ALGORITHM
call SCDGET and SCFMAP to map and to read the standard descriptors.
.RETURNS
return status ( 0 = o.k. )
.REMARKS
for a description of the parameters , see text for SCF... and SCD... routines
--------------------------------------------------------------------------*/

char	*name	 /* IN : data frame name */;
int dattype /* IN : data type */;
int iomode  /* IN : mode for opening of frame */;
int filtype /* IN : type no: 1 = image, 2 = mask, 3 = table  */;
int maxdim  /* IN : maximum number of dimensions */;
int *naxis  /* OUT: no of dimensions of the image */;
int *npix   /* OUT: size of each dimension  */;
double  *start   /* OUT: start coordinates: start is the address of an \
		    array of naxis elements */;
double  *step    /* OUT: stepsizes : step is the address of an array of \
		    naxis elements */;
char    *ident   /* IN/OUT: ascii identifier of image */;
char    *cunit   /* IN/OUT: unit of each axis (16 char per unit) */;
char	**pntr   /* OUT: pointer to mapped data */;
int *imno   /* OUT: file no. of data frame */;


{
char  *mypntr;

int   unit, status, n, kk;
int   maxval, npi[6], mnaxis, size, first_elem;
int   nullo , act_size;


*imno = -1;			/* so it is set to something... */


/*  check maxdim and iomode */

if ((maxdim < 1) || (maxdim > 6))
   {
   status = ERR_INPINV;
   error_ret(name," + MAXDIM",10,status);
   }

else if ((iomode != F_I_MODE) && (iomode != F_IO_MODE))
   {
   status = ERR_INPINV;
   error_ret(name," + IOMODE",10,status);
   }

MID_E3("SCIGET");		/* store interface name in case of need... */


/*  make sure all npix are set to 1 */

for (n=0; n<maxdim; n++)
   npix[n] = 1;


/*  open frame + get descriptors  */

status = SCFOPN(name,dattype,0,filtype,imno);
if (status != ERR_NORMAL)
   {
   error_ret(name," + SCFOPN",10,status);
   return status;
   }

status = SCDRDI(*imno,"NAXIS",1,1,&maxval,&mnaxis,&unit,&nullo);
if (status != ERR_NORMAL) 
   error_ret(name," + NAXIS",10,status);
else if (mnaxis < 1)
   {
   status = ERR_NODATA;
   error_ret(name," + NAXIS < 1",10,status);
   }

if (mnaxis > 6) mnaxis = 6;		/* currently our maximum...  */
if (maxdim < mnaxis) mnaxis = maxdim;
    
status = SCDRDI(*imno,"NPIX",1,mnaxis,&maxval,npi,&unit,&nullo);
if (status != ERR_NORMAL) 
   error_ret(name," + NPIX",10,status);


kk = mnaxis - 1;		/* trailing NPIX = 1 is ignored...  */
for (n=kk; n>0; n--)
   {
   if (npi[n] == 1)
      mnaxis --;
   else
      break;
   }
*naxis = mnaxis;		/* that's the NAXIS we return  */

for (n=0; n<mnaxis; n++)
   npix[n] = npi[n];
    
status = SCDRDD(*imno,"START",1,mnaxis,&maxval,start,&unit,&nullo);
if (status != ERR_NORMAL) 
   error_ret(name," + START",10,status);
status = SCDRDD(*imno,"STEP",1,mnaxis,&maxval,step,&unit,&nullo);
if (status != ERR_NORMAL) 
   error_ret(name," + STEP",10,status);

kk = (int)strlen(ident);
if (kk > 0)
   {
   status = SCDRDC(*imno,"IDENT",1,1,kk,&maxval,ident,&unit,&nullo);
   if (status != ERR_NORMAL) 
      error_ret(name," + IDENT",10,status);
   }

kk = (int)strlen(cunit);
if (kk > 0)
   {
   status = SCDRDC(*imno,"CUNIT",1,1,kk,&maxval,cunit,&unit,&nullo);
   if (status != ERR_NORMAL) 
      error_ret(name," + CUNIT",10,status);
   }


first_elem = 1;
size = npi[0];
for (n=1; n<mnaxis; n++)
   size *= npi[n];


/* finally map bulk data frame for reading/writing */

status = SCFMAP(*imno,iomode,first_elem,size,&act_size,&mypntr);
*pntr = mypntr;

return status;

}

/*

*/

int SCIPUT(name,dattype,iomode,filtype,naxis,npix,start,step,ident,cunit,pntr,imno)

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
create and map complete bulk data frame
and write the standard descriptors
.ALGORITHM
call SCFCRE, SCFMAP and SCDWRx routines
.RETURNS
return status ( 0 = o.k. )
.REMARKS
for a description of the parameters , see text for SCF... and SCD... routines
--------------------------------------------------------------------------*/

char	*name	 /* IN : data frame name */;
int dattype /* IN : data type */;
int iomode  /* IN : mode for opening of frame */;
int filtype /* IN : type no: 1 = image, 2 = mask, 3 = table  */;
int naxis   /* IN : no of dimensions of the image */;
int *npix   /* IN : size of each dimension */;
double  *start   /* IN : start coordinates: start is the address of an \
		    array of naxis elements */;
double  *step    /* IN : stepsizes : step is the address of an array of \
		    naxis elements */;
char    *ident   /* IN : ascii identifier of image */;
char    *cunit   /* IN : unit of each axis (16 char per unit) */;
char	**pntr   /* OUT: pointer to mapped data */;
int *imno   /* OUT: file no. of data frame */;


{

char  temp[84], *mypntr;

int   unit, status, kk, n;
int   tsize, size;

float lhcuts[4];


*imno = -1;			/* so it is set to something... */


/* check naxis and  npix */

if (naxis < 1)
   {
   status = ERR_INPINV;
   error_ret(name," + NAXIS < 1",9,status);
   }

for (n=0; n<naxis; n++)
   {
   if (npix[n] <= 0)
      {
      status = ERR_INPINV;
      error_ret(name," + NPIX",9,status);
      }
   }


/* Input ok -- compute total size of frame */

size = npix[0];
for (n=1; n<naxis; n++) size *= npix[n];
     

/*  create frame  */

status = SCFCRE(name,dattype,iomode,filtype,size,imno);
if (status == ERR_NORMAL) 
   status = SCFMAP(*imno,iomode,1,size,&tsize,&mypntr);
if (status != ERR_NORMAL) return status;

*pntr = mypntr;

if (iomode == F_X_MODE) 
   return status;		/* for scratch files we're already done */


/*  write standard descriptors */

status = SCDWRI(*imno,"NAXIS",&naxis,1,1,&unit);
if (status == ERR_NORMAL)
   {
   status = SCDWRI(*imno,"NPIX",npix,1,naxis,&unit);
   if (status == ERR_NORMAL)
      {
      status = SCDWRD(*imno,"START",start,1,naxis,&unit);
      if (status == ERR_NORMAL) 
         status = SCDWRD(*imno,"STEP",step,1,naxis,&unit);
      }
   }
if (status != ERR_NORMAL) return status;


/* first, create IDENT + CUNIT with correct length and fill with blanks */

memset((void *)temp,32,(size_t)80);
temp[80] = '\0';

status = SCDWRC(*imno,"IDENT",1,temp,1,72,&unit);
kk = (int)strlen(ident);
if (kk > 0) status = SCDWRC(*imno,"IDENT",1,ident,1,kk,&unit);
if (status != ERR_NORMAL) return status;

kk = (naxis+1) * 16;
if (kk > 80) kk = 80;
status = SCDWRC(*imno,"CUNIT",1,temp,1,kk,&unit);
kk = (int)strlen(cunit);
if (kk > 0) status = SCDWRC(*imno,"CUNIT",1,cunit,1,kk,&unit);
if (status != ERR_NORMAL) return status;

for (n=0; n<4; n++) lhcuts[n] = 0.0;
status = SCDWRR(*imno,"LHCUTS",lhcuts,1,4,&unit);

return status;
}
