/*-------------------------------------------------------*/
/* ProjectOmega                 									*/
/* Written by T.Miles												*/
/* ID: 289175															*/
/* Module:	Coordinator Main									   */
/* Provides the gui for the coordinator                  */
/*-------------------------------------------------------*/

// 15/01 - Fixed crash bug - setting a slider to have max 0 isn't a good idea!  
//  		Happened when no input plugins were available and entered assign tracks

#include <exec/types.h>
#include <libraries/mui.h>
#include <libraries/dosextens.h>
#include <libraries/gadtools.h>
#include <clib/exec_protos.h>
#include <clib/muimaster_protos.h>
#include <clib/graphics_protos.h>
#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <pragma/muimaster_lib.h>
#include <mui/nlistview_mcc.h>
#include <mui/guigfx_mcc.h>
#include <workbench/startup.h>

#include <stdio.h>

#include "misc/systemdefs.h"
#include "coordinator/coordinator.h"
#include "misc/filereq.h"

#define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))

#define 	ID_QUIT			1
#define 	ID_I_NAME		2 
#define	ID_I_CONFIG  	3
#define	ID_O_NAME		4
#define	ID_O_CONFIG		5
#define 	ID_ADD			6
#define 	ID_START			7
#define	ID_STOP			8
#define	ID_USE_TEMPO 	9
#define 	ID_INPUT_TEMPO 10
#define	ID_INT_TEMPO	11
#define 	ID_LOAD			12
#define	ID_SAVE			13
#define	ID_USE			14
#define 	ID_CONFIG		15
#define 	ID_CLOSE			16
#define  ID_TRACKS		17
#define	ID_DELETE		18	
#define  ID_SCREEN		19
#define 	ID_APPSCREEN 	20

#define 	MEN_PROJECT		21
#define 	MEN_ABOUT		22
#define 	MEN_QUIT			23

APTR	app=NULL;
APTR 	wi_main, wi_config, wi_tracks;
APTR	lv_input_track, lv_input_name, lv_output_track, lv_output_name, lv_tracks;
APTR 	lv_plugins;
APTR 	bt_addtrack, bt_start, bt_stop, bt_config, bt_ok, bt_tracks, bt_quit;
APTR 	bt_load, bt_save, bt_use, bt_up, bt_down, bt_delete, bt_scr;
APTR 	sl_tempo;
APTR 	cm_use_tempo;
APTR 	str_scrmode;
APTR 	c_inputs=NULL;
APTR 	grp_cycle;
APTR 	lab1, lab2, lab3;
APTR  txt_status;
APTR 	menu=NULL;
APTR 	aboutmui=NULL;

char scrmodebuffer[50];

// An instance of our coordinator.  In retrospect the structure here should
// possibly have been reversed!  Oh well, too late now!

Coordinator mainCoord;
Library *MUIMasterBase, *DosBase, *RealTimeBase, *CyberGfxBase;

static struct NewMenu MenuData[]=
{
	{ NM_TITLE, "Project", 		0 ,0 ,0,	(APTR)MEN_PROJECT},
	{ NM_ITEM , "About MUI",	"?",0 ,0,(APTR)MEN_ABOUT},
	{ NM_ITEM ,  NM_BARLABEL,	0 ,0 ,0,(APTR)0},
	{ NM_ITEM ,  "Quit",			"Q",0 ,0,(APTR)MEN_QUIT},
	
	{ NM_TITLE, "Configure",	0,0,0, (APTR)0},
	{ NM_ITEM,	"Tracks",		"T",0,0,(APTR)ID_TRACKS},
	{ NM_ITEM,	"Plugins",		"P",0,0,(APTR)ID_CONFIG},

	{ NM_END,NULL,0,0,0,(APTR)0 },
};

APTR MakeLV(char *title){
	return(
		NListviewObject,
			MUIA_NListview_NList, NListObject,                      
	      InputListFrame,                              
	      MUIA_List_ConstructHook, MUIV_List_ConstructHook_String,
	      MUIA_List_DestructHook, MUIV_List_DestructHook_String, 
	      MUIA_List_Title, title,
	     	End,
      End
	);
}   

