/* @(#)iir.c	19.1 (ESO-DMD) 02/25/03 13:54:49 */
/*===========================================================================
  Copyright (C) 1995 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
===========================================================================*/

/* ----------------------------------------------------------------- */
/* ---------  IIR -------------------------------------------------- */

/* !!  all roi coords are relative to the associated memory    !!    */
/* !!  (or to the ididev in case of memory = -1)               !!    */
/* !!  (0,0 = bottom left)                                     !!    */
/* ----------------------------------------------------------------- */

/* file IIR.C : contains the following routines
*
*   IIRINR_C      : Initialize Rectangular Region of Interest;
*   IIRRRI_C      : Read Rectangular Region of Interest Position;
*   IIRWRI_C      : Write Rectangular Region of Interest Position;
*                                                                       
*   IICINR_C      : Initialize Circular Region of Interest;
*   IICRRI_C      : Read Circular Region of Interest Position;
*   IICWRI_C      : Write Circular Region of Interest Position;
*                                                                       
*   IIRSRV_C      : Set Region of Interest Visibility;
*                                                                       
***********************************************************************
* V 1.1  871201: P. Santin - Trieste Astronomical Observatory         *
* V 2.0  881219: K. Banse  -  ESO Garching                            *

 010515		last modif

***********************************************************************
*/


# include    <idi.h>             
# include    <idistruct.h>
# include    <proto_idi.h>

static int  dxsize, dysize;

static ROI_DATA   *roi;
/*

*/


/************************************************************************
* IIRINR_C routine : initialize rectangular region of interest          *
*                                                                       *
* synopsis   IIRINR_C (display , memid , roicol , roixmin , roiymin ,   *
*                      roixmax , roiymax , roiid);                      *
*                                                                       *
*       int display;      input   display identifier                    *
*       int memid;        input   memory identifier                     *
*       int roicol;       input   roi color                             *
*       int roixmin;      input   X min                                 *
*       int roiymin;      input   Y min                                 *
*       int roixmax;      input   X max                                 *
*       int roiymax;      input   Y max                                 *
*       int roiid;        output  ROI id                                *
************************************************************************/

int IIRINR_C (display , memid , roicol , roixmin , roiymin ,
              roixmax , roiymax , roiid)

int display , *roiid , memid , roicol;
int roixmin , roiymin , roixmax , roiymax;

{

if (ididev[display].opened == 0) return(DEVNOTOP);

*roiid = 0;
roi = ididev[display].roi;		/* we only use one ROI   */

/* store ROI parameters */

roi->col = roicol;
roi->sh = 0;
roi->vis = 0;

					/* write ROI */
if ((roixmin >= 0) && (roiymin >= 0))
   {
   roi->xmin = roixmin;
   roi->ymin = roiymin;
   roi->xmax = roixmax;
   roi->ymax = roiymax;
   }

return(II_SUCCESS);
}
/*

*/

/************************************************************************
* IIRSRV_C routine : set region of interest visibility                  *
*                                                                       *
* synopsis   IIRSRV_C (display , roiid , vis);                          *
*                                                                       *
*       int display;      input   display identifier                    *
*       int roiid;        input   ROI id                                *
*       int vis;          input   visibility [1 / 0]                    *
************************************************************************/

int IIRSRV_C (display , roiid , vis)

int    display , roiid , vis;

{

int  flag;


if (ididev[display].opened == 0) return(DEVNOTOP);

roi = ididev[display].roi;
if (roi->sh == -1) return(ROINOTDEF);
if (roi->vis == vis) return(II_SUCCESS);

dysize = ididev[display].ysize - 1;

if (vis == 0)				/* so roi->vis currently 1  */
   flag = 2;
else					/* so roi->vis currently 0  */
   flag = 0;

if (roi->sh == 0)			/* rectangle */
   draw_rroi(display,flag,dysize,roi->xmin,roi->ymin,
               roi->xmax,roi->ymax,roi->col);
else			
   {					/* circle */
   int  xcen, ycen;

   xcen = roi->xmin + roi->radiusi;
   ycen = roi->ymin + roi->radiusi;

   draw_croi(display,flag,dysize,xcen,ycen,
            roi->radiusi,roi->radiusm,roi->radiuso,roi->col);
   }

roi->vis = vis;				/* update roi->vis accordingly  */
 
return(II_SUCCESS);
}

