/*===========================================================================
  Copyright (C) 1995-2012 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
===========================================================================*/


#include <string.h>
#include <stdio.h>
#include <stdlib.h>

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

static int  cntitt, cntlut, lut2sz;
static int  d_row = -1, d_colu = -1;

static float array[1536];
static float rlut[6][768];                  /* 4608  values */
static float ritt[6][256];                  /* 1536  values */

extern int  logview_init(), display_it();

/*

*/

#ifdef __STDC__
      static void LUTsav( int iflg )
#else
      static void LUTsav( iflg )
      int iflg;				/*IN: = 0, save current LUT,
					      = 10, save current ITT */
#endif

{
int  nf;
register int nr;

if (iflg < 10)
   {						/*  here for LUTs  */
   nf = cntlut - 1;
   (void) IILRLT_C(QDSPNO,0,0,QLUTSZ,&rlut[nf][0]);     /* read current lut */
  
   for (nr=0; nr<QLUTSZ; nr++)
      {
      array[nr] = rlut[nf][nr];
      array[nr+QLUTSZ] = rlut[nf][nr+QLUTSZ];
      array[nr+lut2sz] = rlut[nf][nr+lut2sz];
      }
   }
else
   {						/* here for ITTs */
   nf = cntitt - 1;
   (void) IILRIT_C(QDSPNO,QIMCH,0,0,QLUTSZ,
                   &ritt[nf][0]); 		  /* read current ITT */
  
   for (nr=0; nr<QLUTSZ; nr++)
      array[nr] = ritt[nf][nr];
   }
}

/*

*/

void auxhelp(flg)
int flg;		 		/* IN: 0, -1 = basic, 1 = VIEW help,
					       -9 init for local view,
					       -10 init for parallel view */

{
static int savflg=0;

static char  *help0 = 
"With cursor inside the display window you can use the following keys:";
static char  *help1 = " h = get this help, z = zoom up, x = zoom down";
static char  *help21 = 
   " c = cycle through different colour LUTs (and enable for zoom window)";
static char  *help22 = 
   " b = load b+w LUT,(and enable for zoom window)";
static char  *help23 = 
   " l = modify LUT via arrow keys (for zoom window)";
static char  *help31 = 
   " i = cycle through different ITTs (and apply to zoom window)";
static char  *help32 = 
   " j = clear ITT (and apply to zoom window)";
static char  *help33 = 
   " k = modify ITT via arrow keys (for zoom window)";
static char  *help4 = 
   " u = toggle looking glass mode (zoom on the fly)";
static char  *help44 = 
" g = get cursor values from last extracted sub-image in zoom window";
static char  *help5 = 
"if not in LUT/ITT modify loop ('l', 'k'), use the arrow keys to scroll image";
static char  
   *help6 = " m = modify cuts and redisplay subimage or full image";
static char  *help71 = 
   " t = cycle through different  plot options (initially = histogram)";
static char  *help72 = 
   " s = cycle through different cut options for zoom window ";
static char  *help81 = 
   " p = make hardcopy of graphics window";
static char  *help82 = 
   " q = make hardcopy of zoom window";
static char  *help83 = 
   " e = extract subimage ";
static char  *help9 = " v = toggle statistics/magnitude option ";
static char  
   *help10 = " a = modify radius for magnitude, nomansland, background";


static char infofile[] = "/tmp/get_cur.info";




if (flg >= 0) 
   savflg = flg; 
else 
   {
   if (flg == -9)
      {
      infofile[0] = '\0';			/* no parallel display */
      (void) logview_init(infofile);
      return;
      }
   else if (flg == -10)
      {
      (void) logview_init(infofile);		/* use parallel display */
      return;
      }
   }
          
(void) display_it(help0,0);
(void) display_it(help1,0);
(void) display_it(help21,0);
(void) display_it(help22,0);
(void) display_it(help23,0);
(void) display_it(help31,0);
(void) display_it(help32,0);
(void) display_it(help33,0);
(void) display_it(help4,0);

if (savflg == 1)     
   {
   (void) display_it(help44,0);
   (void) display_it(help6,0);
   (void) display_it(help71,0);
   (void) display_it(help72,0);
   (void) display_it(help9,0);
   (void) display_it(help10,0);
   (void) display_it(help81,0);
   (void) display_it(help82,0);
   (void) display_it(help83,0);
   }

(void) display_it(help5,0);

}

/*

*/

#ifdef __STDC__
      static void drawline(int *dsp,int iflg,int erase,int *old, 
                           int *current,int *sizaux)
#else
      static void drawline(dsp,iflg,erase,old,current,sizaux)
      int   *dsp, iflg, erase, *old, *current, *sizaux;
#endif

