/*===========================================================================
  Copyright (C) 1993-2010 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
===========================================================================*/

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.IDENTIFIER  PLOTTBL
.AUTHOR      R.M. van Hees IPG-ESO Garching
.KEYWORDS    Graphics, 3-D & 2-D tables
.LANGUAGE    C
.PURPOSE     Plot or overplot one or two columns or planes from a TABLE
      input: IN_A/C/1/80   = input table
             P2/C/1/60     = input string for plane 1
             P3/C/1/60     = input string for plane 2
             P4/R/2        = scales in x and y; default is auto scaling
             p5/C/1/40     = symbol types; default is set by SET/GRAPHIC
             p6/C/1/40     = line types; default is set by SET/GRAPHIC
             INPUTC/C/1/20 = flag which specifies the way the planes are read;
                            default Default, alternative is Other or Opposite:
                               flag = "D" yz-plane, column by column (y)
                                          xz-plane, array by array (z)
                                          xy-plane, column by column (y)
                               flag = "O" yz-plane, array by array (z)
                                          xz-plane, row by row (x)
                                          xy-plane, row by row (x)
.COMMENTS    none
.ENVIRONment MIDAS
             #include <midas_def.h>     Prototypes for MIDAS interfaces
             #include <plot_def.h>      General symbols for Plot routines

.VERSION     1.1     20-Sep-1993   created by R.M. van Hees

 100817		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 <string.h>
#include <stdlib.h>
#include <math.h>

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

#define TBLDIM		3        /* a input table may have upto 3 dimensions */
#define COLMAX		256	     /* maximum number of columns in a TABLE */

/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  LOG_FLAG
.PURPOSE     Find out if the user requested a logaritmic scaling
   in/output   char *string  if this string starts with "LOG", "log", "LN"
                             or "ln", than this is taken away (together with
                             the brackets) and "ilog" is set
      output   int  *ilog    log flag: 0) no log scaling requested
                                       1) decimal log requested
                                       2) natural log requested
.COMMENT     static function
--------------------------------*/
#ifdef __STDC__
      static void LOG_FLAG( char *string, int *ilog )
#else
      static void LOG_FLAG( string, ilog )
      char *string;
      int *ilog;
#endif
{
char *pntr;

*ilog = 0;
if ( strncmp( string, "LOG", 3 ) == 0 || strncmp( string, "log", 3 ) == 0 )
   { *ilog = 1;
     pntr = strchr( string, '(' ) + 1;
     (void) strcpy( string, strtok( pntr, ")" ) );
   }
else if ( strncmp( string, "LN", 2 ) == 0 || strncmp( string, "ln", 2 ) == 0 )
   { *ilog = 2;
     pntr = strchr( string, '(' ) + 1;
     (void) strcpy( string, strtok( pntr, ")" ) );
   }
return;
}

/*++++++++++++++++++++++++++++++
.IDENTIFIER  GET_LABELS
.PURPOSE     write the X and Y label
      input   int  tid       table id
              char *colref   column reference
              int  ilog      log scaling or not
     output   char *label    character string with the label
.COMMENT     static function
--------------------------------*/
#ifdef __STDC__
      static void GET_LABELS( int tid, char *colref, int depth,
                                       int items, int ilog, char *label )
#else
      static void GET_LABELS( tid, colref, depth, items, ilog, label )
      int  tid, depth, items, ilog;
      char *colref, *label;