BOOL InitGUI(){
	if(MUIMasterBase=OpenLibrary("muimaster.library",0)){
		menu = MUI_MakeObject(MUIO_MenustripNM,MenuData,0); 
		app = ApplicationObject,                                                                 
 	    	MUIA_Application_Title,                         "ProjectOmega",                         
        	MUIA_Application_Version,                       "$VER: ProjectOmega 0.5 (4/01/2000)",    
        	MUIA_Application_Copyright,                     "©2000 T.Miles",
        	MUIA_Application_Author,                        "Tom Miles",                
        	MUIA_Application_Description,           		  "Eye Candy Fever",                 
        	MUIA_Application_Base,                          "OMEGA",      
      	MUIA_Application_UseCommodities,						FALSE,
        	MUIA_Application_UseRexx,								FALSE, 
			SubWindow, wi_tracks = WindowObject,               
        		MUIA_Window_ID, MAKE_ID('T','R','C','K'),
        		MUIA_Window_Title, "Configure Tracks",   
        		WindowContents, VGroup,
        			Child, HGroup, 
        				Child, lv_input_name= MakeLV("Inputs"), 
	        			Child, lv_input_track = MakeLV("Tracks"),
        				Child, lv_output_name = MakeLV("Outputs"),
        				Child, lv_output_track = MakeLV("Effects"),
						End,
					Child, BalanceObject, End,
        			Child, HGroup,
        				Child, lv_tracks = MakeLV("Tracks"), 
       				Child, VGroup,
       					MUIA_HorizWeight, 500,
       					Child, bt_addtrack=SimpleButton("_Add Track"),
        					Child, bt_delete=SimpleButton("_Delete Track"),
        					Child, VGroup,
        						MUIA_Frame, MUIV_Frame_Text,
        						Child, HGroup,
        							Child, lab3=Label("Use Internal Tempo:"),
        							Child, RectangleObject,
        								MUIA_FixWidth,16,
        								End,
        							Child, cm_use_tempo=CheckMark(TRUE),
        							End,
        						Child, HGroup,
        							Child, lab2=Label("BPM"),
        							Child, sl_tempo = SliderObject,
        								MUIA_Group_Horiz, TRUE,
        								MUIA_Slider_Min,1,
        								MUIA_Slider_Level, 160,
        								MUIA_Slider_Max,255,
        								End,	  		
        							End,
        						Child, grp_cycle=HGroup, 
        						 	Child, lab1=Label("Use Plugin:"),
									End,
								End,
							End,
						End,
					Child, HGroup,
						Child, Label("Output Screen"),
        				Child, str_scrmode=TextObject,
        					MUIA_Frame, MUIV_Frame_Text,
        					MUIA_Weight, 300,
        					End,
        				Child, bt_scr=PopButton(MUII_PopUp),
        				End,
        			Child, HGroup,
        				MUIA_Weight, 20,
        				Child, bt_save=SimpleButton("_Save"),
        				Child, bt_use=SimpleButton("_Use"),
        				Child, bt_load=SimpleButton("_Load"),	
        				End,
        			End,
        		End,
        	SubWindow, wi_main = WindowObject,
        		MUIA_Window_ID, MAKE_ID('M','A','I','N'),
        		MUIA_Window_Title, "Project Omega",
        		MUIA_Window_Menustrip, menu,
        		WindowContents, VGroup,
        			Child, HGroup,
        				Child, GuigfxObject,
        					MUIA_Guigfx_FileName, "omega.iff",
        					MUIA_FixWidth, 200,
        					MUIA_FixHeight, 200,
        					End,
        				Child, VGroup,		
        					Child, bt_tracks=SimpleButton("_Assign Tracks"),
        					Child, bt_config=SimpleButton("_Config Plugins"),
							Child, VSpace(4),        			
        					Child, bt_start=SimpleButton("_Start"),
        					Child, bt_stop=SimpleButton("S_top"),
        					Child, VSpace(4),
        					Child, bt_quit=SimpleButton("_Quit"),
        				End,
        			End,
        		  	Child, txt_status=TextObject,
        				MUIA_Frame, MUIV_Frame_Text,
        				End,
        			End,
        		End,
        	SubWindow, wi_config = WindowObject,
        		MUIA_Window_ID, MAKE_ID('C','O','N','F'),
        		MUIA_Window_Title, "Configure Plugins",
        		WindowContents, VGroup,
        			Child, lv_plugins=MakeLV("Plugins"),
        			Child, bt_ok=SimpleButton("_OK"),
        			End,
        		End,
        	End;              
        	
		if (app){          
			// Add notifies for main window
			DoMethod((Object *)bt_config,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ID_CONFIG);
			DoMethod((Object *)wi_main,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,app,2,MUIM_Application_ReturnID,ID_QUIT);
			DoMethod((Object *)bt_start,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ID_START);
			DoMethod((Object *)bt_stop,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ID_STOP);
			DoMethod((Object *)bt_tracks,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ID_TRACKS);
			DoMethod((Object *)bt_quit,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ID_QUIT);		

			// Add notifies for plugin config window
			DoMethod((Object *)lv_plugins,MUIM_Notify,MUIA_Listview_DoubleClick,TRUE,app,2,MUIM_Application_ReturnID,ID_O_CONFIG);
			DoMethod((Object *)bt_ok,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ID_CLOSE);
			DoMethod((Object *)wi_config,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,app,2,MUIM_Application_ReturnID,ID_CLOSE);
			
			// Add notifies for track config window		
			DoMethod((Object *)wi_tracks,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,app,2,MUIM_Application_ReturnID,ID_CLOSE);
			DoMethod((Object *)lv_input_name,MUIM_Notify,MUIA_List_Active,MUIV_EveryTime,app,2,MUIM_Application_ReturnID,ID_I_NAME);
			DoMethod((Object *)lv_input_name,MUIM_Notify,MUIA_Listview_DoubleClick,TRUE,app,2,MUIM_Application_ReturnID,ID_I_CONFIG);
			DoMethod((Object *)lv_output_name,MUIM_Notify,MUIA_List_Active,MUIV_EveryTime,app,2,MUIM_Application_ReturnID,ID_O_NAME);
			DoMethod((Object *)lv_output_name,MUIM_Notify,MUIA_Listview_DoubleClick,TRUE,app,2,MUIM_Application_ReturnID,ID_O_CONFIG);
			DoMethod((Object *)bt_addtrack,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ID_ADD);
			DoMethod((Object *)bt_load,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ID_LOAD);
			DoMethod((Object *)bt_use,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ID_USE);
			DoMethod((Object *)bt_save,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ID_SAVE);
			DoMethod((Object *)bt_scr,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ID_SCREEN);
			DoMethod((Object *)cm_use_tempo,MUIM_Notify,MUIA_Selected,MUIV_EveryTime,c_inputs,3, MUIM_Set, MUIA_Disabled, MUIV_TriggerValue);
			DoMethod((Object *)cm_use_tempo,MUIM_Notify,MUIA_Selected,MUIV_EveryTime,sl_tempo,3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue);
			DoMethod((Object *)bt_delete,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,ID_DELETE);
			// Set up a notify for if our screen changes so we can tell the plugins
			DoMethod((Object *)wi_main,MUIM_Notify,MUIA_Window_Screen,MUIV_EveryTime,app,2,MUIM_Application_ReturnID,ID_APPSCREEN);		
			// Disable the stop button
			SetAttrs(bt_stop,MUIA_Disabled,TRUE);
			return TRUE;
		}
	}			
	return FALSE;
}