/*

*/
/************************************************************************
* IIRRRI_C routine : read region of interest position                   *
*                                                                       *
* synopsis   IIRRRI_C (display , inmemid , roiid , roixmin , roiymin ,  *
*                      roixmax , roiymax , outmemid);                   *
*                                                                       *
*       int display;      input   display identifier                    *
*       int inmemid;      input   input memory identifier               *
*       int roiid;        input   ROI id                                *
*       int *roixmin;     output  X min                                 *
*       int *roiymin;     output  Y min                                 *
*       int *roixmax;     output  X max                                 *
*       int *roiymax;     output  Y max                                 *
*       int *outmemid;    output  output memory identifier              *
************************************************************************/

int IIRRRI_C (display , inmemid , roiid , roixmin , roiymin , roixmax , 
          roiymax ,  outmemid)

int display , roiid , inmemid , *outmemid;
int *roixmin , *roiymin , *roixmax , *roiymax;

{
int   i;

CONF_DATA   *conf;
MEM_DATA    *mem;

if (ididev[display].opened == 0) return(DEVNOTOP);

conf = ididev [display].confptr;
roi = ididev[display].roi;
if (roi->sh == -1) return(ROINOTDEF);

*roixmin = roi->xmin;
*roiymin = roi->ymin;
*roixmax = roi->xmax;
*roiymax = roi->ymax;

/* search current memory for cursor */

*outmemid = 0;
for (i=0; i<conf->nmem; i++)
   {
   mem = conf->memory[i];
   if (mem->visibility == 1) 
      {
      *outmemid = i;
      break;
      }
   }

return(II_SUCCESS);
}
/*

*/

/************************************************************************
* IIRWRI_C routine : write region of interest position                  *
*                                                                       *
* synopsis   IIRWRI_C (display , memid , roiid , roixmin , roiymin ,    *
*                      roixmax , roiymax);                              *
*                                                                       *
*       int display;      input   display identifier                    *
*       int memid;        input   memory identifier                     *
*       int roiid;        input   ROI id                                *
*       int roixmin;      input   X min                                 *
*       int roiymin;      input   Y min                                 *
*       int roixmax;      input   X max                                 *
*       int roiymax;      input   Y max                                 *
************************************************************************/

int IIRWRI_C (display, memid, roiid, roixmin, roiymin, roixmax, roiymax)

int display , memid , roiid;
int roixmin , roiymin , roixmax , roiymax;

{

if (ididev[display].opened == 0) return(DEVNOTOP);

roi = ididev[display].roi;		/* we only use one ROI  */

dxsize = ididev[display].xsize - 1;
dysize = ididev[display].ysize - 1;

if (roixmin < 0)
   roixmin = 0;
else
   {
   if (roixmin > dxsize) roixmin = dxsize;
   }
   
if (roiymin < 0)
   roiymin = 0;
else
   {
   if (roiymin > dysize) roiymin = dysize;
   }

if (roixmax < 0)
   roixmax = 0;
else
   {
   if (roixmax > dxsize) roixmax = dxsize;
   }
   
if (roiymax < 0)
   roiymax = 0;
else
   {
   if (roiymax > dxsize) roiymax = dysize;
   }
   
roi->xmin = roixmin;
roi->ymin = roiymin;
roi->xmax = roixmax;
roi->ymax = roiymax;

return(II_SUCCESS);
}

         
/* 

*/
  