#endif
{
int  bytes, dtype, nc, ncol, ndepth, icol[COLMAX], sflag[COLMAX];
char cunit1[17], cunit2[17], buff[41];

char *err_fcol = "*** FATAL: column has character format";

(void) TCCSEL( tid, colref, COLMAX, icol, sflag, &ncol );

nc = 0;
(void) TCBGET( tid, icol[nc], &dtype, &ndepth, &bytes );
if ( dtype == D_C_FORMAT ) (void) SCETER( 1, err_fcol );

(void) TCLGET( tid, icol[nc], label );
(void) TCUGET( tid, icol[nc], cunit1 );
if ( ncol > 1 )
   { nc++;
     do { (void) strcpy( cunit2, cunit1 );
          (void) TCBGET( tid, icol[nc], &dtype, &ndepth, &bytes );
          if ( dtype == D_C_FORMAT ) (void) SCETER( 1, err_fcol );
          (void) TCUGET( tid, icol[nc], cunit1 );
        }
     while( strcmp( cunit1, cunit2 ) == 0 && ++nc < ncol );
     if ( nc != ncol ) (void) strcpy( cunit1, "MIXED UNITS" );
   }
/*
 * write the column names
 */
if ( ncol == 1 )
   { if ( strlen( label ) == 0 )
        (void) sprintf( buff, "Column: #%-d", icol[0] );
     else
        (void) strcpy( buff, label );
   }
else
   (void) sprintf( buff, "Column: #%-d..%-d", icol[0], icol[ncol-1] );
/*
 * add if requered depth & range
 */
if ( ndepth > 1 )
   { if ( items == 1 )
        (void) sprintf( buff, "%s[%-d]", buff, depth );
     else if ( items > 1 )
        (void) sprintf( buff, "%s[%-d..%-d]", buff, depth, depth + items-1 );
     else
        (void) sprintf( buff, "%s[%-d..LAST]", buff, depth );
     (void) strcat( label, buff );
   }
/*
 * add if requered column unit and log flag 
 */
if ( ilog == 0 )
   (void) sprintf( label, "%s (%s)", buff, cunit1 );
else if ( ilog == 1 )
   (void) sprintf( label, "LOG10 %s (%s)", buff, cunit1 );
else
   (void) sprintf( label, "LN %s (%s)", buff, cunit1 );
}

/*++++++++++++++++++++++++++++++
.IDENTIFIER  GET_SLTYPE
.PURPOSE     fill two array with the requested Symbol and Line types
      input   char *cstype  symbol types given by the user
              char *cltype  line types given by the user
              int  nrdraw   numbers of drawn lines
  in/output   int  *stype   symbol types, upon input: default symbol type
              int  *ltype   line type, upon input: default line type
.COMMENT     static function
--------------------------------*/
#ifdef __STDC__
      static void GET_SLTYPE( char *cstype, char *cltype, int nrdraw, 
                                              int *stype, int *ltype )
#else
      static void GET_SLTYPE( cstype, cltype, nrdraw, stype, ltype )
      char *cstype, *cltype;
      int nrdraw, *stype, *ltype;
#endif
{
int  ii, nsym, nlin;
char *cbuff;

char  *err_usrin = "*** FATAL: too many symbol or line types given";

(void) strtok( cstype, " " );
(void) strtok( cltype, " " );
/*
 * get symbol types 
 */
if ( strcmp( cstype, "?" ) == 0 )
   for ( ii = 1; ii < nrdraw; ii++ ) *(stype+ii) = *stype;
else
   { cbuff = (char *) stype;
     if ( USRINP( 'i', cstype, nrdraw, cbuff, &nsym ) != ERR_NORMAL )
        (void) SCETER( 2, err_usrin );
     for ( ii = 0; ii < nrdraw - nsym; ii++ ) *(stype+nsym+ii) = *(stype+ii);
   }
/*
 * get line types 
 */
if ( strcmp( cltype, "?" ) == 0 )
   { for ( ii = 0; ii < nrdraw; ii++ ) 
        { if ( *(stype+ii) != 0 )
             *(ltype+ii) = 0;
          else
             *(ltype+ii) = *ltype;
        }
   }
else
   { cbuff = (char *) ltype;
     if ( USRINP( 'i', cltype, nrdraw, cbuff, &nlin ) != ERR_NORMAL )
        (void) SCETER( 2, err_usrin );
     for ( ii = 0; ii < nrdraw - nlin; ii++ ) *(ltype+nlin+ii) = *(ltype+ii);
   }
return;
}
/*

*/