void ChangeInputTracks(UINT in){
	DoMethod((Object *)lv_input_track,MUIM_List_Clear);
	PluginTrack thisTrk;
	char *effect;

	if (in<mainCoord.GetTotalInputs()){
		thisTrk=mainCoord.GetInputPlugin(in);
		for (int n=0;n<thisTrk.pt_Tracks;n++){
			effect=thisTrk.pt_EffectList[n];
			DoMethod((Object *)lv_input_track,MUIM_List_InsertSingle,(APTR)effect,MUIV_List_Insert_Bottom);
		}
	}		
}

void ShowStatus(char *txt){
	SetAttrs(txt_status,MUIA_Text_Contents,(ULONG *)txt);
}

void ChangeOutputTracks(UINT in){
	DoMethod((Object *)lv_output_track,MUIM_List_Clear);
	PluginTrack thisTrk;
	char *effect;

	if (in<mainCoord.GetTotalOutputs()){
		thisTrk=mainCoord.GetOutputPlugin(in);
		for (int n=0;n<thisTrk.pt_Tracks;n++){
			effect=thisTrk.pt_EffectList[n];
			DoMethod((Object *)lv_output_track,MUIM_List_InsertSingle,(APTR)effect,MUIV_List_Insert_Bottom);
		}
	}		
}

