/*
***************************************************************************
*
* Datei:
*	  RSysExtern.c
*
* Inhalt:
*
*      --- Globale Routinen ---
*
*    BPTR AskFileMode ( char *filename , struct Window *wind );
*    int GetFile ( struct Window *wind , char *dir , char *file , char *pattern , char *title , char *oktext );
*    int InitSpeech ( void );
*    int SysStarted ( int type );
*    void RemoveSpeech ( void );
*    void SaveList ( struct Window *wind , char *filename , char *title , struct List *list , int withheader );
*    void Speak ( char *text );
*
*      --- Lokale  Routinen ---
*
*    static char *strip ( char *src , char *dest );
*
* Bemerkungen:
*	  Verwaltung externer Daten und Schnittstellen zu Dateien.
*
* Erstellungsdatum:
*	  07-Jul-93 	Rolf Böhme
*
* Änderungen:
*	  07-Jul-93 	Rolf Böhme	  Erstellung
*
***************************************************************************
*/

#include "RSys.h"

char _file[PATHPARTWIDTH],_dir[MAXFULLNAME];

static char *
strip(char *src, char *dest)
{
	BYTE s = 0, d = 0, l = strlen(src);

	while(s < l)
	{
		if(!strchr("'-:/ ", (int)src[s])) dest[d++] = src[s++];
		else
			s++;
	}

	dest[d] = STRINGEND;

	return dest;
}


	/*
	 * GetFile() bietet einen Filerequester zur Auswahl einer Datei
	 * an. Dabei wird unterschieden, ob die Datei zum Sichern oder zum
	 * Laden verwendet wird.
	 */
int
GetFile(struct Window *wind,char *dir,char *file,char *pattern,char *title,char *oktext)
{
	struct FileRequester *AslFileRequest = NULL;
	BYTE	Result = FALSE;
	APTR	req = NULL;
	UWORD l = 20,t = 20;
	int mask = FILF_PATGAD;
	char _oktext[MAXSHOW],_title[40],_pattern[10] = "#?",*_cancel = "Cancel";

	DPOS;

	PrintInfo("Selecting file", NO_SPEAK, 0);

	if (Flags.speakmode) Speak(title);

	if (AslBase = OpenLibrary((UBYTE *) "asl.library", 37L))
	{
		if(wind)
		{
			req = LockWindow(wind);
			CenterWindow(wind->WScreen,&t,&l,(UWORD)260,(UWORD)170);
		}

		if(dir && *dir) strncpy(_dir,dir,MAXFULLNAME);
		else
			strcpy(_dir,"RAM:");

		if(file && *file)
		{
			char header[PATHPARTWIDTH];

			strip(file, header);

			strncpy(_file,header,PATHPARTWIDTH);
		}
		else strcpy(_file,"unknown");

		if(pattern && *pattern) strncpy(_pattern,pattern,10);
		else
			strcpy(_pattern,"#?");

		if(title && *title) strncpy(_title,title,40);
		else
			strcpy(_title,"Select file");

		if(oktext && *oktext) strncpy(_oktext,oktext,MAXSHOW);
		else
			strcpy(_oktext,"Select");

		if(strstr(_oktext,"Save")) mask |= FILF_SAVE;

		if (AslFileRequest = AllocAslRequestTags(ASL_FileRequest,
										ASL_Window, 	 (ULONG)wind,
										ASL_Hail,		 (ULONG)_title,
										ASL_LeftEdge,	 (ULONG)l,
										ASL_TopEdge,	 (ULONG)t,
										ASL_OKText, 	 (ULONG)_oktext,
										ASL_CancelText, (ULONG)_cancel,
										ASL_File,		 (ULONG)_file,
										ASL_Dir, 		 (ULONG)_dir,
										ASL_Pattern,	 (ULONG)_pattern,
										ASL_FuncFlags,  (ULONG)mask,
										TAG_DONE))
		{
			if (AslRequest(AslFileRequest, NULL))
			{
				if (AslFileRequest->rf_File)
				{
               strncpy(_fullpath,AslFileRequest->rf_Dir,MAXFULLNAME);
					AddPart((UBYTE *)_fullpath,(UBYTE *)AslFileRequest->rf_File, MAXFULLNAME);
/*
					if(AslFileRequest->rf_Dir)
					{
						strncpy(_fullpath,AslFileRequest->rf_Dir,MAXFULLNAME);
						AddPart((UBYTE *)_fullpath,(UBYTE *)AslFileRequest->rf_File,
								  MAXFULLNAME);
					}
					else strncpy(_fullpath,AslFileRequest->rf_File,MAXFULLNAME);
*/
					Result = TRUE;
				}

				if(AslFileRequest->rf_Pat) strncpy(_pattern,AslFileRequest->rf_Pat,10);
			}

			FreeAslRequest(AslFileRequest);
		}
		else ErrorHandle("AllocAslRequest()", MEMORY_ERR, ALLOC_FAIL, NO_KILL);

		CloseLibrary(AslBase);

		UnlockWindow(req);
	}
	else ErrorHandle("asl.library", LIBRARY_ERR, OPEN_FAIL, NO_KILL);

	if (strcmp(_oktext, "Check")) PrintStatistics();

	return Result;
}