/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 *
 * here starts the code of the function
 *
   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

int main()
{
register int ii;

int    actcol, actrow, actvals, allcol, allrow, bytes, dtype, icol,
       mxdepth, nrdraw, ndepth, nrcol, nrrow, nsort, nconn, nnull, tid, 
       count, stat, x_or_y, xy, *inul[PLDIM2], *ltype, *stype,
       dir[PLDIM2], ilog[PLDIM2], index[PLDIM2], items[PLDIM2], 
       nline[PLDIM2], row[PLDIM2], type[PLDIM2];
int    selcolo, noselcolo, lastsel, unit, knul, *sele;

void    getColor();
int    tbl_readyzplane(),tbl_readplaneyz(),tbl_readplanexz(),tbl_readplanexy();



float  *rval[PLDIM2], wcfram[8];

char   *pntr, cflag[21], cmnd[21], colref[41], cltype[41], 
       cstype[41], table[81], buff[128], sel[81], *column[PLDIM2], 
       *string[PLDIM2], *label[4];
char   ocoltxt[12], scoltxt[12], nscoltxt[12], colstr[24];
/*
 * initialised variables
 */
int  plmode = -1,                      /* plot mode taken from keyword PMODE */
     access =  0,                     /* parameter for PCOPEN: NEW plot mode */
     tbldim = TBLDIM;                     /* default for the table dimension */

char  *err_row   = "*** FATAL: no (selected) points in this table ....",
      *err_clmn  = "*** FATAL: you should give at least one column",
      *err_plane = "*** FATAL: problems with plane: col=%s row=%-d [%d..%d]",
      *war_null  = "*** WARNING: Table contains %d illegal or NULL values",
      *war_sltyp = "*** WARNING: STYPE and LTYPE equal 0: no data plotted",
      *err_dim   = "*** FATAL: The data to be plotted does not have the same dimension in X or Y";

static char *axis[PLDIM2] = { "MANU", "MANU" },
            *err_flat[PLDIM2] = 
                     { "*** WARNING: zero dynamics range in x: %13.8g",
                       "*** WARNING: zero dynamics range in y: %13.8g" };
/*
 * allocate memory for different character pointers and initialise a few
 */
for ( xy = 0; xy < PLDIM2; xy++ )
   {
   column[xy] = osmmget(41);
   string[xy] = osmmget(61);
   *column[xy] = '\0';
   nline[xy] = 0;
   }
for ( ii = 0; ii < 4; ii++ )
   {
   label[ii]  = osmmget(81);
   *label[ii] = '\0';
   }
(void) strcpy( label[2], "Table: " );
sele = 0;  

(void) SCSPRO( "PLTTBL" );                /*contact with the MIDAS monitor*/

/*
 * find file name and read header information
 */
   

(void) SCKGETC( "IN_A", 1, 80, &actvals, table );

/*
 * Try to open table, this routine EXITS the program if the table can not 
 * be found !!
 */
(void) TCTOPN( table, F_I_MODE, &tid );

/*
 * read table size information: number of columns, rows and depth
 */
(void) TCIGET( tid, &nrcol, &nrrow, &nsort, &allcol, &allrow );
(void) TCSCNT( tid, &count);
if ( nrrow == 0 || count <= 0 ) 
   {
   SCTPUT(err_row );
   return SCSEPI();
   }

mxdepth = 1;
for ( ii = 1; ii <= nrcol; ii++ )
    { (void) TCBGET( tid, ii, &dtype, &ndepth, &bytes );
      mxdepth = MYMAX( mxdepth, ndepth );
    }
if ( mxdepth == 1 ) tbldim = 2;                               /* a 2-D table */

/*
 * get description of the planes in the table and their orientation
 */
(void) SCKGETC( "P2", 1, 60, &actvals, string[0] );
(void) SCKGETC( "P3", 1, 60, &actvals, string[1] );

LOG_FLAG( string[0], ilog );
LOG_FLAG( string[1], ilog+1 );

TBL_USRINP( string[0], type, column[0], row, index, items );
TBL_USRINP( string[1], type+1, column[1], row+1, index+1, items+1 ); 
if ( type[0] == 0 && type[1] == 0 ) SCETER( 2, err_clmn );

/*
 * The user may have used a short hand for the description of the planes if 
 * the orientation of the planes are the same. We have to check and repair!
 */
if ( tbldim != 2 && type[0] == type[1] )
   { if ( type[0] == 1 || type[0] == 2 )
        { if ( items[0] != items[1] && items[0] == 0 ) 
             { (void) TCCSER( tid, column[0], &icol );
               (void) TCBGET( tid, icol, &dtype, &ndepth, &bytes );
               if ( ndepth != 1 )
                  { index[0] = index[1];
                    items[0] = items[1];
                  }
             }
        }
     if ( type[0] == 2 || type[0] == 3 )
        { if ( strcmp( column[0], column[1] ) != 0 )
             if ( *column[0] == '\0' ) (void) strcpy( column[0], column[1] );
        }
   }
/*
 * Get flag for storage direction of data of the requested planes
 */
(void) SCKGETC( "INPUTC", 1, 20, &actvals, cflag );
CGN_LOWSTR( cflag );
dir[0] = ( *cflag == 'd' ) ? 0 : 1;
if ( (pntr = strchr( cflag, ',' )) == NULL ) 
   dir[1] = dir[0];
else
   dir[1] = ( *(pntr+1) == 'd' ) ? 0 : 1;

/*
 * test, if it's plot/selected or plot/table command (via the select-color)
 */

(void) SCKGETC( "INPUTC", 21, 22, &actvals, colstr );
if (strncmp(colstr,"NOCOL",5) == 0)
   selcolo = -99;
else
   {				/* get default color (from SET/GRAPH) */
   (void) SCKRDI("PLISTAT",9,1,&actvals,&selcolo,&unit,&knul);
   (void) sprintf(ocoltxt,"color=%1d",selcolo);

   getColor(colstr,&selcolo,&noselcolo);	/* color name -> no. */
   if (selcolo < 0) selcolo = 2;		/* default to red */
   (void) sprintf(scoltxt,"color=%1d",selcolo);
   if (noselcolo < 0)				/* use default color */
      (void) strcpy(nscoltxt,ocoltxt);
   else
      (void) sprintf(nscoltxt,"color=%1d",noselcolo);
   }

/*
 * read table data
 */
for ( xy = 0; xy < PLDIM2; xy++ )
    { (void) strcpy( colref, column[xy] );

      if ( type[xy] == 1 )                   /* data from column or YZ-plane */
         { inul[xy] = (int *) osmmget(mxdepth * nrrow * sizeof(int));
           rval[xy] = (float *) osmmget(mxdepth * nrrow * sizeof(float));

           if (selcolo != -99)
              {
              sele = (int *) osmmget(mxdepth * nrrow * sizeof(int));
              stat = tbl_readyzplane(tid, colref, index[xy], items[xy], 1, 
                                     dir[xy], nrrow, items+xy, &actrow, 
                                     rval[xy], inul[xy], sele );
              if (stat != ERR_NORMAL)
                 SCETER(33,"multicolor mode only supported for 2d tables...");
              }
           else
              stat = tbl_readplaneyz( tid, colref, index[xy], items[xy], 1, 
                       dir[xy], nrrow, items+xy, &actrow, rval[xy], inul[xy] );

           if ( stat != ERR_NORMAL ) 
              { (void) sprintf( buff, err_plane, column[xy], row[xy], 
                                      index[xy], index[xy]+items[xy]-1 );
                (void) SCETER(10, buff );
              }

           if ( xy == 0 || type[0] == 0 )                 /* numb. of points */
              { nconn = actrow;
                if ( dir[xy] == 1 ) nconn = items[xy];
              }
           else if ( (dir[xy] == 0 && actrow != nconn)
                    || (dir[xy] == 1 && items[xy] != nconn) )
              (void) SCETER( 4, err_dim );

           nline[xy] = items[xy];                          /* numb. of lines */
           if ( dir[xy] == 1 ) nline[xy] = actrow;
         }

      else if ( type[xy] == 2 )                 /* data from row or XZ-plane */
         { inul[xy] = (int *) osmmget(mxdepth * nrcol * sizeof(int));
           rval[xy] = (float *) osmmget(mxdepth * nrcol * sizeof(float));
           stat = tbl_readplanexz( tid, colref, row[xy], index[xy], items[xy], 
                           1, dir[xy], &actcol, items+xy, rval[xy], inul[xy] );
           if ( stat != ERR_NORMAL ) 
              { (void) sprintf( buff, err_plane, column[xy], row[xy], 
                                      index[xy], index[xy]+items[xy]-1 );
                (void) SCETER(10, buff );
              }

           if ( xy == 0 || type[0] == 0 )                 /* numb. of points */
              { nconn = items[xy];
                if ( dir[xy] == 1 ) nconn = actcol;
              }
           else if ( (dir[xy] == 0 && items[xy] != nconn)
                    || (dir[xy] == 1 && actcol != nconn) )
              SCETER( 4, err_dim );

           nline[xy] = actcol;                             /* numb. of lines */
           if ( dir[xy] == 1 ) nline[xy] = items[xy];
         }
      else if ( type[xy] == 3 )       /* data from array (depth) or XY-plane */
         { inul[xy] = (int *) osmmget( nrrow * nrcol * sizeof(int));
           rval[xy] = (float *) osmmget( nrrow * nrcol * sizeof(float));
           stat = tbl_readplanexy( tid, colref, index[xy], nrrow, 1, dir[xy],
                                        &actrow, &actcol, rval[xy], inul[xy] );
           if ( stat != ERR_NORMAL ) 
              { (void) sprintf( buff, err_plane, column[xy], row[xy], 
                                      index[xy], index[xy]+items[xy]-1 );
                (void) SCETER(10, buff );
              }

           if ( xy == 0 || type[0] == 0 )                 /* numb. of points */
              { nconn = actrow;
                if ( dir[xy] == 1 ) nconn = actcol;
              }
           else if ( (dir[xy] == 0 && actrow != nconn )
                    || (dir[xy] == 1 && actcol != nconn) )
              (void) SCETER( 4, err_dim );

           nline[xy] = actcol;                             /* numb. of lines */
           if ( dir[xy] == 1 ) nline[xy] = actrow;
         }
      else                                       /* axis is the row sequence */
         nline[xy] = 1;
/* 
 * log scaling or not... 
 */
     if ( type[xy] != 0 && ilog[xy] == 1 )
        { for ( ii = 0; ii < nconn * nline[xy]; ii++ )
              if (*(rval[xy] + ii) > 0.0) 
                 *(rval[xy] + ii) = (float) log10( *(rval[xy] + ii));
              else
                 *(inul[xy] + ii) = 1;
        }
     else if ( type[xy] != 0 && ilog[xy] == 2 )
        { for ( ii = 0; ii < nconn * nline[xy]; ii++ )
              if (*(rval[xy] + ii) > 0.0) 
                 *(rval[xy] + ii) = (float) log( *(rval[xy] + ii));
              else
                 *(inul[xy] + ii) = 1;
        }
   }
/*
 * fill array with values if the row sequence is used
 */
if ( ( type[0] == 0 ) || ( type[1] == 0 ) )
   {
    if ( type[0] == 0 )
        xy = 0;
     else 
        xy = 1;

     inul[xy] = (int *) osmmget( nconn * sizeof(int));
     rval[xy] = (float *) osmmget( nconn * sizeof(float));
     for ( ii = 0; ii < nconn; ii++ ) 
         { *(inul[xy]+ii) = 0;
           *(rval[xy]+ii) = ii+1;
         }
   }
/*
 * reject NULL values and issue warning
 */

if (selcolo != -99)		/* selection flags sync'ed with Null values */
   SSKIPNULL( nline, inul, rval, &nconn, &nnull, sele);
else
   SKIPNULL( nline, inul, rval, &nconn, &nnull);
if ( nnull > 0 ) 
   { (void) sprintf( buff, war_null, nnull );
     SCTPUT( buff );
     SCTPUT( "             Data points not plotted" );
   }
/*
 * set the number of lines to be plotted
 */
if ( nline[0] == 1 || nline[1] == 1 )
   nrdraw = MYMAX( nline[0], nline[1] );
else
   nrdraw = MYMIN( nline[0], nline[1] );

/*
 * Plot mode or Overplot mode??
 */
(void) SCKGETC( "MID$CMND", 1, 20, &actvals, cmnd );
if ( *cmnd != 'P' ) access = 1;

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

/*
 * If plot mode: write labels, and determine frame size
 */
if ( access == 0 )
   {
   for (xy = 0; xy < PLDIM2; xy++ )
      {
      if ( type[xy] != 0 ) 
         {
         GET_LABELS(tid,column[xy],index[xy],items[xy],ilog[xy],label[xy]);
         LABSTR( label[xy] );
         }
      else
         (void) strcpy( label[xy], "Sequence" );

      x_or_y = ( xy == 0 ) ? FOR_X : FOR_Y;
      if ((fabs(*(wcfram+x_or_y)) < PLT_EPS) && 
          (fabs(*(wcfram+x_or_y+1)) < PLT_EPS))
         {
         axis[xy] = "AUTO";


/*************** type = 0 indicates ? or seq
   we remove the simplified range calculation for (type == 0):

                if ( type[xy] == 0 )
                   { wcfram[x_or_y]   = *rval[0];
                     wcfram[x_or_y+1] = *(rval[0])+nconn-1;
                   }
                else
                   { MINMAX( rval[xy],(nconn * nline[xy]), 
                             wcfram + x_or_y, wcfram + x_or_y+1 );
                   }
*****************************************/

         MINMAX( rval[xy],(nconn * nline[xy]), 
                 wcfram + x_or_y, wcfram + x_or_y+1 );
         if ( wcfram[x_or_y] == wcfram[x_or_y+1] )
            {
            (void) sprintf( buff, err_flat[xy], wcfram[x_or_y] );
            SCTPUT( buff );
            }

         wcfram[x_or_y+2] = wcfram[x_or_y+3] = 0.0;
         }

      GETFRM( axis[xy], wcfram+x_or_y );  /* calc. large, small tick marks */
      }

   PCKWRR( "XWNDL", 4, wcfram );
   PCKWRR( "YWNDL", 4, wcfram+FOR_Y );
   }

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

/*
 * get symbol and line types 
 */
(void) SCKGETC( "P5", 1, 40, &actvals, cstype );            /* stype by user */
(void) SCKGETC( "P6", 1, 40, &actvals, cltype );            /* ltype by user */
stype = (int *) osmmget( nrdraw * sizeof( int ));
ltype = (int *) osmmget( nrdraw * sizeof( int ));
PCKRDI( "STYPE", 1, &actvals, stype );                      /* default stype */
PCKRDI( "LTYPE", 1, &actvals, ltype );                      /* default ltype */

/* force only ltype or stype to non-zero values */
GET_SLTYPE( cstype, cltype, nrdraw, stype, ltype );


/* do the work */

if (selcolo != -99)
   {
   lastsel = 0;


   if (stype[0] != 0)
      {
      unit = stype[0];

      for (ii=0; ii<nconn; ii++)
         {
         if ( sele[ii] != lastsel )
            {
            if (lastsel == 0)        	/* now selected element */
               AG_SSET(scoltxt);	/* switch to selection color */
            else
               AG_SSET(nscoltxt);

            lastsel = sele[ii];
            }
			/* for symbols we just draw each single element */
         PCDATA(unit,0,0,rval[0]+ii,rval[1]+ii,0.0,1);
         }
      }

   unit = ltype[0];
   if (unit == 0)			/* STYPE = LTYPE = 0 is bad... */
      {
      SCTPUT( war_sltyp );
      goto draw_axis;
      }

   for (ii=0; ii<(nconn-1); ii++)
      {
      if ( sele[ii] != lastsel )
         {
         if (lastsel == 0)
            AG_SSET(scoltxt);        /* now selected element */
         else
            AG_SSET(nscoltxt);
         lastsel = sele[ii];
         }

      /* for line segments we need always two elements */
      PCDATA(0,unit,0,rval[0]+ii,rval[1]+ii,0.0,2);
      }


   /* check, if we have to redraw the last element */

   if ( sele[nconn-1] != lastsel )
      {
      float  lastx[2], lasty[2];
   
      lastx[1] = lastx[0] = *(rval[0]+nconn-1);
      lasty[1] = lasty[0] = *(rval[1]+nconn-1);

      if (lastsel == 0)
         AG_SSET(scoltxt);        /* now selected element */
      else
         AG_SSET(nscoltxt);

      PCDATA(0,unit, 0, lastx, lasty, 0.0, 2 );
      }

   goto draw_axis;
   }

/* if table elements are arrays and stype = 0,
   we have to toggle some values to get solid lines  (KB 080714) */

if ((mxdepth > 1) && (nrrow == 1) && (stype[0] == 0))
   {
   nconn = mxdepth; 
   nrdraw = 1;
   }

for ( ii = 0; ii < nrdraw; ii++ )
   {
   register int k = ii * nconn;

   if ( ltype[ii] == 0 && stype[ii] == 0 )
      SCTPUT( war_sltyp );

   else
      {
      if ( stype[ii] != 0 )
         {
         if ( ii >= nline[0] )
            PCDATA( stype[ii], 0, 0, rval[0], rval[1]+k, 0.0, nconn );
         else if ( ii >= nline[1] )
            PCDATA( stype[ii], 0, 0, rval[0]+k, rval[1], 0.0, nconn );
         else
            PCDATA( stype[ii],0, 0, rval[0]+k, rval[1]+k,0.0, nconn );
         }

      if ( ltype[ii] != 0 )
         {
         if ( ii >= nline[0] )
            PCDATA( 0, ltype[ii], 0, rval[0], rval[1]+k, 0.0, nconn );
         else if ( ii >= nline[1] )
            PCDATA( 0, ltype[ii], 0, rval[0]+k, rval[1], 0.0, nconn );
         else
            PCDATA( 0, ltype[ii], 0, rval[0]+k, rval[1]+k,0.0, nconn );
         }
      }
   }

/* draw the axes and the label */

draw_axis:
AG_SSET(ocoltxt);

if ( plmode >= 0 && access == 0 )
   {					/* plot axes and labels */
     PCFRAM( wcfram, wcfram+FOR_Y, label[0], label[1] );

     (void) TCSINF( tid, sel );
     if ( plmode == 1 )
        { (void) strcat ( label[2], table );
          (void) sprintf( label[3], "Sel: %s", sel );
          PLIDEN( plmode, label[2], label[3] );
        }
     else if ( plmode == 2 )
        PLTBLI( plmode, tid, table, string, sel, tbldim );
   }
PCCLOS();

return SCSEPI();
}