void AddTrackToList(ULONG in,ULONG i_trk,ULONG out,ULONG o_trk, BOOL tellCoord=TRUE){
	PluginTrack iTrack,oTrack;
	char *names[4];
	char track[255];
	for (int n=0;n<255;n++)
		track[n]=0;
	UINT index, len;
	BOOL addItem=TRUE;
	
	// Signal the appropriate input
	if (tellCoord)
		addItem=mainCoord.InitInput(in,i_trk,out,o_trk);
		
		// Get pointers to the plugin names and track names
	if (addItem){
		iTrack=mainCoord.GetInputPlugin(in);
		oTrack=mainCoord.GetOutputPlugin(out);
		names[0]=iTrack.pt_Name;
		names[1]=iTrack.pt_EffectList[i_trk];
		names[2]=oTrack.pt_Name;
		names[3]=oTrack.pt_EffectList[o_trk];
			// build a track name
		index=0;
		for (n=0;n<4;n++){
			len=strlen(names[n]);
			if (n==1 || n==3)
				memcpy(&track[index++], "(",1);
			memcpy(&track[index], names[n],len);
			index+=len;
			if (n==1 || n==3)
				memcpy(&track[index++], ")",1);	
			if (n==1){
				memcpy(&track[index],"->",2);
				index+=2;
			}
		}
		DoMethod((Object *)lv_tracks,MUIM_List_InsertSingle,(APTR)track,MUIV_List_Insert_Bottom);
	}
}
	
	
void ReadPlugins(APTR inputList, APTR outputList){
	UINT totOut=mainCoord.GetTotalOutputs();
	UINT totIn=mainCoord.GetTotalInputs();
	UINT n;
	PluginTrack thisTrk;
	// Clear all the lists we've got (except the tracks one!)
	DoMethod((Object *)lv_input_name,MUIM_List_Clear);
	DoMethod((Object *)lv_output_name,MUIM_List_Clear);
	DoMethod((Object *)lv_plugins,MUIM_List_Clear);
	DoMethod((Object *)lv_input_track,MUIM_List_Clear);
	DoMethod((Object *)lv_output_track,MUIM_List_Clear);
	
	for (n=0;n<totIn;n++){
		thisTrk=mainCoord.GetInputPlugin(n);
		DoMethod((Object *)inputList,MUIM_List_InsertSingle,(APTR)thisTrk.pt_Name,MUIV_List_Insert_Bottom);
	}
	for (n=0;n<totOut;n++){
		thisTrk=mainCoord.GetOutputPlugin(n);
		DoMethod((Object *)outputList,MUIM_List_InsertSingle,(APTR)thisTrk.pt_Name,MUIV_List_Insert_Bottom);
	}
}

