#include <libraries/mui.h>
#include <libraries/locale.h>

#include <clib/locale_protos.h>
#include <clib/muimaster_protos.h>
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>

#include <devices/narrator.h>

#include <stdlib.h>
#include <stdio.h>

#include "speak.h"

//#define CATCOMP_CODE
#define CATCOMP_BLOCK
#include "speakstrings.h"
//#undef CATCOMP_CODE
#undef CATCOMP_BLOCK

#define DEFAULT_STR		"Hey, I am the M.U.I. Speechtoy, brought to you by Y.E.T."

BYTE audio_chn[4] = {3,5,10,12};

enum ids {  RET_DUMMY,
			RET_TEXT,
			RET_HEIGHT,
			RET_SPEED,
			RET_VOLUME,
			RET_SEX,
			RET_KIND,
			RET_PERTUB,
			RET_ENTHU,
			RET_SPEAK, };

struct LocaleBase * 	LocaleBase;
struct Library * 		MUIMasterBase;
struct MsgPort *		SpeakMP;

struct Locale *			locale = NULL;
struct Catalog *		Catalog = NULL;


struct narrator_rb * 	SpeakIO;
struct ObjApp * 		App	= NULL;

int PITCH	= 120;
int SPEED	= 120;
int VOLUME	= 64;
int SEX		= MALE;
int KIND	= ROBOTICF0;
int ENTHU   = 0;
int PERTUB  = 0;

void main(int argc,char **argv);

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

int wbmain(struct WBStartup *wb_startup)
{

	main(0, NULL);
}


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

char * MyTranslate(char * str)
{
	char ph_buf[255];

	Translate(str , strlen(str) , (APTR) ph_buf , 255);
		
	return ph_buf;
}

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

void Speak(char *str)
{
	static char ph_buf[255];

	Translate(str , strlen(str) , (APTR) ph_buf , 255);

	setstring( App->STR_PHONEME , ph_buf);

	set( App->STR_TEXT , MUIA_String_BufferPos , 0);
	set( App->STR_PHONEME , MUIA_String_BufferPos , 0);


	SpeakIO->message.io_Command	= CMD_WRITE;
	SpeakIO->message.io_Offset	= 0;
	SpeakIO->message.io_Data	= ph_buf;
	SpeakIO->message.io_Length	= strlen( ph_buf );

	SpeakIO->ch_masks			= audio_chn;
	SpeakIO->nm_masks			= sizeof(audio_chn);
	SpeakIO->rate				= SPEED;
	SpeakIO->pitch				= PITCH;
	SpeakIO->volume				= VOLUME;
	SpeakIO->sex				= SEX;
	SpeakIO->mode				= KIND;
	SpeakIO->F0enthusiasm		= ENTHU;
	SpeakIO->F0perturb			= PERTUB;
	
	DoIO((struct IORequest *) SpeakIO);
}

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

void init(void)
{
	if (!(MUIMasterBase =  OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN)))
	{
		exit(0);
	}
	
	SpeakMP = CreateMsgPort();
	SpeakIO = (struct narrator_rb *) CreateExtIO(SpeakMP,sizeof(struct narrator_rb));
	SpeakIO->flags = NDF_NEWIORB;
				
	OpenDevice("narrator.device",0,(struct IORequest *) SpeakIO,NULL);
}

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

