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

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.COPYRIGHT   (c) 1993 European Southern Observatory
.IDENTIFIER  PLOTPER
.AUTHOR      R.M. van Hees IPG-ESO Garching
.KEYWORDS    MIDAS plotting, three dimensionnal plots
.LANGUAGE    C
.PURPOSE     Makes three dimensional plots of a bidimensionnal image, part
             of a larger image, with smoothing option uses two rotation angles
        input: IN_A/C/1/60   = name of frame to be plotted
               IN_B/C/1/60   = coordinate string
               INPUTR/R/1/2  = view angles; default -45.0 and 30.0
               INPUTR/R/3/2  = scale and offset parameter: default 1/DATAMAX,0
               INPUTI/I/1/2  = smooting parameter: size of the smooting box
               INPUTC/C/1/2  = XY perspective lines: grid in X, or Y or X & Y

.COMMENTS    PLPER has a few restrictions:
              - features unter the surface are not shown.

.ENVIRONment MIDAS
             #include <midas_def.h>     Prototypes for MIDAS interfaces
             #include <plot_def.h>      General symbols for Plot routines

.VERSION     1.3     19-Apr-1994   negative steps are allowed, RvH
 030722		last modif
------------------------------------------------------------*/
/*
 * Define _POSIX_SOURCE to indicate
 * that this is a POSIX program
 */
#define  _POSIX_SOURCE 1

/*
 * definition of the used functions in this module
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

#define MAXPIX          512	/* maximum frame dimension (X,Y) */
#define MAXSIZ          (MAXPIX * MAXPIX)

/*
 * define some macros and constants
 */
#include <midas_def.h>
#include <plot_def.h>

/*
 * here start the code of the function
 */
