/*===========================================================================
  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   PLERR
.AUTHOR      R.M. van Hees IPG-ESO Garching
.KEYWORDS    low level plot routine
.LANGUAGE    C
.PURPOSE     Overplot error bars from one or two columns of a TABLE
        input: int   tid    Table identifier
               int   nrow   number of rows
               int   *col   column index
               int   *ilog  logarithm flag: 0) Lineair, 1) LOG10, 2) LN
                     int    loc    orientation of the error bar:
                                       1) pos X, 3) neg X, 5) both
                                       2) pos Y, 4) neg Y, 6) both
               char *bar    cross bar (y) or not (n)

.COMMENTS    none
.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.1     10-Sep-1993   FORTRAN --> ANSI-C    RvH

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 <math.h>

#include <midas_def.h>

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

/*
 * here start the code of the function
 */
void PLERR( tid, nrow, col, ilog, loc, bar )
char *bar;
int tid, nrow, *col, *ilog, loc;

{
register int ii, jj, nc;
int    actvals, isel, inull, ltype, nopoint, stat;

float  xmin, ymin, xerr, yerr, xbar[2], ybar[2], xval[2], yval[2], 
       xn[2], yn[2], xch[3], ych[3], pval[3], wcfram[8];

char   buff[81];

/*
 * pick up the frame settings
 */
PCKRDR( "XWNDL", 4, &actvals, wcfram );
PCKRDR( "YWNDL", 4, &actvals, wcfram+FOR_Y );

xmin = MYMIN( *wcfram, wcfram[1] );
ymin = MYMIN( wcfram[FOR_Y], wcfram[FOR_Y+1] );
                     
/*
 * initialise plot settings to normal
 */
(void) AG_IGET( "lstyl", &ltype );
AG_SSET( "lstyl=0" );                               /*set line style to solid*/

AG_TGET( "M", xch, ych );
xerr = xch[0] / 1.5;
yerr = ych[1] / 2.0;

for ( ii = 1; ii <= nrow; ii++ )
    { nopoint = FALSE;
      stat = TCSGET( tid, ii, &isel );
      if ( isel )
         { 
/*
 * pick up the values for resp. X-pos, Y-pos, Error bar:
 */
           for ( nc = 0; nc < 3; nc++ )
               { if ( col[nc] == 0 ) 
                    pval[nc] = ii;
                else if ( ! nopoint )
                    { stat = TCERDR( tid, ii, col[nc], pval+nc, &inull );
                      if ( inull || stat != ERR_NORMAL ) nopoint = TRUE;
                    }
               }
           if ( pval[2] < 0.0 ) pval[2] *= -1;

           if ( ! nopoint )
              { switch ( loc ) 
                   { case 1:                         /* error bars in pos. X */
                         xval[0] = *pval;
                         xval[1] = *pval + pval[2];
                         yval[0] = yval[1] = pval[1];
                         break;
                     case 3:                         /* error bars in neg. X */
                         xval[0] = *pval;
                         xval[1] = *pval - pval[2];
                         yval[0] = yval[1] = pval[1];
                         break;
                     case 5:                     /* two error bars in X dir. */
                         xval[0] = *pval - pval[2];
                         xval[1] = *pval + pval[2];
                         yval[0] = yval[1] = pval[1];
                         break;
                     case 2:                         /* error bars in pos. Y */
                         xval[0] = xval[1] = *(pval);
                         yval[0] = pval[1];
                         yval[1] = pval[1] + pval[2];
                         break;
                     case 4:                         /* error bars in neg. Y */
                         xval[0] = xval[1] = *(pval);
                         yval[0] = pval[1];
                         yval[1] = pval[1] - pval[2];
                         break;
                     case 6:                     /* two error bars in Y dir. */
                         xval[0] = xval[1] = *(pval);
                         yval[0] = pval[1] - pval[2];
                         yval[1] = pval[1] + pval[2];
                         break;
                   }
                if ( ! nopoint && ilog[0] != 0 )            /* log. X-values */
		   { if ( xval[1] > 0.0) 
                        { if ( xval[0] <= 0) xval[0] = xmin;
                          for ( jj = 0; jj < PLDIM2; jj++ )
                              { if ( xval[jj] > 0.0) 
                                   {
                                   if ( ilog[0] == 1 )
                                      xval[jj] = (float) log10( xval[jj] );
                                   else
                                      xval[jj] = (float) log( xval[jj] );
		                   }
			      }
                        }
                     else
                        nopoint = TRUE;
                   }

                if ( ! nopoint && ilog[1] != 0 )            /* log. Y-values */
		   { if ( yval[1] > 0.0) 
                        { if (yval[0] <= 0) yval[0] = ymin;
                          for ( jj = 0; jj < PLDIM2; jj++ )
                              { if ( yval[jj] > 0) 
                                   {
                                   if ( ilog[1] == 1 )
                                      yval[jj] = (float) log10( yval[jj] );
                                   else
                                      yval[jj] = (float) log( yval[jj] );
		                   }
			      }
                        }
                     else
                        nopoint = TRUE;
		   }
/*
 * check on logarithmic axes settings
 */
                if ( wcfram[3] < 0 )
                   { if ( xval[1] <= 0 )
                        nopoint = TRUE;
                     else if ( *xval <= 0 )
                        { if ( CGN_NINT( wcfram[3] ) == -1 )
                             *xval = (float) pow( 10.0, xmin );
                          else
                             *xval = (float) exp( xmin );
                        }
                   }
                if ( wcfram[FOR_Y+3] < 0 )
                   { if ( yval[1] <= 0 )
                        nopoint = TRUE;
                     else if ( *yval <= 0 )
                        { if ( CGN_NINT( wcfram[FOR_Y+3] ) == -1 )
                             *yval = (float) pow( 10.0, ymin );
                          else
                             *yval = (float) exp( ymin );
                        }
                   }
              }
/*
 * start the plotting
 */
           if ( ! nopoint )
              { AG_GPLL( xval, yval, 2 );
/*
 * draw the error bar
 */
                if ( *bar == 'y' || *bar == 'Y' ) 
                   { switch ( loc )
                        { case 5:
                              AG_VU2N( xval[0], yval[0], xn, yn );
                              *(xn+1) = *xn;
                              *yn     -= yerr / 2;
                              *(yn+1) = *yn + yerr;
                              AG_VN2U( *xn, *yn, xbar, ybar );
                              AG_VN2U( *(xn+1), *(yn+1), xbar+1, ybar+1 );
                              AG_GPLL( xbar, ybar, 2 );
                          case 1:
                          case 3:
                              AG_VU2N( xval[1], yval[0], xn, yn );
                              *(xn+1) = *xn;
                              *yn     -= yerr / 2;
                              *(yn+1) = *yn + yerr;
                              AG_VN2U( *xn, *yn, xbar, ybar );
                              AG_VN2U( *(xn+1), *(yn+1), xbar+1, ybar+1 );
                              AG_GPLL( xbar, ybar, 2 );
                              break;
                          case 6:
                              AG_VU2N( xval[0], yval[0], xn, yn );
                              *xn     -= xerr / 2;
                              *(xn+1) = *xn + xerr;
                              *(yn+1) = *yn;
                              AG_VN2U( *xn, *yn, xbar, ybar );
                              AG_VN2U( *(xn+1), *(yn+1), xbar+1, ybar+1 );
                              AG_GPLL( xbar, ybar, 2 );
                          case 2:
                          case 4:
                              AG_VU2N( xval[0], yval[1], xn, yn );
                              *xn     -= xerr / 2;
                              *(xn+1) = *xn + xerr;
                              *(yn+1) = *yn;
                              AG_VN2U( *xn, *yn, xbar, ybar );
                              AG_VN2U( *(xn+1), *(yn+1), xbar+1, ybar+1 );
                              AG_GPLL( xbar, ybar, 2 );
                              break;
                        }
                   }
              }
         }
    }
if ( ltype > 0 )
   { (void) sprintf( buff, "lstyl=%1d", ltype );
     AG_SSET( buff );
   }
}

