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

/*+++++++++++++++++++++++++++ SC interface module SCDX +++++++++++++++++++++++
.LANGUAGE C
.IDENTIFICATION Module SCDB
.AUTHOR         K. Banse 		ESO - Garching
.KEYWORDS       standard interfaces, descriptors
.ENVIRONMENT    VMS and UNIX
.COMMENTS	holds xwdscdir, xSCDWRi, xSCDHWi
.NOTE           the xSCDHWi routines work only for the Yformat...

.VERSION  [1.00] 920211:  pulled out from scd.c
 090327		last modification

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

#include <stdlib.h>
#include <fileexts.h>



static char   dtype[4], help[72];
static char   realdescr[52];

static int    dblock, dindx, dunit, helpflag=0;

static struct FCT_STRUCT  *fctpntr;

/*

*/

int xwdscdir(imno,descr,bytelem,nval)

/*++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
hdnale lower level descr directory stuff common to all descr tytpes
.ALGORITHM
.RETURNS
return status  ( 0 = o.k. )
--------------------------------------------------*/

int  imno	/* IN : no. of data frame */;
char  *descr	/* IN : descriptor name */;
int  bytelem  	/* IN : CHAR*noelm  */;
int  nval	/* IN : no. of data values to write */;

{
int   status, dsclen;




dunit = 0;			/* not used yet */

fctpntr = FCT.ENTRIES + imno;
dsclen = DSCNAM_COPY(realdescr,descr);	/* build uppercase name */

status = MID_YDSCDIR(imno,'a',realdescr,dtype,&bytelem,
                     &nval,&dunit,&dblock,&dindx,help);      /* add descr */

if (dtype[0] == 'H') dtype[0] = 'h';		/* to indicate Yformat... */

fctpntr->KAUX[2] = 1;

return status;
}
/*

*/

int xSCDWRH(imno,descr,values,felem,nval)

/*++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
Write help text of a descriptor
.ALGORITHM
The help text is added and linked into the descr. entry. This routine
must be called directly after the descr itself has been written,
otherwise it is NOT safe!
.RETURNS
return status  ( 0 = o.k. )
.REMARKS
if 'felem' = -1, descriptor values are appended to existing ones
--------------------------------------------------*/

int   imno	/* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
char   *values  /* IN : buffer with descriptor data */;
int felem	/* IN : position of 1st descriptor value to be accessed */;
int nval	/* IN : no. of data values to write */;

{
int   status;





dtype[0] = 'H';
helpflag = 0;				/* only needed for old Zformat) */
status = xwdscdir(imno,descr,1,nval); 

if (status == ERR_NORMAL)
   {
   if (dtype[0] == 'H')
      (void) MID_WDSCRC(fctpntr->IOCHAN,dblock,dindx,values,0,1,nval);  
   }
else
   MID_E2(5,imno,descr,status,1);     

return (status);
}
/*

*/

int xSCDHWC(imno,descr,noelm,values,felem,nval,unit,htext)

int   imno	/* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
int noelm  	/* IN : CHAR*noelm  */;
char   *values  /* IN : buffer with descriptor data */;
int felem	/* IN : position of 1st descriptor value to be accessed */;
int nval	/* IN : no. of data values to write */;
int   *unit	/* IN : unit-pointer */;
char   *htext   /* IN : help text */;

{
help[0] = '\0';
if (htext != (char *) 0)
   {
   if (htext[0] != '\0')
      {
      (void) strncpy(help,htext,(size_t)71);
      help[71] = '\0';
      }
   }


helpflag = 1;
return (xSCDWRC(imno,descr,noelm,values,felem,nval,unit));
}


int xSCDWRC(imno,descr,noelm,values,felem,nval,unit)

/*++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
Write a descriptor and its data
.ALGORITHM
A new descriptor is written at the end of the existing 
descriptor area or exisitng descriptor data is modified
and extended, if necessary.
.RETURNS
return status  ( 0 = o.k. )
.REMARKS
if 'felem' = -1, descriptor values are appended to existing ones
--------------------------------------------------*/

int   imno	/* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
int noelm  	/* IN : CHAR*noelm  */;
char   *values  /* IN : buffer with descriptor data */;
int felem	/* IN : position of 1st descriptor value to be accessed */;
int nval	/* IN : no. of data values to write */;
int   *unit	/* IN : unit-pointer */;

