/*===========================================================================
  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  SCP +++++++++++++++++++++++
.LANGUAGE C
.IDENTIFICATION Module SCP
.AUTHOR         K. Banse  	ESO - Garching
.KEYWORDS       standard interfaces, data frames
.ENVIRONMENT    VMS and UNIX
.COMMENTS holds SCPGET, SCPPUT
.VERSION [1.00]	950622:	creation

 090403		last modif
-----------------------------------------------------------------------------*/

#include <fileexts.h>			/* includes <midas_def.h> */

/*

*/

int SCPGET(imno,plandir,planno,bufadr)

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
get a plane along a major axis of a cube
.ALGORITHM
.RETURNS
return status ( ERR_NORMAL (=0) means o.k. )
.REMARKS
--------------------------------------------------------------------------*/

int imno;	/* IN: file no. of data cube */
int plandir;	/* IN: direction of plane (x, y or z) */
int planno;	/* IN: no. of plane, starting with 1 */
char *bufadr;	/* IN: address of data buffer  */


{
int   unit, nullo, status;
int   iav, xyplansiz, linsiz, felem, mm, first;
register int  nr, nrr;

char  *inpntr;

struct FCT_STRUCT  *fctpntr;

static int  old_imno = -1;
static int  naxis, npi[3];


/*  get descriptors NAXIS + NPIX  */

if (imno != old_imno)
   {
   naxis = npi[0] = npi[1] = npi[2] = 0;

   (void) SCDRDI(imno,"NAXIS",1,1,&iav,&naxis,&unit,&nullo);
   if (naxis == 0) MID_E2(12,imno,"NAXIS",ERR_INPINV,1);

   if (naxis != 3)
      {
      if ((naxis == 2) && (plandir == X_Y_PLANE) && (planno == 1))
         npi[2] = 1;
      else
         MID_E2(12,imno,"NAXIS",ERR_INPINV,1);
      }

   (void) SCDRDI(imno,"NPIX",1,naxis,&iav,npi,&unit,&nullo);
   if (npi[0] == 0) MID_E2(12,imno,"NPIX",ERR_INPINV,1);

   old_imno = imno;
   }

status = ERR_NORMAL;
if (plandir == X_Y_PLANE)
   mm = 2;
else if (plandir == X_Z_PLANE)
   mm = 1;
else if (plandir == Z_Y_PLANE)
   mm = 0;
else
   {
   MID_E2(12,imno,"plandir ",ERR_INPINV,1);
   return ERR_INPINV;
   }

if ( (planno > npi[mm]) || (planno < 1) )
   MID_E2(12,imno,"planno ",ERR_INPINV,1);


xyplansiz = npi[0] * npi[1];
fctpntr = FCT.ENTRIES + imno;

switch (plandir)
   {
  case X_Y_PLANE:			/* get x-y plane of data cube */
   first = (planno-1)*xyplansiz + 1;

   status = SCFGET(imno,first,xyplansiz,&iav,bufadr);
   break;

  case X_Z_PLANE:			/* get x-z plane of data cube */
   linsiz = npi[0];
   first = (planno-1)*npi[0] + 1;
   inpntr = bufadr;

   for (nr=0; nr<npi[2]; nr++)
      {
      status = SCFGET(imno,first,linsiz,&iav,inpntr);
      inpntr += linsiz*fctpntr->NOBYTE;
      first += xyplansiz;   
      }
   break;

  case Z_Y_PLANE:                      /* get z-y plane of data cube */
   felem = planno;
   inpntr = bufadr;

   if (fctpntr->FILTYP > 0)
      {					/* FITS file */
      for (nr=0; nr<npi[1]; nr++)
         {
         first = felem;
         for (nrr=0; nrr<npi[2]; nrr++)
            {
            status = SCFGET(imno,first,1,&iav,inpntr);
            inpntr += fctpntr->NOBYTE;
            first += xyplansiz;
            }
         felem += npi[0];
         }
      }

   else
      {
      if (fctpntr->DATTYP != fctpntr->FORMAT)
         {
         int nobytes;
         char  dummy[24], *oldpntr;
     
         oldpntr = dummy;
         nobytes = get_byte(fctpntr->DATTYP);

         for (nr=0; nr<npi[1]; nr++)
            {
            first = felem;
            for (nrr=0; nrr<npi[2]; nrr++)
               {
               status = rddisk(imno,first,1,&iav,oldpntr);
               conv_pix(inpntr,oldpntr,fctpntr->DATTYP,fctpntr->FORMAT,1);
               inpntr += nobytes;
               first += xyplansiz;
               }
            felem += npi[0];
            }
         }
      else
         {
         for (nr=0; nr<npi[1]; nr++)
            {
            first = felem;
            for (nrr=0; nrr<npi[2]; nrr++)
               {
               status = rddisk(imno,first,1,&iav,inpntr);
               inpntr += fctpntr->NOBYTE;
               first += xyplansiz;
               }
            felem += npi[0];
            }
         }
      }
   }

return status;
}
/*

*/