void ConfigPlugins(){
	ULONG plugin, sig, id;
	BOOL loop;
	ULONG totInputs=mainCoord.GetTotalInputs();
	
	SetAttrs(wi_main, MUIA_Window_Open, FALSE);
	SetAttrs(wi_config, MUIA_Window_Open, TRUE);
	ReadPlugins(lv_plugins,lv_plugins);
	while(loop){
		switch (id = DoMethod((Object *)app, MUIM_Application_NewInput, &sig)){     
		case 0:
			break;
		case ID_CLOSE:
			SetAttrs(wi_config, MUIA_Window_Open, FALSE);
			SetAttrs(wi_main, MUIA_Window_Open, TRUE);
			loop=FALSE;				
			break;
		case ID_O_CONFIG:
			GetAttr(MUIA_List_Active, lv_plugins, &plugin);
			if (plugin<totInputs)
				mainCoord.MessagePlugin(OMEGAINPUT, plugin, OM_CONFIG);
			else
				mainCoord.MessagePlugin(OMEGAOUTPUT, plugin-totInputs, OM_CONFIG);
			break;
		}
		if (loop && sig!=0)	
				Wait(sig); 		
	}
}

void ShowDisplayInfo(){
   NameInfo name;
	UINT namelen;
	char *buffer=new char[DISPLAYNAMELEN];
	ULONG id=mainCoord.GetScreenMode();
	
   namelen= GetDisplayInfoData(NULL,(char *)&name,sizeof(struct NameInfo),DTAG_NAME,id);                                                                
	sprintf(buffer,"%s",name.Name);
	SetAttrs(str_scrmode,MUIA_Text_Contents, buffer);
	delete[]buffer;
}

void UpdateInputList(){
	char **inputlist=mainCoord.GetInputList();
	
	if (DoMethod((Object *)grp_cycle,MUIM_Group_InitChange)){
		if (c_inputs)
			DoMethod((Object *)grp_cycle,OM_REMMEMBER,c_inputs);
		c_inputs=CycleObject,
			MUIA_Cycle_Entries, inputlist,
      	End;
		DoMethod((Object *)grp_cycle,OM_ADDMEMBER,c_inputs);
		DoMethod((Object *)grp_cycle,MUIM_Group_Sort,lab1,c_inputs,NULL);
		DoMethod((Object *)grp_cycle,MUIM_Group_ExitChange);
	}
	else
		cout << "Couldn't change group" << endl;
} 