{
int   status, newl;
register int  nr;



dtype[0] = 'C';	
status = xwdscdir(imno,descr,noelm,nval);

if (status == ERR_NORMAL)
   {
   newl = nval * noelm;		/* char array -> flat string */
   for (nr=0; nr<newl; nr++)
      {
      if (values[nr] == '\0')		/* we don't have enough data */
         {
         char  *xpntr, *zpntr;
         int   kk;
         register int mr;

         kk = nr;
         xpntr = malloc((size_t)newl);
         if (xpntr == (char *) 0)
            {
            xpntr = values;
            newl = kk;			/* all what we can do ...  */
            }
         else
            {
            zpntr = xpntr;
            (void) strcpy(zpntr,values);	/* first, copy the data */
            zpntr += kk;
            for (mr=kk; mr<newl; mr++)	/* then, pad with blanks */
               *zpntr++ = ' ';
            }

         (void) MID_WDSCRC(fctpntr->IOCHAN,dblock,dindx,xpntr,0,1,newl);
         free(xpntr);		/* free allocated memory again */
         return status;
         }
      }

   (void) MID_WDSCRC(fctpntr->IOCHAN,dblock,dindx,values,0,1,newl);
   }
else
   MID_E2(5,imno,descr,status,1);

return (status);
}
/*

*/

int xSCDHWD(imno,descr,values,felem,nval,unit,htext)

int   imno	/* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
double *values  /* IN : buffer with descriptor data */;
int felem	/* IN : position of 1st descriptor value to be accessed */;
int  nval	/* IN : no. of data values to write */;
int   *unit	/* IN : unit-pointer */;
char   *htext   /* IN : help text */;

{
help[0] = '\0';
if (htext != (char *) 0)
   {
   if (htext[0] != '\0')
      {
      (void) strncpy(help,htext,(size_t)71);
      help[71] = '\0';
      }
   }

helpflag = 1;
return (xSCDWRD(imno,descr,values,felem,nval,unit));
}


int xSCDWRD(imno,descr,values,felem,nval,unit)

/*++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
Write a descriptor and its data
.ALGORITHM
  A new descriptor is written at the end of the existing 
  descriptor area or existing descriptor data is modified
  and extended, if necessary.
.RETURNS
return status  ( 0 = o.k. )
.REMARKS
if 'felem' = -1, descriptor values are appended to existing ones
--------------------------------------------------*/

int   imno	/* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
double *values  /* IN : buffer with descriptor data */;
int felem	/* IN : position of 1st descriptor value to be accessed */;
int  nval	/* IN : no. of data values to write */;
int   *unit	/* IN : unit-pointer */;

{
int   n, newlen, status, *ipntr;


	

dtype[0] = 'D';	
status = xwdscdir(imno,descr,DD_SIZE,nval);

if (status == ERR_NORMAL) 
   {		     /* use MID_WDSCRI to write double precision descr... */
   n = DD_SIZE/II_SIZE;
   newlen = n * nval;
   ipntr = (int *) values;
   (void) MID_WDSCRI(fctpntr->IOCHAN,dblock,dindx,ipntr,0,1,newlen);
   }
else
   MID_E2(5,imno,descr,status,1);
return (status);
}
/*

*/

int xSCDHWS(imno,descr,values,felem,nval,unit,htext)

int   imno	/* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
size_t *values  /* IN : buffer with descriptor data */;
int felem	/* IN : position of 1st descriptor value to be accessed */;
int  nval	/* IN : no. of data values to write */;
int   *unit	/* IN : unit-pointer */;
char   *htext   /* IN : help text */;

{
help[0] = '\0';
if (htext != (char *) 0)
   {
   if (htext[0] != '\0')
      {
      (void) strncpy(help,htext,(size_t)71);
      help[71] = '\0';
      }
   }

helpflag = 1;
return (xSCDWRS(imno,descr,values,felem,nval,unit));
}


int xSCDWRS(imno,descr,values,felem,nval,unit)

/*++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
Write a descriptor and its data
.ALGORITHM
  A new descriptor is written at the end of the existing 
  descriptor area or existing descriptor data is modified
  and extended, if necessary.
.RETURNS
return status  ( 0 = o.k. )
.REMARKS
if 'felem' = -1, descriptor values are appended to existing ones
--------------------------------------------------*/

int   imno	/* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
size_t *values  /* IN : buffer with descriptor data */;
int felem	/* IN : position of 1st descriptor value to be accessed */;
int  nval	/* IN : no. of data values to write */;
int   *unit	/* IN : unit-pointer */;

{
int   n, newlen, status, *ipntr;


	

dtype[0] = 'S';	
status = xwdscdir(imno,descr,SS_SIZE,nval);

if (status == ERR_NORMAL) 
   {		     /* use MID_WDSCRI to write size_t descr... */
   n = SS_SIZE/II_SIZE;
   newlen = n * nval;
   ipntr = (int *) values;
   (void) MID_WDSCRI(fctpntr->IOCHAN,dblock,dindx,ipntr,0,1,newlen);
   }
else
   MID_E2(5,imno,descr,status,1);
return (status);
}
/*

*/

int xSCDHWL(imno,descr,values,felem,nval,unit,htext)

int   imno	/* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
int *values  /* IN : buffer with descriptor data */;
int felem	/* IN : position of 1st descriptor value to be accessed */;
int  nval	/* IN : no. of data values to write */;
int   *unit	/* IN : unit-pointer */;
char   *htext   /* IN : help text */;

