/* -	BioRhythm - */
#define xedvars 1

#include "stdio.h"
#include "types.h"
#include "math.h"
#include "intuition/intuition.h"
#include "intuition/screens.h"
#include "graphics/gfxbase.h"
#include "graphics/text.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"
#include "exec/memory.h"

#include "bio.p"

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct NewScreen gfxscn;
struct Screen *gfxscreen;
struct NewWindow frame;
struct Window *gfxwin, *txwin;
struct IntuiMessage *txmsg,*gfxmsg;
struct RastPort *txrp, *gxrp;
struct MsgPort *xport;
struct IOStdReq *iport;
struct Device *ConsoleDevice;

struct InputEvent ievent = /*raw key input event*/
{
	NULL,					/*next event*/
	IECLASS_RAWKEY,	/*class*/
	0,0,0
};

int MaxStLen = 256;
#define MAXSTR 256  /*maxstlen */

int TOP = 1;
int BOT = 23;
int PW = 39;
int LLen;
int GX, GY;
ulong COLOR=3, BCOLOR=2;
ulong Tstyle;
char buff[10];
char func;
char Nstr[82],Path[258];
char *Msg;

/* Define the size of the screen */
#define SC_WIDTH	320
#define SC_HEIGHT 200

/* -	-	Menu	-	-	*/
/* back to front */
#define EDIT_MENU 0

#define SDAY_ITEM 0
#define BDAY_ITEM 1
#define PLOT_ITEM 2
#define CLSC_ITEM 3
#define QUIT_ITEM 4

static struct IntuiText quit_text =
{
   9,1,JAM1,0,1,NULL,"Quit",NULL
};

struct MenuItem quit_item =
{
	NULL,
	0,41,75,10,
	ITEMTEXT |ITEMENABLED |HIGHCOMP,
	0,(APTR) &quit_text,
	NULL,0,NULL,MENUNULL
};

static struct IntuiText clsc_text =
{
   9,1,JAM1,0,1,NULL,"Cls",NULL
};

struct MenuItem clsc_item =
{
	&quit_item,
	0,31,75,10,
	ITEMTEXT |ITEMENABLED |HIGHCOMP,
	0,(APTR) &clsc_text,
	NULL,0,NULL,MENUNULL
};

static struct IntuiText plot_text =
{
   4,1,JAM1,0,1,NULL,"Plot",NULL
};

struct MenuItem plot_item =
{
	&clsc_item,
	0,21,75,10,
	ITEMTEXT |ITEMENABLED |HIGHCOMP,
	1,(APTR) &plot_text,
	NULL,0,NULL,MENUNULL
};

static struct IntuiText bday_text =
{
   4,1,JAM1,LOWCHECKWIDTH,1,NULL,"Birthday",NULL
};

struct MenuItem bday_item =
{
	&plot_item,
	0,11,75,10,
	ITEMTEXT |ITEMENABLED |CHECKIT |HIGHCOMP,
	1,(APTR) &bday_text,
	NULL,0,NULL,MENUNULL
};

static struct IntuiText sday_text =
{
   4,1,JAM1,LOWCHECKWIDTH,1,NULL,"1st day",NULL
};

struct MenuItem sday_item =
{
	&bday_item,
	0,1,75,10,
	ITEMTEXT |ITEMENABLED |CHECKIT |HIGHCOMP,
	2,(APTR) &sday_text,
	NULL,0,NULL,MENUNULL
};

struct Menu edit_menu =
{
	NULL,
	0,0,83,0,
	MENUENABLED,
   "Menu",
	&sday_item
};
/* -	-	Menu	-	-	*/

short colours[16] =
{
 /* RGB */
 0x0000, /*0 black	*/
 0x0DDD, /*1 white	*/
 0x0444, /*2 brown	*/
 0x0888, /*3 yellow	*/
 0x0900, /*4 d red	*/
 0x0F00, /*5 red		*/
 0x0808, /*6 d mag	*/
 0x0E0E, /*7 mag		*/
 0x0009, /*8 d blue	*/
 0x000F, /*9 blue		*/
 0x0088, /*10 d cyan */
 0x00EE, /*11 cyan	*/
 0x0080, /*12 d green*/
 0x00E0, /*13 green	*/
 0x0444, /*14 d gray */
 0x0888	/*15 gray	*/
};
#define BLK 0
#define WHITE 1
#define DGRAY 2
#define GRAY 3
#define RED 5
#define BLU 9
#define CYAN 11
#define DGRN 12
#define GRN 13
#define BRN 14
#define YLO 15