int main()
{
int    actvals, imf, knul, ii, ismooth, naxis, nrpix, stat, unit, 
       sublo[2], subhi[2], ndum[PLDIM2], npix[PLDIM2], xy[2];

float  *p_img, angle[2], area[4], scales[2], image[4], wcfram[12];
float  rbuf[8];

double start[PLDIM2], step[PLDIM2];

char   second[3], name[61], cunit[49], ident[33], input[73], *label[5];

/*
 * initialised variables
 */
int   access =  0,                   /* parameter for PCOPEN: NEW plot mode  */
      plmode = -1;                     /* plot mode taken from keyword PMODE */

char  *err_1dim  = "*** FATAL: Frame has only one dimension",
      *err_size  = "*** FATAL: Frame is too large ( > 512 * 512 )",
      *err_coord = "*** FATAL: invalid coordinate input ...",
      *err_alt   = "*** WARNING: resonable values for the altitude are between 0 and 90 deg.",
      *err_azi   = "*** WARNING: resonable values for the azimuth are between 0 and 360 deg.";

static char  *axis[PLDIM3] = { "MANU", "MANU", "MANU" };

/*
 * allocate memory for different character pointers and initialise a few
 */
for ( ii = 0; ii < 5; ii++ ) label[ii] = osmmget(81);

(void) strcpy( label[0], "Position(" );
(void) strcpy( label[1], "Position(" );
(void) strcpy( label[2], "Pixel value(" );
(void) strcpy( label[3], "Frame: " );
(void) strcpy( label[4], "Ident: " );

/*
 * start of executable code
 */
(void) SCSPRO( "PLTPER" );		/*contact with the MIDAS monitor*/

ii = 1;
(void) SCPSET(F_FITS_PARM,&ii);          /* don't read in ESO.xyz keywords */


/*
 * find file name and read header information
 */
(void) SCKGETC( "IN_A", 1, 60, &actvals, name );
(void) SCFOPN( name, D_R4_FORMAT, 0, F_IMA_TYPE, &imf );
(void) SCDRDI( imf, "NAXIS", 1, 1, &actvals, &naxis, &unit, &knul );
(void) SCDRDI( imf, "NPIX" , 1, PLDIM2, &actvals, npix , &unit, &knul );
/*
 * check frame parameters
 */
if ( naxis < 2 || (npix[0] == 1 || npix[1] == 1) ) SCETER( 1, err_1dim );

/*
 * read the descriptor
 */
(void) SCDRDD( imf, "START", 1, PLDIM2, &actvals, start, &unit, &knul );
(void) SCDRDD( imf, "STEP" , 1, PLDIM2, &actvals, step , &unit, &knul );
(void) SCDGETC( imf, "IDENT", 1, 32, &actvals, ident );
(void) SCDGETC( imf, "CUNIT", 1, 48, &actvals, cunit );

/*
 * Get the manual setting for the axes
 */
PCKRDR( "XAXIS", 4, &actvals, wcfram );
PCKRDR( "YAXIS", 4, &actvals, wcfram+FOR_Y );
PCKRDR( "ZAXIS", 4, &actvals, wcfram+FOR_Z );

/*
 * read window coordinates and take action
 */
(void) SCKGETC( "IN_B", 1, 60, &actvals, input );
 
if ( *input == 'm' || *input == 'M' )		/* manual scaling */
   { BOXWTP( wcfram,       npix[0], start[0], step[0], image );
     BOXWTP( wcfram+FOR_Y, npix[1], start[1], step[1], image+2 );
   }
else
   {
   if ( *input == 'c' || *input == 'C' )	/* display input */
      {
      (void) SCKRDR("OUTPUTR",10,7,&actvals,rbuf,&unit,&knul);
      image[0] = rbuf[0];
      image[1] = rbuf[5];
      image[2] = rbuf[1];
      image[3] = rbuf[6];
      }
   else						/* automatic scaling */
        { stat = Convcoo(1,imf,input,PLDIM2,ndum,sublo,subhi);
          if ( stat != ERR_NORMAL ) SCETER( 2, err_coord );
          image[0] = sublo[0] + 1;
          image[1] = subhi[0] + 1;
          image[2] = sublo[1] + 1;
          image[3] = subhi[1] + 1;
        }
   }
BOXPTW( image,   npix[0], start[0], step[0], area );
BOXPTW( image+2, npix[1], start[1], step[1], area+2 );
PCKWRR( "PIXEL", 4, image );

/*
 * get the smooting parameter
 */
(void) SCKRDI( "INPUTI", 1, 1, &actvals, &ismooth, &unit, &knul);

/*
 * extract the data
 */
nrpix = (int)(1+fabs(image[1] - image[0])) * (1+fabs(image[3]-image[2]));
if ( nrpix > MAXSIZ ) SCETER( 3, err_size );
 
p_img = (float *) osmmget( nrpix * sizeof( float ));
GETDAT( imf, MAXSIZ, npix, image, ismooth, p_img );
(void) SCFCLO( imf );

/*
 * get size of frame along X-axis
 */
if ( fabs( *wcfram ) < PLT_EPS && fabs( *(wcfram+1) ) < PLT_EPS )
   { axis[0] = "AUTO";
     wcfram[0] = ( step[0] < 0 ) ? area[1] : area[0];
     wcfram[1] = ( step[0] < 0 ) ? area[0] : area[1]; 
     wcfram[2] = wcfram[3] = 0.0;
   }
/*
 * get size of frame along Y-axis
 */
if ( fabs( *(wcfram+FOR_Y) ) < PLT_EPS && fabs( *(wcfram+FOR_Y+1) ) < PLT_EPS )
   { axis[1] = "AUTO";
     wcfram[FOR_Y]   = ( step[1] < 0 ) ? area[3] : area[2];
     wcfram[FOR_Y+1] = ( step[1] < 0 ) ? area[2] : area[3]; 
     wcfram[FOR_Y+2] = wcfram[FOR_Y+3] = 0.0;
   }
/*
 * get size of frame along Z-axis
 */
if ( fabs( *(wcfram+FOR_Z) ) < PLT_EPS && fabs( *(wcfram+FOR_Z+1) ) < PLT_EPS )
   { axis[2] = "AUTO";
     MINMAX( p_img, nrpix, wcfram+FOR_Z, wcfram+FOR_Z+1 );
     wcfram[FOR_Z+2] = wcfram[FOR_Z+3] = 0.0;
   }
/*
 * calculate small and large tickmarks
 */
GETFRM( axis[0], wcfram );
GETFRM( axis[1], wcfram + FOR_Y );
GETFRM( axis[2], wcfram + FOR_Z );
PCKWRR( "XWNDL", 4, wcfram );
PCKWRR( "YWNDL", 4, wcfram+FOR_Y );
PCKWRR( "ZWNDL", 4, wcfram+FOR_Z );

/*
 * get angles
 */
(void) SCKRDR( "INPUTR", 1, 2, &actvals, angle, &unit, &knul);
if ( angle[0] < 0.0 || angle[0] > 90.0 )
   { SCTPUT( err_alt );
     angle[0] -= 90 * floor( angle[0] / 90 );
     if ( angle[0] < 0.0 ) angle[0] += 90.0 ;
   }
if ( angle[1] < 0.0 || angle[1] >= 360.0 )
   { SCTPUT( err_azi );
     angle[1] -= 360 * floor( angle[1] / 360 );
     if ( angle[1] < 0.0 ) angle[1] += 360.0 ;
   }
/*
 * X and/or Y grid
 */
(void) SCKGETC( "INPUTC", 1, 2, &actvals, second );
CGN_LOWSTR( second );
xy[0] = xy[1] = 0;
if ( strchr( second, 'x' ) != NULL ) xy[0] = 1;
if ( strchr( second, 'y' ) != NULL ) xy[1] = 1;

/*
 * setup graphic device according to MIDAS settings
 */
PCOPEN( " ", " ", access, &plmode );

/*
 * get the Z-axis scaling and offset
 */
(void) SCKRDR( "INPUTR", 3, 2, &actvals, scales, &unit, &knul);

/*
 * plot the data and draw the axes
 */
PLPER( wcfram, p_img, image, start, step, angle, scales, xy );

/*
 * write labels
 */
if ( plmode >= 0 )
   { if ( strlen( cunit ) > (size_t) 32 )
        { (void) strcat( label[1], cunit+32 );
          *(cunit+32) = '\0';
        }
     if ( strlen( cunit ) > (size_t) 16 )
        { (void) strcat( label[0], cunit+16 );
          *(cunit+16) = '\0';
        }
     (void) strcat( label[2], cunit );
     (void) strcat( label[3], name );
     (void) strcat( label[4], ident );

     for ( ii = 0; ii < PLDIM3; ii++ ) 
         { (void) strcat( label[ii], ")" );
           LABSTR( label[ii] );
         }
/*
 * draw the axes
 */
     PLFRM3( wcfram, wcfram+FOR_Y, wcfram+FOR_Z, label[0], label[1], label[2], 
             angle, scales[0] );

     if ( plmode == 1 )
        PLIDEN( plmode, label[3], label[4] );
     else if ( plmode == 2 )
        PLPERI( plmode, name, ident, image, angle, wcfram );
   }

/*
 * close plot file and terminate graphic operations
 */
PCCLOS();

return SCSEPI();
}

