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

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.IDENTifer   PCK
.AUTHOR      R.M. van Hees IPG-ESO Garching
.KEYWORDS    Plot keyword setting, high level plot interface
.LANGUAGE    C
.PURPOSE     Routines to read or write values in MIDAS Plot keywords
               - for reading resp. PCKRDC, PCKRDI, PCKRDR
               - for writing resp. PCKWRC, PCKWRI, PCKWRR
               - or set them to default    PCKDEF

.COMMENTS    Correspondence between parameter values and keyword:

            PARAM.NAME  POSITION DEFAULT   DESCRIPTION
            ----------  -------- -------   -----------
   KEYWORD  PLCSTAT
            BINMODE       1 -  4    OFF    bin mode "ON  " or "OFF "
            COLMODE       5 -  8    SUB    colour mode: "Sub" or "Xor"
            CLEARGRA      9 - 12    ON     erase for plot commands
            DEBUG        13 - 16    OFF    debug mode: "ON" or "OFF"
            FRAME        17 - 20    AUTO   AUTO scaling or SQUAre frame
            XFORMAT      21 - 28    AUTO   format of values along the X-axis
            YFORMAT      29 - 36    AUTO   format of values along the Y-axis
            ZFORMAT      37 - 44    AUTO   format of values along the Z-axis
            CXSC         45 - 48    WO     Coordinates for the X scale
            CYSC         49 - 52    WO     Coordinates for the Y scale
            CXOF         53 - 56    MM     Coordinates for the X offset
            CYOF         57 - 60    MM     Coordinates for the Y offset
            free         61 - 80    --     not used

   KEYWORD  PLCMETA
            PLNAME        1 - 60           name of plotfile
            free         61 - 80

   KEYWORD  PLCDATA
            DNAME         1 - 60           name of data stucture
            DTYPE        61 - 80           type of data

   KEYWORD  PLISTAT
            PMODE         1 -  1    2      pmode mode (ranging from -1 to 2)
            FONT          2 -  2    0      font used (ranging from 0 to 6)
            free          3 -  4
            LTYPE         5 -  5    1      line line (ranging from 0 to 6)
            STYPE         6 -  6    5      symbol type (ranging from 0 to 21)
            LWIDT         7 -  7    1      line width (ranging from 1 to 4)
            TWIDT         8 -  8    1      text width (ranging from 1 to 4)
            COLOUR        9 -  9    1      colour (ranging from 0 to 8)
            BCOLOR       10 - 10    0      background colour (0 to 8)
            free         11 - 40

   KEYWORD  PLRSTAT
            XAXIS         1 -  4  0,0,0,0  x axis frame limits and ticks
            YAXIS         5 -  8  0,0,0,0  y axis frame limits and ticks
            ZAXIS         9 - 12  0,0,0,0  z axis frame limits and ticks
            XSCALE       13 - 13    0.0    scale set by user in x
            YSCALE       14 - 14    0.0    scale set by user in y
            ZSCALE       15 - 15    0.0    scale set by user in z
            XOFFSET      21 - 21  -999.0   offset in mm set by user in x
            YOFFSET      22 - 22  -999.0   offset in mm set by user in y
            free         23 - 24
            SSIZE        25 - 25    1.0    symbol multiplier
            TSIZE        26 - 26    1.0    text size multiplier
            free         27 - 40

   KEYWORD  PLRGRAP
            XWNDL         1 -  4  0,0,0,0  x axis frame limits and ticks
            YWNDL         5 -  8  0,0,0,0  y axis frame limits and ticks
            ZWNDL         9 - 12  0,0,0,0  z axis frame limits and ticks
            SCALE        13 - 15      0.0  scale parameters in x, y, z
            free         16 - 20
            CLPL         21 - 24  0,0,0,0  clip coordinates in x and y
            PIXEL        25 - 28  0,0,0,0  pixel area of BDF file plotted
            OFFSET       29 - 30 -999,-999 offset parameters in x and y
            OCOUNT       31 - 31        0  overplot counter
  
.ENVIRONment MIDAS
             #include <agl.h> 		Prototypes for AGL application programs
             #include <midas_def.h>     Prototypes for MIDAS interfaces

.VERSION     1.0     06-Oct-1993   Created 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 in this module
 */
#include <stdio.h>
#include <string.h>