BOOL OpenGFXScreen()
{
	gfxscn.LeftEdge = 0;
	gfxscn.TopEdge	 = 0;
	gfxscn.Width	 = SC_WIDTH;
	gfxscn.Height	 = SC_HEIGHT;
	gfxscn.Depth	 = 4;
	gfxscn.DetailPen= GRAY;
	gfxscn.BlockPen = DGRAY;
	gfxscn.ViewModes= 0;
	gfxscn.Type		 = 0;
	gfxscn.Font		 = 0;
   gfxscn.DefaultTitle = "";
	gfxscn.Gadgets	 = 0;
	gfxscreen = (struct Screen *)OpenScreen(&gfxscn);
	return(BOOL)(gfxscreen != 0);
}

BOOL OpenTWindow(T,tstr,wide,high)
int T;
char *tstr;
int wide,high;
{
	int left,top,width,height;
	if(T == 0) { width = SC_WIDTH; height = SC_HEIGHT; left=top=0; }
	else { width = wide; height = high; top = 85; left = 40; }
	frame.LeftEdge = left;
	frame.TopEdge	= top;
	frame.Width		= width;
	frame.Height	= height;
	frame.DetailPen= 1;
	frame.BlockPen = 15;
	frame.IDCMPFlags = MENUPICK| RAWKEY;
	frame.Flags		= WINDOWDRAG| BORDERLESS |SMART_REFRESH| ACTIVATE;
	frame.Title		= tstr;
	frame.Screen	= gfxscreen;
	frame.MinWidth = width;
	frame.MaxWidth = width;
	frame.MinHeight= height;
	frame.MaxHeight= height;
	frame.Type		= CUSTOMSCREEN;
	if(T == 0)
	{
		gfxwin = (struct Window *)OpenWindow(&frame);
		gxrp = gfxwin->RPort; txrp = gxrp;
		txwin = gfxwin; Delay(2);
		return(BOOL)(gfxwin != 0);
	} else {
		txwin = (struct Window *)OpenWindow(&frame);
		txrp = txwin->RPort; Delay(2);
		return(BOOL)(txwin != 0);
	}
}

Reqest(Side,wide,tstr,bstr) /* !Returns a string */
int Side, wide;
char *tstr, *bstr;
{
	int b,p,v,w,i,h;
	w = (wide + 1) * 8; h = 30;
	OffMenu(gfxwin,0x600); /* this doesn't seem cwite cosher */
	p = PW; PW = wide - 1;
	b = OpenTWindow(1,tstr,w,h);
	w--; h--;
	SetAPen(txrp,(ulong)GRAY); RectFill(txrp,0,0,w,h);
	SetAPen(txrp,(ulong)WHITE); SetBPen(txrp,(ulong)GRAY);
	GX = 3; GY = 7; WriteStr(tstr);
	GX = 3; GY = 26; WriteStr(bstr);
	v = w; i = h; v--; i--;
	Move(txrp,(long)1,(long)0); Draw(txrp,v,0);
	Move(txrp,(long)2,(long)1); Draw(txrp,v-1,1);
	Move(txrp,(long)0,(long)1); Draw(txrp,0,i);
	Move(txrp,(long)1,(long)2); Draw(txrp,1,i-1);
	SetAPen(txrp,(ulong)DGRAY);
	Move(txrp,(long)v,(long)h); Draw(txrp,1,h);
	Move(txrp,(long)w,(long)i); Draw(txrp,w,1);
	Move(txrp,(long)v-(long)1,i); Draw(txrp,2,i);
	Move(txrp,(long)v,(long)i-1); Draw(txrp,v,2);
   GX = 3; GY = 18; Msg = "»"; GetStM();
	CloseWindow(txwin);
	txrp = gxrp; txwin = gfxwin;
	PW = p;
	OnMenu(gfxwin,0x600);
/* return(Path);*/
}

/* - - SCREEN - - */
#include "SCREEN.P";
#include "SCREEN.C";
/* - - SCREEN - - */

