/**************************************************************************
 *                                                                        *
 * 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.                        *
 *                                                                        *
 **************************************************************************/


/*	repairs data files

	impatch fits_file box= [box=]

	by replacing the data values in fits_file with the specified
	box(es) with values derived from bilinear interpolation from off
	the boxes.

	slight change: added "fits_resetscale" call if this program is 
	NOT called with the "outfile" argument.  MWR 8/1/1993

*/
#include "pcvista.h"
#include "fits.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>

#define MAXBOX 10

#ifdef PROTO
int main(int, char **);
static void patchit(FITS_HANDLE,FITS_HANDLE,int box , int nrow,int ncol);
static void copydata(FITS_HANDLE,FITS_HANDLE,int nrow,int ncol);
#else
int main();
static void patchit();
static void copydata();
#endif

#define USAGE "usage: impatch fits_file box= [box=..] [outfile] [help]"


int
main(argc,argv)
int argc;
char *argv[];
{
	FITS_HANDLE fh, fout;
	int i ,nbox=0, boxno[MAXBOX],nrow,ncol;
	char *gotit,outfile[NBUF];
	int new_file=0;

	if(argc == 1) {
		error(-1, USAGE);
	}
	if (strcmp(argv[1], "help") == 0) {
		printf("%s\n", USAGE);
		exit(0);
	}

	fh = fits_open(argv[1], "r", &nrow, &ncol);
	strcpy(outfile,argv[1]);

	for(i = 2; i < argc; i++) {
		if (keyword("help", argv[i])) {
			printf("%s\n", USAGE);
			exit(0);
		}
		if ((gotit = find("box", argv[i])) != NULL) {
			boxno[nbox++] = (int)evaluate(gotit);
			if(nbox == MAXBOX)
				error(1,"too many boxes");
			continue;
		}
		if ((gotit = find("outfile", argv[i])) != NULL) {
			strcpy(outfile,gotit);
			new_file=1;
			continue;
		}
		fprintf(stderr,"unknown option '%s'\n",argv[i]);
		exit(1);
	}

	if(nbox== 0) 
		error(1,"at least one box must be specified");

	/*	if it is a new file copy the header and the data */
	if(new_file){
		fout = fits_open(outfile, "w", &nrow, &ncol);
		fits_copyheader(fh,fout, FITS_CHECK);
		copydata(fh,fout,nrow,ncol);
	}else{
		fout = fits_open(outfile, "x", &nrow, &ncol);
		copydata(fh,fout,nrow,ncol);
		/* in this case, IF the file started out with BSCALE/BZERO != 1/0,
		   we've just translated all data in this file into 16-bit signed 
		   ints, so we should reset the in-core header so that it doesn't 
		   think it has to scale the data any more.  MWR 8/1/1993 */
		fits_resetscale(fh);
	}

	for(i=0; i<nbox; i++)
		patchit(fh,fout,boxno[i],nrow,ncol);
	fits_close(fout);
	exit(0);
}

/* replace the data interior to the box with that interpolated
	from all four edges 
*/

static void patchit(fh,fout,box,nrow,ncol)
FITS_HANDLE fh,fout;
int nrow,ncol,box;
{

	int i,j,sr,sc,nr,nc;
	int16 data[NMAX],rl[NMAX],ru[NMAX];
	double x,y,row_value,col_value;

	if(getbox(box,&sr,&sc,&nr,&nc)){
		fprintf(stderr,"can't find box %d\n",box);
		exit(1);
	}
	check_box(box,nrow,ncol);

	/*	fill the upper and lower rows */
	fits_get_data(fh, sr, sc, rl, nc);
	fits_get_data(fh, sr+nr-1, sc, ru, nc);

	for (i=1 ; i<(nr-1) ; i++) {
		fits_get_data(fh, sr+i, sc, data, nc);
		y=((double) i/(double)(nr-1));
		for (j = 1; j < (nc-1) ;j++) {
			row_value=(1.-y)*rl[j] + y*ru[j];
			x=((double)j/(double)(nc-1));
			col_value=(1.-x)*data[0] + x*data[nc-1];
			data[j]=(int16)(0.5*row_value + 0.5*col_value +0.5);
		}
		fits_put_data(fout,sr+i,sc,data,nc);
	}
}

static void copydata(fh,fout,nrow,ncol)
FITS_HANDLE fh,fout;
int nrow,ncol;
{
	int i;
	int16 data[NMAX];

	for(i=0; i<nrow; i++){
		fits_get_data(fh,i,0,data,ncol);
		fits_put_data_fast(fout,data,ncol);
	}
}