#include <midas_def.h>

/*
 * define some macros and constants
 */
#define MAXARR		 4
#define CNUM		20                /* number of character parameters  */
#define CDEF            12                /* number of parameters in PLCSTAT */
#define MNUM		 1                /* number of parameters in PLCMETA */
#define DNUM		 2                /* number of parameters in PLCDATA */
#define INUM		 8                /* number of parameters in PLISTAT */
#define RNUM		10                /* number of parameters in PLRSTAT */
#define GNUM		 8                /* number of parameters in PLRGRAP */

/*
 * Local external initialised variables, see also SETPLOT.C
 */ 
                                                  /* names of parameters */
static char *ckeynam[CNUM] = { "BINMODE", "COLMOD", "CLEAR",  "DEBUG", 
                               "FRAME",   "XFORM",  "YFORM",  "ZFORM", 
                               "CXSC",    "CYSC",   "CXOF",   "CYOF",
                               "XAXIS",   "YAXIS",  "ZAXIS",  "XSCALE", 
                               "YSCALE",  "ZSCALE", "XOFF",   "YOFF"},
            *mkeynam[MNUM] = { "PLNAM" },
            *dkeynam[DNUM] = { "DNAME",   "DTYPE" },
            *ikeynam[INUM] = { "PMODE",   "FONT",   "LTYPE",  "STYPE", "LWIDTH", 
                               "TWIDTH",  "COLOUR", "BCOLOUR" },
            *rkeynam[RNUM] = { "XAXIS",   "YAXIS",  "ZAXIS", 
                               "XSCALE",  "YSCALE", "ZSCALE", 
                               "XOFF",    "YOFF",   "SSIZE",  "TSIZE" },
            *gkeynam[GNUM] = { "XWNDL",   "YWNDL",  "ZWNDL",  "SCALE",
                               "CLPL",    "PIXEL",  "OFFSET", "OCOUNT" };

              /* minimum number op characters needed to identify a parameter */
              /* Note that we here only have to identify char from char, int
                 from int and real from real....                             */
static int ckeyiden[CNUM] = { 2, 4, 2, 2, 
                              2, 2, 2, 2, 
                              3, 3, 3, 3,
                              2, 2, 2, 2, 
                              2, 2, 2, 2},
           mkeyiden[MNUM] = { 2 }, 
           dkeyiden[DNUM] = { 2, 2 },
           ikeyiden[INUM] = { 2, 2, 2, 2, 2, 
                              2, 4, 2 },
           rkeyiden[RNUM] = { 2, 2, 2, 
                              3, 3, 3, 
                              2, 2, 2, 2 }, 
           gkeyiden[GNUM] = { 2, 2, 2, 2, 
                              2, 2, 3, 2 };

                                                  /* dimension of parameters */
static int ckeylen[CDEF]  = { 4, 4, 4, 4, 4, 
                              8, 8, 8, 
                              4, 4, 4, 4},
           mkeylen[MNUM]  = { 60 }, 
           dkeylen[DNUM]  = { 60, 20 },
           ikeylen[INUM]  = { 1, 1, 1, 1, 1, 1, 1, 1 },
           rkeylen[RNUM]  = { 4, 4, 4, 1, 1, 1, 1, 1, 1, 1 },
           gkeylen[GNUM]  = { 4, 4, 4, 3, 4, 4, 2, 1 };

                                   /* position of parameters in the keywords */
static int ckeypnt[CDEF]  = { 1, 5, 9, 13, 
                              17, 21, 29, 37,
                              45, 49, 53, 57},
           mkeypnt[MNUM]  = { 1 }, 
           dkeypnt[DNUM]  = { 1, 61 },
           ikeypnt[INUM]  = { 1, 2, 5, 6, 7, 8, 9, 10 },
           rkeypnt[RNUM]  = { 1, 5, 9, 13, 14, 15, 21, 22, 25, 26 },
           gkeypnt[GNUM]  = { 1, 5, 9, 13, 21, 25, 29, 31 };

                                                           /* default values */
static char *ckeydef[]    = { "OFF ", "SUB ", "ON  ", "OFF ", 
                              "AUTO", "G       ", "G       ", "G       ", 
                              "WO  ", "WO  ", "MM  ", "MM  "};
