/*===========================================================================
  Copyright (C) 1993-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 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding 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
===========================================================================*/

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.IDENTifer   PLFRM3
.AUTHOR      R.M. van Hees IPG-ESO Garching
.KEYWORDS    perspective plots
.LANGUAGE    C
.PURPOSE     Draws a perspective frame including tickmarks and labels
     input:   float xwcfrm[4]   axis definition for x: min, max & tick marks
                    ywcfrm[4]   axis definition for y: min, max & tick marks
                    zwcfrm[4]   axis definition for y: min, max & tick marks
              char  *labelx     label along X-axis
                    *labely     label along Y-axis
                    *labelz     label along Y-axis
              float angle[2]    altitude and azimuth
              float scale       scale of the Z coordinate

.COMMENTS    the axes are only drawn if PLMODE is greater than zero
.ENVIRONment MIDAS and AGL
             #include <agl.h>           Prototypes for AGL application programs
             #include <midas_def.h>     Prototypes for MIDAS interfaces
             #include <plot_def.h>      Symbols used by the PLT interfaces

.VERSION     1.3     16-Dec-1993   made it FORTRAN 2 C friendly, RvH
             1.2     14-Dec-1993   removed some small bugs, RvH
             1.1     10-Sep-1993   Creation by R.M. van Hees

090422		last modif
------------------------------------------------------------*/
/*
 * Define _POSIX_SOURCE to indicate
 * that this is a POSIX program
 */
#define  _POSIX_SOURCE 1

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

#include <midas_def.h>

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

#define SMALL_AX	1

/*
 * here start the code of the function
 */
#ifdef __STDC__
      void PLFRM3( float *xwcfrm, float *ywcfrm, float *zwcfrm, 
                   char *labelx, char *labely, char *labelz, 
                   float *angle, float scale )
#else
      void PLFRM3(xwcfrm, ywcfrm, zwcfrm, labelx, labely, labelz, angle, scale)
      float *xwcfrm, *ywcfrm, *zwcfrm, *angle, scale;
      char  *labelx, *labely, *labelz;
#endif