BPTR
AskFileMode(char *filename, struct Window *wind)
{
   int mode = OVERWRITE;
   BPTR fout = NULL;

   if(exist(filename)) mode = MyEasyRequest(wind, (UBYTE *) NAME " ask you",
                                            (UBYTE *) "Append|Overwrite|Cancel",
                                            (UBYTE *) "The file <%s> exists!",
                                            filename);

	switch (mode)
	{
		case APPEND:
			fout = Open((UBYTE *) filename, MODE_OLDFILE);
			if(fout) Seek(fout, 0L, OFFSET_END);
			break;

		case OVERWRITE:
			fout = Open((UBYTE *) filename, MODE_NEWFILE);
			break;
	}

   if(mode && !fout) ErrorHandle(filename, FILE_ERR, OPEN_FAIL, NO_KILL);

   return fout;
}

	/*
	 * SaveList() speichert die Einträge einer Liste (vom Hauptfenster oder
	 * intern) in eine Datei ab oder direkt ins Clipboard.
	 */
void
SaveList(struct Window *wind, char *filename, char *title,
			struct List *list, int withheader)
{
	BPTR	fout;
	struct Node *node;
	char	out[MAXWRITESIZE], fmt[MAXWRITESIZE];
	int noheader;

	DPOS;

	PrintInfo("Save list to file", NO_SPEAK, 0);

   fout = AskFileMode(filename, wind);

	if (fout)
	{
		noheader = RSysFormatOutput(wind, fmt);

		if(!noheader)
		{
			sprintf(out, "----------------------------------------------\n"
					  "%s\n"
					  "----------------------------------------------\n\n",
					  title);

			Write(fout, out, strlen(out));

			if (withheader)
			{
				sprintf(out, "%s\n----------------------------------------------\n",
						  EntryAttr[LastID].ea_header);
				Write(fout, out, strlen(out));
			}
		}

		for (node = list->lh_Head; node->ln_Succ /*&& !IoErr()*/;
			  node = node->ln_Succ)
		{
			sprintf(out, fmt, node->ln_Name);
			strcat((char *)out,"\n");

			Write(fout, out, strlen(out));
		}

		if (IoErr()) ErrorHandle(filename, FILE_ERR, WRITE_FAIL, NO_KILL);
		else
		{
			Write(fout, (UBYTE *)"\n",1);
         PrintInfo("List was written to file", SPEAK, SEC);
		}

		Close(fout);
	}

	PrintStatistics();

	return;
}

	/*
	 * SysStarted() überprüft, ob RSys ein zweites Mal gestartet wurde
	 * und sendet im zutreffenden Fall einen Argumenttyp der Art der
	 * anzuzeigenden Liste an den Task des zuerst gestarteten Programmes
	 */
