

#include <stdio.h>
#include <math.h>
#include "bait.h"
#include "pf.h"
#include "multipht.h"

struct s_imsort {
	int index;			/* index into the image_arr[] array */
	double mjd;			/* mjd of index'th image */
};

struct s_stsort {
	struct s_hash *hash;	/* pointer to hash-list entry for this star */
	double xc;				/* xc coord of this star in master list */
};

static void eliminate( /* int flags */ );
static void write_it( /* FILE *fp */ );
static int good_images( /* */ );
static int good_stars( /* */ );
static int write_stars( /* FILE *fp */ );
static int write_one_star( /* FILE *fp; struct s_hash *p */ );
static int comp_stsort( /* struct s_stsort **s1, **s2 */ );
static int write_images( /* FILE *fp */ );
static int write_one_image( /* FILE *fp; struct s_image *im */ );
static int comp_imsort( /* struct s_imsort **i1, **i2 */ );


	/* write information on all 'acceptable' images and stars to
	   the given file (or stdout, if passed an empty string "") */

write_output(file, flags)
int flags;
char *file;
{
	int i, naper, pos;
	char line[PF_LEN + 1];
	FILE *fp;

	if (strcmp(file, "") == 0)
		fp = stdout;
	else if ((fp = fopen(file, "w")) == NULL) {
		fprintf(stderr, "write_output: can't open file %s for writing\n", file);
		exit(-1);
	}

	eliminate(flags);
	write_it(fp);

	if (fp != stdout)
		fclose(fp);

}

	/* set to zero the 'w3' weight of all stars which are either
	   in an 'unacceptable' image, or an instance of an 'unacceptable'
	   star.  if not AUTO, ask the user if she wishes to get rid
	   of all saturated stars. */

static void 
eliminate(flags)
int flags;
{
	int i, j;
	char str[STRLEN];
	struct s_starp *sp;
	struct s_hashp *hp;

	for (i = 0; i < num_images; i++)
		if (image_arr[i].include == 0)
			for (j = 0; j < image_arr[i].num_star; j++)
				image_arr[i].stars[j].w3 = 0;

	for (hp = star_list; hp != NULL; hp = hp->next) 
		if (hp->hash->include == 0)
			for (sp = hp->hash->starp; sp != NULL; sp = sp->next)
				sp->star->w3 = 0;

	if ((flags & AUTO) == 0) {
		printf("do you wish to eliminate all saturated stars (y/n)? ");
		scanf("%s", str);
		if ((str[0] == 'y') || (str[0] == 'Y')) {
			for (i = 0; i < num_images; i++)
				for (j = 0; j < image_arr[i].num_star; j++)
					if (image_arr[i].stars[j].saturated != 0)
						image_arr[i].stars[j].w3 = 0;
		}
	}
		
}



	/* the actual writing routine */

static void 
write_it(fp)
FILE *fp;
{
	int goodim, goodstar;

	/* there are two kinds of information to print out: information 
	   about images (in the 'image_arr[]' array), and information
	   about stars (in the 'star_list' list of hashp structures. 
	   the first thing to do is to write how many images and how many
	   stars will appear in the output. */

	goodim = good_images();
	goodstar = good_stars();
	fprintf(fp, "%4d images  %6d stars \n", goodim, goodstar);

	/* now write information on each image: use one line per image */
	write_images(fp);	

	/* and now write information on each star: use N+1 lines per star,
	   where N is the number of 'acceptable' images of each star */
	write_stars(fp);

}

	/* calculate the number of 'good' images, and return it */

static int 
good_images()
{
	int i, sum;

	sum = 0;
	for (i = 0; i < num_images; i++)
		if (image_arr[i].include != 0) 
			sum++;
	return(sum);
}

	/* calculate the number of 'good' stars, and return it.  Make sure
	   that there is at least one 'good' instance of each star. */

static int
good_stars()
{
	int sum;
	struct s_starp *sp;
	struct s_hashp *hp;

	sum = 0;
	for (hp = star_list; hp != NULL; hp = hp->next) {
		if (hp->hash->include != 0) {
			for (sp = hp->hash->starp; sp != NULL; sp = sp->next) {
				if (sp->star->w3 != 0) {
					sum++;
					break;
				}
			}
		}
	}
	
	return(sum);
}

	/* write out information on each star, putting them in order 
	   by master list x-coordinate */

