
/**************************************************************************
 *                                                                        *
 * Copyright (c) 1996 Michael Richmond and Richard Treffers               *
 *                                                                        *
 *                    This software may be copied and distributed for     *
 *                    educational, research and not for profit services   *
 *                    provided that this copyright and statement are      *
 *                    included in all such copies.                        *
 *                                                                        *
 **************************************************************************/


/*	
	window managing routines - SEVERELY modified for RT use under X windows 

	all file names are put into lower case

	2/7/91 - fixed bug in 'get_data'; old method of calculating r, c doesn't
	         work the same under X-Windows.         MWR
	9/22/92 - removed the 'not needed in X' routines
*/

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "pcvista.h"
#include "fits.h"

static struct window {
	int exist;
	int xmin;
	int xmax;
	int ymin;
	int ymax;
	int zoom;
	int sr;
	int sc;
	int er;
	int ec;
	int bin;
	int zero;
	int span;
	int dither;				/* 1 means dither, 0 means don't */
	FITS_HANDLE fh;
	int windowid;
	char fname[NBUF];
} win[NWINDOW];

extern int image_matrix[];

static int my_id;		/* ID of the window created by the current process */
  

/*	
	returns 1 if successful, or 0 if the cursor is not over part of the image. 
	returns row and column and data of image 
	at x,y on screen.

	input x and y
	returns *prow, *pcol, *pdata
*/

int
get_data(x, y, prow, pcol, pdata, ndata, fname, pbin, pzoom)
int x, y, *prow, *pcol;
int16 *pdata;
int ndata;
char **fname;
int *pbin, *pzoom;
{
	int i, x_prime, y_prime, r, c;
	int nrow, ncol;

	i = my_id;

	if (win[i].fh == -1)
		win[i].fh = fits_open(win[i].fname, "r", &nrow, &ncol);

	x_prime = (x*win[i].bin)/win[i].zoom;
	y_prime = (y*win[i].bin)/win[i].zoom;

	r = win[i].sr + image_matrix[0]*x_prime + image_matrix[1]*y_prime;
	c = win[i].sc + image_matrix[2]*x_prime + image_matrix[3]*y_prime;

#ifdef DEBUG
	printf("x %d y %d x_prime %d y_prime %d r %d c %d\n", x, y, x_prime,
			y_prime, r, c);
#endif

	if ((r < win[i].sr) || (r > win[i].er) ||
		(c < win[i].sc) || (c > win[i].ec))
		return(0);

	*prow = r;
	*pcol = c;
	*fname = win[i].fname;
	*pbin = win[i].bin;
	*pzoom = win[i].zoom;
	fits_get_data(win[i].fh, *prow, *pcol, pdata, ndata);

	return(1);
}

	/* return a bunch of information on the starting and ending position
	   of the given window, its zoom and bin factors, etc.  Note that the
	   given window must always be number 0.  return 1 if
	   there's a problem, or 0 if all is OK. */

int
get_win_data(fname, x_origin, x_end, y_origin, y_end, zoom, sr, endrow, 
		sc, endcol, bin, zero, span, dither)
int *x_origin, *x_end, *y_origin, *y_end, *zoom;
int *sr, *endrow, *sc, *endcol, *bin, *zero, *span, *dither;
char **fname;
{
	if (win[0].exist == 0)
		return(1);

	*fname = win[0].fname;
	*x_origin = win[0].xmin;
	*x_end = win[0].xmax;
	*y_origin = win[0].ymin;
	*y_end = win[0].ymax;
	*zoom = win[0].zoom;
	*sr = win[0].sr;
	*sc = win[0].sc;
	*endrow = win[0].er;
	*endcol = win[0].ec;
	*bin = win[0].bin;
	*zero = win[0].zero;
	*span = win[0].span;
	*dither = win[0].dither;

	return(0);
}



	/* store all the window information for a new window.  */
	   

void
store_window(fname, x_origin, y_origin, zoom, sr, endrow, sc, endcol, 
	bin, zero, span, dither)
char *fname;
int x_origin, y_origin, zoom, sc, endcol, sr, endrow, bin, zero, span, dither;
{
	int xmax, ymax, nrow, ncol, wind_num;

	nrow = zoom*(endrow - sr)/bin;
	ncol = zoom*(endcol - sc)/bin;

	xmax = x_origin + image_matrix[0]*nrow + image_matrix[2]*ncol;
	ymax = y_origin + image_matrix[1]*nrow + image_matrix[3]*ncol;

	/* get window number assignment */	
	wind_num = 0;
	my_id = wind_num;
	win[wind_num].exist = 1;
	strncpy(win[wind_num].fname, fname, NBUF);
	win[wind_num].xmin = x_origin;
	win[wind_num].xmax = xmax;
	win[wind_num].ymin = y_origin;
	win[wind_num].ymax = ymax;
	win[wind_num].zoom = zoom;
	win[wind_num].sr = sr;
	win[wind_num].sc = sc;
	win[wind_num].er = endrow - 1;
	win[wind_num].ec = endcol - 1;
	win[wind_num].bin = bin;
	win[wind_num].zero = zero;
	win[wind_num].span = span;
	win[wind_num].dither = dither;
	win[wind_num].fh = -1;
}


	/* given some row and col in a window, find the x and y coords 
	   ON THE DISPLAY and put them in *px and *py.  That is, the x and y
	   coords of the whole screen, not just the x and y coords inside this
	   particular window.

	   return 1 if all ok, 0 if fail. */

int
xform_window(i, row, col, px, py)
int i, row, col, *px, *py;			
{									
	/* leave it here for now, but really should go away */

	int row_offset, col_offset;
	
	if (win[i].exist == 0)
		return(0);
	row_offset = win[i].zoom*(row - win[i].sr)/win[i].bin + win[i].zoom/2;
	col_offset = win[i].zoom*(col - win[i].sc)/win[i].bin + win[i].zoom/2;
	*px = win[i].xmin + image_matrix[0]*row_offset + image_matrix[2]*col_offset;
	*py = win[i].ymin + image_matrix[1]*row_offset + image_matrix[3]*col_offset;
	if ((*px >= win[i].xmin) && (*px <= win[i].xmax) &&
	    (*py >= win[i].ymin) && (*py <= win[i].ymax))
		return(1);
	return(0);
}

	/* given some row and col in a window, find the x and y coords 
	   INSIDE THE WINDOW and put them in *px and *py.  That is, the x and y
	   coords just inside this particular window, so that (0, 0) corresponds
	   to the position of the 'first' pixel in the image.
	
	   return 1 if all ok, 0 if fail. */

int
xform_in_window(i, row, col, px, py)
int i, row, col, *px, *py;			
{									

	int row_offset, col_offset;
	
	if (win[i].exist == 0)
		return(0);
	row_offset = win[i].zoom*(row - win[i].sr)/win[i].bin;
	col_offset = win[i].zoom*(col - win[i].sc)/win[i].bin;
	*py = image_matrix[0]*row_offset + image_matrix[2]*col_offset;
	*px = image_matrix[1]*row_offset + image_matrix[3]*col_offset;

	return(1);
}