int
SysStarted(int type)
{
	struct MsgPort *TestPort;
	struct MsgPort *ReplyPort = NULL;
	SysMsg *mess;
	int	ret = FALSE;

	DPOS;

   ReplyPort = CreatePort((UBYTE *) "RSys-Reply-Port", 0L);

	if (ReplyPort)
	{
		mess = (SysMsg *) MyAllocVec(sizeof(SysMsg), MEMF_CLEAR | MEMF_PUBLIC, NO_KILL);

		if (mess)
		{
			mess->sm_message.mn_Node.ln_Type = NT_MESSAGE;
			mess->sm_message.mn_ReplyPort = ReplyPort;
			mess->sm_message.mn_Length = sizeof(SysMsg);
			mess->sm_newtype = type;

			Forbid();

			if (TestPort = FindPort((UBYTE *) ID_PORT_NAME))
			{
				PutMsg(TestPort, (struct Message *) mess);

   			Permit();

				WaitPort(ReplyPort);

				ret = TRUE;
			}
         else Permit();

			MyFreeVec(mess);
		}

		DeletePort(ReplyPort);
	}

	return ret;
}

struct Library *TranslatorBase = NULL;
struct MsgPort *narratorPort;
struct narrator_rb request;

	/*
	 * RemoveSpeech() entfernt die Ressourcen für die Sprachausgabe
	 * und schließt das Device, das für die Sprachausgabe des Amigas
	 * zuständig ist, das narrator.device
	 */
void
RemoveSpeech(void)
{
	DPOS;

	if (narratorPort) DeleteMsgPort(narratorPort);
	if (TranslatorBase) CloseLibrary(TranslatorBase);
	if (request.message.io_Device) CloseDevice((struct IORequest *) &request);

	return;
}

	/*
	 * InitSpeech() öffnet die Ressourcen für die Sprachausgabe
	 * Anm: Auf einem 4000er stürzt an dieser Stelle das Programm ab!
	 */
int
InitSpeech(void)
{
	DPOS;

	if (TranslatorBase = OpenLibrary((UBYTE *) "translator.library", 0))
   {
		if (narratorPort = CreateMsgPort())
		{
			if (NOT(OpenDevice((UBYTE *) "narrator.device", 0,(struct IORequest *) & request, 0)))
				return (TRUE);
			else
				ErrorHandle("narrator.device", DEVICE_ERR, OPEN_FAIL, NO_KILL);
		}
		else ErrorHandle("CreateMsgPort()", PORT_ERR, CREATE_FAIL, NO_KILL);
   }
	else ErrorHandle("translator.library", LIBRARY_ERR, OPEN_FAIL, NO_KILL);

	RemoveSpeech();

	return FALSE;
}

	/*
	 * Speak() gibt einen Text über das narrator.device aus
	 */
void
Speak(char *text)
{
	UBYTE help[BUFSIZE + 2];
	UBYTE translate[3 * BUFSIZE];
	UBYTE Channel[4] = { 1, 2, 4, 8 };

	DPOS;

   if(!Flags.speakmode)

	strncpy((char *)help, text, BUFSIZE);

	if (!ispunct((int)text[strlen(text) - 1])) strcat((char *)help, ".");

	if (NOT(Translate(help, (strlen((char *)help) * sizeof(char)), translate, sizeof(translate))))
	{
		request.message.io_Message.mn_ReplyPort = narratorPort;
		request.message.io_Command = CMD_WRITE;
		request.message.io_Data = (APTR) translate;
		request.message.io_Length = sizeof(translate);

		request.rate			= DEFRATE;  /* Worte pro Minute: 40 < rate < 400 */
		request.pitch			= DEFPITCH; /* 65 < pitch < 320 */
		request.sex 			= DEFSEX;   /* Geschlecht : auch MALE */
		request.volume 		= DEFVOL;   /* Lautstaerke max 64 */
		request.mode			= DEFMODE;  /* Aussprache-Modus */
		request.sampfreq		= DEFFREQ;
		request.F0enthusiasm = DEFF0ENTHUS;
		request.F0perturb 	= DEFF0PERT;
		request.priority		= DEFPRIORITY;
		request.ch_masks		= (UBYTE *) Channel; /* Kanaele */
		request.nm_masks		= sizeof(Channel);

		DoIO((struct IORequest *) &request);
	}

	return;
}