static int   ikeydef[]    = { 2, 0, 0, 0, 1, 5, 1, 1, 1, 0 };
static float rkeydef[]    = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
                              0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
                             -999.0, -999.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 },
             gkeydef[]    = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
                              0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                              0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -999.0, -999.0 ,
                              0.0 };

/*++++++++++++++++++++++++++++++
.IDENTifer   CHECK_FMT
.PURPOSE     checks a given format
    in/output: char *format  string with given format

.COMMENTS    SCETER is called if a not allowed format is given
--------------------------------*/
#ifdef  __STDC__
      static void CHECK_FMT( char *format )
#else
      static void CHECK_FMT( format )
      char *format;
#endif
{
register int ii;

int  len;
char *buff;

static int  nallow   = 22;
static char *allowed = ".0123456789IFEDGPXAHUMS",
            *err_fmt = "WARNING from PCK: a unknown format is given!";
ii = 0;
while ( ii < nallow && *format != allowed[ii] ) ii++;

if ( ii == nallow )
   SCETER( 10, err_fmt );
else
   { if ( (len = strlen( format )) > 1 && ii > 10 && ii < 14 )
        { buff = osmmget( len+1 );
          (void) strcpy( buff, format );
          (void) strcpy( format, buff+1);
          if ( ii == 11 ) 
             (void) strcat( format, "D" );
          else if ( ii == 12 ) 
             (void) strcat( format, "F" );
          else 
             (void) strcat( format, "E" );
          (void) osmmfree( buff );
        }
   }
}

/*++++++++++++++++++++++++++++++
.IDENTifer   PCKRDC
.PURPOSE     Reads character values from keyword PLCSTAT, PLCMETA or PLCDATA
        input: char *cpar    name of the parameter to be read
               int  maxvals  maximum number of characters to be read
       output: int  *actvals actual number of characters in CVAL
               char *cval    value(s) for the parameter 
--------------------------------*/
void PCKRDC( cpar, maxvals, actvals, cval )
char *cpar, *cval;
int  maxvals, *actvals;

{
char text[81];
register int nc, nm, nd;

char *err_inp = "*** FATAL: PCKRDC, not existing character keyword: %s";

/*
 * Is it a parameter from PLCSTAT?
 */
nc = 0;
while ( nc < CDEF && strncmp( cpar, ckeynam[nc], ckeyiden[nc] ) != 0 ) nc++;
if ( nc < CDEF )
   { 
   (void) SCKGETC( "PLCSTAT", ckeypnt[nc], maxvals, actvals, cval );
   return;
   }
/*
 * Is it a parameter from PLCMETA?
 */
nm = 0;
while ( nm < MNUM && strncmp( cpar, mkeynam[nm], mkeyiden[nm] ) != 0 ) nm++;
if ( nm < MNUM )
   { (void) SCKGETC( "PLCMETA", mkeypnt[nm], maxvals, actvals, cval );
     return;
   }
/*
 * Is it a parameter from PLCDATA?
 */
nd = 0;
while ( nd < DNUM && strncmp( cpar, dkeynam[nd], dkeyiden[nd] ) != 0 ) nd++;
if ( nd < DNUM )
   { (void) SCKGETC( "PLCDATA", dkeypnt[nd], maxvals, actvals, cval );
     return;
   }

(void) sprintf( text, err_inp, cpar );
SCETER( 1, text );
}

/*++++++++++++++++++++++++++++++
.IDENTifer   PCKRDI
.PURPOSE     Reads integer values from keyword PLISTAT
        input: char *ipar    name of a variable in PLISTAT
               int  maxvals  maximum number of integers to be read
       output: int  *actvals actual number of integers in IVAL
               int  *ival    value(s) for the parameter 
--------------------------------*/
void PCKRDI( ipar, maxvals, actvals, ival )
char *ipar;
int  maxvals, *actvals, *ival;

{
int  knul, unit;
char text[81];
register int ni;

char *err_inp = "*** FATAL: PCKRDI, not existing integer keyword: %s";

/*
 * which parameter has to be set?
 */
ni = 0;
while ( ni < INUM && strncmp( ipar, ikeynam[ni], ikeyiden[ni] ) != 0 ) ni++;

if ( ni >= INUM )
   { (void) sprintf( text, err_inp, ipar );
     SCETER( 1, text );
   }
else
   (void) SCKRDI( "PLISTAT", ikeypnt[ni], maxvals, 
                                          actvals, ival, &unit, &knul );
return;
}

