/*===========================================================================
  Copyright (C) 1995-2005 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  module TRACESUBS
.LANGUAGE    C
.AUTHOR      K. Banse			IPG-ESO Garching
.KEYWORDS    
.COMMENTS    holds routines: SWAP_PNT, CURS_SETUP, GET_CPOS & END_PNT

.ENVIRONment MIDAS
             #include <midas_def.h>   Prototypes for MIDAS interfaces
             #include <idinumd.h>     Global variables for DISPLAY interfaces
 
.VERSIONS    1.00       940712  from TRACE.FOR    R.M. van Hees

 051019		last modif

------------------------------------------------------------*/

/* Define _POSIX_SOURCE to indicate that this is a POSIX program */

#define  _POSIX_SOURCE 1

#include <midas_def.h>
#include <idinumd.h>

#ifndef TRUE
#define TRUE            1
#define FALSE           0
#endif
 
/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  SWAP_PNT
.PURPOSE     swap two points in a struct
.INPUT/OUTPUT
  input:
         int    indx1        :
         int    indx2        :
         struct Point *array :	
         
.RETURNS     nothing
--------------------------------*/

void SWAP_PNT( indx1, indx2, array )
int    indx1, indx2;
struct Point *array;

{
struct Point swap[1];

swap->px  = array[indx1].px;
swap->py  = array[indx1].py;
array[indx1].px = array[indx2].px;
array[indx1].py = array[indx2].py;
array[indx2].px = swap->px;
array[indx2].py = swap->py;
}
 
/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  CURS_SETUP
.PURPOSE     initialize cursor(s)
.INPUT/OUTPUT
  input:
         int    ncurs         : number of cursors
         int    cform         : shape of cursor
         int    color         : color of cursor
         
.RETURNS     nothing
--------------------------------*/

void CURS_SETUP(ncurs,cform,color)
int    ncurs, cform, color;

{
int pos[4];
int actvals, knul, unit, dazhld[2];

pos[0] = pos[1] = 255;
pos[2] = pos[3] = 400;

(void) SCKRDI( "DAZHOLD", 1, 2, &actvals, dazhld, &unit, &knul );


/* if cursors are already used, do not overwrite them...  */

if ( dazhld[1] != -1 )
   {
   if ( *dazhld == 0 )
      pos[0] = pos[1] = -1;                        /* use old cursor0 */
   else if ( *dazhld == 1 )
      pos[2] = pos[3] = -1;                        /* use old cursor1 */
   else
      {
      pos[0] = pos[1] = -1;                  /* use old ROI corners */
      pos[2] = pos[3] = -1;
      }
   }

if (ncurs > 1) 
   SETCUR_C(QDSPNO,1,cform,color,pos+2);
SETCUR_C(QDSPNO,0,cform,color,pos);
}
 
/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  GET_CPOS
.PURPOSE     return raw cursor positions
.INPUT/OUTPUT
  input:
         int   zoomwn  :        zoom window flag (>0 = yes)
         char  *actflg :        '1' for extra/trace;
				'2' for extra/rotatated;
				'3' for extra/rtrace;
				'4' for extra/ctrace
         int   curfl   :        cursor flag
         int   ncurs   :	number of cursors
  in/output:
         int   *iter   :        number of times the user get's a new chance
  output:
         int   *enter  :	enter key pushed or not
         struct Point cpos[2] :	raw cursor position
         
.RETURNS     if status != 0: user wants to leave the program
--------------------------------*/

int GET_CPOS(zoomwn,actflg,curfl,ncurs,iter,enter,cpos)
int    zoomwn, curfl, ncurs, *iter, *enter;
char  *actflg;
struct Point *cpos;