int SCPPUT(imno,plandir,planno,bufadr)

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE
write a plane along a major axis of a cube
.ALGORITHM
.RETURNS
return status ( ERR_NORMAL (=0) means o.k. )
.REMARKS
--------------------------------------------------------------------------*/

int imno;	/* IN: file no. of data cube */
int plandir;	/* IN: direction of plane (x, y or z) */
int planno;	/* IN: no. of plane, starting with 1 */
char *bufadr;	/* IN: address of data buffer  */

{
int   unit, nullo, status;
int   iav, xyplansiz, linsiz, felem, mm, first;
register int  nr, nrr;

char  *inpntr;

struct FCT_STRUCT  *fctpntr;

static int  old_imno = -1;
static int  naxis, npi[3];



/*  get descriptors NAXIS + NPIX  */

status = ERR_NORMAL;
if (imno != old_imno)
   {
   naxis = npi[0] = npi[1] = npi[2] = 0;

   (void) SCDRDI(imno,"NAXIS",1,1,&iav,&naxis,&unit,&nullo);
   if (naxis == 0) MID_E2(13,imno,"NAXIS",ERR_INPINV,1);

   if (naxis != 3)
      {
      if ((naxis == 2) && (plandir == X_Y_PLANE) && (planno == 1))
         npi[2] = 1;
      else
         MID_E2(12,imno,"NAXIS",ERR_INPINV,1);
      }

   (void) SCDRDI(imno,"NPIX",1,naxis,&iav,npi,&unit,&nullo);
   if (npi[0] == 0) MID_E2(13,imno,"NPIX",ERR_INPINV,1);

   old_imno = imno;
   }

if (plandir == X_Y_PLANE)
   mm = 2;
else if (plandir == X_Z_PLANE)
   mm = 1;
else if (plandir == Z_Y_PLANE)
   mm = 0;
else
   {
   MID_E2(13,imno,"plandir ",ERR_INPINV,1);
   return ERR_INPINV;
   }

if ( (planno > npi[mm]) || (planno < 1) )
   MID_E2(13,imno,"planno ",ERR_INPINV,1);


xyplansiz = npi[0] * npi[1];
fctpntr = FCT.ENTRIES + imno;

switch (plandir)
   {
  case X_Y_PLANE:                      /* put x-y plane of data cube */
   first = (planno-1)*xyplansiz + 1;
   status = SCFPUT(imno,first,xyplansiz,bufadr);
   break;

  case X_Z_PLANE:                      /* put x-z plane of data cube */
   linsiz = npi[0];
   first = (planno-1)*npi[0] + 1;
   inpntr = bufadr;

   for (nr=0; nr<npi[2]; nr++)
      {
      status = SCFPUT(imno,first,linsiz,inpntr);
      inpntr += linsiz*fctpntr->NOBYTE;
      first += xyplansiz;
      }
   break;

  case Z_Y_PLANE:                      /* put z-y plane of data cube */
   felem = planno;
   inpntr = bufadr;

   if (fctpntr->FILTYP > 0)
      {                                 /* FITS file */
      for (nr=0; nr<npi[1]; nr++)
         {
         first = felem;
         for (nrr=0; nrr<npi[2]; nrr++)
            {
            status = SCFPUT(imno,first,1,inpntr);
            inpntr += fctpntr->NOBYTE;
            first += xyplansiz;
            }
         felem += npi[0];
         }
      }

   else
      {
      if (fctpntr->DATTYP != fctpntr->FORMAT)
         {
         int nobytes;
         char  dummy[24], *newpntr;

         newpntr = dummy;
         nobytes = get_byte(fctpntr->DATTYP);

         for (nr=0; nr<npi[1]; nr++)
            {
            first = felem;
            for (nrr=0; nrr<npi[2]; nrr++)
               {
               conv_pix(newpntr,inpntr,fctpntr->FORMAT,fctpntr->DATTYP,1);
               status = wrdisk(imno,first,1,newpntr);
               inpntr += nobytes;
               first += xyplansiz;
               }
            felem += npi[0];
            }
         }
      else
         {
         for (nr=0; nr<npi[1]; nr++)
            {
            first = felem;
            for (nrr=0; nrr<npi[2]; nrr++)
               {
               status = wrdisk(imno,first,1,inpntr);
               inpntr += fctpntr->NOBYTE;
               first += xyplansiz;
               }
            felem += npi[0];
            }
         }
      }
   }

return status;
}