void ConfigTracks(){
	BOOL loop=TRUE;
	ULONG sig,id;
	ULONG in, i_trk, out, o_trk, plugin, tempo, useinternal;
	ULONG newTempo, use_internal, external, coordID;
	UINT n,newTracks; // Used by LoadTracks
	ULONG inputID;
	FILE *file;
	FileReq myReq(mainCoord.myScreen);
	
	CoordinatorTrack *pCTrack;
	
	UpdateInputList(); 
	tempo=mainCoord.GetTempo();
	SetAttrs(sl_tempo,MUIA_Slider_Level,tempo);
	
//	external=mainCoord.GetTotalInputs();	
//	if (external!=0)
		SetAttrs(cm_use_tempo,MUIA_Disabled, FALSE);
//	else
//		SetAttrs(cm_use_tempo,MUIA_Disabled, TRUE);
			
	SetAttrs(wi_main, MUIA_Window_Open, FALSE);
	SetAttrs(wi_tracks, MUIA_Window_Open, TRUE);
	ReadPlugins(lv_input_name,lv_output_name);
	
	while (loop){                                                                   
		switch (id = DoMethod((Object *)app, MUIM_Application_NewInput, &sig)){                                                           
		case 0:
			break;
		case ID_USE: 
			GetAttr(MUIA_Cycle_Active, c_inputs, &external);
			GetAttr(MUIA_Slider_Level, sl_tempo, &newTempo);
			GetAttr(MUIA_Selected, cm_use_tempo, &use_internal);
			if (use_internal)
				mainCoord.SetTempo(newTempo, TRUE);
			else
				mainCoord.MessagePlugin(OMEGAINPUT,external,OM_TEMPO);
			SetAttrs(wi_tracks, MUIA_Window_Open, FALSE);
			SetAttrs(wi_main, MUIA_Window_Open, TRUE);
		case ID_CLOSE:
			loop=FALSE;				
			break;
		case ID_ADD:
			GetAttr(MUIA_List_Active, lv_input_name, &in);
			GetAttr(MUIA_List_Active, lv_input_track, &i_trk);
			GetAttr(MUIA_List_Active, lv_output_name, &out);
			GetAttr(MUIA_List_Active, lv_output_track, &o_trk);
			if (in!=-1 && i_trk !=-1 && out!=-1 && o_trk !=-1)
				AddTrackToList(in, i_trk, out, o_trk);
			break;
		case ID_I_NAME:
			GetAttr(MUIA_List_Active, lv_input_name, &in);
			ChangeInputTracks(in);
			break;
		case ID_O_NAME:
			GetAttr(MUIA_List_Active, lv_output_name, &in);
			ChangeOutputTracks(in);
			break;
		case ID_I_CONFIG:
			GetAttr(MUIA_List_Active, lv_input_name, &in);
			mainCoord.MessagePlugin(OMEGAINPUT,in, OM_ABOUT);
			break;
		case ID_O_CONFIG:
			GetAttr(MUIA_List_Active, lv_output_name, &out);
			mainCoord.MessagePlugin(OMEGAOUTPUT, out, OM_ABOUT);
			break;
		case ID_DELETE:
			GetAttr(MUIA_List_Active, lv_tracks, &in);
			DoMethod((Object *)lv_tracks,MUIM_List_Remove,MUIV_List_Remove_Active);
			// Okay, things are getting tricky - we need to be able to tell what
			// track we've deleted so we'll have to keep a record
			// Looks like I'll have to lose my funky one line list swap stuff too!
			if (in!=-1)
				mainCoord.CancelTrack(in);
			break;
		case ID_SAVE:
			file=myReq.CreateRequester("Select Config File",NULL,NULL,"#?.cfg",TRUE);
			
			if (file && !myReq.Cancelled()){
				GetAttr(MUIA_Cycle_Active, c_inputs, &plugin);
				printf("Plugin %d\n",plugin);
				inputID=(ULONG)mainCoord.GetPluginID(OMEGAINPUT,plugin);
				if (inputID==(UWORD)-1){
					mainCoord.Error("Internal Error","Couldn't find plugin");
					inputID=0;
				}
				GetAttr(MUIA_Slider_Level, sl_tempo, &tempo);
				GetAttr(MUIA_Selected, cm_use_tempo, &useinternal);
				in=mainCoord.GetScreenMode();
				coordID=MAKE_ID('C','N','T','R');
				fprintf(file,"%x\n%ld\n%d %x %d\n",coordID,in, useinternal, inputID, tempo);
				mainCoord.SaveTracks(file);
				myReq.CloseFile();
			}
			else
				if (!myReq.Cancelled())
					mainCoord.SaveTracks(NULL);	// Prints up an error message
			break;	
		case ID_LOAD:
			file=myReq.CreateRequester("Select Config File",NULL,NULL,"#?.cfg",FALSE);
			if (file && !myReq.Cancelled()){
				if (fscanf(file,"%x\n",&coordID) && coordID==MAKE_ID('C','N','T','R')){
					DoMethod((Object *)lv_tracks,MUIM_List_Clear);
					// If we're running then stop the show!
					if (mainCoord.IsRunning()){
						mainCoord.Stop();
						SetAttrs(bt_start,MUIA_Disabled,FALSE);
						SetAttrs(bt_stop,MUIA_Disabled,TRUE);
					}
					mainCoord.ResetTracks();
					fscanf(file,"%ld\n",&in);
					if (in!=0)
						mainCoord.SetScreenMode(in);
					ShowDisplayInfo();
					fscanf(file,"%d%x%d",&useinternal,&inputID,&tempo);
					// Set the cycle gadget to the plugin wanted
					plugin=mainCoord.FindPluginIndex(OMEGAINPUT,inputID);
					if (plugin==-1){
						mainCoord.Error("Unable To Find Plugin","For External Tempo Sync.");
						plugin=0;
					}
					SetAttrs(cm_use_tempo, MUIA_Selected, useinternal);
					SetAttrs(sl_tempo, MUIA_Slider_Level, tempo);				
					SetAttrs(c_inputs, MUIA_Cycle_Active, plugin);
					newTracks=mainCoord.LoadTracks(file);
					for (n=0;n<newTracks;n++){
						pCTrack=mainCoord.GetTrack(n);
						AddTrackToList(pCTrack->ct_Input,pCTrack->ct_InputTrk,
										pCTrack->ct_Output,pCTrack->ct_OutputTrk, FALSE);
					}
					myReq.CloseFile();
				}
				else
					mainCoord.Error("Incorrect Config File",NULL);
			}
			else
				if (!myReq.Cancelled())
					mainCoord.LoadTracks(NULL);
			break;
		case ID_SCREEN:
			mainCoord.SetScreenMode(0);
			ShowDisplayInfo();
			break;
		case ID_APPSCREEN:
			cout << "Screen Changed - Notify Plugins" << endl;
			break;	
		default:
			break;
		}
		if (loop && sig!=0)	
				Wait(sig); 
	}
}

