#include <intuition/intuition.h>

#include <libraries/mui.h>
#include <libraries/locale.h>
#include <libraries/gadtools.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_BLOCK
#include "speakstrings_cat.h"

#undef CATCOMP_BLOCK

#define DEFAULT_STR		"Hello. This is Amiga speaking."

BYTE audio_chn[3][4] ={ {1,8,0,0},  {2,4,0,0}, {3,5,10,12} };


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;
int OUTPUT_CHANNEL =2;
int F1ADJ	= 0;
int F2ADJ	= 0;
int F3ADJ	= 0;
int A1ADJ	= 0;
int A2ADJ	= 0;
int A3ADJ	= 0;
int ARTIC	= 0;
int AVBIAS	= 0;
int AFBIAS	= 0;
int CENT	= 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);

	set( App->TX_PHONEME , MUIA_Text_Contents,ph_buf);

	set( App->STR_TEXT , 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[OUTPUT_CHANNEL];
	SpeakIO->nm_masks			= sizeof(audio_chn)/3;
	SpeakIO->rate				= SPEED;
	SpeakIO->pitch				= PITCH;
	SpeakIO->volume				= VOLUME;
	SpeakIO->sex				= SEX;
	SpeakIO->mode				= KIND;
	SpeakIO->F0enthusiasm		= ENTHU;
	SpeakIO->F0perturb			= PERTUB;

	SpeakIO->F1adj				= F1ADJ;
	SpeakIO->F1adj				= F2ADJ;
	SpeakIO->F1adj				= F3ADJ;
	SpeakIO->A1adj				= A1ADJ;
	SpeakIO->A2adj				= A2ADJ;
	SpeakIO->A3adj				= A3ADJ;
	SpeakIO->articulate			= ARTIC;
	SpeakIO->AVbias				= AVBIAS;
	SpeakIO->AFbias				= AFBIAS;
	SpeakIO->centralize			= CENT;
	
	DoIO((struct IORequest *) SpeakIO);
}

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

void init(void)
{
	if (!(MUIMasterBase =  OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN)))
	{
		printf("Can't open muimaster.library V %d+\n",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;
	int i;

	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,"muispeak.catalog",tags);

         }
	}	

	init();

	App = CreateApp();

	get(App->CY_SEX,MUIA_Cycle_Active,&SEX);
	get(App->CY_KIND,MUIA_Cycle_Active,&KIND);
	get(App->SL_SPEED,MUIA_Slider_Level,&SPEED);
	get(App->SL_HEIGHT,MUIA_Slider_Level,&PITCH);
	get(App->SL_VOLUME,MUIA_Slider_Level,&VOLUME);
	get(App->SL_PERTUBATION,MUIA_Slider_Level,&PERTUB);
	get(App->SL_ENTHUSIASMUS,MUIA_Slider_Level,&ENTHU);

	set(App->CY_OUTPUT,MUIA_Cycle_Active,&OUTPUT_CHANNEL);

	
	setstring( App->STR_TEXT , DEFAULT_STR);
	set( App->TX_PHONEME , MUIA_Text_Contents,MyTranslate(DEFAULT_STR));


	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_OUTPUT:
				get(App->CY_OUTPUT,MUIA_Cycle_Active,&OUTPUT_CHANNEL);
				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_F1ADJ:
				get(App->SL_F1ADJ,MUIA_Slider_Level,&F1ADJ );
				break;	

			case RET_F2ADJ:
				get(App->SL_F2ADJ,MUIA_Slider_Level,&F2ADJ );
				break;	

			case RET_F3ADJ:
				get(App->SL_F3ADJ,MUIA_Slider_Level,&F3ADJ );
				break;	

			case RET_A1ADJ:
				get(App->SL_A1ADJ,MUIA_Slider_Level,&A1ADJ );
				break;	

			case RET_A2ADJ:
				get(App->SL_A2ADJ,MUIA_Slider_Level,&A2ADJ );
				break;	

			case RET_A3ADJ:
				get(App->SL_A3ADJ,MUIA_Slider_Level,&A3ADJ );
				break;	

			case RET_AFBIAS:
				get(App->SL_AFBIAS,MUIA_Slider_Level,&AFBIAS);
				break;	

			case RET_AVBIAS:
				get(App->SL_AVBIAS,MUIA_Slider_Level,&AVBIAS);
				break;	

			case RET_ARTIC:
				get(App->SL_ARTIC,MUIA_Slider_Level,&ARTIC);
				break;	

			case RET_CENT:
				get(App->SL_CENT,MUIA_Slider_Level,&CENT);
				break;	

			case RET_TEXT:
				char *x;
				get(App->STR_TEXT,MUIA_String_Contents,&x);
				set( App->TX_PHONEME , MUIA_Text_Contents, MyTranslate(x));
				set( App->STR_TEXT , 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);
}


char * GetString(int 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);}