/*++++++++++++++++++++++++++++++
.IDENTifer   PCKRDR
.PURPOSE     Reads real values from keyword PLRSTAT or PLRGRAP
        input: char  *rpar    name of a variable in PLRSTAT or PLRGRAP
               int   maxvals  maximum number of reals to be read
       output: int   *actvals actual number of reals in RVAL
               float *rval    value(s) for the parameter 
--------------------------------*/
void PCKRDR( rpar, maxvals, actvals, rval )
char  *rpar; 
int   maxvals, *actvals; 
float *rval;

{
int  knul, unit;
char text[81];
register int nr, ng;

char *err_inp = "*** FATAL: PCKRDR, not existing real keyword: %s";

/*
 * Is it a parameter from PLRSTAT?
 */
nr = 0;
while ( nr < RNUM && strncmp( rpar, rkeynam[nr], rkeyiden[nr] ) != 0 ) nr++;

if ( nr < RNUM )
   { (void) SCKRDR( "PLRSTAT", rkeypnt[nr], maxvals, 
                                            actvals, rval, &unit, &knul);
     return;
   }
/*
 * Is it a parameter from PLRGRAP?
 */
ng = 0;
while ( ng < GNUM && strncmp( rpar, gkeynam[ng], gkeyiden[ng] ) != 0 ) ng++;

if ( ng < GNUM )
   { (void) SCKRDR( "PLRGRAP", gkeypnt[ng], maxvals, 
                                            actvals, rval, &unit, &knul);
     return;
   }

(void) sprintf( text, err_inp, rpar );
SCETER( 1, text );
}

/*++++++++++++++++++++++++++++++
.IDENTifer   PCKWRR
.PURPOSE     Writes real values in keyword PLRSTAT
        input: char  *rpar    name of a variable in PLRSTAT
               int   nrval    number of values to be written
                              nrval = 0 ==> set RPAR to default
               float *rval    value(s) for the parameter 
--------------------------------*/

void PCKWRR( rpar, nrval, rval )
char  *rpar; 
int   nrval; 
float *rval;