/************************************************************************
* IICINR_C routine : initialize circular region of interest             *
*                                                                       *
* synopsis   IICINR_C (display, memid, roicol, roixcen, roiycen,        *
*                      radiusi, radiusm, radiuso, roiid);               *
*                                                                       *
*       int display;      input   display identifier                    *
*       int memid;        input   memory identifier                     *
*       int roicol;       input   roi color                             *
*       int roixcen;      input   X cen                                 *
*       int roiycen;      input   Y cen                                 *
*       int radiusi;      input   inner radius                          *
*       int radiusm;      input   middle radius (maybe = 0)             *
*       int radiuso;      input   outer radius (maybe = 0)              *
*       int roiid;        output  ROI id   (not used - always 0)        *
************************************************************************/

int IICINR_C (display, memid, roicol, roixcen, roiycen,  
              radiusi, radiusm, radiuso, roiid)

int   display, *roiid, memid, roicol;
int   roixcen, roiycen , radiusi, radiusm, radiuso;

{

int  xmin, ymin;



if (ididev[display].opened == 0) return(DEVNOTOP);

*roiid = 0;
roi = ididev[display].roi;		/* we only use one ROI   */


roi->col = roicol;			/* store ROI parameters */
roi->sh = 1;				/* indicate circle */
roi->vis = 0;

					/* write ROI */
if (radiusi < 1) return (BADINPUT);
roi->radiusi = radiusi;

if (radiusm < 1)
   roi->radiusm = 0;
else
   {
   if (radiusm < radiusi) 
      roi->radiusm = radiusi;
   else
      roi->radiusm = radiusm;
   }

if (radiuso < 1) 
   roi->radiuso = 0;
else
   {
   if (roi->radiusm > 0)
      {
      if (radiuso < roi->radiusm) 
         roi->radiuso = roi->radiusm;
      else
         roi->radiuso = radiuso;
      }
   else
      {
      if (radiuso < roi->radiusi) 
         roi->radiuso = roi->radiusi;
      else
         roi->radiuso = radiuso;
      }
   }

if ((roixcen >= 0) && (roiycen >= 0))
   {
   dxsize = ididev[display].xsize - 1;
   dysize = ididev[display].ysize - 1;

   xmin = roixcen - roi->radiusi;
   if (xmin < 0)
      {
      roixcen = roi->radiusi;
      if (roixcen > dxsize) roixcen = dxsize/2;
      }
   else
      {
      xmin = roixcen + roi->radiusi;
      if (xmin > dxsize) roixcen = dxsize - roi->radiusi;
      if (roixcen < 0) roixcen = dxsize/2;
      }
  
   ymin = roiycen - roi->radiusi;
   if (ymin < 0)
      {
      roiycen = roi->radiusi;
      if (roiycen > dysize) roiycen = dysize/2;
      }
   else
      {
      ymin = roiycen + roi->radiusi;
      if (ymin > dysize) roiycen = dysize - roi->radiusi;
      if (roiycen < 0) roiycen = dysize/2;
      }

   roi->xmin = roixcen;
   roi->ymin = roiycen;
   }

roi->xmax = radiusi;			/* start with inner radius as ref. */
loc_mod(display,0,-14);			/* init `radiusno' in idiutil2.c */

return(II_SUCCESS);
}

/*

*/

/************************************************************************
* IICRRI_C routine : read region of interest position                   *
*                                                                       *
* synopsis   IICRRI_C (display, inmemid, roiid, roixcen, roiycen,       *
*                      radiusi, radiusm, radiuso, outmemid)             *
*                                                                       *
*       int display;      input   display identifier                    *
*       int inmemid;      input   input memory identifier               *
*       int roiid;        input   ROI id                                *
*       int *roixcen;     output  X cen                                 *
*       int *roiycen;     output  Y cen                                 *
*       int *radiusi;     output  radiusi                               *
*       int *radiusm;     output  radiusm                               *
*       int *radiuso;     output  radiuso                               *
*       int *outmemid;    output  output memory identifier              *
************************************************************************/