int main(){
	BOOL loop=TRUE;
	ULONG id, sig, c_sig;
	ULONG wakeup;
	ULONG win, screen;
	
	if (InitGUI() && mainCoord.Initialise()){
		// Open Main Window
		SetAttrs(wi_main, MUIA_Window_Open, TRUE);
		GetAttr(MUIA_Window_Window,wi_main, &win);
		// Tell the coordinator which screen it's on
		GetAttr(MUIA_Window_Screen,wi_main, &screen);
		mainCoord.myScreen=(Screen *)screen;
		ShowStatus("Stopped");
		c_sig=1 << mainCoord.GetSignalBit();
		// Main loop - This Deals with input from both the main window and the config window
		// 				Need to seperate this out	
		while (loop){                                                                   
	      switch (id = DoMethod((Object *)app, MUIM_Application_NewInput, &sig)){                                                           
			case 0:
				break;
			case ID_TRACKS:
				ConfigTracks();
				break;
			case ID_CONFIG:
				ConfigPlugins();
				break;
			case MEN_QUIT:
			case ID_QUIT:
				loop=FALSE;
				ShowStatus("Notifying Plugins");
				mainCoord.Quit();
			  	break;
			case ID_START:
				ShowStatus("Notifying Plugins");
				if(mainCoord.Start()){
					SetAttrs(bt_start,MUIA_Disabled,TRUE);
					SetAttrs(bt_stop,MUIA_Disabled,FALSE);
					ShowStatus("Running");
				}
				break;
			case ID_STOP:
				ShowStatus("Notifying Plugins");
				if(mainCoord.Stop()){
					SetAttrs(bt_start,MUIA_Disabled,FALSE);
					SetAttrs(bt_stop,MUIA_Disabled,TRUE);
					ShowStatus("Stopped");
				}
				break;
			case MEN_ABOUT:
				if (!aboutmui){
					aboutmui=AboutmuiObject,
						MUIA_Aboutmui_Application, app,
						End;
				}
				if (aboutmui)
					SetAttrs(aboutmui,MUIA_Window_Open,TRUE);
				break;				
			}
			if (loop && sig!=0){	
				wakeup=Wait(sig | c_sig);
				if (wakeup & c_sig)
					mainCoord.DealWithMessages();
			}
		}
		
		MUI_DisposeObject((Object *)app);
		if (MUIMasterBase)
			CloseLibrary(MUIMasterBase);
		return 0;
	}
	else{
		printf("Unable To Create App - Try resetting and start again!\n");
		if (MUIMasterBase)
			CloseLibrary(MUIMasterBase);
		return -10;
	}
}

int wbmain(WBStartup *msg){
	return(main());
}