_getback() { if(LLen > 0) { WriteCh(' '); GX -= 16; --LLen; } else LLen = 0; }
GetStM() /* Path << kb ESC LLen*/
{
	char C;
	Path[0] = 0; LLen = 0; KY(); WriteStr(Msg);
	do {
		SetBPen(txrp,(ulong)GRN); WriteCh(' '); GX -= 8; C = GetKey();
		SetAPen(txrp,(ulong)BLK); SetBPen(txrp,(ulong)GRAY);
		if(C > 31)
		{
			if((C < 127) || (C > 159)) WriteCh(C); else WriteCh(169);
			Path[LLen++] = C;
		} else {
			switch (C)
			{
			case 30:/* BS */
			case	8:/* ^H */ _getback(); break;
			case 27:/*ESC */ C = 13; Path[0] = 10; LLen = 1; break;
			default: break;
			}
		}
		if(LLen >= PW) { do { _getback(); } while(LLen >= PW); }
	}
	while(C != 13);
	Path[LLen] = 0;
}

Clgs()
{
	SetAPen(gxrp,(ulong)0);
	RectFill(gxrp,0L,12L,(long)SC_WIDTH,(long)SC_HEIGHT);
}

char BDate[12];
char SDate[12];
int Month[14];
int bday=1,bmon=1,byr=0;
int sday=1,smon=1,syr=0;

int Getnum(str)
char *str;
{
	int a=0,e=0,n=0; char c;
	do {
		n = n + str[a++] - '0';
		c = str[a];
		if((c >= '0') && (c <= '9')) n *= 10; else e = 1;
	} while(e == 0);
	return(n);
}

GetDate(N)
int N;
{
	int a,e,d,m,y; char c; char *tstr;
   if(N == 1) tstr = " START Date "; else tstr = " BirthDay   ";
   Reqest(1,12,tstr," DD MM YYYY");
			 /*dd mm yyyy+2*/
	if((Path[0] >= '0') && (Path[0] <= '9')) {
      if(LLen < 10) { do { StCat(Path," "); } while(LLen < 10); }
		if(N == 1) StCopy(SDate,Path); else StCopy(BDate,Path);
		tstr = Path;
		d = Getnum(tstr);
		if((d > 0) && (d < 32)) {
			a = 0; e = 0;
			do {
				c = Path[a];
				if((c >= '0') && (c <= '9')) a++; else e = 1;
			} while((a < 10) && (e < 1));
			do {
				c = Path[a];
				if((c >= '0') && (c <= '9')) e = 2; else Path[a++] = '-';
			} while((a < 10) && (e < 2));
			tstr = &Path[a];
			m = Getnum(tstr);
			if((m > 0) && (m < 13)) {
				do {
					c = Path[a];
					if((c >= '0') && (c <= '9')) a++; else e = 3;
				} while((a < 10) && (e < 3));
				do {
					c = Path[a];
					if((c >= '0') && (c <= '9')) e = 4; else Path[a++] = '-';
				} while((a < 10) && (e < 4));
				if(a < 10)
				{
					tstr = &Path[a];
					y = Getnum(tstr);
					if((y > -1) && (y < 16300)) {
						if(N == 1) { sday=d; smon=m; syr=y; }
						else { bday=d; bmon=m; byr=y; }
					}
				}
			}
		}
	}
}

Sinus(s,p,col) /*start period colour*/
ulong s;
int p,col;
{
	int a,y; double b,i;
	SetAPen(gxrp,(ulong)col);
	b = (2.0 * PI * (double)(s % p)) / p; /*PDC HAS A PROBLEM WITH INT > DOUBLE*/
	i = (2.0 * PI) / (p * 10);
	for(a = 4; a < 315; a++) {
		y = 95 - (sin(b) * 80);
		WritePixel(gxrp,a,y);
		b += i;
	}
}

