
	/* routines to read in the information for all current targets,
	   calculate some probabilities, and spit the condensed information
	   out into a file that the list generator will read. 

	   this is going to turn into the "noon gardener" program that
	   runs mainly at noon each day, preparing all the possible targets
	   for the next night and putting all ineligible targets away in
	   a storage shed for later use.

	   although it runs mainly at noon, it also should be called
	   whenever a new request file comes into the garden. */


#include <stdio.h>
#include "bait.h"
#include "listgen.h"

#define DEBUG

#define LINELEN 255		/* max length of lines in the target database file */
#define COMMENT_CHAR '#'	/* if first char of line is this, skip line */

static eligible();
static plant();
static put_is_shed();
static weed_out();

#define BUFLEN  100

static char err_msg[BUFLEN];
static char buf[BUFLEN];


	/* check to see if there is the special NEW_RQS_FILE file in the
	   target directory that contains names of new request files; if
	   there is, process those files and then delete the NEW_RQS_FILE.
	   return 0 if all OK,
	   or -1 if there was some error (such as not being able to open one
	   of the listed request files. */

static int
get_new_rqs()
{
	FILE *fp;

	if ((fp = fopen(NEW_RQS_FILE, "r")) == NULL) {
		return(0);
	}
	else {
		while (fgets(buf, BUFLEN, fp) != NULL) {
			if (process_rqs(buf) < 0)
				return(-1);
		}
		fclose(fp);
		if (unlink(NEW_RQS_FILE) < 0) {
			fprintf(stderr, "error in get_new_rqs while unlinking file %s\n",
					NEW_RQS_FILE);
			return(-1);
		}
	}
	return(0);
}



	/* read information for all current, viable targets into the array
	   of target structures pointed to by 'list'. return the number of 
	   viable targets. */

read_input()
{
	int cur_number, priority, interval, obs_left;
	long start_jd, end_jd, last_jd, exp_type;
	char line[LINELEN], ra_str[20], dec_str[20], req_id[50];
	double ra, dec, old_ra, old_dec, epoch, exp_time, start_ut, max_ha;
	double prob;
	FILE *fp;
	struct target *cur_target;

	cur_number = 0;
	cur_target = list;

	/* prepare to read in targets */
	if ((fp = fopen(INFILE, "r")) == NULL) {
		sprintf(err_msg, "can't open target database file %s", INFILE);
		error(1, err_msg);
	}

	while (1) {

		/* first, read in a target. eventually, this will mean opening
		   a FITS header file and getting keyword-value pairs out of
		   it.  For now, just read the information from a file already
	 	   nicely formatted */

		if (fgets(line, LINELEN, fp) == NULL)
			break;
		if ((line[0] == COMMENT_CHAR) || (line[0] == '\n'))
			continue;

		/* this string, 'req_id', will be the request file name */
		sprintf(req_id, "req%05d", cur_number);
		if (sscanf(line, "%s %s %lf %lf %d %ld %ld %lf %d %ld %ld %lf %d", 
				ra_str, dec_str, &epoch, &exp_time, &priority, &start_jd, 
				&end_jd, &start_ut, &interval, &last_jd, &exp_type, 
				&prob, &num_left) != 13) {
			sprintf(err_msg, "bad input line: %s");
			error(1, err_msg);
		}
	
		/* now, convert the RA and Dec to standard epoch 2000.0 */
		read_ra_to_degrees(ra_str, &old_ra);
		read_dec_to_degrees(dec_str, &old_dec);	
		to_j2000(epoch, old_ra, old_dec, &ra, &dec);

		/* one could make sanity checks of the input at this point */
		/*    (reasonable RA, Dec, exposure time, priority!, etc.) */

		/* now (since all the information seems to be OK), put it into
		   the next target structure in the list */
		strcpy(req_id, cur_target->req_id);
		cur_target->ra = ra;
		cur_target->dec = dec;
		cur_target->epoch = 2000.0;
		cur_target->exp_time = exp_time;
		cur_target->tot_time = exp_time;	/* should be TOTAL time */
		cur_target->exp_type = exp_type;
		cur_target->delay_time = 0.0;
		cur_target->priority = priority;
		cur_target->start_jd = start_jd;
		cur_target->end_jd = end_jd;
		cur_target->start_ut = start_ut;
		cur_target->interval = interval;
		cur_target->last_jd = last_jd;	
		cur_target->num_left = num_left;
		cur_target->probability = prob;

		/* other information in the target structure can be initialized here */
		cur_target->tonight_status = ACTIVE;
		cur_target->setup_time = SETUP_TIME;
		if (cur_target->start_ut >= 0.0) {
			cur_target->lst_min = ut_to_lst((double)start_jd, start_ut);
			cur_target->lst_max = ut_to_lst((double)start_jd, start_ut);
		}
		else {
			max_ha = largest_ha(dec);
			cur_target->lst_min = ra - max_ha;
			if (cur_target->lst_min < 0.0)
				cur_target->lst_min = 0.0;
			cur_target->lst_max = ra + max_ha - cur_target->exp_time;
			if (cur_target->lst_max) > 360.0)
				cur_target->lst_max > 360.0;
		}
#ifdef DEBUG
		printf("read in target number %4d, ID = %10s\n", cur_number + 1,
				cur_target->req_id);
#endif
		cur_target++;

		/* okay, now that we've read it all in, check it for elegibility
		   and classify it as eligible now, later or never. */
		classify(tar);

		if (++cur_number >= MAX_TARGETS) {
			sprintf(err_msg, "reading only first %d of all possible targets",
					cur_number);
			error(0, err_msg);
			break;
		}
	}

	fclose(fp);
	return(cur_number);
}

	/* check a target to see if it is eligible for observation tonight -
	   if yes, then set the probability for tonight's observation. 
	   Otherwise, either weed the target or put it back in the shed.

	   returns 0 if the target is not eligible tonight, or 1 if it is. */

