/*

	Convert comet elements in the formats used
	by the Minor Planet Center (and in the Minor Planet
	Electronic Circulars) to our CSV format.  Multiple
	comet announcements can be extracted from a file
	containing other irrelevant information.
	
	Designed and implemented by John Walker in November of 1994.
	
	PERIODIC COMET SHOEMAKER 4 (1994k)
	
				. . .
	 
	     T = 1994 Oct. 31.231 TT          Peri. = 196.521
	     e = 0.52851                      Node  =  92.603   2000.0
	     q = 2.92503 AU                   Incl. =  25.345
	       a =  6.20375 AU     n = 0.063786     P =  15.45 years
			  1         2         3         4         5         6         7
	01234567890123456789012345678901234567890123456789012345678901234567890

	COMET MUELLER (1994c)
                                                                               
					. . .
                                                                         						 
	     T = 1993 Dec.  3.990 TT          Peri. = 102.512
   	                                      Node  =   4.933   2000.0
	     q = 1.81118 AU                   Incl. = 145.454
			  1         2         3         4         5         6         7
	01234567890123456789012345678901234567890123456789012345678901234567890

	
	Name,Perihelion time,Perihelion AU,Eccentricity,Long. perihelion,Long. node,Inclination,Semimajor axis,Period
	P/Encke,94-02-09,0.331,0.85,186,335,11.9,7,0
	P/Halley,86-02-09,0.587,0.97,112,59,162.2,26,0
	P/Schwassman-Wachmann 1,89-10-26,5.772,0.04,50,313,9.4,17,0

	
*/

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>

#ifdef unix
#define _strnicmp strncasecmp
#endif

static char s[8][132];					/* Buffer to hold complete entry */

static int rs(char *s, FILE *fp)
{
	if (fgets(s, 132, fp) == NULL) {
		return 0;
	}
	while (strlen(s) > 0 && s[strlen(s) - 1] < ' ') {
		s[strlen(s) - 1] = 0;
	}
	return 1;
}

static void sc(char *b, int line, int start, int end) {
	char *c = s[line];
	int i, n;
	
	for (i = 0, n = start; n <= end; n++) {
		if (c[n] == 0) {
			break;
		}
		if (!isspace(c[n])) {
			b[i++] = c[n];
		}
	}
	b[i] = 0;
}


static void sct(char *b, int line, int start, int end)
{
    char *c = s[line], sb[132];

    memcpy(sb, c + start, (end - start) + 1);
    sb[(end - start) + 1] = 0;
    while (strlen(sb) > 0 && isspace(sb[strlen(sb) - 1])) {
		sb[strlen(sb) - 1] = 0;
    }
    c = sb;
    while (*c && isspace(*c)) {
		c++;
    }
    strcpy(b, c);
}