static int
write_stars(fp)
FILE *fp;
{
	int i, index;
	struct s_stsort *stsort;
	struct s_hash *hash;
	struct s_hashp *hp;

	/* effectively, sort the stars by their master xc coord */
	if ((stsort = (struct s_stsort *) calloc(num_ids, sizeof(struct s_stsort))) == NULL) {
		fprintf(stderr, "write_stars: can't calloc for stsort array \n");
		exit(-1);
	}
	for (i = 0, hp = star_list; (i < num_ids) && (hp != NULL); i++, hp = hp->next) {
		stsort[i].hash = hp->hash;
		stsort[i].xc = hp->hash->xc;
	}	
	qsort((char *) stsort, num_ids, sizeof(struct s_stsort), comp_stsort);

	for (i = 0; i < num_ids; i++) {
		hash = stsort[i].hash;
		if (hash->include != 0)
			write_one_star(fp, hash);
	}
}

	/* write the pertinent information from a single hash-entry structure 
	   (which records all instances of the same star) to the given 
	   FILE pointer.  Each 'master star' gets N+1 lines of output,
	   where N is the number of 'good' instances of the star.  The first
	   line includes the number N at its end.  */

static int
write_one_star(fp, hash)
FILE *fp;
struct s_hash *hash;
{
	int good;
	static int newid = 0;
	struct s_starp *sp;

	good = 0;
	for (sp = hash->starp; sp != NULL; sp = sp->next) 
		if (sp->star->w3 != 0)
			good++;

	fprintf(fp, "%6d %7.2lf %7.2lf %6d \n", newid, hash->xc, hash->yc, good);
	for (sp = hash->starp; sp != NULL; sp = sp->next) {
		if (sp->star->w3 != 0) {
			fprintf(fp, "  %6d %6d %1d %5.0lf %5.2lf %5.2lf %6.2lf    %6.3lf %6.0lf\n",
						newid, sp->star->image->index, sp->star->saturated,
						sp->star->peak, sp->star->fwhm, sp->star->sharp,
						sp->star->round, sp->star->mag[0], sp->star->w4);
		}
	}
	newid++;
}


	/* return -1 if the first star has an xc smaller than the second
	           0                             equal to 
              +1                             larger than
	 */

static int
comp_stsort(s1, s2)
struct s_stsort *s1, *s2;
{
	if (s1->xc < s2->xc)
		return(-1);
	if (s1->xc > s2->xc)
		return(1);
	return(0);
}
		

	/* write out information on each image, putting them in order 
	   by date and time of observation */

static int
write_images(fp)
FILE *fp;
{
	int i, index, n;
	struct s_imsort *imsort;

	/* effectively, sort the images by their time of observation */
	if ((imsort = (struct s_imsort *) calloc(num_images, sizeof(struct s_imsort))) == NULL) {
		fprintf(stderr, "write_images: can't calloc for imsort array \n");
		exit(-1);
	}
	for (i = 0; i < num_images; i++) {
		imsort[i].index = i;
		imsort[i].mjd = image_arr[i].mjd;
	}	
	qsort((char *) imsort, num_images, sizeof(struct s_imsort), comp_imsort);

	n = 0;
	for (i = 0; i < num_images; i++) {
		index = imsort[i].index;
		if (image_arr[index].include != 0) {
			image_arr[index].index = n++;
			write_one_image(fp, &(image_arr[index]));
		}
	}
}

	/* write the pertinent information from a single image structure to
	   the give FILE pointer */

static int
write_one_image(fp, im)
FILE *fp;
struct s_image *im;
{
	int i;

	for (i = 0; i < strlen(im->object); i++)
		if (im->object[i] == ' ')
			im->object[i] = '_';

	fprintf(fp, "%6d %10s %30s %10s %6.1lf %4.2lf %8.5lf %11.5f %6d %6d\n",
			im->index, im->name, im->object, im->filter, im->exptime, 
			im->airmass, im->ut, im->mjd, im->num_star, im->num_match);

}


	/* return -1 if the first image has an mjd before the second
	           0                               same as
              +1                               after
	 */

static int
comp_imsort(i1, i2)
struct s_imsort *i1, *i2;
{
	if (i1->mjd < i2->mjd)
		return(-1);
	if (i1->mjd > i2->mjd)
		return(1);
	return(0);
}
		