static
eligible(tar)
struct target *tar;
{
	double cur_jd, cur_ut, cur_lst;

	now(&cur_jd, &cur_ut, &cur_lst);

	/* the first decisions are based simply on whether tonight
	   is within the JD window, and whether there are any observations
	   left to be made. */
	if ((tar->end_jd <= cur_jd) || (tar->obs_left < 1)) {
		weed_out(tar);
		return(0);
	}
	if (tar->start_jd > cur_jd + 1.0) {
		put_in_shed(tar);
		return(0);
	}

	/* now it gets more tricky.  Here are some sample rules, but they
	   may certainly change:

	          0. if not observed yet
	                   observe at probability = 1.0

	             otherwise,
	                let x = (days since last observed)/interval

	          1. if (0 < x < 0.5)
	                   put_in_shed()
	          2. if (0.5 <= x < 0.9)
	                   observe at probability = 0.2
	          3. if (0.9 <= x <= 1.0)
	                   observe at probability = 1.0
	          4. if (x > 1.0)
	                   observe at probability = 1.0
	                   make higher priority than normal
	*/
		
	if (cur_target->last_jd < 0) {
		probability = 1.0;
		return(0);
	}
	x = (cur_jd - cur_target->last_jd) / (double)cur_target->interval;
	if (x < 0.5) {
		put_in_shed(tar);
		return(0);
	}
	if (x < 0.9) {
		tar->probability = 0.2;
		plant(tar);
		return(1);
	}
	if (x <= 1.0) {
		tar->probability = 1.0;
		plant(tar);
		return(1);
	}
	else {
		tar->probability = 1.0;
		tar->priority--;
		plant(tar);
		return(1);
	}
}

	/* this observation has been marked as eligible for the coming
	   (or present) night - the final version of this program should
	   leave the request file (with updated info, perhaps) in the
	   garden, and append a line with info about this target for
	   the list generator to the list-generator file */

plant(tar)
struct target *tar;
{
	fprintf(stderr, "planting object ..%s.. for observation \n",
			tar->req_id);
	tar->tonight_status = ACTIVE;
}	
	
	/* this observation has been rejected for the coming evening - 
	   it should be put back into the storage shed for consideration
	   on future nights, though */

static
put_in_shed(tar)
struct target *tar;
{
	fprintf(stderr, "putting object ..%s.. into storage shed\n",
			tar->req_id);
	tar->tonight_status = INACTIVE;
}

	/* this target is FINISHED - as many observations have been
	   made as planned, or past its ending Julian date, or 
	   whatever.  It is to be dis-carded.  It is extinct, 
	   deceased, defunct.  It has ceased to be.  It is pushin'
	   up the daisies.  This ... is an EX-target! */

static
weed_out(tar)
struct target *tar;
{
	fprintf(stderr, "destroying the request file for object ..%s..\n",
			tar->req_id);
}