{
int   statA, statB, xyA[5], xyB[5];

float xyinfoA[7], xyinfoB[7];
 

static int  ipo, auxflg, old_ncurs = -1;
static char *info_usr = "switch cursor(s) on - next time we exit...";
static char *actio = "NNY ZC ";
static char frame[80];



/* we work with a zoom window  */

if (zoomwn > 0)
   {
   if (old_ncurs != ncurs)
      {
      old_ncurs = ncurs;
      (void) strcpy(frame,"   ");
      if (ncurs == 0)
         actio[6] = '0';
      else
         actio[6] = '3';

      if (*actflg == '1')
         auxflg = 19;
      else if (*actflg == '3')
         auxflg = 17;
      else if (*actflg == '4')
         auxflg = 18;
      ipo = 2;
      }

Cw_loop:
   GetCursor(actio,frame,xyinfoA,&statA,xyinfoB,&statB);
   if ( ncurs < 2 ) statB = 0;

   if ( statA == 0 && statB == 0 )                 /* EXIT pushed */
      {
      if ( *iter > 0 )
         {
         *iter = 0;
         SCTPUT( info_usr );
         (void) strcpy(frame,"   ");
         goto Cw_loop;                              /* try again */
         }
      else
         return (1);                               /* return EXIT */
      }


   /* return the raw cursor position (for one or both cursors) */

   cpos[0].px = xyinfoA[0];
   cpos[0].py = xyinfoA[1];
   if ( ncurs > 1 )
      {
      cpos[1].px = xyinfoB[0];
      cpos[1].py = xyinfoB[1];
      }
   
   (void) Cauxwnd(auxflg,&ipo,xyA,xyB);
   ipo = 3;					/* erase + plot new one */
   }


/* we work without a zoom window  */

else
   {
   if (old_ncurs != ncurs)
      {
      old_ncurs = ncurs;
      (void) Ccursin(QDSPNO,0,ncurs,xyA,&statA,xyB,&statB);
      }

C_loop:
   (void) Ccursin(QDSPNO,curfl,ncurs,xyA,&statA,xyB,&statB);
   if ( ncurs < 2 ) statB = 0;

   if ( statA == 0 && statB == 0 )                 /* EXIT pushed */
      {
      if ( *iter > 0 )
         {
         *iter = 0;
         SCTPUT( info_usr );
         (void) Ccursin(QDSPNO,0,ncurs,xyA,&statA,xyB,&statB);
         goto C_loop;                              /* try again */
         }
      else
         return (1);                               /* return EXIT */
      }


   /* return the raw cursor position (for one or both cursors) */

   cpos[0].px = xyA[3];
   cpos[0].py = xyA[4];
   if ( ncurs > 1 )
      {
      cpos[1].px = xyB[3];
      cpos[1].py = xyB[4];
      }
   }


*enter = ( statA < 0 ) ? TRUE : FALSE;                 /* enter key touched? */
return (0);
}
 
/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  END_PNT
.PURPOSE     returns (given the dimensions of the image display) the end points
             of a line through a cursor position with a given angle
.INPUT/OUTPUT
  input:
         double rm            :	slope of the line through CPOS
         struct Point *cpos   :	CPOS contains a cursor position
  output:
         int    disp[4]       :	line across the image display
                                 (x_min, x_max, y_min, y_max)
.RETURNS     nothing
--------------------------------*/

void END_PNT( rm, cpos, disp )
int    *disp;
double rm;
struct Point *cpos;

{

disp[0] = 0;						/* get y at x = 0 */
disp[2] = cpos->py - CGN_NINT( cpos->px * rm );

if ( disp[2] < 0 )
   {
   disp[2] = 0;
   disp[0] = cpos->px - CGN_NINT( cpos->py / rm );
   }
else if ( disp[2] > (QDSZY - 1))
   {
   disp[2] = QDSZY - 1;
   disp[0] = cpos->px + CGN_NINT( (disp[2] - cpos->py) / rm );
   }

disp[1] = QDSZX - 1;					/* get y at x = nsx */
disp[3] = CGN_NINT( (disp[1] - cpos->px) * rm ) + cpos->py;
if ( disp[3] < 0 )
   {
   disp[3] = 0;
   disp[1] = cpos->px - CGN_NINT( cpos->py / rm );
   }
else if ( disp[3] > (QDSZY - 1))
   {
   disp[3] = QDSZY - 1;
   disp[1] = cpos->px + CGN_NINT( (disp[3] - cpos->py) / rm );
   }

}

