/*===========================================================================
  Copyright (C) 1993-2011 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  GCURSR
.AUTHOR      R.M. van Hees IPG-ESO Garching
.KEYWORDS    Graphics, Cursor, Table descriptor
.LANGUAGE    C
.PURPOSE     Extract the coordinates and pixel values which can be 
             included/appended in a descriptor, table or keyword
      input: IN_A/C/1/60  = output descriptor, table
             INPUTC/C/1/1 = append flag; default: create/overwrite
             CURSOR/R     = maximum number of coordinate pairs read

.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.2     14-Dec-1993   removed bugs, used lplus, RvH

 110930		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>

#include <midas_def.h>

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

#define MAXPIX          512                 /* maximum frame dimension (X,Y) */
#define MAXSIZ          (MAXPIX * MAXPIX)
#define KEY_EXIT	32	      /* AGL key code for middle mouse buton */

/*
 * here starts the code of the function
 */
int main()
{
int     actvals, allcol, allrow, ii, imf, index, iplx, iply, knul, mxpos, 
        naxis, ncol, nrpix, nsort, stype, tid, xmin, xmax, ymin, ymax, unit, 
        npix[DIMMAX], col[7];
int     linflag;

float   image[4], *p_img;

double  start[PLDIM2], step[PLDIM2];
double  dd1[3], dd2[3]; 		/* for worldcoord conv. */


char    appflg[2], descr[60], uname[82], name[82], table[82], 
        buff[81], text[81], *cpntr, *plnam, *plsrc, *pltyp;
/*
 * initialised variables
 */
int    access = -1,                   /* parameter for PCOPEN set for cursor */
       plmode = -1,                    /* plot mode taken from keyword PMODE */
       felem  =  1,     /* position of the first descriptor value, NO APPEND */
       nrow   =  0,                         /* in case we create a new table */
       nrpos  =  0,                     /* actual number of coordinate pairs */
       key = KEY_EXIT - 1,         /* initial value is not equal to KEY_EXIT */
       tblflg = FALSE,             /* default: output not written to a table */
       desflg = FALSE;        /* default: output not written to a descriptor */

static float  data[7];            /* initialize in/output values for AG_VLOC */

static char tbluni[][17] = { " ", " ", " ", " ", " ", " ", " " }, 
       tbllab[][17] = { "X_AXIS", "Y_AXIS", "PIXEL_NO", "LINE_NO", 
                        "X_COORD", "Y_COORD", "VALUE"}, 
       tblfmt[][17] = { "G13.6", "G13.6", "I6", "I6",
                        "G13.8", "G13.8", "G13.6"},
       trmfmt[][17] = { "%13.6g", "%13.6g", "%6.0f", "%6.0f",
                        "%13.8g", "%13.8g", "%13.6g"},
       *l_header = "     X-axis       Y-axis   Pixel  Line   X-position   Y-position   Pixel_value",
       *s_header = "   Index       X-axis         Y-axis";

char  *inf_app   = "*** INFO: Appending existing table file",
      *inf_cre   = "*** INFO: Creating new table file",
      *err_plot  = "*** WARNING: Graphic cursor outside plotted area";

plnam = osmmget(82);
pltyp = osmmget(21);

/*
 * start of executable code
 */
(void) SCSPRO( "GCURSOR" );                   /*contact with the MIDAS monitor*/

/*
 * get the cursor keyword contents
 */
(void) SCKRDI( "CURSOR", 1, 1, &actvals, &mxpos, &unit, &knul);
PCKRDC( "DNAM", 60, &actvals, plnam );
plnam = strtok( plnam, " " );
PCKRDC( "DTYP", 20, &actvals, pltyp );
pltyp = strtok( pltyp, " " );
CGN_LOWSTR( pltyp );
if ( strncmp( pltyp, "frame", 5 ) == 0 )
    ncol = 7;
else
    ncol = 2;


/*
 * find file name and read header information
 */
(void) SCKGETC("IN_A",1,80,&actvals,name);
(void) CGN_UPCOPY(uname,name,80);

if ( *name != '?'  && strstrs( uname, ",D" ) == NULL )
   { tblflg = TRUE;
     (void) strcpy( table, name );
     if ( (cpntr = strstrs( uname, ",T" )) != NULL )
        *(table + (cpntr-uname)) = '\0';

     if ( (cpntr = strstrs( table, ".tbl" )) != NULL )
        *cpntr = '\0';

     (void) SCKGETC( "INPUTC", 1, 1, &actvals, appflg );
     if ( *appflg == 'a' || *appflg == 'A' )
        { SCTPUT( inf_app );
          (void) TCTOPN( table, F_IO_MODE, &tid );
          (void) TCIGET( tid, &ncol, &nrow, &nsort, &allcol, &allrow );
          for ( ii = 0; ii < ncol; ii++ ) col[ii] = ii+1;
        }
     else
        { SCTPUT( inf_cre );
          (void) TCTINI( table, F_TRANS, F_O_MODE, ncol, nrow, &tid );
          for ( ii = 0; ii < ncol; ii++ )
              (void) TCCINI( tid, D_R4_FORMAT, 1, tblfmt[ii] , tbluni[ii],
                                                  tbllab[ii], col+ii );
        }
   }
else if ( *name != '?'  && (cpntr = strstrs( uname, ",D" )) != NULL )
   { desflg = TRUE;
     (void) strncpy( descr, name, (cpntr - uname));
     *(descr + (cpntr-uname)) = '\0';
     (void) SCKGETC( "INPUTC", 1, 1, &actvals, appflg );
     if ( *appflg == 'a' || *appflg == 'A' ) felem = -1;

     if ( strncmp( pltyp, "table", 5 ) == 0 )
        (void) TCTOPN( plnam, F_IO_MODE, &tid );
   }

/*
 * restore the graphics display
 */

PCOPEN( " ", " ", access, &plmode );

AG_SSET( "user" );
PCKRDI( "STYPE", 1, &actvals, &stype );
stype -= 1;

/*
 * image files
 */

if ( strncmp( pltyp, "frame", 5 ) == 0 )
   { (void) sprintf( buff, "Frame: %s", plnam );
     SCTPUT( buff );
     SCTPUT( l_header );
/*
 * get frame characteristics
*/
     (void) SCFOPN( plnam, D_R4_FORMAT, 0, F_IMA_TYPE, &imf );
     (void) SCDRDI( imf, "NAXIS", 1, 1, &actvals, &naxis, &unit, &knul );
     naxis = MYMIN( naxis, PLDIM2 );
     (void) SCDRDI( imf, "NPIX" , 1, naxis, &actvals, npix , &unit, &knul );
     for ( nrpix = 0, ii = 0; ii < naxis ; ii++ ) nrpix *= npix[ii];
     (void) SCDRDD( imf, "START", 1, naxis, &actvals, start, &unit, &knul );
     (void) SCDRDD( imf, "STEP" , 1, naxis, &actvals, step , &unit, &knul );

     linflag = fp2wc(0,imf,dd1,dd2);       /* init + test, if `real' WCS */
     for (ii=0; ii<3; ii++)
       {
       dd1[ii] = 1.0;
       dd2[ii] = 0.0;
       }


     if (desflg)
        (void) SCFMAP( imf, F_IO_MODE, 1, nrpix, &actvals, &cpntr );
     else
        (void) SCFMAP( imf, F_I_MODE, 1, nrpix, &actvals, &cpntr );
     p_img = (float *) cpntr;

/*
 * get size of the plot
 */     
     PCKRDR( "PIXEL", 4, &actvals, image );
     xmin = (int) MYMIN( image[0], image[1] );
     xmax = (int) MYMAX( image[0], image[1] );
     ymin = (int) MYMIN( image[2], image[3] );
     ymax = (int) MYMAX( image[2], image[3] );

     while ( key != KEY_EXIT && nrpos++ < mxpos )
        { if ( PCGCUR( data, data+1, &key ) == ERR_NORMAL && key != KEY_EXIT )
             { if ( image[0] == image[1] )
                  { iplx = (int) image[0];
                    iply = NINT( (data[0] - start[1])/step[1] ) + 1;
                  }
               else if ( image[2] == image[3] )
                  { iplx = NINT( (data[0] - start[0])/step[0] ) + 1;
                    iply = (int) image[2];
                  }
               else 
                  { iplx = NINT( (data[0] - start[0])/step[0] ) + 1;
                    iply = NINT( (data[1] - start[1])/step[1] ) + 1;
                  }

               if ( (iplx < xmin || iplx > xmax) || 
                    (iply < ymin || iply > ymax) ) 
                  SCTPUT( err_plot );
               else
                  { AG_GPLM( data, data+1, 1, stype );
                    index = (iply - 1) * npix[0] + iplx;
                    data[2] = (float) iplx;
                    data[3] = (float) iply;
                    data[6] = *(p_img + index-1);

/*  orig. code used only linear world coord system	KB 011024

		   if ( image[0] == image[1] )
                       data[4] = data[0];
                    else
		       data[4] = (float) ((iplx - 1) * step[0] + start[0]); 
                    if ( image[2] == image[3] )
                       data[5] = data[1];
                    else
		       data[5] = (float) ((iply - 1) * step[1] + start[1]); 
*/

		    /* convert frame pixels to world coords */

                    dd1[0] = (double) iplx;
                    dd1[1] = (double) iply;
                    if (fp2wc(1,imf,dd1,dd2) != 0)             /* flag = 1: fp -> wc */
                       SCETER(77,"conversion to world coords. failed...");
		    else
                       {
		       data[4] = (float) dd2[0];
		       data[5] = (float) dd2[1];
		       }

                    (void) SCKWRR( "OUTPUTR", data, 1, ncol, &unit );
		  
                    if ( tblflg )
                       { nrow ++;
                         (void) TCRWRR( tid, nrow, ncol, col, data );
                       }
                    else if ( desflg )
                       { (void)SCDWRR( imf, descr, data, felem, ncol, &unit );
                    if (felem != -1)
                       felem = felem+ncol;
                       }
/*
 * write to terminal
 */
                    *buff = '\0';
                    for ( ii = 0; ii < ncol; ii++ )
                        { (void) sprintf( text, trmfmt[ii], data[ii] );
                          (void) strcat( buff, text );
                        }
                    SCTPUT( buff );
                  }
             }
        }
     (void) SCFUNM( imf );
   }

else
   { if ( strncmp( pltyp, "table", 5 ) == 0 )
        (void) sprintf( buff, "Table: %s", plnam );
     else if ( strncmp( pltyp, "descr", 5 ) == 0 )
        { if ( (plsrc = strchr( plnam, ',' )) != NULL )
	    {
             cpntr = strstrs(plnam, "," );
             *(plnam + (cpntr-plnam)) = '\0';
             (void) sprintf( buff, "Frame/Table: %s - Descriptor: %s", 
                             plnam, ++plsrc );
	    }
          else
             (void) sprintf( buff, "Frame/Table: %s - Descriptor: %s",
                             plnam, "unknown" );
        }
     else if ( strncmp( pltyp, "keywd", 5 ) == 0 )
        (void) sprintf( buff, "Keyword: %s", plnam );
     else
        (void) sprintf( buff, "Unknown data source: %s", plnam );
     SCTPUT( buff );
     SCTPUT( s_header );

     while ( key != KEY_EXIT && nrpos < mxpos )
        { if ( PCGCUR( data, data+1, &key ) == ERR_NORMAL && key != KEY_EXIT )
             { AG_GPLM( data, data+1, 1, stype );
               (void) SCKWRR( "OUTPUTR", data, 1, ncol, &unit );

               if ( tblflg )
                  { nrow++;
                    (void) TCRWRR( tid, nrow, ncol, col, data );
                  }
               else if ( strncmp( pltyp, "table", 5 ) == 0 && desflg )
                  { (void) SCDWRR( tid, descr, data, felem, ncol, &unit );
                    if (felem != -1)
                       felem = felem+ncol;
                  }
/*
 * write to terminal
 */
               nrpos++;
               (void) sprintf( buff, "%5d %13.6g %13.6g", 
                               nrpos, data[0], data[1] );
               SCTPUT( buff );
             }
        }
  }
/*
 * good bye and finish
 */
if ( tblflg || ( strncmp( pltyp, "table", 5 ) == 0 && desflg ) )
   {
   char  bbb[120];

   ii = (int) strlen(plnam);
   if (ii > 80) plnam[80] = '\0';
   ii = sprintf(bbb,"Created via GET/GCURSOR with image: %s",plnam);
   if (ii < 80)
      ii = 80;
   else
      ii = ii + 2;
   (void) SCDWRC(tid,"HISTORY",1,bbb,1,ii,&unit);
   (void) TCTCLO( tid );
   }

PCCLOS();

return SCSEPI();
}