Plot()
{
	int a,n; ulong b,s;
	Clgs();
	SetAPen(gxrp,(ulong)14);
	for(a = 0; a < 32; a++) { /*verticals*/
		n = 4 + (a * 10); Move(gxrp,(long)n,(long)15); Draw(gxrp,n,175);
	}
	for(a = 0; a < 11; a++) { /*horizontals*/
		n = 15 + (a * 16); Move(gxrp,(long)4,(long)n); Draw(gxrp,314,n);
	}
	SetAPen(gxrp,(ulong)15); Move(gxrp,(long)4,(long)95); Draw(gxrp,314,95); /*c/l*/
	n = sday; Nstr[2] = 0;
	for(a = 0; a < 31; a++) {
		Nstr[0] = (n / 10) + 48; Nstr[1] = (n % 10) + 48;
		Move(gxrp,(long)(a * 10),(long)160 + ((a % 2) * 8));
		if(n > 9) Text(gxrp,Nstr,(ulong)2); else Text(gxrp,&Nstr[1],(ulong)1);
		n += 1; if(n > Month[smon]) n = 1;
	}

	s = (sday << 7) + (smon * 3896) + (syr * 46751);
	b = (bday << 7) + (bmon * 3896) + (byr * 46751);
	if(s >= b) {
		s = (s - b) >> 7;
		Sinus(s,23,GRN); /*physical*/
		Sinus(s,28,RED); /*emotional*/
		Sinus(s,33,BLU); /*intellectual*/
		Move(gxrp,(long)4,(long)184);
      SetAPen(gxrp,(ulong)GRN); Text(gxrp,(char *)"Physical ",(ulong)9);
      SetAPen(gxrp,(ulong)RED); Text(gxrp,(char *)"Emotional ",(ulong)10);
      SetAPen(gxrp,(ulong)BLU); Text(gxrp,(char *)"Intellectual",(ulong)12);
		Move(gxrp,(long)4,(long)192);
		SetAPen(gxrp,(ulong)GRAY); Text(gxrp,SDate,(ulong)10);
	}
}

 int done = 0;
MenuCmd()
{
	ulong class;
	ushort code, qualifier;
	Wait(1 << txwin->UserPort->mp_SigBit);
	while(!done)
	{
		while(((gfxmsg = (struct IntuiMessage *)GetMsg(txwin->UserPort)) != NULL))
		{
			class = gfxmsg->Class;
			code	= gfxmsg->Code;
			qualifier = gfxmsg->Qualifier;
			ReplyMsg(gfxmsg);
			if(class == MENUPICK)
			{
				if(code != MENUNULL)
				{
					if(MENUNUM(code) == EDIT_MENU)
					{
						switch(ITEMNUM(code))
						{
							case SDAY_ITEM: GetDate(1); break;
							case BDAY_ITEM: GetDate(2); break;
							case PLOT_ITEM: Plot(); break;
							case CLSC_ITEM: Clgs(); break;
							case QUIT_ITEM: done = 1; break;
							default: break;
						}
					}
				}
			}
		}
	}
}

Start()
{
   StCopy(SDate,"J D Gray  ");
	Month[0] = 29; Month[1] = 31; Month[2] = 28; Month[3] = 31;
	Month[4] = 30; Month[5] = 31; Month[6] = 30; Month[7] = 31;
	Month[8] = 31; Month[9] = 30; Month[10] = 31; Month[11] = 30;
	Month[12] = 31; Month[13] = 31;
	Plot();
	MenuCmd();
}

main(argc,argv)
int argc;
char *argv[];
{
	long d;
   if((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0)) != 0)
	{
      if((GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0)) != 0)
		{
			if(OpenGFXScreen())
			{
				LoadRGB4(&gfxscreen->ViewPort,colours,16L); /* Set the Colours */
            if(OpenTWindow(0,"BioRhythms",0,0))
				{
					SetMenuStrip(gfxwin, &edit_menu); /* Set up the menu strip */
               if((xport = (struct MsgPort *)CreatePort("conread",0)) != 0L)
					{
						if((iport = (struct IOStdReq *)CreateStdIO(xport)) != 0L)
/* for kbd */		{
                     if((d = OpenDevice("console.device",-1,iport,0)) == 0)
							{
								ConsoleDevice = iport->io_Device;

								Start();

								if((d = CheckIO(iport)) == FALSE) AbortIO(iport);
							}
							DeleteStdIO(iport);
						}
						DeletePort(xport);
					}
					ClearMenuStrip(gfxwin);
					CloseWindow(gfxwin);
				}
				CloseScreen(gfxscreen);
			}
		}
	}
}