int IICRRI_C (display, inmemid, roiid, roixcen, roiycen,
     radiusi, radiusm, radiuso, outmemid)  

int display , roiid , inmemid , *outmemid;
int *roixcen , *roiycen , *radiusi, *radiusm, *radiuso;

{
int   i;

CONF_DATA   *conf;
MEM_DATA    *mem;

if (ididev[display].opened == 0) return(DEVNOTOP);

conf = ididev [display].confptr;
roi = ididev[display].roi;
if (roi->sh == -1) return(ROINOTDEF);

*roixcen = roi->xmin;
*roiycen = roi->ymin;
*radiusi = roi->radiusi;
*radiusm = roi->radiusm;
*radiuso = roi->radiuso;


/* search current memory for cursor */

*outmemid = 0;
for (i=0; i<conf->nmem; i++)
   {
   mem = conf->memory[i];
   if (mem->visibility == 1) 
      {
      *outmemid = i;
      break;
      }
   }

return(II_SUCCESS);
}
/*

*/

/************************************************************************
* IICWRI_C routine : write region of interest position                  *
*                                                                       *
* synopsis   IICWRI_C (display, memid, roiid, roixcen, roiycen,         *
*                      radiusi, radiusm, radiuso)                       *
*                                                                       *
*       int display;      input   display identifier                    *
*       int memid;        input   memory identifier                     *
*       int roiid;        input   ROI id                                *
*       int roixcen;      input   X cen                                 *
*       int roiycen;      input   Y cen                                 *
*       int radiusi;      input   inner radius                          *
*       int radiusm;      input   middle radius (maybe = 0)             *
*       int radiuso;      input   outer radius (maybe = 0)              *
************************************************************************/

int IICWRI_C (display, memid, roiid, roixcen, roiycen,
              radiusi, radiusm, radiuso) 

int   display, memid, roiid;
int   roixcen, roiycen, radiusi, radiusm, radiuso;

{
int  xmin, ymin;



if (ididev[display].opened == 0) return(DEVNOTOP);

roi = ididev[display].roi;		/* we only use one ROI  */

if (radiusi < 1) return (BADINPUT);
roi->radiusi = radiusi;

if (radiusm < 1)
   roi->radiusm = 0;
else
   {
   if (radiusm < radiusi)
      roi->radiusm = radiusi;
   else
      roi->radiusm = radiusm;
   }

if (radiuso < 1)
   roi->radiuso = 0;
else
   {
   if (roi->radiusm > 0)
      {
      if (radiuso < roi->radiusm)
         roi->radiuso = roi->radiusm;
      else
         roi->radiuso = radiuso;
      }
   else
      {
      if (radiuso < roi->radiusi)
         roi->radiuso = roi->radiusi;
      else
         roi->radiuso = radiuso;
      }
   }

if ((roixcen >= 0) && (roiycen >= 0))
   {
   dxsize = ididev[display].xsize - 1;
   dysize = ididev[display].ysize - 1;

   xmin = roixcen - roi->radiusi;
   if (xmin < 0)
      {
      roixcen = roi->radiusi;
      if (roixcen > dxsize) roixcen = dxsize/2;
      }
   else
      {
      xmin = roixcen + roi->radiusi;
      if (xmin > dxsize) roixcen = dxsize - roi->radiusi;
      if (roixcen < 0) roixcen = dxsize/2;
      }
   
   ymin = roiycen - roi->radiusi;
   if (ymin < 0)
      {
      roiycen = roi->radiusi;
      if (roiycen > dysize) roiycen = dysize/2;
      }
   else
      {
      ymin = roiycen + roi->radiusi;
      if (ymin > dysize) roiycen = dysize - roi->radiusi;
      if (roiycen < 0) roiycen = dysize/2;
      }

   roi->xmin = roixcen;
   roi->ymin = roiycen;
   }

roi->xmax = roi->radiusi;
loc_mod(display,0,-14);			/* set initial distance */

return(II_SUCCESS);
}
