/* drawform.c */
/* Copyright 1990 Thomas E. Janzen All Rights Reserved */
/*
**  FACILITY:
**
**	AlgoRhythms music improviser on Commodore (TM) Amiga (TM)
**	compiled with Lattice (TM) C 5.05
**
**  ABSTRACT:
**
**	Algorhythms improvises music over the MIDI serial port.
**
**  AUTHORS: Thomas E. Janzen
**
**  CREATION DATE:	26-MAR-1990
**
**  MODIFICATION HISTORY:
**    DATE	NAME	DESCRIPTION
**--
*/
#include <intuition/intuition.h>
#include <graphics/text.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <math.h>

struct Parameter {
	double CenterCycle;
	double CenterPhase;
	double SpreadCycle;
	double SpreadPhase;
};

const static char PitchLabelString[16]="Pitch";
const static char RhythmLabelString[16]="Rhythm";
const static char DynamicsLabelString[16]="Dynamics";
const static char TextureLabelString[16]="Texture";
	
static struct IntuiText PitchLabelTxt=
	{1,1,JAM1,5,12,NULL,PitchLabelString,NULL};
static struct IntuiText RhythmLabelTxt=
	{1,1,JAM1,5,56,NULL,RhythmLabelString,&PitchLabelTxt};
static struct IntuiText DynamicsLabelTxt=
	{1,1,JAM1,5,100,NULL,DynamicsLabelString,&RhythmLabelTxt};
static struct IntuiText TextureLabelTxt=
	{1,1,JAM1,5,144,NULL,TextureLabelString,&DynamicsLabelTxt};

extern struct Window *w;
extern struct RastPort *rp;

extern struct GfxBase *GfxBase;
extern struct IntuitionBase *IntuitionBase;
extern struct DOSBase *DOSBase;
extern struct MathBase *MathBase;

void DrawForm(const double Duration,
	const struct Parameter *PitchForm, 
	const struct Parameter *RhythmForm, 
	const struct Parameter *DynamicsForm,
	const struct Parameter *TextureForm)
{
	static int Xlim,Ylim;
	register int inttime=0;
	register double curtime = 0.0;
	double HeightRatio = 12.0;
	double timeratio;

	double Spreadfixed, Mean, Top, Bottom;
	register int intTop, intBottom;
	double phase;

	int intLength=631;

	register int intMean;
	register int Step=22;
	
	ClearScreen(rp);
	SetAPen(rp,0);			/* Set foreground pen to white */
	for (inttime=0;inttime<25;inttime++) {
		Move(rp,0,inttime); /*erase part of screen */
		Draw(rp,631,inttime); /*that ClearScreen didn't clear*/
	}
	Xlim = w->GZZWidth;
	Ylim = w->GZZHeight;
	intLength=Xlim;
	Step=Ylim/8;
	timeratio=((double)intLength)/(Duration);
	HeightRatio=12*Ylim/200;
	
	SetAPen(rp,3);			/* Set foreground pen to white */
	SetDrMd(rp,JAM1);		/* Draw with foreground pen */

	for (inttime=0;inttime<intLength;inttime++) {
		curtime=(double)inttime/timeratio;
		phase=2 * PI * curtime;
		Spreadfixed=(1+
		sin(phase/(PitchForm->SpreadCycle)+
			PitchForm->SpreadPhase))/4.0;
		Mean=
		sin(phase/(PitchForm->CenterCycle)+
			PitchForm->CenterPhase);
		Top=Mean+(Spreadfixed); /*could be -1.5 to 1.5*/
		Bottom=Mean-(Spreadfixed);
		intMean=Step;
		intBottom=-(Bottom*HeightRatio)+intMean;
		intTop=-(Top*HeightRatio)+intMean;
		Move(rp,inttime,intTop);
		Draw(rp,inttime,intBottom);

		Spreadfixed=(1+
		sin(phase/(RhythmForm->SpreadCycle)+
			RhythmForm->SpreadPhase))/4.0;
		Mean=
		sin(phase/(RhythmForm->CenterCycle)+
			RhythmForm->CenterPhase);
		Top=Mean+(Spreadfixed); /*could be -1.5 to 1.5*/
		Bottom=Mean-(Spreadfixed);
		intMean=Step*3;
		intBottom=-(Bottom*HeightRatio)+intMean;
		intTop=-(Top*HeightRatio)+intMean;
		Move(rp,inttime,intTop);
		Draw(rp,inttime,intBottom);
		
		Spreadfixed=(1+
		sin(phase/(DynamicsForm->SpreadCycle)+
			DynamicsForm->SpreadPhase))/4.0;
		Mean=
		sin(phase/(DynamicsForm->CenterCycle)+
			DynamicsForm->CenterPhase);
		Top=Mean+(Spreadfixed); /*could be -1.5 to 1.5*/
		Bottom=Mean-(Spreadfixed);
		intMean=Step*5;
		intBottom=-(Bottom*HeightRatio)+intMean;
		intTop=-(Top*HeightRatio)+intMean;
		Move(rp,inttime,intTop);
		Draw(rp,inttime,intBottom);
		
		Top=(1+
		sin(phase/(TextureForm->SpreadCycle)+
			TextureForm->SpreadPhase))/2.0;
		/*Top=SpreadFixed;*/
		Bottom=-(Top);
		intMean=Step*7;
		intBottom=-(Bottom*HeightRatio)+intMean;
		intTop=-(Top*HeightRatio)+intMean;
		Move(rp,inttime,intTop);
		Draw(rp,inttime,intBottom);
	}
	SetAPen(rp,1);
	for(inttime=0;inttime<4;inttime++) {
		Move(rp,0,Step*((2*inttime)+1));
		Draw(rp,Xlim,Step*((2*inttime)+1));
	}
	PitchLabelTxt.TopEdge=Step*(1/2);
	RhythmLabelTxt.TopEdge=Step*(5/2);
	DynamicsLabelTxt.TopEdge=Step*(9/2);
	TextureLabelTxt.TopEdge=Step*(13/2);
	PrintIText(rp,&TextureLabelTxt,1,1);
}

void DrawTime(const double CurTime, const double Duration)
{
	static int Xlim,Ylim;
	register int inttime=0;

	double timeratio;

	double HeightRatio=12;

	int intMean;
	SetAPen(rp,2);			/* Set foreground pen to white */

	Xlim = w->GZZWidth;
	Ylim = w->GZZHeight;

	intMean=Ylim/8;
	timeratio=((double)Xlim)/Duration;
	HeightRatio=(12.0*Ylim)/200.0;
	SetDrMd(rp,JAM1);		/* Draw with foreground pen */
	inttime=(int)(CurTime*timeratio);
	Move(rp,0,intMean);
	Draw(rp,inttime,intMean);
	SetAPen(rp,1);			/* Set foreground pen to white */
	Draw(rp,Xlim,intMean);
}