{
int  actvals, unit;
char debug[5], text[81];
register int  nr, ng;

char *err_inp  = "*** FATAL: PCKWRR, not existing real keyword: %s",
     *err_num  = "*** WARNING: PCKWRR, you gave %-d values, only %-d will be stored",
     *err_xaxs = "*** FATAL: Specify at least x-start and x-end values",
     *err_off  = "*** FATAL: Offset must be larger than 0.0",
     *err_xtic = "*** FATAL: You cannot have a LOG axis without specifying the big ticks";

/*
 * Suppress AGL messages if (MIDAS) DEBUG mode is OFF 
 */
PCKRDC( "DEBUG", 4, &actvals, debug );
if ( strncmp( debug, "ON", 2 ) != 0 ) AG_SSET( "msgs" );

/*
 * do we have to set a parameter of PLRGRAP?
 */
ng = 0;
while ( ng < GNUM && strncmp( rpar, gkeynam[ng], gkeyiden[ng] ) != 0 ) ng++;

if ( ng < GNUM )
   { if ( nrval == 0 ) 
        (void) SCKWRR( "PLRGRAP", gkeydef+(gkeypnt[ng]-1), 
                                  gkeypnt[ng], gkeylen[ng], &unit );
     else 
        { if ( ng == 6 && ((*rval < 0 && *rval != -999.0)          /* OFFSET */
                   || (*(rval+1) < 0 && *(rval+1) != -999.0)) )
               SCETER( 1, err_off );

          if ( nrval > gkeylen[ng] )
             { (void) sprintf( text, err_num, nrval, gkeylen[ng] );
               SCTPUT( text );
               nrval = gkeylen[ng];
             }
          (void) SCKWRR( "PLRGRAP", rval, gkeypnt[ng], nrval, &unit );
        }
     return; 
   }
/*
 * do we have to set a parameter of PLRSTAT?
 */
nr = 0;
while ( nr < RNUM && strncmp( rpar, rkeynam[nr], rkeyiden[nr] ) != 0 ) nr++;

if ( nr < RNUM )
   { if ( nrval == 0 )
        { (void) SCKWRR( "PLRSTAT", rkeydef+(rkeypnt[nr]-1), 
                                    rkeypnt[nr], rkeylen[nr], &unit );
          if ( nr == 8 )
             { (void) sprintf( text, "sydi=%-.3f", rkeydef[nr] );
               AG_SSET( text ); 
             }
          else if ( nr == 9 )
             { (void) sprintf(text,"chdi=%-.3f,%-.3f",rkeydef[nr],rkeydef[nr]);
               AG_SSET( text ); 
             }
        }
     else
/*
 * check if we have to write a resonable value
 */
        { switch( nr )
             { case 0:                                       /* XAXIS */
               case 1:                                       /* YAXIS */
               case 2:                                       /* ZAXIS */
                   if ( nrval < 2 ) 
                      SCETER( 2, err_xaxs );
                   else if ( *(rval+3) < 0.0 && *(rval+2) == 0.0 ) 
                      SCETER( 3, err_xtic );
                   else if ( nrval < rkeylen[nr] )
                      { while ( nrval < rkeylen[nr] ) rval[nrval++] = 0;
                        GETFRM( "MANU", rval );
                      }
                   break;
               case 6:                                       /* XOFFS */
               case 7:                                       /* YOFFS */
                   if ( *rval < 0 && *rval != -999.0 )
                      SCETER( 4, err_off );
                   break;
               case 8:                                       /* SSIZE */
                   if ( *rval < 0 )
                      SCETER( 5, "*** FATAL: Illegal symbol size" );
                   else
                      { (void) sprintf( text, "sydi=%-.3f", *rval );
                        AG_SSET( text ); 
                      }
                   break;
               case 9:                                       /* TSIZE */
                   if ( *rval < 0 )
                      SCETER( 6, "*** FATAL: Illegal text size" );
                   else
                      { (void) sprintf(text, "chdi=%-.3f,%-.3f", *rval, *rval);
                        AG_SSET( text ); 
                      }
                   break;
             }
          if ( nrval > rkeylen[nr] )
             { (void) sprintf( text, err_num, nrval, rkeylen[nr] );
               SCTPUT( text );
               nrval = rkeylen[nr];
             }
          (void) SCKWRR( "PLRSTAT", rval, rkeypnt[nr], nrval, &unit );
        }
     return; 
   }
else
   { (void) sprintf( text, err_inp, rpar );
     SCETER( 7, text );
   }
}

/*++++++++++++++++++++++++++++++
.IDENTifer   PCKWRI
.PURPOSE     Writes integer values in keyword PLISTAT
        input: char  *ipar    name of a variable in PLISTAT
               int   nrval    number of values to be written
                              nrval = 0 ==> set IPAR to default
               int   *ival    value(s) for the parameter 
-------------------------------*/
void PCKWRI( ipar, nrval, ival )
char *ipar;
int  nrval, *ival;

