/* biorythm plotting program ported from BASIC */

#include <stdio.h>
#include "graph.h"
#include <math.h>

char *month[13] = { " ", "January", "February", "March", "April", "May",\
	"June", "July", "August", "September", "October", "November",\
	"December" };

int i, j, k, a[13] = {0, 10, 8, 5, 5, 3, 4, 4, 6, 9, 10, 8, 8 }, x;
int b, f, h, g, e, c, z;
unsigned m, d, y;
double pi = 3.1415926;
long date;
char instr[160], outmsg[80];

void linput ();
void pause();

main ()
	{
	linput ( "Do you want an explanation (N/y)? " , instr);
	if ( tolower ( instr[0] ) == 'y' )
		{
		printf ( "\n\n  A biorythm is a theoretical metabolic cycle that is\n" );
		printf ( "constantly going on in piople, starting at birth.  To date,\n" );
		printf ( "3 cycles have been discovered.  They are:\n\n" );
		printf ( "Physical:\n" );
		printf ( "  The physical cycle is 23 days logn.  This cycle is said to\n" );
		printf ( "afffect muscle fibers, and, therefore, physical strength,\n" );
		printf ( "endurance, and general physical well-being.\n\n" );
		printf ( "Sensitivity:\n" );
		printf ( "  The sensitivity cycle is 28 days long.  It is said to be closely\n" );
		printf ( "related to the nervous system, affecting cooperation, friendliness,\n" );
		printf ( "and optimism.  On the down-side of this cycle, one is most likely to\n" );
		printf ( "be irritable, frustrated, and stubborn.\n\n" );
		printf ( "Cognitive:\n" );
		printf ( "  The cognitive cycleis 33 days long.  It affects the thought\n" );
		printf ( "processes, the abilities to privide fast, accurate answers, to\n" );
		printf ( "absorb information, and to create.   The down-side of this cycle\n" );
		printf ( "is probably a good time to review old concepts.\n\n" );
		printf ( "Press ENTER for additional explanations." );
		gets (instr);
		printf ( "\n\nThe up-side of the cycle is the discharge period when you are the\n" );
		printf ( "most able in the areas that the cycle affects.  The down-side of the\n" );
		printf ( "cycle is a recuperative period.  Neither of these is necessarily\n" );
		printf ( "good or bad, but it is a good idea to do the most important things\n" );
		printf ( "on the up-side of the cycle, and to rest on the down-side.\n\n" );
		printf ( "  The critical day, on the other hand, is definitely a bad day.\n" );
		printf ( "A good analogy is a light bulb-- the times it is most likely\n" );
		printf ( "to burn out are when it is turned on or turned off.  The times you\n" );
		printf ( "most likely to face an accident are on the days when the cycles change\n" );
		printf ( "polarity.\n\n" );
		}
	do
		{
		k = 1;
		linput ( "Enter date of birth (MMDDYY) ", instr );
		i = sscanf ( instr, "%ld", &date );
		if ((i == 0) || (i == EOF))
			{
			printf ( "\nInvalid date\n\n" );
			k = 0;
			}
		else
			{
			m = date / 10000;
			if ((m < 1) || (m > 12))
				{
				printf ( "Invalid month\n\n" );
				k = 0;
				}
			else
				{
				d = (unsigned) ((date - m * 10000)) / 100;
				if ((d < 1) || (d > 31))
					{
					printf ( "Invalid day\n\n" );
					k = 0;
					}
				}
			y = date - m * 10000 - d * 100;
			if ((y < 0) || (y > 99))
				{
				printf ( "Invalid year\n\n" );
				k = 0;
				}
			y = y + 1900 - 100 * (y > 89);	/* test for birthday-year after current year */
			}				/* implies born 100 year ago */
		}
	while (k == 0);
	do
		{
		linput ( "Enter year to be plotted ", instr );
		i = sscanf ( instr, "%d", &x );
		if ((i == 0) || (i == EOF)) printf ( "\nA numeric value is required\n\n" );
		else
			{
			x =  (x > 100) ? x : x + 1900;
			if (x < 1753) printf ( "\nGregorian calendar doesn't begin until 1753\n\n" );
			}
		}
	while ((k == 0) || (k == EOF) || (x < 1753));

printf ( "month %d, day %d, year %d, plot year %d\n", m, d, y, x );
	do
		{
		linput ( "Enter number of month to plot ", instr );
		i = sscanf ( instr, "%d", &b );
		if ((i == 0) || (i == EOF))
			printf ( "\nA numeric value is required\n" );
		else
			if ((b < 1) || (b > 12))
				printf ( "\nMonth number out of range\n" );
		}
	while (( i == EOF) || (i == 0) || ( b < 1) || (b > 12));
	g_init ( CGA_640x200 );
	z = fnt (m + 1) - fnt (m) + fnl (y) * (m == 2) - d;
	c = 365 + fnl (y) * ((m <= 2) && ((m * d) != 58)) - fnt (m + 1) + z;
	if (x == y) 
		c -= (365 + fnl (x) * (b == 1) - fnt (b) );
	else
		{
			if ((x + 1) != y)
				{
				for (i = y + 1; i < x; ++i) c += 365 + fnl (i);
				}
			c += fnt (b) + fnl (x) * (b > 2);
		}
	e = fnt (b + 1) - fnt (b) + fnl (x) * (b == 2);
	scale (0, 88, 0, 68);
	f = a[b];
	f = f + 6;
	csize(5, 0, 0);
	move (44, 60);
	lorg (4);
	labelf ("%s %4d",month[b], x);
	scale (0, 31, -1.5, 1.5);
	move (1, 0);
	for (i = 2; i <= 31; ++i)	/* draw axes of graph */
		{
		draw (i, 0);
		move (i, -.03);
		draw (i, .03);
		if ((i == 7) || (i == 14) || (i == 21) || (i == 28))
			{
			move (i,-.06);
			draw (i, +.06);
			}
		move (i, 0);
		}
	move (1, -1);
	draw (1.15, -1);
	move (1, -1);
	draw (1, 1);
	draw (1.15, 1);
	unclip ();
	lorg (6);
	csize ((15 / 4.54), 0, 0);
	for (i = 7; i <= 28; i += 7)
		{
		move (i, -.10);
		labelf ("%d", i);
		}
	g = 5;
	move (0, 0);
	lorg (5);
	csize (2.8, 0, 0);
	for (h = 23; h <= 33; h += 5)
		{
		line_type (2 * (h - 23) / 5 + 1, 0);
		penup ();
		f = 1;
		for (i = c + 1; i <= c + e; ++i)
			{
			plot (f, .8 * sin (i * (2 * pi / h)) ,1);
			++f;
			}
		penup ();
		++g;
		}
	scale (0, 88, 0, 68);
	unclip ();
	lorg (2);
	for (j = 1; j <= 5; j += 2)
		{
		line_type (1,0);
		move (20, 12 - 1.3 * j);
		switch (j)
			{
			case 1: labelf ("Physical");
				break;
			case 3: labelf ("Sensitivity");
				break;
			case 5: labelf ("Cognitive");
				break;
			}
		line_type (j,0);
		move (45, 12 - 1.3 * j);
		draw (65, 12 - 1.3 * j);
		}
	pause ();
	graphics_off ();
	}
 

void linput (msg, input) char *msg, *input;
	{
	printf ( "%s ", msg );
	gets ( input );
	sscanf ( input, " %c", input );
	return;
	}
int fnt (x) int x;
	{
	return 31 * (x - 1) - floor ( 2.2 + .4 * x) * (x > 2);
	}
int fnl (x) int x;
	{
	return ((x == (4 * (x / 4))) && (x != (100 * (x / 100))) || (x = (400 * (x / 400))));
	}
void pause ()
	{
	while (getch () != '\r');	/* wait for a <cr> */
	return;
	}