{
help[0] = '\0';
if (htext != (char *) 0)
   {
   if (htext[0] != '\0')
      {
      (void) strncpy(help,htext,(size_t)71);
      help[71] = '\0';
      }
   }

helpflag = 1;
return (xSCDWRL(imno,descr,values,felem,nval,unit));
}


int xSCDWRL(imno,descr,values,felem,nval,unit)
 
/*++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
Write a descriptor and its data
.ALGORITHM
  A new descriptor is written at the end of the existing
  descriptor area or exisitng descriptor data is modified
  and extended, if necessary.
.RETURNS
return status  ( 0 = o.k. )
.REMARKS
if 'felem' = -1, descriptor values are appended to existing ones
--------------------------------------------------*/

int   imno      /* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
int *values  /* IN : buffer with descriptor data */;
int felem       /* IN : position of 1st descriptor value to be accessed */;
int  nval       /* IN : no. of data values to write */;
int   *unit     /* IN : unit-pointer */;

{
int   status;




dtype[0] = 'L';
status = xwdscdir(imno,descr,II_SIZE,nval);

if (status == ERR_NORMAL)
   (void) MID_WDSCRI(fctpntr->IOCHAN,dblock,dindx,values,0,1,nval);
else
   MID_E2(5,imno,descr,status,1);
return (status);
}
/*

*/

int xSCDHWI(imno,descr,values,felem,nval,unit,htext)

int   imno	/* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
int *values  /* IN : buffer with descriptor data */;
int felem	/* IN : position of 1st descriptor value to be accessed */;
int  nval	/* IN : no. of data values to write */;
int   *unit	/* IN : unit-pointer */;
char   *htext   /* IN : help text */;

{
help[0] = '\0';
if (htext != (char *) 0)
   {
   if (htext[0] != '\0')
      {
      (void) strncpy(help,htext,(size_t)71);
      help[71] = '\0';
      }
   }

helpflag = 1;
return (xSCDWRI(imno,descr,values,felem,nval,unit));
}


int xSCDWRI(imno,descr,values,felem,nval,unit)
 
/*++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
Write a descriptor and its data
.ALGORITHM
  A new descriptor is written at the end of the existing 
  descriptor area or exisitng descriptor data is modified
  and extended, if necessary.
.RETURNS
return status  ( 0 = o.k. )
.REMARKS
if 'felem' = -1, descriptor values are appended to existing ones
--------------------------------------------------*/

int   imno	/* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
int *values  /* IN : buffer with descriptor data */;
int felem	/* IN : position of 1st descriptor value to be accessed */;
int  nval	/* IN : no. of data values to write */;
int   *unit	/* IN : unit-pointer */;

{
int   status;




dtype[0] = 'I';
status = xwdscdir(imno,descr,II_SIZE,nval);
	
if (status == ERR_NORMAL)
   (void) MID_WDSCRI(fctpntr->IOCHAN,dblock,dindx,values,0,1,nval);
else
   MID_E2(5,imno,descr,status,1);
return (status);
}
/*

*/

int xSCDHWR(imno,descr,values,felem,nval,unit,htext)

int   imno	/* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
float *values  /* IN : buffer with descriptor data */;
int felem	/* IN : position of 1st descriptor value to be accessed */;
int  nval	/* IN : no. of data values to write */;
int   *unit	/* IN : unit-pointer */;
char   *htext   /* IN : help text */;

{
help[0] = '\0';
if (htext != (char *) 0)
   {
   if (htext[0] != '\0')
      {
      (void) strncpy(help,htext,(size_t)71);
      help[71] = '\0';
      }
   }

helpflag = 1;
return (xSCDWRR(imno,descr,values,felem,nval,unit));
}



int xSCDWRR(imno,descr,values,felem,nval,unit)

/*++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
Write a descriptor and its data
.ALGORITHM
  A new descriptor is written at the end of the existing 
  descriptor area or exisitng descriptor data is modified
  and extended, if necessary.
.RETURNS
return status  ( 0 = o.k. )
.REMARKS
if 'felem' = -1, descriptor values are appended to existing ones
--------------------------------------------------*/

int   imno	/* IN : no. of data frame */;
char   *descr   /* IN : descriptor name (max. 48 char.) */;
float *values  /* IN : buffer with descriptor data */;
int felem	/* IN : position of 1st descriptor value to be accessed */;
int  nval	/* IN : no. of data values to write */;
int   *unit	/* IN : unit-pointer */;

{
int   status;




dtype[0] = 'R';
status = xwdscdir(imno,descr,RR_SIZE,nval);
	

if (status == ERR_NORMAL)
      (void) MID_WDSCRR(fctpntr->IOCHAN,dblock,dindx,values,0,1,nval);
else
    MID_E2(5,imno,descr,status,1);
return (status);
}