{
int  actvals, unit;
char debug[5], text[81];
register int ni; 

char *err_inp   = "*** FATAL: PCKWRI, not existing integer keyword: %s",
     *err_num   = "*** WARNING: PCKWRI, you gave %-d values, only %-d will be stored";
/*
 * Suppress AGL messages if (MIDAS) DEBUG mode is OFF 
 */
PCKRDC( "DEBUG", 4, &actvals, debug );
if ( strncmp( debug, "ON", 2 ) != 0 ) AG_SSET( "msgs" );

/*
 * which parameter has to be set?
 */
ni = 0;
while ( ni < INUM && strncmp( ipar, ikeynam[ni], ikeyiden[ni] ) != 0 )
      ni++;

if ( ni < INUM ) 
   { if ( nrval == 0 ) 
        (void) SCKWRI( "PLISTAT", ikeydef+(ikeypnt[ni]-1), 
                                  ikeypnt[ni], ikeylen[ni], &unit );
     else 
        { if ( ni == 0 )				/* PLOT MODE */
             { if ( *ival < -1 || *ival > 2 )
                  SCETER( 1, "*** FATAL: Unknown plot mode" );
             }
          else if ( ni == 1 )                           /* FONT */
             { if ( *ival < 0 || *ival > 6 )
                  SCETER( 2, "*** FATAL: Unknown font type" );
               else
                  { (void) sprintf( text, "font=%1d", *ival );
                    AG_SSET( text );
                  }
             }
          else if ( ni == 2 )                           /* LTYPE */
             { if ( *ival < 0 || *ival > 6 )
                  SCETER( 3, "*** FATAL: Unknown line type" ); 
               else
                  { (void) sprintf( text, "lstyl=%1d", *ival - 1 );
                    AG_SSET( text );
                  }
             }
          else if ( ni == 3 )                           /* STYPE */
             { if ( *ival < 0 || (*ival > 21 && *ival < 32) || *ival > 126 )
                  SCETER( 4, "*** FATAL: Unknown symbol type" );
             }
          else if ( ni == 4 )                           /* LWIDTH */
             { if ( *ival < 1 || *ival > 4 )
                  SCETER( 5, "*** FATAL: Unknown line width" );
               else
                  { (void) sprintf( text, "lwidt=%1d", *ival - 1 );
                    AG_SSET( text );
                  }
             }
          else if ( ni ==  5 )                          /* TWIDTH */
             { if ( *ival < 1 || *ival > 4 )
                  SCETER( 6, "*** FATAL: Unknown text width" );
               else
                  { (void) sprintf( text, "twidt=%1d", *ival );
                    AG_SSET( text );
                  }
             }
          else if ( ni ==  6 )                          /* COLOUR */
             { if ( *ival < 0 || *ival > 8 )
                  SCETER( 7, "*** FATAL: Unknown colour" );
               else
                  { (void) sprintf( text, "color=%1d", *ival );
                    AG_SSET( text );
                  }
             }
          else                                          /* BCOLOUR */
             { if ( *ival < 0 || *ival > 8 )
                  SCETER( 8, "*** FATAL: Unknown backgound colour" );
               else
                  { (void) sprintf( text, "back=%1d", *ival );
                    AG_SSET( text );
                  }
             }
          if ( nrval > ikeylen[ni] )
             { (void) sprintf( text, err_num, nrval, ikeylen[ni] );
               SCTPUT( text );
               nrval = ikeylen[ni];
             }
          (void) SCKWRI( "PLISTAT", ival, ikeypnt[ni], nrval, &unit );
        }
   }
else
   { (void) sprintf( text, err_inp, ipar ); 
     SCETER( 9, text );
   }
}

/*++++++++++++++++++++++++++++++
.IDENTifer   PCKWRC
.PURPOSE     Writes character values in keyword PLCSTAT
        input: char  *cpar    name of a variable in PLCSTAT
               char  *cvals   value(s) for the parameter
-------------------------------*/
void PCKWRC( cpar, cvals )
char *cpar, *cvals;

