/*===========================================================================
  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 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  OVRLIN
.AUTHOR      R.M. van Hees IPG-ESO Garching
.KEYWORDS    Graphics, table, one-dimensional plotting
.LANGUAGE    C
.PURPOSE     Plot a line in an existing plot
      input: INPUTI/I/1/1 = l_type (default: solid line )
             P2/C/1/32    = start world coordinates or "C" for the curcur
             P3/C/1/32    = if (P2 != "C") end world coordinates 

.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>      General symbols for Plot routines

.VERSION     1.1     13-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
 */
#include <string.h>
#include <stdio.h>

#include <midas_def.h>

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

#undef  REAL
#define REAL		2                  /* type conversion in CGN-routine */
#define NRXY		2      /*maximal no. of output values for CGN-routine*/

/*
 * here starts the code of the function
 */
int main()
{
int     actvals, color, ii, knul, key, len, ltype, pixval, unit, 
        idum[2], stat,  xysize[2], ixmin, ixmax, iymin, iymax;
float   dval[2], xy[2], xant[2], yant[2], 
        xmin, xmax, ymin, ymax, clpl[4], wcfram[8];
double  ddum[2];
char    *pntr, copt[3], draw[13], nodraw[13], cinput[33], cstring[33], 
        text[81], cmnd[256];

char    *device, *dname, *kname;

/*
 * initialised variables
 */
int     access =  1,                 /* parameter for PCOPEN: overplot mode  */
        plmode = -1,                   /* plot mode taken from keyword PMODE */
        nocolo = 8,
        move   = 0,                       /* cursor move = 1 or non-move = 0 */
        pos    = FALSE;

static float xx[2], yy[2],
       nclip[] = { 0.0, 1.0, 0.0, 1.0 },
       nfram[] = { 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0 };
        
char *fmt      = "OVERPLOT/LINE %1d %12.6f, %12.6f %12.6f, %12.6f",
     *err_1inp = "*** FATAL: Illegal first coordinate input, try again",
     *err_2inp = "*** FATAL: Illegal second coordinate input, try again",
     *err_noln = "*** FATAL: Line type is ZERO (0); invisible line",
     *err_ltyp = "*** FATAL: Undefined line type: no line drawn",
     *err_xmm  = "*** FATAL: x coordinate should fall between: %6.1f and %6.1f mm",
     *err_ymm  = "*** FATAL: y coordinate should fall between: %6.1f and %6.1f mm",
     *err_sc   = "*** FATAL: x/y screen coordinate illegal; display has %4d x %4d screen pixels",
     *errdev   = "*** FATAL: screen coordinates only supported for display devices";
/*
 * start of executable code
 */
(void) SCSPRO( "OVRLIN" );                   /*contact with the MIDAS monitor*/

/*
 * get User parameters
 */
(void) SCKGETC( "P2", 1, 32, &actvals, cinput );
CGN_LOWSTR( cinput );
/*
 * get the first coordinate
 */
if ( *cinput != 'c' )
      { pos = TRUE;

     if ( (pntr = strstrs( cinput, ",wo" )) != NULL )
        { (void) strcpy( copt, "wo" );
          (void) strncpy( cstring, cinput, (pntr - cinput));
          cstring[pntr - cinput] = '\0';
	}
     else if ( (pntr = strstrs( cinput, ",mm" )) != NULL )
        { (void) strcpy( copt, "mm" );
          (void) strncpy( cstring, cinput, (pntr - cinput));
          cstring[pntr - cinput] = '\0';
        }
     else if ( (pntr = strstrs( cinput, ",sc" )) != NULL )
        { (void) strcpy( copt, "sc" );
          (void) strncpy( cstring, cinput, (pntr - cinput));
          cstring[pntr - cinput] = '\0';
        }
     else if ( (pntr = strstrs( cinput, ",no" )) != NULL )
        { (void) strcpy( copt, "no" );
          (void) strncpy( cstring, cinput, (pntr - cinput));
          cstring[pntr - cinput] = '\0';
        }
     else
        { (void) strcpy( copt, "wo" );
          (void) strcpy( cstring, cinput );
        }

     actvals = CGN_CNVT( cstring, REAL, NRXY, idum, xy, ddum );
     if ( actvals < 2 ) SCETER( 1, err_1inp );
     xx[0] = xy[0];
     yy[0] = xy[1];

/*
 * get the second coordinate
 */
     (void) SCKGETC( "P3", 1, 32, &actvals, cinput );
     CGN_LOWSTR( cinput );
     if ( (pntr = strstrs( cinput, ",wo" )) != NULL )
        { (void) strcpy( copt, "wo" );
          (void) strncpy( cstring, cinput, (pntr - cinput));
          cstring[pntr - cinput] = '\0';
	}
     else if ( (pntr = strstrs( cinput, ",mm" )) != NULL )
        { (void) strcpy( copt, "mm" );
          (void) strncpy( cstring, cinput, (pntr - cinput));
          cstring[pntr - cinput] = '\0';
        }
     else if ( (pntr = strstrs( cinput, ",sc" )) != NULL )
        { (void) strcpy( copt, "sc" );
          (void) strncpy( cstring, cinput, (pntr - cinput));
          cstring[pntr - cinput] = '\0';
        }
     else if ( (pntr = strstrs( cinput, ",no" )) != NULL )
        { (void) strcpy( copt, "no" );
          (void) strncpy( cstring, cinput, (pntr - cinput));
          cstring[pntr - cinput] = '\0';
        }
     else
        { (void) strcpy( copt, "wo" );
          (void) strcpy( cstring, cinput );
        }

     actvals = CGN_CNVT( cstring, REAL, NRXY, idum, xy, ddum );

     if ( actvals < 2 ) SCETER( 2, err_2inp );
     xx[1] = xy[0];
     yy[1] = xy[1];
   }
/*
 * setup graphic device according to MIDAS settings
 */
PCOPEN( " ", " ", access, &plmode );

(void) SCKRDI( "INPUTI", 1, 1, &actvals, &ltype, &unit, &knul );
if ( ltype == 0 ) SCETER( 3, err_noln );
if ( ltype < 0 || ltype > 7 ) SCETER( 4, err_ltyp );

/*
 * set line type to solid line
 */
(void) sprintf( text, "lstyl=%1d", ltype-1 );
AG_SSET( text );

/*
 * get color
 */ 
(void) AG_IGET( "colo", &color );
(void) sprintf( draw, "color= %1d", color );
(void) sprintf( nodraw, "color= %1d", nocolo );

/*
 * get viewport settings
 */
PCKRDR( "CLPL",  4, &actvals, clpl );
PCKRDR( "XWNDL", 4, &actvals, wcfram );
PCKRDR( "YWNDL", 4, &actvals, wcfram+FOR_Y );

/*
 * symbol by coordinate input of cursor
 */
if ( pos )
   { if ( strncmp( copt, "wo", 2 ) == 0 )
        { nfram[0] = wcfram[0] -
                     clpl[0] * (wcfram[1] - wcfram[0])/(clpl[1] - clpl[0]);
          nfram[1] = wcfram[1] + (1.0 - clpl[1]) * (wcfram[1] - wcfram[0])/
                                                   (clpl[1] - clpl[0]);
          nfram[2] = wcfram[2];
          nfram[3] = wcfram[3];
          nfram[4] = wcfram[4] -
                     clpl[2] * (wcfram[5]-wcfram[4]) / (clpl[3] - clpl[2]);
          nfram[5] = wcfram[5] + (1.0 - clpl[3]) * (wcfram[5] - wcfram[4])/
                                                   (clpl[3] - clpl[2]);
          nfram[6] = wcfram[6];
          nfram[7] = wcfram[7];
        }

     else if ( strncmp( copt, "mm", 2 ) == 0 )
        { (void) AG_RGET( "devd", dval );

          /* This part is special for the ESO-DFO group
          and redefines the coordinate reference point for mm */
          SCKGETC("PLCSTAT",74, 7, &actvals, cinput );
          if ( (pntr = strstrs( cinput, "ESO-DFO" )) != NULL )
             { xmin = - 10 * clpl[0] * dval[0];
               xmax = 10 * (1 - clpl[0]) * dval[0];
               ymin = - 10 * clpl[2] * dval[1];
               ymax = 10 * (1 - clpl[2]) * dval[1];}

          else
	    /* This is the default none ESO-DFO part */
             { xmin = 0.0;
               xmax = 10 * dval[0];
               ymin = 0.0;
               ymax = 10 * dval[1];}

          if ( MYMIN( xx[0], xx[1] ) < xmin
               || MYMAX( xx[0], xx[1] ) > xmax )
             { (void) sprintf( text, err_xmm, xmin, xmax );
               SCTPUT( text );
               SETWND( wcfram );
               (void) SCSEPI();
             }
          if ( MYMIN( yy[0], yy[1] ) < ymin
               || MYMAX( yy[0], yy[1] ) > ymax )
             { (void) sprintf( text, err_ymm, xmin, xmax );
               SCTPUT( text );
               SETWND( wcfram );
               (void) SCSEPI();
             }
             
	  /* This part is special for the ESO-DFO group
             and redefines the coordinate reference point */
          if ( (pntr = strstrs( cinput, "ESO-DFO" )) != NULL )
	    { xx[0] = clpl[0] + xx[0] / (10 * dval[0]);
              xx[1] = clpl[0] + xx[1] / (10 * dval[0]);
              yy[0] = clpl[2] + yy[0] / (10 * dval[1]);
              yy[1] = clpl[2] + yy[1] / (10 * dval[1]);}

          else
          /* This is the default none ESO-DFO part */
             { xx[0] = xx[0] / (10 * dval[0]);
               xx[1] = xx[1] / (10 * dval[0]);
               yy[0] = yy[0] / (10 * dval[1]);
               yy[1] = yy[1] / (10 * dval[1]);}              
          }

     else if ( strncmp( copt, "sc", 2 ) == 0 )
        { 
          device = osmmget(31);
          kname  = osmmget(21);
          dname  = osmmget(21);
          (void) SCKGETC( "MID$PLOT", 1, 30, &actvals, device );
          CGN_LOWSTR( device );
          (void) strncpy( kname, device, 20 );
          stat = GETDEV( kname, dname );
          if (strncmp( dname, "graph", 5 ) == 0 )
             (void) SCKRDI("IDIDEV", 32, 2, &actvals, xysize, &unit, &knul);
          else if (strncmp( dname, "image", 5 ) == 0 )
             (void) SCKRDI("IDIDEV", 2, 2, &actvals, xysize, &unit, &knul);
          else 
             (void) SCETER( 2, errdev );

          ixmin = 0;
          ixmax = xysize[0]-1;
          iymin = 0;
          iymax = xysize[1]-1;

           if ( MYMIN( xx[0], xx[1] ) < ixmin
               || MYMAX( xx[0], xx[1] ) > ixmax )
             { (void) sprintf( text, err_sc, ixmax, iymax );
               SCTPUT( text );
               SETWND( wcfram );
               (void) SCSEPI();
             }
           if ( MYMIN( yy[0], yy[1] ) < iymin
               || MYMAX( yy[0], yy[1] ) > iymax )
             { (void) sprintf( text, err_sc, ixmax, iymax );
               SCTPUT( text );
               SETWND( wcfram );
               (void) SCSEPI();
             }

          xx[0] = xx[0]/xysize[0];
          xx[1] = xx[1]/xysize[0];
          yy[0] = yy[0]/xysize[1];
          yy[1] = yy[1]/xysize[1];
        }

     else if ( strncmp( copt, "no", 2 ) == 0 )
        {
          xmin = 0.0;
          xmax = 1.0;
          ymin = 0.0;
          ymax = 1.0;

          if ( MYMIN( xx[0], xx[1] ) < xmin
               || MYMAX( xx[0], xx[1] ) > xmax )
             { (void) sprintf( text, err_xmm, xmin, xmax );
               SCTPUT( text );
               SETWND( wcfram );
               (void) SCSEPI();
             }
          if ( MYMIN( yy[0], yy[1] ) < ymin
               || MYMAX( yy[0], yy[1] ) > ymax )
             { (void) sprintf( text, err_ymm, xmin, xmax );
               SCTPUT( text );
               SETWND( wcfram );
               (void) SCSEPI();
             }

          xx[0] = xx[0];
          xx[1] = xx[1];
          yy[0] = yy[0];
          yy[1] = yy[1];
        }

     (void) AG_CDEF( nclip[0], nclip[1], nclip[2], nclip[3] );
     SETWND( nfram );
     AG_GPLL( xx, yy, 2 );
     move = 1;
     for ( ii = 0; ii < 2; ii++ )
         { xant[ii] = xx[ii];
           yant[ii] = yy[ii];
	 }
   }
else
   { nfram[0] = wcfram[0] -
                clpl[0] * (wcfram[1] - wcfram[0]) / (clpl[1] - clpl[0]);
     nfram[1] = wcfram[1] + (1.0 - clpl[1]) * (wcfram[1] - wcfram[0])/
                                              (clpl[1] - clpl[0]);
     nfram[2] = wcfram[2];
     nfram[3] = wcfram[3];
     nfram[4] = wcfram[4] -
                clpl[2] * (wcfram[5]-wcfram[4]) / (clpl[3]-clpl[2]);
     nfram[5] = wcfram[5] + (1.0 - clpl[3]) * (wcfram[5] - wcfram[4])/
                                              (clpl[3] - clpl[2]);
     nfram[6] = wcfram[6];
     nfram[7] = wcfram[7];
     (void) AG_CDEF( nclip[0], nclip[1], nclip[2], nclip[3] );
     SETWND( nfram );

     AG_MSUS();
     key  = 1; 
     while ( key == 1 )
           { AG_VLOC( xx, yy, &key, &pixval );
             if ( key == 1 ) AG_VLOC( xx+1, yy+1, &key, &pixval );
             if ( move == 1 )
                { AG_SSET( nodraw );
                  AG_GPLL( xant, yant, 2 );
                }
             AG_SSET( draw );
             if ( key == 1 )
                { AG_GPLL( xx, yy, 2 );
                  for ( ii = 0; ii < 2; ii++ )
                      { xant[ii] = xx[ii];
                        yant[ii] = yy[ii];
                      }
                  move = 1;
                }   
           }
     if ( move == 1 )
        { AG_MRES();
          AG_GPLL( xant, yant, 2 );
          AG_VUPD();
        }
   }

if (move == 1)
   {
   (void) sprintf( cmnd, fmt, ltype, xant[0], yant[0], xant[1], yant[1] );
   len = strlen( cmnd );
   stat = SCKWRC("MID$LINE", 1, cmnd, 1, len, &unit );
   }
/*
 * goodbye and finish
 */
(void) AG_CDEF( clpl[0], clpl[1], clpl[2], clpl[3] );
SETWND( wcfram );

PCCLOS();

return SCSEPI();
}

