#include "inc.h"
#include "defs.H"

#define SETVOL 		scroll[0].Prop.Info.HorizPot = vol*65535/127;
#define SETMOD	 	scroll[1].Prop.Info.HorizPot = mod*65535/127;
#define SETPITCH	scroll[2].Prop.Info.HorizPot = pitch*65535/255;

void Controllers(void);
void TransmitVolume(int);
void TransmitModulation(int);
void TransmitPitch(int);

void Controllers(void)
{
	struct NewWindow nw;
	struct Window 	*WIN;
	struct RastPort *RP;
	int 			i,id;
	static struct ScrollBlock scroll[3];
	static struct GadgetBlock buf[4];
	struct Gadget *gad;
	long vol,mod,pitch;
	char str[20];

	nw.LeftEdge = 20;
	nw.TopEdge = 20;
	nw.Width = 400;
	nw.Height = 80;
	nw.DetailPen = 0;
	nw.BlockPen = 1;
	nw.Title ="K1-II - MIDI Controllers";
	nw.Flags = RMBTRAP|ACTIVATE|WINDOWCLOSE|REPORTMOUSE|SMART_REFRESH|WINDOWDRAG|(SCREEN == 0 ? WINDOWDEPTH : NULL) ;
	nw.IDCMPFlags = CLOSEWINDOW|MOUSEBUTTONS|GADGETUP|GADGETDOWN;
	nw.Type = (SCREEN != 0 ? CUSTOMSCREEN : WBENCHSCREEN);
	nw.CheckMark = NULL;
	nw.Screen = (SCREEN != 0 ? scr : NULL);
	nw.BitMap = NULL;
	nw.MinWidth = 0;
	nw.MinHeight = 0;
	nw.MaxWidth = 0;
	nw.MaxHeight = 0;

	for (i=0;i<=2;i++)	
	{
		MakeScrollBar(&scroll[i],HORIZSLIDER,250,100,15+15*i);
		scroll[i].ArrowUpLt.GadgetID = 3*i;
		scroll[i].ArrowDnRt.GadgetID = 3*i+1;
		scroll[i].Prop.Gadget.GadgetID = 3*i+2;
	}

	scroll[0].Prop.Info.HorizBody =65535/127; 
	scroll[1].Prop.Info.HorizBody =65535/127; 
	scroll[2].Prop.Info.HorizBody =65535/255; 

	vol=64;
	mod=0;
	pitch=127;

	SETVOL
	SETMOD
	SETPITCH	

	nw.FirstGadget=&scroll[0].ArrowUpLt;
	scroll[0].Prop.Gadget.NextGadget=&scroll[1].ArrowUpLt;
	scroll[1].Prop.Gadget.NextGadget=&scroll[2].ArrowUpLt;
	scroll[2].Prop.Gadget.NextGadget=NULL;

	MakeGadget(&buf[0],"Reset",30,65);
	buf[0].Gadget.NextGadget=nw.FirstGadget;
	buf[0].Gadget.GadgetID=20;
	nw.FirstGadget=&buf[0].Gadget;

	MakeGadget(&buf[1],"All notes off",90,65);
	buf[1].Gadget.NextGadget=nw.FirstGadget;
	buf[1].Gadget.GadgetID=21;
	nw.FirstGadget=&buf[1].Gadget;

	MakeGadget(&buf[2],"Omni on",210,65);
	buf[2].Gadget.NextGadget=nw.FirstGadget;
	buf[2].Gadget.GadgetID=22;
	nw.FirstGadget=&buf[2].Gadget;

	MakeGadget(&buf[3],"Omni off",280,65);
	buf[3].Gadget.NextGadget=nw.FirstGadget;
	buf[3].Gadget.GadgetID=23;
	nw.FirstGadget=&buf[3].Gadget;

	Center(&nw,0,0);
	WIN=(struct Window *) OpenWindow(&nw);
	if (WIN==NULL) Error("Can't open controller window");
	RP=WIN->RPort;
	SetFont(RP,textfont);

	Print(WIN,10,22,"Volume");
	Print(WIN,10,37,"Modulation");
	Print(WIN,10,52,"Pitchbend");

	for (i=0;i<=2;i++) RefreshGList(&scroll[i].Prop.Gadget,WIN,NULL,1);
	
Loop: ;
	sprintf(str,"%4ld",vol);
	Print(WIN,350,22,str);
	sprintf(str,"%4ld",mod);
	Print(WIN,350,37,str);
	sprintf(str,"%4ld",pitch-127);
	Print(WIN,350,52,str);

	WaitPort(WIN->UserPort);
	while(mesg = (struct IntuiMessage *) GetMsg(WIN->UserPort))
	{
		class=mesg->Class; 
		code=mesg->Code;
		if (class == GADGETUP || class == GADGETDOWN)
		{
			gad=mesg->IAddress;
			id=gad->GadgetID;
		}
		ReplyMsg((struct Message *)mesg);
	
		switch(class)
		{
			case CLOSEWINDOW:
			{   
				while(mesg = (struct IntuiMessage *) GetMsg(WIN->UserPort)) ReplyMsg((struct Message *)mesg);
				CloseWindow(WIN);
				return;
				break;
			}
		
			case MOUSEBUTTONS:
			{
				if (code==MENUDOWN)
				{
					while(mesg = (struct IntuiMessage *) GetMsg(WIN->UserPort)) ReplyMsg((struct Message *)mesg);
					CloseWindow(WIN);
					return;
				}	
				break;
			}
	
			case GADGETUP:
			{
				int nr,pos;
	
				nr=id / 3;
				pos=id % 3;
		
				if (id==20)							/* Reset */
				{
					vol=64;
					mod=0;
					pitch=127;
	
					TransmitVolume(vol);
					TransmitModulation(mod);
					TransmitPitch(pitch);
	
					SETVOL
					SETMOD
					SETPITCH	
	
					for (i=0;i<=2;i++) RefreshGList(&scroll[i].Prop.Gadget,WIN,NULL,1);
				}
	
				if (id==21)						/* All notes off */
				{
					unsigned char buf[3];
					int i;
	
					buf[0]=128+MASTERCHANNEL;
					buf[2]=0;
					for (i=0;i<=127;i++)
					{
						buf[1]=i;
						PutMidiMsg(source,buf);
						Delay(1);
					}
				}	
				
				if (id==22)						/* Omni on */
				{
					unsigned char buf[3];
	
					buf[0]=176; buf[1]=125; buf[2]=0;
					PutMidiMsg(source,buf);
					Delay(1);
				}	
				
				if (id==23)						/* Omni off */
				{
					unsigned char buf[3];
	
					buf[0]=176; buf[1]=124; buf[2]=0;
					PutMidiMsg(source,buf);
					Delay(1);
				}	
			
				if (pos<=1)
				{
					vol  =127*scroll[0].Prop.Info.HorizPot/65535;
					mod  =127*scroll[1].Prop.Info.HorizPot/65535;
					pitch=255*scroll[2].Prop.Info.HorizPot/65535;
				
				}	
	
				if (pos==2)
				{
					if (nr==0)	vol=127*scroll[0].Prop.Info.HorizPot/65535;
					if (nr==1)	mod=127*scroll[1].Prop.Info.HorizPot/65535;
					if (nr==2)	pitch=255*scroll[2].Prop.Info.HorizPot/65535;
	
					sprintf(str,"%4ld",vol);
					Print(WIN,350,22,str);
					sprintf(str,"%4ld",mod);	
					Print(WIN,350,37,str);
					sprintf(str,"%4ld",pitch-127);	
					Print(WIN,350,52,str);
	
					if (nr==0) TransmitVolume(vol);
					if (nr==1) TransmitModulation(mod);
					if (nr==2) TransmitPitch(pitch);    
				}
				break;
			}
	
			case GADGETDOWN:
			{
				int nr,pos;
	
				nr=id / 3;
				pos=id % 3;
				
				if (pos==2 && id<10)
				{
					while (scroll[0].Prop.Gadget.Flags & SELECTED || scroll[1].Prop.Gadget.Flags & SELECTED || scroll[2].Prop.Gadget.Flags & SELECTED )
					{
						if (nr==0)	vol  =127*scroll[0].Prop.Info.HorizPot/65535;
						if (nr==1)	mod  =127*scroll[1].Prop.Info.HorizPot/65535;
						if (nr==2)	pitch=255*scroll[2].Prop.Info.HorizPot/65535;
	
						sprintf(str,"%4ld",vol);
						Print(WIN,350,22,str);
						sprintf(str,"%4ld",mod);	
						Print(WIN,350,37,str);
						sprintf(str,"%4ld",pitch-127);	
						Print(WIN,350,52,str);
	
						if (nr==0) TransmitVolume(vol);
						if (nr==1) TransmitModulation(mod);
						if (nr==2) TransmitPitch(pitch);    
					}
						vol=127*scroll[0].Prop.Info.HorizPot/65535;
						mod=127*scroll[1].Prop.Info.HorizPot/65535;
						pitch=255*scroll[2].Prop.Info.HorizPot/65535;
	
						sprintf(str,"%4ld",vol);
						Print(WIN,350,22,str);
						sprintf(str,"%4ld",mod);	
						Print(WIN,350,37,str);
						sprintf(str,"%4ld",pitch-127);	
						Print(WIN,350,52,str);
	
						if (nr==0) TransmitVolume(vol);
						if (nr==1) TransmitModulation(mod);
						if (nr==2) TransmitPitch(pitch);    
				}
				break;
			}	
	
			default: goto Loop;
		}		
	}
goto Loop;
}

/**********************************************************************************/
/***                                                                            ***/
/**********************************************************************************/

void TransmitVolume(int val)
{
	unsigned char buf[3];

	buf[0]=176; 
	buf[1]=7;
	buf[2]=val;

	PutMidiMsg(source,buf);
}

/**********************************************************************************/
/***                                                                            ***/
/**********************************************************************************/

void TransmitModulation(int val)
{
	unsigned char buf[3];

	buf[0]=176; 
	buf[1]=1;
	buf[2]=val;

	PutMidiMsg(source,buf);
}

/**********************************************************************************/
/***                                                                            ***/
/**********************************************************************************/

void TransmitPitch(int val)
{
	unsigned char buf[3];

	buf[0]=224; 
	buf[1]=0;
	buf[2]=val/2;

	PutMidiMsg(source,buf);
}