{
register int nc, nm, nd;
int    ibuff[MAXARR], actvals, nrval, unit;
float  fbuff[MAXARR];
double dbuff[MAXARR];
char   debug[5], text[81];
char   *value, valbuf[84];

char *err_inp  = "*** FATAL: PCKWRC, not existing character keyword: %s",
     *war_binm = "*** WARNING: Unknown bin mode; set to default",
     *war_eras = "*** WARNING: Unknown erase option; set to default",
     *war_debm = "*** WARNING: Unknown debug mode; set to default",
     *war_colm = "*** WARNING: Unknown colour mode; set to default",
     *war_coo  = "*** WARNING: Unknown coordinate system; set to default";
/*
 * Suppress AGL messages if (MIDAS) DEBUG mode is OFF 
 */
PCKRDC( "DEBUG", 4, &actvals, debug );
if ( strncmp( debug, "ON", 2 ) != 0 ) AG_SSET( "msgs" );

/*
 * parameter from PLCSTAT?
 */

(void) strncpy(valbuf,cvals,80);
valbuf[80] = '\0';
value = valbuf;

nrval = nc = 0;
while ( nc < CNUM && strncmp( cpar, ckeynam[nc], ckeyiden[nc] ) != 0 ) nc++;
memset((char *) fbuff, 0, sizeof(fbuff));
if ( nc < CNUM ) 
   { if ( nc > 11 )
        { if ( *value == 'A' || *value == 'N'
               || strncmp( value, "DEF", 3 ) == 0 )
             nrval = 0;
          else
             nrval = CGN_CNVT( value, 2, MAXARR, ibuff, fbuff, dbuff );

          if ( nc == 12 )                                     /* XAXIS */
             PCKWRR( "XAXIS", nrval, fbuff );
          else if ( nc == 13 )                                /* YAXIS */
             PCKWRR( "YAXIS", nrval, fbuff );
          else if ( nc == 14 )                                /* ZAXIS */
             PCKWRR( "ZAXIS", nrval, fbuff );
          else if ( nc == 15 )                                /* XSCALE */
             PCKWRR( "XSCALE", nrval, fbuff );
          else if ( nc == 16 )                                /* YSCALE */
             PCKWRR( "YSCALE", nrval, fbuff );
          else if ( nc == 17 )                                /* ZSCALE */
             PCKWRR( "ZSCALE", nrval, fbuff );
          else if ( nc == 18 )                                /* XOFFSET */
             PCKWRR( "XOF", nrval, fbuff );
          else                                                /* YOFFSET */
             PCKWRR( "YOF", nrval, fbuff );
        }

/* Here fo rthe character keywords */
     else if ( strncmp( value, "DEF", 3 ) == 0 
          || ckeydef[nc] == strstrs( ckeydef[nc], value ) )
          { (void) SCKWRC( "PLCSTAT", 1, ckeydef[nc], 
                                       ckeypnt[nc], ckeylen[nc], &unit );
          if ( nc == 3 )
             AG_SSET( "debu=0" );
          else if ( nc == 1 )
             AG_SSET( "mode=Sub" );
          }
   
     else 
          { switch( nc )
             { case 0:                                       /* BINMODE */
                   if ( strncmp( value, "ON", 2 ) == 0 )
                      (void) strcpy( value, "ON  " );
                   else
                      { SCTPUT( war_binm );
                        (void) strcpy( value, ckeydef[nc] );
                      }
                   nrval = ckeylen[nc];
                   break;
               case 1:                                       /* COLOUR MODE */
                   if ( strncmp( value, "XO", 2 ) == 0 )
                      { (void) strcpy( value, "XOR " );
                        AG_SSET( "mode=Xor" );
                      }
                   else
                      { SCTPUT( war_colm );
                        (void) strcpy( value, ckeydef[nc] );
                        AG_SSET( "mode=Sub" );
                      }
                   nrval = ckeylen[nc];
                   break;
               case 2:                                       /* CLEAR GRAPH */
                   if ( strncmp( value, "OF", 2 ) == 0 )
                      (void) strcpy( value, "OFF " );
                   else
                      { SCTPUT( war_eras );
                        (void) strcpy( value, ckeydef[nc] );
                      }
                   nrval = ckeylen[nc];
                   break;
               case 3:                                      /* DEBUG MODE */
                   if ( strncmp( value, "ON", 2 ) == 0 )
                      { (void) strcpy( value, "ON  " );
                        AG_SSET( "debug=1;errf=aglerr.log" );
                      }
                   else
                      { SCTPUT( war_debm );
                        (void) strcpy( value, ckeydef[nc] );
                        AG_SSET( "debug=0" );
                      }
                   nrval = ckeylen[nc];
                   break;
               case 4:                                       /* FRAME */
                   if ( *value == 'S' )
                      { (void) strcpy( value, "SQUA" );
                      }
                   else
                      { (void) strcpy( value, ckeydef[nc] );
                        fbuff[0] = 0.0;
                        PCKWRR( "XSCAL", 1, fbuff );
                        PCKWRR( "YSCAL", 1, fbuff );
                        PCKWRR( "ZSCAL", 1, fbuff );
                      }
                   nrval = ckeylen[nc];
                   break;
               case 5:                                       /* XFORMAT */
               case 6:                                       /* YFORMAT */
               case 7:                                       /* ZFORMAT */
                   if ( strncmp( value, "NO", 2 ) == 0 )
                      (void) strcpy( value, "NONE     " );
                   else if ( strncmp( value, "AUT", 3 ) == 0 )
                      (void) strcpy( value, ckeydef[nc] );
                   else
                      CHECK_FMT( value );
                   nrval = ckeylen[nc];
                   break;
               case 8:                                       /* CXSC */
                   if ( strncmp( value, "W", 1 ) == 0 )
                      (void) strcpy( value, "WO  " );
                   else if ( strncmp(  value, "M", 1 ) == 0 )
                      (void) strcpy( value, "MM  " );
                   else if ( strncmp( value, "N", 1 ) == 0 )
                      (void) strcpy( value, "NO  " );
                   else if ( strncmp( value, "S", 1 ) == 0 )
                      (void) strcpy( value, "SC  " );
                   else
                      { SCTPUT( war_coo );
                        (void) strcpy( value, ckeydef[nc] );
                      }
                   nrval = ckeylen[nc];
                   break;

               case 9:                                       /* CYSC */
                   if ( strncmp( value, "W", 1 ) == 0 )
                      (void) strcpy( value, "WO  " );
                   else if ( strncmp( value, "M", 1 ) == 0 )
                      (void) strcpy( value, "MM  " );
                   else if ( strncmp( value, "N", 1 ) == 0 )
                      (void) strcpy( value, "NO  " );
                   else if ( strncmp( value, "S", 1 ) == 0 )
                      (void) strcpy( value, "SC  " );
                   else
                      { SCTPUT( war_coo );
                        (void) strcpy( value, ckeydef[nc] );
                      }
                   nrval = ckeylen[nc];
                   break;

               case 10:                                       /* CXOF */
                   if ( strncmp( value, "M", 1 ) == 0 )
                      (void) strcpy( value, "MM  " );
                   else if ( strncmp( value, "N", 1 ) == 0 )
                      (void) strcpy( value, "NO  " );
                   else if ( strncmp( value, "S", 1 ) == 0 )
                      (void) strcpy( value, "SC  " );
                   else
                      { SCTPUT( war_coo );
                        (void) strcpy( value, ckeydef[nc] );
                      }
                   nrval = ckeylen[nc];
                   break;

               case 11:                                       /* CYOF */
                   if ( strncmp( value, "M", 1 ) == 0 )
                      (void) strcpy( value, "MM  " );
                   else if ( strncmp( value, "N", 1 ) == 0 )
                      (void) strcpy( value, "NO  " );
                   else if ( strncmp( value, "S", 1 ) == 0 )
                      (void) strcpy( value, "SC  " );
                   else
                      { SCTPUT( war_coo );
                        (void) strcpy( value, ckeydef[nc] );
                      }
                   nrval = ckeylen[nc];
                   break;
             }
          (void) SCKWRC( "PLCSTAT",1, value, ckeypnt[nc], nrval, &unit );
	  }

     return;
   }
/*
 * write in PLCMETA
 */
nm = 0;
while ( nm < MNUM && strncmp( cpar, mkeynam[nm], mkeyiden[nm] ) != 0 ) nm++;
if ( nm < MNUM )
   { (void) SCKWRC( "PLCMETA", 1, value, mkeypnt[nm], mkeylen[nm], &unit );
     return;
   }
/*
 * write in PLCDATA
 */
nd = 0;
while ( nd < DNUM && strncmp( cpar, dkeynam[nd], dkeyiden[nd] ) != 0 ) nd++;
if ( nd < DNUM )
   { (void) SCKWRC( "PLCDATA", 1, value, dkeypnt[nd], dkeylen[nd], &unit );
     return;
   }

(void) sprintf( text, err_inp, cpar );
SCETER( 1, text );
}

/*++++++++++++++++++++++++++++++
.IDENTifer   PCKDEF
.PURPOSE     Writes default values in PLCSTAT, PLISTAT, PLRSTAT and PLRGRAP
--------------------------------*/
void PCKDEF()
{
register int nc;
int   slen, unit;
char  plckey[81];

/*
 * set character keyword PLCSTAT to default
 */
*(plckey+ckeypnt[0]-1) = '\0';
for ( nc = 0; nc < CDEF; nc++ )
    (void) strncat( plckey, ckeydef[nc], ckeylen[nc]);
slen = strlen( plckey );
(void) SCKWRC( "PLCSTAT", 1, plckey, 1, slen, &unit );

/*
 * set integer keyword PLISTAT to default
 */
slen = (int) (sizeof(ikeydef)/sizeof(int));
(void) SCKWRI( "PLISTAT", ikeydef, 1, slen, &unit );

/*
 * set real keyword PLRSTAT to default
 */
slen = (int) (sizeof(rkeydef)/sizeof(float));
(void) SCKWRR( "PLRSTAT", rkeydef, 1, slen, &unit );  

return;
}