{
register int ii, xyz;

int    actvals, ltype, nval, axis, tmarks[PLDIM3];
float  scof[2], wcfram[PLDIM3 * 4], tkstr[PLDIM3], tkend[PLDIM3], 
       adat[PLDIM3][7], ends[PLDIM3][4];
char   *label, format[9], tkfrm[10], text[81];

float  halfpi  = 0.5 * PI,
       rad2deg = 180 / PI;

struct Odata  data[2 * PLDIM3];
struct Pdata  proj[2 * PLDIM3];

/*
 * set character and symbol sizes for the MIDAS layout
 */
PCTSET();

/*
 * Store the old line style, and set line style to solid
 */
(void) AG_IGET( "lstyl", &ltype );
AG_SSET( "lstyl=0" );

/*
 * get the order right
 */
for ( xyz = 0; xyz < PLDIM3; xyz++ ) 
    { switch ( xyz )
         { case 1: 
               axis = FOR_Y;
               for ( ii = 0; ii < 4; ii++ ) wcfram[ii+axis] = ywcfrm[ii];
               break;
           case 2:
               axis = FOR_Z; 
               for ( ii = 0; ii < 4; ii++ ) wcfram[ii+axis] = zwcfrm[ii];
               break;
           default:
               axis = FOR_X;
               for ( ii = 0; ii < 4; ii++ ) wcfram[ii+axis] = xwcfrm[ii];
               break;
          }
      GETTIC( wcfram + axis, tkstr+xyz, tkend+xyz );
      adat[xyz][0] = MYMIN( *(wcfram+axis), *(wcfram+axis+1) );
      adat[xyz][1] = MYMAX( *(wcfram+axis), *(wcfram+axis+1) );
      adat[xyz][4] = *(wcfram+axis+2);
      adat[xyz][5] = MYMIN( *(wcfram+axis+2), *(wcfram+axis+3) );
      adat[xyz][6] = 0.0;

      adat[xyz][2] = MYMIN( tkstr[xyz], tkend[xyz] );
      adat[xyz][3] = MYMAX( tkstr[xyz], tkend[xyz] );
   }
/*
 * The matrix DATA contains the start and end values of the axes in (x,y,z).
 * The function GETPROJ will be used to project them to (X,Y) in viewport
 *     coordinates, but first we have to store the values properly in DATA.
 */
nval = 2 * PLDIM3;
for ( ii = 0; ii < nval; ii++ )
    { data[ii].xx = adat[0][0];
      data[ii].yy = adat[1][0];
      data[ii].zz = adat[2][0];
    }
data[1].xx = adat[0][1];
data[3].yy = adat[1][1];
data[5].zz = adat[2][1];

/*
 * Get start and end positions of the axes projected in viewport coordinates
 */
scof[0] = scale;
scof[1] = 0.0;
GETPROJ( wcfram, angle, scof, nval, data, proj );
for ( xyz = ii = 0; xyz < PLDIM3; xyz++ )
    { ends[xyz][0] = (float) proj[ii].px;
      ends[xyz][1] = (float) proj[ii++].py;
      ends[xyz][2] = (float) proj[ii].px;
      ends[xyz][3] = (float) proj[ii++].py;
    }
/*
 * calculate angle of the tickmarks
 */
if ( ends[1][2] - ends[1][0] != 0.0 )
   adat[0][6] = (float) atan2( ends[1][3]-ends[1][1], ends[1][2]-ends[1][0] );
else
   { adat[0][6] = halfpi; 
     if ( ends[1][3] - ends[1][1] < 0.0 ) adat[0][6] *= -1;
   }
adat[0][6] *= rad2deg;

if ( ends[0][2] - ends[0][0] != 0.0 )
   adat[1][6] = (float) atan2( ends[0][3]-ends[0][1], ends[0][2]-ends[0][0] )
                + PI;
else
   { adat[1][6] = halfpi; 
     if ( ends[0][3] - ends[0][1] < 0.0 ) adat[1][6] *= -1;
   }
adat[1][6] *= rad2deg;

/*
 * let the axes start from the right position
 */
tmarks[2] = 3;
if ( angle[1] <= 90.0 )
   { 
/*
 * translate the z-axis along the y-axis
 */
     ends[2][3] += ends[1][3] - ends[2][1];
     ends[2][0] = ends[1][2];
     ends[2][1] = ends[1][3];
     ends[2][2] = ends[2][0];
     adat[2][6] = adat[1][6];          /* z-tickmarks parallel to the x-axis */
     tmarks[0] = 2;
     tmarks[1] = 3;
   }
else if ( angle[1] <= 180.0 )
   { 
/*
 * translate the x-axis along the y-axis
 */
     ends[0][2] += ends[1][2] - ends[0][0];
     ends[0][3] += ends[1][3] - ends[0][1];
     ends[0][0] = ends[1][2];
     ends[0][1] = ends[1][3];
/*
 * translate the z-axis to the end of the x-axis
 */
     ends[2][3] += ends[0][3] - ends[2][1];
     ends[2][0] = ends[0][2];
     ends[2][1] = ends[0][3];
     ends[2][2] = ends[2][0];
     adat[2][6] = adat[0][6];          /* z-tickmarks parallel to the y-axis */
     tmarks[0] = tmarks[1] = 3;
   }
else if ( angle[1] <= 270.0 )
   { 
/*
 * translate the y-axis and the z-axis along the x-axis
 */
     ends[1][2] += ends[0][2] - ends[1][0];
     ends[1][3] += ends[0][3] - ends[1][1];
     ends[1][0] = ends[0][2];
     ends[1][1] = ends[0][3];
     ends[2][3] += ends[0][3] - ends[2][1];
     ends[2][0] = ends[0][2];
     ends[2][1] = ends[0][3];
     ends[2][2] = ends[2][0];
/*
 * translate the x-axis along the y-axis
 */
     ends[0][0] += ends[1][2] - ends[0][2];
     ends[0][1] += ends[1][3] - ends[0][3];
     ends[0][2] = ends[1][2];
     ends[0][3] = ends[1][3];
     adat[2][6] = adat[1][6] - 180;    /* z-tickmarks parallel to the x-axis */
     tmarks[1] = 2;
     tmarks[0] = 3;
   }
else 
   { 
/*
 * translate the y-axis along the y-axis
 */
     ends[1][2] += ends[0][2] - ends[1][0];
     ends[1][3] += ends[0][3] - ends[1][1];
     ends[1][0] = ends[0][2];
     ends[1][1] = ends[0][3];
     adat[2][6] = adat[0][6] - 180;    /* z-tickmarks parallel to the y-axis */
     tmarks[0] = tmarks[1] = 2;
   }
/*
 * get format and labels for the axes & draw the axes
 */
for ( xyz = 0; xyz < PLDIM3; xyz++ ) 
    { if ( xyz == 0 )
         { PCKRDC( "XFORM", 8, &actvals, format );
           label = labelx;
         }
      else if ( xyz == 1 )
         { PCKRDC( "YFORM", 8, &actvals, format );
           label = labely;
         }
      else
         { PCKRDC( "ZFORM", 8, &actvals, format );
           label = labelz;
         }
      CGN_LOWSTR( format );
      
      *tkfrm = '\0';
      if ( strncmp( format, "none", 4 ) != 0 ) 
         { (void) strcpy( tkfrm, "%" );
           (void) strncat( tkfrm, format, 8 );
         }

      if ( strlen(label) == 0 || strncmp( label, "\"\"", 2 ) == 0 ) 
         *label = '\0';

      AG_ORAX( tmarks[xyz], ends[xyz], adat[xyz], tkfrm, label );
    }
/*
 * reset LTYPE
 */
if ( ltype > 0 )
   { (void) sprintf( text, "lstyl=%1d", ltype );
     AG_SSET( text );
   }

return;
}