void main(int argc,char **argv)
{
	BOOL	running = TRUE;
	ULONG	signal;

	LocaleBase = (struct LocaleBase *) OpenLibrary("locale.library",37);

	if (LocaleBase != NULL)
	{
	    struct TagItem tags[3];
	
		locale = OpenLocale(NULL);

        if (strcmp(locale->loc_LanguageName,"deutsch.language"))   // Builtin language != locale Language
        {
            tags[0].ti_Tag  = OC_BuiltInLanguage;
            tags[0].ti_Data = (ULONG) "deutsch";    

            tags[1].ti_Tag  = OC_Version;
            tags[1].ti_Data = (ULONG) 1;

            tags[2].ti_Tag  = OC_BuiltInCodeSet;    // Default, requested from Commodore
            tags[2].ti_Data = (ULONG) 0;

            Catalog=OpenCatalogA(NULL,"muispeechtoy.catalog",tags);

         }
	}	

	init();

	App = CreateApp();

	DoMethod(App->WIN_MAIN, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, App->App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
	
	setstring( App->STR_TEXT , DEFAULT_STR);
	setstring( App->STR_PHONEME , MyTranslate(DEFAULT_STR));

	set( App->STR_TEXT , MUIA_String_BufferPos , 0);
	set( App->STR_PHONEME , MUIA_String_BufferPos , 0);

	set( App->STR_TEXT , MUIA_String_BufferPos , 0);

	setslider( App->SL_SPEED,  SPEED);
	setslider( App->SL_HEIGHT, PITCH);
	setslider( App->SL_VOLUME, VOLUME);
	setslider( App->SL_ENTHUSIASMUS, ENTHU);
	setslider( App->SL_PERTUBATION, PERTUB);



	DoMethod(App->WIN_MAIN,MUIM_Window_SetCycleChain,
				App->CY_SEX,
				App->CY_KIND,
				App->SL_HEIGHT,
				App->SL_SPEED,
				App->SL_VOLUME,
				App->SL_ENTHUSIASMUS,
				App->SL_PERTUBATION,
				App->STR_TEXT,
				App->STR_PHONEME,
				App->BT_SPEAK,
				NULL);

	DoMethod( App->STR_TEXT, MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,App->App,2,MUIM_Application_ReturnID,RET_TEXT);
	DoMethod( App->BT_SPEAK, MUIM_Notify,MUIA_Pressed,FALSE,App->App,2,MUIM_Application_ReturnID,RET_SPEAK);
	DoMethod( App->SL_HEIGHT,MUIM_Notify,MUIA_Slider_Level,MUIV_EveryTime,App->App,2,MUIM_Application_ReturnID,RET_HEIGHT);
	DoMethod( App->SL_SPEED, MUIM_Notify,MUIA_Slider_Level,MUIV_EveryTime,App->App,2,MUIM_Application_ReturnID,RET_SPEED);
	DoMethod( App->SL_VOLUME,MUIM_Notify,MUIA_Slider_Level,MUIV_EveryTime,App->App,2,MUIM_Application_ReturnID,RET_VOLUME);
	DoMethod( App->SL_ENTHUSIASMUS,MUIM_Notify,MUIA_Slider_Level,MUIV_EveryTime,App->App,2,MUIM_Application_ReturnID,RET_ENTHU);
	DoMethod( App->SL_PERTUBATION,MUIM_Notify,MUIA_Slider_Level,MUIV_EveryTime,App->App,2,MUIM_Application_ReturnID,RET_PERTUB);
	DoMethod( App->CY_SEX,   MUIM_Notify,MUIA_Cycle_Active,MUIV_EveryTime,App->App,2,MUIM_Application_ReturnID,RET_SEX);
	DoMethod( App->CY_KIND,  MUIM_Notify,MUIA_Cycle_Active,MUIV_EveryTime,App->App,2,MUIM_Application_ReturnID,RET_KIND);


	set( App->WIN_MAIN, MUIA_Window_Open, TRUE );

	
	while (running)
	{
		switch (DoMethod(App->App,MUIM_Application_Input,&signal))	
		{
			case RET_SPEAK:
				char *x;
				get(App->STR_TEXT,MUIA_String_Contents,&x);
				Speak(x);
				break;

			case RET_SEX:
				get(App->CY_SEX,MUIA_Cycle_Active,&SEX);
				break;

			case RET_KIND:
				get(App->CY_KIND,MUIA_Cycle_Active,&KIND);
				break;

			case RET_SPEED:
				get(App->SL_SPEED,MUIA_Slider_Level,&SPEED);
				break;

			case RET_HEIGHT:
				get(App->SL_HEIGHT,MUIA_Slider_Level,&PITCH);
				break;

			case RET_VOLUME:
				get(App->SL_VOLUME,MUIA_Slider_Level,&VOLUME);
				break;

			case RET_PERTUB:
				get(App->SL_PERTUBATION,MUIA_Slider_Level,&PERTUB);
				break;

			case RET_ENTHU:
				get(App->SL_ENTHUSIASMUS,MUIA_Slider_Level,&ENTHU);
				break;


			case RET_TEXT:
				char *x;
				get(App->STR_TEXT,MUIA_String_Contents,&x);
				setstring( App->STR_PHONEME , MyTranslate(x));
				set( App->STR_TEXT , MUIA_String_BufferPos , 0);
				set( App->STR_PHONEME , MUIA_String_BufferPos , 0);
				break;

			case MUIV_Application_ReturnID_Quit:
            	running = FALSE;
                        break;
		}
	}        

	if (running && signal) Wait(signal);


	CloseDevice((struct IORequest *) SpeakIO);
	DeleteIORequest((struct IORequest *) SpeakIO);
	DeleteMsgPort(SpeakMP);

	DisposeApp(App);
	CloseLibrary(MUIMasterBase);
	CloseLibrary((struct Library *) LocaleBase);
}

STRPTR GetString(LONG stringNum)
{
	LONG   *l;
	UWORD  *w;
	STRPTR  builtIn;

	l = (LONG *)CatCompBlock;

	while (*l != stringNum)
	{
		w = (UWORD *)((ULONG)l + 4);
		l = (LONG *)((ULONG)l + (ULONG)*w + 6);
	}
	builtIn = (STRPTR)((ULONG)l + 6);


    if (LocaleBase)
        return(GetCatalogStr(Catalog,stringNum,builtIn));

    return(builtIn);
}