{
int xya[2], xyb[2];



if (iflg == 1)			/* draw a horizontal line */
   {
   xya[0] = 0;
   xya[1] = sizaux[0] - 1;
   if (erase != 2)			/* erase old line */
      {
      if (*old == -1) *old = *current;
      if (d_row != -1)
         {
         xyb[0] = sizaux[1] + (*old);
         xyb[1] = xyb[0];
         (void) IIGPLY_C(*dsp,*(dsp+1),xya,xyb,2,99,1);
         d_row = -1;
         }
      }

   if (erase != 1)			/* draw new line */
      {
      if (d_row != 1)
         {
         xyb[0] = sizaux[1] + *current;
         xyb[1] = xyb[0];
         (void) IIGPLY_C(*dsp,*(dsp+1),xya,xyb,2,99,1);
         d_row = 1;
         }
      *old = *current;
      }
   }

else if (iflg == 2)			/* draw a vertical line */
   {
   xyb[0] = 0;
   xyb[1] = sizaux[0] - 1;
   if (erase != 2)			/* erase old line */
      {
      if (*old == -1) *old = *current;
      if (d_colu != -1)
         {
         xya[0] = sizaux[1] + (*old);
         xya[1] = xya[0];
         (void) IIGPLY_C(*dsp,*(dsp+1),xya,xyb,2,99,1);
         d_colu = -1;
         }
      }

   if (erase != 1)			/* draw new line */
      {
      if (d_colu != 1)
         {
         xya[0] = sizaux[1] + (*current);
         xya[1] = xya[0];
         (void) IIGPLY_C(*dsp,*(dsp+1),xya,xyb,2,99,1);
         d_colu = 1;
         }
      *old = *current;
      }
   }

else				/*  connect the two cursors */
   {
   if (erase != 2)                  /* erase old line */
      {
      if (*old == -1) *old = current[0];
      if (old[1] == -1) old[1] = current[1];
      if (old[2] == -1) old[2] = current[2];
      if (old[3] == -1) old[3] = current[3];
      xya[0] = *old;
      xya[1] = old[2];
      xyb[0] = old[1];
      xyb[1] = old[3];
      (void) IIGPLY_C(*dsp,*(dsp+1),xya,xyb,2,99,1);
      }

   if (erase != 1)			/* draw new line */
      {
      xya[0] = current[0];
      xya[1] = current[2];
      xyb[0] = current[1];
      xyb[1] = current[3];
      (void) IIGPLY_C(*dsp,*(dsp+1),xya,xyb,2,99,1);
      *old = current[0];
      old[1] = current[1];
      old[2] = current[2];
      old[3] = current[3];
      }
   }
}

/*

*/

/*++++++++++++++++++++++++++++++++++++++++++++++++++

 main function Cauxwnd

.LANGUAGE  C

.IDENTIFICATION 
  routine Cauxwnd			1.00	940228,	from auxwnd.for

.AUTHOR
  K. Banse         			ESO - Garching

.KEYWORDS:
  ImageDisplay, cursor, Xwindow system

.PURPOSE:
  high level interface to read the position of the two cursors
  on a zoomed window and get density of relevant pixel

.ALGORITHM:
  Use single cursor and read screen pixels from zoomed window

.RETURNS
  int status		for `flag' = 2, status of cursor 0:
				          0 = off, 1 = on
.VERSIONS
 030211		last modif

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

int Cauxwnd(flag,info,xya,xyb)
int flag;		/* IN: 0 = initialize
                               3 = redraw square in main window
                                   to get rid of it
                               4 = take action according to key pressed
                                   arrow keys L,R,D,U (counted as -4,-3,-2,-1)
                                   or 0, ..., 9 (counted as 1,..., 10)
                                   or special keys (counted as 11,12,...)
                               5 = only copy memory to zoom w.
                               6 = return updated info of zoom w.
                               7 = draw horizontal trace in main w.
                               8 = draw vertical trace in main w.
                               9 = modify current LUT
                              10 = only get corners of extracted window
                                   and redraw rectangle  
                              17 = draw horizontal trace in zoom w.
                              18 = draw vertical trace in zoom w.
                              19 = connect cursors in zoom w.
                              21 = start cursor input in zoom w.
                              22 = get cursor input in zoom w. */

int *info;		/* IN/OUT: info array, depending on `flag' as follows:
                                   flag=0, 5 input values:
                                     zoomfactor, offsets + size of zoom_window
                                   flag=3, 1 input value:
                                     overlay channel
                                   flag=4, 1 input value:
                                     value depends upon key pressed
                                   flag=5, 2 input values:
                                     memory involved, overlay channel
                                   flag=6, 11 output values:
                                    dispno of zoom_window,x,y-sizes,
				    eff. x,y-zoomfacts,corners of rectangle,
				    cursor pixels
                                   flag=7, 1 input value:
                                     1, erase old line
                                     2, draw new line
                                   flag=8, 1 input value:
                                     1, erase old vertical line
                                     2, draw new vertical line
                                   flag=9, 1 input value:
                                     25 for LUT, 26 for ITT
                                   flag=10, 2 input values:
                                     memory involved, overlay channel
                                   flag=11, 1 input value:
                                     value depends upon key pressed  
                                   flag=21, 5 input values:
                                     memory involved, overlay channel, spare,
                                     cursno for zoom window, polling mode
                                   flag=22, 2 input values:
				     start frame pixels in main w.  */