int main(int argc, char *argv[])
{
	int i, running = 1, written = 0;
	FILE *fi = stdin, *fo = stdout;			/* Input and output file names */
	static char cname[80], epoch[80], periau[80], perilong[80],
				eccen[80], longnode[80], inclin[80], semimaj[80], period[80];
	
	if (argc > 1) {
		fi = fopen(argv[1], "r");			/* Input file */
		if (fi == NULL) {
			fprintf(stderr, "Cannot open input file %s\n", argv[1]);
			return 2;
		}
		if (argc > 2) {
			fo = fopen(argv[2], "w");		/* Output file */
			if (fo == NULL) {
				fprintf(stderr, "Cannot open output file %s\n", argv[2]);
				return 2;
			}
		}
	}

	fprintf(fo, "Name,Perihelion time,Perihelion AU,Eccentricity,Long. perihelion,\
Long. node,Inclination,Semimajor axis,Period\n");
	
	while (running) {
		int periodic = -1;
		char *u, *v;
	    
	    while (1) {
	    	if (!rs(s[0], fi)) {
	    		running = 0;
	    		break;
	    	}
	    	if (strncmp(s[0], "COMET ", 6) == 0) {
	    		sct(cname, 0, 6, 80);
	    		periodic = 0;
	    		break;  
	    	} else if (strncmp(s[0], "PERIODIC COMET ", 15) == 0) {
	    		sct(cname, 0, 15, 80);
	    		periodic = 1;
	    		break;
	    	} 
	    }
	    
	    if (!running) {
	    	break;
	    }
	    
	    /* Scan until we either find a line which begins with the "T ="
	       specification or run into another comet header (indicating
	       this circular didn't contain elements. */
	       
		while (1) {
			char t[132];
		
	    	if (!rs(s[0], fi)) {
	    		running = 0;
	    		break;
	    	}
	    	if (strncmp(s[0], "COMET ", 6) == 0) {
	    		sct(cname, 0, 6, 80);
	    		periodic = 0;
	    		continue;  
	    	} else if (strncmp(s[0], "PERIODIC COMET ", 15) == 0) {
	    		sct(cname, 0, 15, 80);
	    		periodic = 1;
	    		continue;
	    	}
	    	sc(t, 0, 0, 80);
	    	if (strncmp(t, "T=", 2) == 0 && isdigit(t[2])) {
	    		char y[20], m[20], daf[20];
	    		static char mname[] = "janfebmaraprmayjunjulaugsepoctnovdec";
	    		
	    		sscanf(u = strchr(s[0], '=') + 1, "%s %s", y, m);
	    		for (i = 0; i < 12; i++) {
	    			if (_strnicmp(m, mname + i * 3, 3) == 0) {
	    				sprintf(m, "%d", i + 1);
	    				break;
	    			}
	    		}
	    		
	    		/* Tiptoe up to the start of the year, since in the
	    		   case of "Sept.199x" the month runs into the first
	    		   digit of the year.  This code is relsilient in case
	    		   a space is added later. */
	    		
	    		while (*u && isspace(*u)) {
	    			u++;
	    		}
	    		while (*u && !isspace(*u)) {
	    			u++;
	    		}
	    		while (*u && isspace(*u)) {
	    			u++;
	    		}
	    		while (*u && !isdigit(*u)) {
	    			u++;
	    		}
	    		sscanf(u, "%s", daf);
	    		sprintf(epoch, "%s-%s-%s", y, m, daf);
	    		v = strchr(u, '=');
	    		if (v != NULL) {
	    			sc(perilong, 0, (v + 1) - s[0], 80);
	    		} else {
	    			continue;
	    		}
	    		
	    		/* Process second line. */
	    		
		    	if (!rs(s[0], fi)) {
		    		running = 0;
		    		break;
		    	}
		    	sc(t, 0, 0, 80);
		    	if (strncmp(t, "e=", 2) == 0) {
		    		sscanf(u = strchr(s[0], '=') + 1, "%s", eccen);
		    		v = strchr(u, '='); 
		    	} else {
		    		strcpy(eccen, "1");			/* Parabolic */
		    		v = strchr(s[0], '=');
		    	}
		    	if (v != NULL) {
		    		sscanf(v + 1, "%s", longnode);
		    	} else {
		    		continue;
		    	}
	    		
	    		/* Process third line. */
	    		
		    	if (!rs(s[0], fi)) {
		    		running = 0;
		    		break;
		    	}
		    	u = strchr(s[0], '=');
		    	if (u != NULL) {
		    		v = strchr(u + 1, '=');
		    	}
		    	if (u != NULL && v != NULL) {
		    		sscanf(u + 1, "%s", periau);
		    		sscanf(v + 1, "%s", inclin);
		    	} else {
		    		continue;
		    	}
		    	
	    		/* Process fourth line if comet is periodic. */
	    		
	    		strcpy(semimaj, "");
	    		strcpy(period, "Parabolic");
	    		if (periodic) {
			    	if (!rs(s[0], fi)) {
			    		running = 0;
			    		break;
			    	}
			    	u = strchr(s[0], '=');
			    	if (u != NULL) {
			    		v = strchr(u + 1, '=');
			    		if (v != NULL) {
			    			v = strchr(v + 1, '=');
			    		}
			    	}
			    	if (u != NULL && v != NULL) {
			    		char t1[30], t2[30];
			    		
			    		sscanf(u + 1, "%s %s", t1, t2);
			    		sprintf(semimaj, "%s %s", t1, t2);
			    		sscanf(v + 1, "%s %s", t1, t2);
			    		sprintf(period, "%s %s", t1, t2);
			    	} else {
			    		continue;
			    	}
		    	}
	    		 
	    		break;
	    	} 
		}
	    
	    if (!running) {
	    	break;
	    }
		
		/* Output information in CSV format. */

		fprintf(fo, "%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
					cname, epoch, periau, eccen, perilong, longnode, inclin,
					semimaj, period);
		written++;					
	}
	
	fclose(fi);
	fclose(fo);
	fprintf(stderr, "%d record%s written.\n", written, written == 1 ? "" : "s");		
	
	return 0;
}