int *xya;		/* IN/OUT: if flag = 0, xya[0] = 1/0 to yes/no 
					   write the initial zoom factor
                                   = 5, lower left corner of window (OUT) 
				   = 21, screen-chan pixels in main window (IN)
                                   = 22, frame pixels of cursor 0 in
                                        zoom window (OUT)  */

int *xyb;		/* IN/OUT: if flag = 5, upper right corner of 
				         window (OUT) 
                                   = 22, frame pixels of cursor 1 in
                                        zoom window (OUT)  */


{
int   stata, stat, iav, uni, nulo;
int   xtmp[5], ytmp[5], imno, dspinfo[2], sizaux[2];
register int nr;
static int  jinc = 3, xc = -1, yc = -1, lmodif = 0, imodif = 0;
static int  dszy, rcdraw, oldyc, oldxc, poll, zoomch, lsta;
static int  luton, itton, fixlut, mx, my;
static int  kk[14], xr[5], yr[5], hix, hiy;
static int  znoc, zoomwn[5], efzoom[2];
static int  curco[5], oldxz, oldyz, oldxzz, oldyzz, trgsta[10];
static int  cursint, lastdraw, ma, mb, memo, ovmem;

char   cb, outp[78];

static float rr, rx, ry, rlo, rhi, rd, rz, rval, rql;





/* first non-arrow key breaks LUT/ITT loop */

if (lmodif == 1)     
   {
   if ((flag != 9) && (flag != 4)) lmodif = 0;
   }
if (imodif == 1)     
   {
   if ((flag != 9) && (flag != 4)) imodif = 0;
   }


/*  branch according to `flag' */

switch (flag)
   {

   case 0:

   /*  FLAG = 0  -  get geometry of zoom window  */

   zoomwn[2] = info[0];                   /* zoom factor */
   if (info[1] > 0)                    /* xsize,ysize */
      {
      zoomwn[0] = info[1];
      zoomwn[1] = info[2];
      }
   else
      {
      zoomwn[0] = QDSZX / 2;
      zoomwn[1] = QDSZY / 2;
      }
   if (info[3] >= 0)                    /* xoff,yoff */
      {
      zoomwn[3] = info[3];
      zoomwn[4] = info[4];
      }
   else
      {
      zoomwn[3] = QDSZX + 2;
      zoomwn[4] = 0;
      }

   if (QXAUX < 1)		/* zoom window not there yet */
      {
      int dazdevr[20], dinfo[10];

      (void) SCKRDI("DAZDEVR",1,20,&iav,dazdevr,&uni,&nulo);
      dinfo[0] = 0;
      dinfo[1] = zoomwn[0];
      dinfo[2] = zoomwn[1];
      dinfo[3] = zoomwn[3];
      dinfo[4] = zoomwn[4];
      dinfo[5] = QNOLUT;
      dinfo[6] = QLUTSZ;
      dinfo[7] = dazdevr[0];  
      dinfo[8] = dazdevr[3];  
      dinfo[9] = 0;  
      Getactdsp(outp, outp+20 );	  /* get Midas unit + display window */
      outp[5] = outp[20];
      outp[6] = 'z';
      outp[7] = '\0';		                         /* outp = "sxw220z" */
      (void) strcpy( outp+20, "zoom " );
      (void) SetupIDI( outp, outp+20, dinfo );
      }

   DCOPEN(3);                                   /* ZDSPNO set in DCOPEN... */

   if ((QXAUX < 1) || (QYAUX < 1)) 
      SCETER(63,"ididev(19,20) are corrupted...");
   zoomwn[0] = QXAUX;
   zoomwn[1] = QYAUX;
 
   dszy = QDSZY - 1;
   (void) IIDRST_C(ZDSPNO);
   xtmp[0] = 0;
   xtmp[1] = 1;
   (void) IIMCMY_C(ZDSPNO,xtmp,2,0);	/* clear ima, ovchan of zoom_window */

   rcdraw = 0;                                   /* indicate it's first time */
   lastdraw = 0;
   cursint = 0;
   oldxc = -1;
   oldyc = -1;
   oldxz = -1;
   oldyz = -1;
   zoomch = 1;                                   /* clear zoom_window */
   lut2sz = QLUTSZ + QLUTSZ;
   
   hix = SSPX + NSX - 1;
   hiy = SSPY + NSY - 1;


   /*  here we fill the LUTs and ITTs  */

   (void) SCKGETC( "HCITTLUT", 1, 40, &iav, outp );
   rr = 1./(QLUTSZ-1);                      /* construct black + white LUT */

   for (nr=0; nr<QLUTSZ; nr++)
      {
      rval = nr * rr;
      ritt[5][nr] = rval;
      rlut[5][nr] = rval;
      rlut[5][QLUTSZ+nr] = rval;
      rlut[5][lut2sz+nr] = rval;
      }

   if ( strncmp( outp+20, "ramp ", 5 ) == 0 )
      {
      for (nr=0; nr<QLUTSZ; nr++)
         {
         rlut[0][nr] = ritt[5][nr];
         rlut[0][QLUTSZ+nr] = ritt[5][nr];
         rlut[0][lut2sz+nr] = ritt[5][nr];
         }
      (void) IILWLT_C(QDSPNO,0,0,QLUTSZ,&rlut[0][0]);
      }
   else
      {
      (void) IILRLT_C(QDSPNO,0,0,QLUTSZ,&rlut[0][0]);  /* read current LUT */
      }

   if (strncmp(outp,"ramp ",5) == 0)
      {
      for (nr=0; nr<QLUTSZ; nr++)
         ritt[0][nr] = ritt[5][nr];
      (void) IILWIT_C(QDSPNO,QIMCH,0,0,QLUTSZ,&ritt[0][0]);
      }
   else							/* read current ITT */
      (void) IILRIT_C(QDSPNO,QIMCH,0,0,QLUTSZ,&ritt[0][0]); 


   /*  now get the fixed LUTs + ITTs from frame MID_SYSTAB:viewluts.aux  */

   stat = SCFINF("MID_SYSTAB:viewluts.aux",99,xyb);
   if (stat == 0)                  /* all o.k., the file is there */
      {
      imno = -1;			/* avoid UMC messages in Ourify */
      (void) SCFOPN("MID_SYSTAB:viewluts.aux",D_R4_FORMAT,0,F_IMA_TYPE,&imno);
      (void) SCFGET(imno,1,1536,&iav,(char *)array);
      MakeLUT(256,array,QLUTSZ,&rlut[1][0]);		/* move to QLUTSZ */
      MakeLUT(256,&array[768],QLUTSZ,&rlut[2][0]);

      (void) SCFGET(imno,1537,1536,&iav,(char *)array);
      MakeLUT(256,array,QLUTSZ,&rlut[3][0]);		/* move to QLUTSZ */
      MakeLUT(256,&array[768],QLUTSZ,&rlut[4][0]);

      (void) SCFGET(imno,3073,1024,&iav,(char *)array);
      MakeITT(256,array,QLUTSZ,&ritt[1][0]);
      MakeITT(256,&array[256],QLUTSZ,&ritt[2][0]);
      MakeITT(256,&array[512],QLUTSZ,&ritt[3][0]);
      MakeITT(256,&array[768],QLUTSZ,&ritt[4][0]);
      (void) SCFCLO(imno);
      fixlut = 1;				/* Yes, we can cycle */
      }
   else
      {
      display_it("could not open frame MID_SYSTAB:viewluts.aux ...",0);
      display_it("so only current LUT and ITT used",0);
      fixlut = 0;				/* so we don't cycle... */
      }

   cntitt = 1;
   cntlut = 1;
   luton = fixlut;
   itton = fixlut;


   /*  show current zoomfactor  */

   if (xya[0] == 1)     
      goto sect_4600;
   else
      return (0);


   case 5:
   case 10:

   /* FLAG = 5 or 10  - copy memory + display it in zoom_window */

   memo = info[0];
   ovmem = info[1];
   if (rcdraw > 0) (void) IIGPLY_C(QDSPNO,ovmem,xr,yr,5,99,1);


   /*  work on lower left corner */

   kk[0] = zoomwn[0] / zoomwn[2];           /* total x-size */
   xc = xya[0];
   kk[4] = xc - (kk[0]/2);                  /* kk[4] = x offset */
   if (SCALX < -1)     
      {
      kk[2] = -SCALX;
      mb = kk[0] / kk[2];
      kk[0] = mb * kk[2];
      }
   else
      {
      kk[2] = 1;
      }
   if (kk[4] < SSPX) kk[4] = SSPX ;

   kk[1] = zoomwn[1] / zoomwn[2];           /* total y-size */
   yc = xya[1];
   kk[5] = yc - (kk[1]/2);                  /* kk[5] = y offset) */
   if (SCALY < -1)     
      {
         kk[3] = -SCALX;
         mb = kk[1] / kk[3];
      kk[1] = mb * kk[3];
      }
   else
      {
      kk[3] = 1;
      }
   if (kk[5] < SSPY) kk[5] = SSPY;


   /*  work on upper right corner */

   ma = kk[4] + kk[0] - kk[2];
   if (ma > hix)     
      {
      kk[4] = kk[4] - (ma - hix);           /* try to adjust lower bound */
      if (kk[4] < SSPX) kk[4] = SSPX;
      ma = hix ;
      }
   kk[6] = ma - kk[4] + 1;                  /* kk[7] = x-size */
   kk[8] = kk[4] + kk[0] - 1;
   if (kk[8] > hix)     
      {
      kk[8] = hix;
      kk[0] = kk[8] - kk[4] + 1;
      }

   ma = kk[5] + kk[1] - kk[3];
   if (ma > hiy)     
      {
      kk[5] = kk[5] - (ma - hiy);           /* try to adjust lower bound */
      if (kk[5] < SSPY) kk[5] = SSPY;
      ma = hiy ;
      }
   kk[7] = ma - kk[5] + 1;                  /* kk[8] = y-size */
   kk[9] = kk[5] + kk[1] - 1;
   if (kk[9] > hiy)     
      {
      kk[9] = hiy;
      kk[1] = kk[9] - kk[5] + 1;
      }
   
   kk[10] = 0;                              /* offset in destination memory */
   kk[11] = 0;
   kk[12] = kk[4] + kk[6] - 1;              /* kk[12,13] = x,y end points */
   kk[13] = kk[5] + kk[7] - 1 ;


   /*  calculate coords of square around cursor and draw it
       convert image memory channel pixels back to display screen pixels */


   xr[0] = kk[4];
   yr[0] = kk[5];
   Sc2ch(-1,xr,yr);
   xr[1] = kk[8];
   yr[2] = kk[9];
   Sc2ch(-1,&xr[1],&yr[2]);
   xr[2] = xr[1];
   xr[3] = xr[0];
   xr[4] = xr[0];
   yr[1] = yr[0];
   yr[3] = yr[2];
   yr[4] = yr[0];
   (void) IIGPLY_C(QDSPNO,ovmem,xr,yr,5,99,1);
   rcdraw = 1;

   xya[0] = kk[4];                   /* get lower left */
   xya[1] = kk[5];                   /* and upper right corner */
   xyb[0] = kk[12];
   xyb[1] = kk[13];
   if (flag == 10) return (0);

   xtmp[0] = 0;
   if (zoomch == 1)     
      {
      zoomch = 0;
      (void) IIMCMY_C(ZDSPNO,xtmp,1,0);        /* clear image memory */
      }


   /*  copy and zoom memory data + make it visible */

   mb = kk[5];
   if (dzmemi[0] > 0)                        /* was image top-down loaded? */
      kk[5] = (QMSZY-1) - kk[13];
   (void) IIMCPV_C(QDSPNO,memo,&kk[4],ZDSPNO,xtmp[0],&kk[10],&kk[0],zoomwn[2]);
   kk[5] = mb;
   return (0);


   case 21:

   memo = info[0];
   ovmem = info[1];

   if (rcdraw > 0) (void) IIGPLY_C(QDSPNO,ovmem,xr,yr,5,99,1);


   /*  calculate coords of square around cursor and draw it
       convert image memory channel pixels back to display screen pixels */

   xr[0] = xya[0];
   yr[0] = xya[1];
   xr[1] = xya[2];
   yr[1] = yr[0];
   xr[2] = xr[1];
   yr[2] = xya[3];
   xr[3] = xr[0];
   yr[3] = yr[2];
   xr[4] = xr[0];
   yr[4] = yr[0];
   (void) IIGPLY_C(QDSPNO,ovmem,xr,yr,5,99,1);
   rcdraw = 1;

   /* start up cursor input in zoom_window */

   znoc = info[3];
   curco[0] = -1;
   curco[1] = -1;
   if (znoc == 12)     			/* circular ROI */
      {
      curco[2] = 10;
      curco[3] = 20;
      curco[4] = 30;
      (void) IICINR_C(ZDSPNO,-1,0,curco[0],curco[1], curco[2],
                      curco[3],curco[4],&mb);
      }
   else
      {
      curco[2] = -1;
      curco[3] = -1;
      if (znoc == 0)
         (void) IICINC_C(ZDSPNO,-1,0,3,0,curco[0],curco[1]);
      else if (znoc == 2)
         (void) IIRINR_C(ZDSPNO,-1,0,curco[0],curco[1],
                                     curco[2],curco[3],&mb);
      else 				/* znoc = 3 => both cursors 0, 1 */
         {
         (void) IICINC_C(ZDSPNO,-1,0,3,0,curco[0],curco[1]);
         (void) IICINC_C(ZDSPNO,-1,1,3,0,curco[2],curco[3]);
         }
      }
   Ccursin(ZDSPNO,0,znoc,xtmp,&stata,ytmp,&stat);

   poll = info[4];                  /* save polling mode for cursor reads */
   cursint = 1;
   return (0);


   case 22:

   /*  FLAG = 22  -  wait for cursor input in zoom_window
		     info[0,1] = start frame pixels in parent display  */

   if (cursint == 1)
      {
      cursint = 0;
      if (znoc == 0)
         (void) IICSCV_C(ZDSPNO,znoc,1);
      else if (znoc == 2)
         (void) IIRSRV_C(ZDSPNO,0,1);
      else if (znoc == 3)
         {
         (void) IICSCV_C(ZDSPNO,0,1);
         (void) IICSCV_C(ZDSPNO,1,1);
         }
      else				/* only circle left */
         (void) IIRSRV_C(ZDSPNO,0,1);

      /* update cross/rectangle/circle drawing in zoom window */

      if (lastdraw > 0)
         {				/* erase last line in zoom w. */
         dspinfo[0] = ZDSPNO;
         dspinfo[1] = 1;
         sizaux[1] = 0;

         if (lastdraw == 1)
            {
            sizaux[0] = zoomwn[0];
            drawline(dspinfo,lastdraw,1,&oldyz,&curco[1],sizaux);
            }
         else if (lastdraw == 2)
            {
            sizaux[0] = zoomwn[1];
            drawline(dspinfo,lastdraw,1,&oldxz,&curco[0],sizaux);
            }
         else 
            {
            ytmp[0] = oldxz;
            ytmp[1] = oldyz;
            ytmp[2] = oldxzz;
            ytmp[3] = oldyzz;
            drawline(dspinfo,lastdraw,1,ytmp,curco,sizaux);
            }
         lastdraw = 0;
         }
      }


sect_22000:
   (void) IIIEIW_C(ZDSPNO,trgsta);
   if (trgsta[0] == 1)     
      {
      (void) IIISTI_C(ZDSPNO);
      return (0);
      }

   if (poll == 1)     			/* if nothing came in loop */
      {
      if ((trgsta[1] == 0) && (trgsta[2] == 0)) goto sect_22000;
      }

   stata = 1;
   if (znoc == 0)     
      {
      (void) IICRCP_C(ZDSPNO,-1,0,&xya[0],&xya[1],&ma);
      }
   else if (znoc == 2)     
      (void) IIRRRI_C(ZDSPNO,-1,0,&xya[0],&xya[1],&xyb[0],&xyb[1],&ma);
   else if (znoc == 3)     
      {
      (void) IICRCP_C(ZDSPNO,-1,0,&xya[0],&xya[1],&ma);
      (void) IICRCP_C(ZDSPNO,-1,1,&xyb[0],&xyb[1],&mb);
      }
   else
      (void) IICRRI_C(ZDSPNO,-1,0,&xya[0],&xya[1],&xyb[0],&xyb[1],&xyb[2],&ma);

   curco[0] = xya[0];		/* cursor coords. in zoom window */
   curco[1] = xya[1];
   curco[2] = xyb[0];
   curco[3] = xyb[1];

   if (trgsta[2] == 1) stata = -2;
   if (trgsta[1] == 1) stata = -1;

   xya[0] = (curco[0] / efzoom[0]) + info[0];
   xya[1] = (curco[1] / efzoom[1]) + info[1];

   if (znoc == 12)     
      {
      xyb[0] = xyb[0] / efzoom[0];
      xyb[1] = xyb[1] / efzoom[1];
      xyb[2] = xyb[2] / efzoom[0];
      }
   else if (znoc >= 2)     
      {
      xyb[0] = (xyb[0] / efzoom[0]) + info[0];
      xyb[1] = (xyb[1] / efzoom[1]) + info[1];
      }
   return (stata);


   case 3:

   /*  FLAG = 3  -  draw again square to actually erase it...  */

   ovmem = info[0];
   if (rcdraw > 0)     
      {
      (void) IIGPLY_C(QDSPNO,ovmem,xr,yr,5,99,1);
      rcdraw = 0;
      }
   return (0);


   case 4:

   /*  FLAG = 4  -  process arrow keys L,R,D,U (counted as -4,-3,-2,-1)
                    and number keys 0,1,2,3,... (counted as 1,2,3,4,...) */

   if (info[0] < 0)                             /* arrow keys */
      {
      mx = 0;
      my = 0;

      if (lmodif == 1)    	 		/* arrow key used for LUT */
         {
         if (info[0] == -3)     
            mx = jinc;
         else if (info[0] == -4)     
            mx = -jinc;
   
         iav = QLUTSZ-1;
         mx /= 3;
         lsta += mx;
         if (lsta >= QLUTSZ) lsta -= iav;	/* update offset in LUT */
         if (lsta < 0) lsta += iav;
      
         ma = cntlut - 1;			/*  build new LUT */
         for (nr=0; nr<QLUTSZ-lsta; nr++)
            {
            rlut[ma][nr+lsta] = array[nr];
            rlut[ma][QLUTSZ+nr+lsta] = array[QLUTSZ+nr];
            rlut[ma][lut2sz+nr+lsta] = array[lut2sz+nr];
            }
         if (lsta > 0)
            {
            mb = QLUTSZ - lsta;
            for (nr=0; nr<lsta; nr++)
               {
               rlut[ma][nr] = array[nr+mb];
               rlut[ma][QLUTSZ+nr] = array[QLUTSZ+nr+mb];
               rlut[ma][lut2sz+nr] = array[lut2sz+nr+mb];
               }
            }
            (void) IILWLT_C(QDSPNO,0,0,QLUTSZ,&rlut[ma][0]);
         return (0);
         }

      if (imodif == 1)     
         {
         if (info[0] == -3)     
            mx = jinc;
         else if (info[0] == -4)     
            mx = -jinc;
         else if (info[0] == -1)     
            my = jinc;
         else
            my = -jinc;

         if (mx != 0)
            {
            rx += (mx/3);
            if (rx > rql) rx = rql;
            if (rx < rlo) rx = rlo;
            ry = rx + rd;
            }
         if (my != 0)
            {
            ry += (my/3);
            if (ry < (rx+1.)) ry = rx + 1.;
            if (ry > rhi) ry = rhi;
            }
         rd = ry - rx;
         rval = QLUTSZ/rd;

         ma = cntitt - 1;			/*  build new ITT */
         for (nr=0; nr<QLUTSZ; nr++)
            {
            ritt[ma][nr] = 0.;
            if ((nr >= rx) && (nr <= ry))
               {
               mb = CGN_NINT((nr-rx)*rval);
               if ((mb > 0) && (mb <= QLUTSZ)) ritt[ma][nr] = array[mb-1];
               }
            }
         (void) IILWIT_C(QDSPNO,QIMCH,0,0,QLUTSZ,&ritt[ma][0]);
         return (0);
         }


      if (rcdraw > 0)     
         {
         d_colu = d_row = -1;
         (void) IIMCMY_C(QDSPNO,&QOVCH,1,0);
         rcdraw = 0;
         }

      if (info[0] == -3)     
         SCROLX -= jinc;
      else if (info[0] == -4)     
         SCROLX += jinc;
      else if (info[0] == -1)     
         SCROLY -= jinc;
      else
         SCROLY += jinc;
      (void) Cdazscr(QDSPNO,QIMCH,&SCROLX,&SCROLY);
      return (0);
      }

   else 					/* keys 0,1,...,9 */
      {
      jinc = info[0] * 3;
      return (0);
      }
   

   case 6:

   /*  FLAG = 6  -  return info about zoom_window to main program */

   info[0] = ZDSPNO;
   info[1] = zoomwn[0];
   info[2] = zoomwn[1];
   info[3] = efzoom[0];                /* effective zoom takes scaling */
   info[4] = efzoom[1];                /* of image into account */
   return (0);


   case 7:

   /*  FLAG = 7  -  draw a horizontal trace at center of rectangle */

   dspinfo[0] = QDSPNO;
   dspinfo[1] = ovmem;
   sizaux[0] = QDSZX;
   sizaux[1] = dszy - SCROLY;
   drawline(dspinfo,1,info[0],&oldyc,&yc,sizaux);
   return (0);


   case 11:

   /*  FLAG = 11  - handle h, c/b, i/j, x/z */

   cb = (char) info[0];

   if (cb == 'h')                               /* help */
      {
      auxhelp(-1);
      return (0);
      }

   else if (cb == 'x')                          /* zoom down */
      {
      if (zoomwn[2] > 1)
         {
         zoomch = 1;
         zoomwn[2] --;
         }
      goto sect_4600;
      }

   else if (cb == 'z')                          /* zoom */
      {
      if (zoomwn[2] < 99)
         {
         zoomch = 1;
         zoomwn[2] ++;
         }
      goto sect_4600;
      }


   /*  still to be processed:  c, b  and  i, j */

   memset((void *)outp,32,(size_t)77);
   outp[77] = '\0';

   if (cb == 'c')		/* cycle through LUTs */
      {
      lmodif = 0;

      cntlut += luton;
      if (cntlut == 1)
         (void) strncpy( outp, "LUT = current LUT ", 17 );
      else if (cntlut == 2)
         (void) strncpy( outp, "LUT = heat        ", 10 );
      else if (cntlut == 3)
         (void) strncpy( outp, "LUT = rainbow1    ", 14 );
      else if (cntlut == 4)
         (void) strncpy( outp, "LUT = backgr      ", 12 );
      else if (cntlut == 5)
         (void) strncpy( outp, "LUT = random4     ", 13 );
      else
         {
         (void) strncpy( outp, "LUT = current LUT ", 17 );
         cntlut = 1;
         }
      luton = fixlut;                         /* enable next cycling */
      (void) display_it( outp, 99 );
      (void) IILWLT_C(QDSPNO,0,0,QLUTSZ,&rlut[cntlut-1][0]);
      }

   else if (cb == 'b')
      {
      (void) strncpy( outp, "LUT off ", 7 );
      (void) display_it( outp, 99 );
      (void) IILWLT_C(QDSPNO,0,0,QLUTSZ,&rlut[5][0]);
      luton = 0;                              /* disable next cycling */
      }

   else if (cb == 'i')		/* cycle through ITTs */
      {
      imodif = 0;

      cntitt += itton;
      if (cntitt == 1)
         (void) strncpy( outp, "ITT = current ITT ", 17 );
      else if (cntitt == 2)
         (void) strncpy( outp, "ITT = neg         ",  9 );
      else if (cntitt == 3)
         (void) strncpy( outp, "ITT = log         ",  9 );
      else if (cntitt == 4)
         (void) strncpy( outp, "ITT = neglog      ", 12 );
      else if (cntitt == 5)
         (void) strncpy( outp, "ITT = gamma       ", 11 );
      else
         {
         (void) strncpy( outp, "ITT = current ITT ", 17 );
         cntitt = 1;
         }
      itton = fixlut;                        /* enable next cycling */
      (void) display_it( outp, 99 );
      (void) IILWIT_C(QDSPNO,QIMCH,0,0,QLUTSZ,&ritt[cntitt-1][0]);
      }

   else			/* 'j' => clear ITT */
      {
      (void) display_it("ITT off ",99);
      (void) IILWIT_C(QDSPNO,QIMCH,0,0,QLUTSZ,&ritt[5][0]);
      itton = 0;                              /* disable next cycling */
      }
   return (0);


   /*  calculate effective zoom */

  sect_4600:
   mb = 0;
   if (SCALX > 1)
      {
      mb = 1;
      efzoom[0] = zoomwn[2]/SCALX ;
      }
   else if (SCALX < -1)
      {
      mb = 1;
      efzoom[0] = zoomwn[2]*(-SCALX );
      }
   else
      efzoom[0] = zoomwn[2];
   if (efzoom[0] < 1) efzoom[0] = 1;

   if (SCALY > 1)
      {
      mb = 1;
      efzoom[1] = zoomwn[2]/SCALY ;
      }
   else if (SCALY < -1)
      {
      mb = 1;
      efzoom[1] = zoomwn[2]*(-SCALY );
      }
   else
      efzoom[1] = zoomwn[2];
   if (efzoom[1] < 1) efzoom[1] = 1;

   if (mb == 1)
      (void) sprintf(outp,"zoomfactor = %d => zoom (%d,%d) with scaling",
                                            zoomwn[2],efzoom[0],efzoom[1]);
   else
      (void) sprintf(outp,"zoomfactor = %d",zoomwn[2]);

   display_it(outp,-9);
   display_it(outp,99);

   return (0);


   case 17:

   /*  FLAG = 17  -  draw a horizontal line at cursor in zoom window */

   dspinfo[0] = ZDSPNO;
   dspinfo[1] = 1;
   sizaux[0] = zoomwn[0];
   sizaux[1] = 0;
   drawline(dspinfo,1,info[0],&oldyz,&curco[1],sizaux);
   lastdraw = 1;
   return (0);


   case 8:

   /*  FLAG = 8  -  draw a vertical trace at center of rectangle  */

   dspinfo[0] = QDSPNO;
   dspinfo[1] = ovmem;
   sizaux[0] = QDSZY;
   sizaux[1] = -SCROLX;
   drawline(dspinfo,2,info[0],&oldxc,&xc,sizaux);
   return (0);


   case 18:

   /*  FLAG = 18  -  draw a vertical trace at cursor in zoom w. */

   dspinfo[0] = ZDSPNO;
   dspinfo[1] = 1;
   sizaux[0] = zoomwn[1];
   drawline(dspinfo,2,info[0],&oldxz,&curco[0],sizaux);
   lastdraw = 2;
   return (0);


   case 19:

   /*  FLAG = 19  -  connect the two cursors in zoom w. */

   dspinfo[0] = ZDSPNO;
   dspinfo[1] = 1;
   ytmp[0] = oldxz;
   ytmp[1] = oldyz;
   ytmp[2] = oldxzz;
   ytmp[3] = oldyzz;
   drawline(dspinfo,3,info[0],ytmp,curco,sizaux);
   if (info[0] != 1)
      {
      oldxz = ytmp[0];
      oldyz = ytmp[1];
      oldxzz = ytmp[2];
      oldyzz = ytmp[3];
      }
   lastdraw = 3;
   return (0);


   case 9:

   /*  FLAG = 9  -  startup LUT/ITT modify loop */

   cb = (char) info[0];
   if (cb == 'l')     			/* do LUT stuff */
      {
      imodif = 1 - imodif;
      lmodif = 1;                 /* indicate that we are in lut modify loop */

      (void) display_it("now, use right/left arrow key to rotate LUT",0);

      lsta = 0;
      LUTsav(0);        /* current LUT -> array */
      return (0);
      }

   lmodif = 1 - lmodif;			/* LUT, ITT jobs are exclusive... */
   (void) display_it( "use up/down arrow key to change slope of ITT", 0 );
   (void) display_it( "use left/right arrow key to move ITT", 0 );
   imodif = 1;                   /* indicate that we are in ITT modify loop */

   rz = QLUTSZ * QLUTSZ;
   rlo = -rz;
   rhi = QLUTSZ + 1. + rz ;
   rx = 0.;
   ry = QLUTSZ;
   rd = QLUTSZ;
   LUTsav(10);      /* current itt -> array */
   rql = QLUTSZ - 1;
   return (0);
   }

return(0);
}
