/*
** Source machine generated by the AREXX Interface Designer for EasyREXX
** which is (c) copyrighted 1995 to Ketil Hunn
** Set TAB=2 for best readability
**
** The source has been modified later to handle the ARexx messages of
** the Designer.
**
** This source calls functions in the AREXX Interface Designer code
** and it will not compile without the FULL source. It is provided
** here as an example on how to make a fully operational AREXX port.
**
** This source also contains functions which show how to load and save
** macro definitions to disk.
**
*/

#ifndef AREXX_INTERFACE_C
#define AREXX_INTERFACE_C

/*** INCLUDES ************************************************************************/
#include "System.h"
#include "Designer_AREXX.h"
#include <clib/iffparse_protos.h>
#include <libraries/iffparse.h>
#include "myinclude:MyIFFfunctions.h"

#include "TASK_About.h"
#include "TASK_Code.h"
#include "TASK_Assign.h"
#include "ProjectIO.h"
#include "GenerateCSource.h"
#include "HandleFlags.h"
#include "Asl.h"

/*** DEFINES *************************************************************************/
#define	NOT_ASSIGNED	"	"

#define ID_MACR	MAKE_ID('M','A','C','R')

#define	NOT_AVAILABLE		"<n/a>"

#define AREXX_ACTIVATE				1
#define AREXX_ADD							2
#define AREXX_APPEND					3
#define	AREXX_BUSY						4
#define AREXX_COMMANDSHELL		5
#define AREXX_COPY						6
#define AREXX_CUT							7
#define	AREXX_DESIGNERTOFRONT	8
#define	AREXX_DESIGNERTOBACK	9
#define AREXX_GENERATE				10
#define AREXX_GETATTR					11
#define	AREXX_HELP						12
#define	AREXX_ICONIFY					13
#define AREXX_MOVE						14
#define AREXX_NEW							15
#define AREXX_OPEN						16
#define AREXX_PASTE						17
#define AREXX_QUIT						18
#define	AREXX_RENAME					19
#define	AREXX_REQUEST					20
#define	AREXX_REQUESTFILE			21
#define AREXX_SAVE						22
#define AREXX_SETATTR					23
#define AREXX_SORT						24
#define	AREXX_UNICONIFY				25
#define AREXX_WINDOW					26

/*** GLOBALS *************************************************************************/
struct Library			*EasyRexxBase	=NULL;
struct ARexxContext	*context			=NULL;
ARexxMacro					macro					=NULL;

struct ARexxCommandTable commandTable[]=
{
	AREXX_ACTIVATE,				"ACTIVATE",				"COMMAND/S,ARGUMENT/S,ITEM/N/A",		NULL,
	AREXX_ADD,						"ADD",						"COMMAND/S,ARGUMENT/S,NAME/F",			NULL,
	AREXX_APPEND,					"APPEND",					"PROJECT/S,FILENAME/F",							NULL,
	AREXX_BUSY,						"BUSY",						"ON/S,OFF/S",												NULL,
	AREXX_COMMANDSHELL,		"COMMANDSHELL",		"OPEN/S,CLOSE/S",										NULL,
	AREXX_COPY,						"COPY",						"COMMAND/S,ARGUMENT/S",							NULL,
	AREXX_CUT,						"CUT",						"COMMAND/S,ARGUMENT/S",							NULL,
	AREXX_DESIGNERTOFRONT,"DESIGNERTOFRONT",NULL,																NULL,
	AREXX_DESIGNERTOBACK,	"DESIGNERTOBACK",	NULL,																NULL,
	AREXX_GENERATE,				"GENERATE",				"C/S,E/S,OBERON/S,MODULA2/S,ASM/S,SOURCE/S,FILENAME/F",	NULL,
	AREXX_GETATTR,				"GETATTR",				"ALWAYS/S,ARGUMENT/S,AUTHOR/S,COMMAND/S,COPYRIGHT/S,FINAL/S,AREXXHANDLER/S,HANDLERTYPE/S,KEYWORD/S,MAIN/S,MULTIPLE/S,NUMBER/S,PORTNAME/S,SWITCH/S,TEMPLATES/S,TOGGLE/S,VERSION/S",	NULL,
	AREXX_HELP,						"HELP",						"TOPIC/A/F",												NULL,
	AREXX_ICONIFY,				"ICONIFY",				NULL,																NULL,
	AREXX_MOVE,						"MOVE",						"COMMAND/S,ARGUMENT/S,UP/S,DOWN/S",	NULL,
	AREXX_NEW,						"NEW",						"PROJECT/S,FILENAME,FORCE/S",				NULL,
	AREXX_OPEN,						"OPEN",						"PROJECT/S,MACROS/S,ENVIRONMENT/S,FILENAME,FORCE/S",				NULL,
	AREXX_PASTE,					"PASTE",					"COMMAND/S,ARGUMENT/S",							NULL,
	AREXX_QUIT,						"QUIT",						"FORCE/S",													NULL,
	AREXX_RENAME,					"RENAME",					"COMMAND/S,ARGUMENT/S,NAME/A/F",		NULL,
	AREXX_REQUEST,				"REQUEST",				"TITLE/A,TEXT/A,GADGETS/A",					NULL,
	AREXX_REQUESTFILE,		"REQUESTFILE",		"TITLE/A,FILE/A,SAVE/S,DRAWERS/S,NOICONS/S",	NULL,
	AREXX_SAVE,						"SAVE",						"PROJECT/S,MACROS/S,ENVIRONMENT/S,AS/S,FILENAME/F",	NULL,
	AREXX_SETATTR,				"SETATTR",				"ALWAYS/N,AUTHOR,COPYRIGHT,FINAL/N,AREXXHANDLER/N,HANDLERTYPE/N,KEYWORD/N,MAIN/N,MULTIPLE/N,NUMBER/N,PORTNAME,SWITCH/N,TEMPLATES/N,TOGGLE/N,VERSION,MACRO/N,MACRONAME,", NULL,
	AREXX_SORT,						"SORT",						"COMMANDS/S,ARGUMENTS/S",						NULL,
	AREXX_UNICONIFY,			"UNICONIFY",			NULL,																NULL,
	AREXX_WINDOW,					"WINDOW",					"MAIN/S,CODE/S,ASSIGN/S,ABOUT/S,OPEN/S,CLOSE/S,ACTIVATE/S,ZOOM/S,ZIP/S,TOFRONT/S,TOBACK/S",	NULL,
	TABLE_END,
};

struct Macro	macros[MAXMACROS];
BYTE					record=FALSE;

/*** FUNCTIONS ***********************************************************************/
void myHandleARexx(struct ARexxContext *c)
{
#ifdef MYDEBUG_H
	DebugOut("myHandleARexx");
#endif
	/*	This application just ignores the AREXX stuff if the library	*/
  /*	was not found	or the context could not be allocated.					*/
	if(EasyRexxBase!=NULL & c!=NULL)
	{
		register UBYTE	*resultstring	=NULL;
		register BYTE		oldrecord			=record;
		register LONG		resultlong		=~0,
										flags					=(argumentnode ? argumentnode->ln_Pri:0L);

		/* temporalily turn off macro recording */
		record=FALSE;
		while(GetARexxMsg(c))
		{
			switch(c->id)
			{
				case AREXX_REQUESTFILE:
					{
						register UBYTE	file[MAXCHARS];
						register ULONG	flags1=0,
														flags2=0;

						if(ARG(c,1))
							strcpy(file, ARGSTRING(c,1));
						if(ARG(c,2))
							flags1|=FRF_DOSAVEMODE;
						if(ARG(c,3))
							flags2=FRF_DRAWERSONLY;
						if(ARG(c,4))
							flags2|=FRF_REJECTICONS;
						if(GetFile(	mainTask.window,
												ARGSTRING(c,0),
												file,
												flags1,
												flags2,
												egGetString(MSG_OK)))
							resultstring=file;
					}
					break;
				case AREXX_ICONIFY:
					egIconify(eg, TRUE);
					break;
				case AREXX_UNICONIFY:
					egIconify(eg, FALSE);
					break;
				case AREXX_DESIGNERTOFRONT:
					ScreenToFront(mainTask.screen);
					break;
				case AREXX_DESIGNERTOBACK:
					ScreenToBack(mainTask.screen);
					break;
				case AREXX_BUSY:
					if(ARG(c,0))
						egLockAllTasks(eg);
					else
						egUnlockAllTasks(eg);
					break;
				case AREXX_COMMANDSHELL:
					if(ARG(c,1))
						ARexxCommandShell(c,
															ER_Close,	TRUE,
															TAG_DONE);
					else
						OpenCommandShell();
					break;
				case AREXX_REQUEST:
					resultlong=egRequest(	mainTask.window,
																ARGSTRING(c,0),
																ARGSTRING(c,1),
																ARGSTRING(c,2),
																NULL);
					break;
				case AREXX_NEW:
					/* clear old project */
					NewProject(ARGBOOL(c,2));
					/* if a name of the new project was provided, copy this name and
					** display the name in the window title.
					*/
					if(ARG(c,1))
					{
						*PathPart(project)='\0';
						AddPart(project, ARGSTRING(c, 1), MAXCHARS-1);
						MakeMainTitle();
					}
					break;
				case AREXX_OPEN:
					if(ARG(c,1) && ARG(c,3))
					{
						ReadMacros(macros, ARGSTRING(c,3));
						UpdateAssignTask();
					}
					else if(ARG(c,1))
						OpenMacros(macros, macrodefinition);
					else if(ARG(c,2) && ARG(c,3))
					{
						if(ReadEnv(&env, ARGSTRING(c,3)))
							egResetAllTasks(eg);
					}
					else if(ARG(c,2))
						OpenEnv(&env, guifile);
					else if(ARG(c,3))
						ReadProject(commandlist, strcpy(project, ARGSTRING(c,3)), ARGBOOL(c,4));
					else
						OpenProject(commandlist, project, ARG(c,3));
					break;
				case AREXX_APPEND:
					if(ARG(c,1))
					{
						/*	a name was provided; just appen the project and do not display
						**	the append-requester
						*/
						ReadIFF(commandlist, strcpy(project, ARGSTRING(c,1)), TRUE);
						egSetGadgetAttrs(	commands, mainTask.window, NULL,
															GTLV_Labels,	commandlist,
															TAG_DONE);
					}
					else
						/*	no name was provided; show the append-requester and let the user
						**	select a project to append
						*/
						AppendProject(commandlist, project);
					break;
				case AREXX_SAVE:
					if(ARG(c,3))
					{
						/*	the switch 'AS' was provided */
						if(ARG(c,1) && ARG(c,4))
							SaveMacros(macros, strcpy(macrofile, ARGSTRING(c,4)));
						else if(ARG(c,1))
							SaveMacrosAs(macros, macrofile);
						else if(ARG(c,2) && ARG(c,4))
							WriteEnv(&env, strcpy(guifile, ARGSTRING(c,4)), TRUE);
						else if(ARG(c,2))
							SaveEnv(&env, guifile, TRUE);
						else if(ARG(c,4))
							WriteIFF(commandlist, strcpy(project, ARGSTRING(c,4)));
						else
							SaveProjectAs(commandlist, project);
					}
					else
					{
						/* just do plain save, use current name */
						if(ARG(c,1))
							SaveMacros(macros, macrofile);
						else if(ARG(c,2))
						{
							WriteEnv(&env, ENVARCGUIFILE, TRUE);
							WriteEnv(&env, ENVGUIFILE, FALSE);
						}
						else
							WriteIFF(commandlist, project);
					}
					break;
				case AREXX_GENERATE:
					{
						register ULONG msg=0L;

						if(ARG(c,6))
							strcpy(generatefile, ARGSTRING(c,6));

						if(ARG(c,0))
							msg=MSG_GENERATECSOURCE;
						if(ARG(c,1))
							msg=MSG_GENERATEESOURCE;
						else if(ARG(c,2))
							msg=MSG_GENERATEOBERONSOURCE;
						else if(ARG(c,3))
							msg=MSG_GENERATEMODULA2SOURCE;
						else if(ARG(c,4))
							msg=MSG_GENERATEASMSOURCE;

						if(msg)
							GenerateSource(MSG_GENERATECSOURCE, ARGBOOL(c,5));
					}
					break;
				case AREXX_SORT:
					if(ARG(c,1))
						/*	sort arguments */
						resultlong=SortArguments();
					else
						/* do this as default, 'SORT' will sort list of commands */
						resultlong=SortCommands();
					break;
				case AREXX_ADD:
					if(ARG(c,1))
					{
						/* add argument */
						AddArgument(ARexxInput(ARGSTRING(c,2)));
						resultlong=activeargument;
					}
					else
					{
						/* do this as default, 'ADD <name>' will add a command */
						AddCommand(ARexxInput(ARGSTRING(c,2)));
						resultlong=activecommand;
					}
					UpdateMainTask();
					break;
				case AREXX_COPY:
					if(ARG(c,1))
						/*	copy argument */
						CopyArgument();
					else
						/* do this as default, 'COPY' will copy the selected command */
						CopyCommand();
					break;
				case AREXX_CUT:
					if(ARG(c,1))
						/*	cut argument */
						CutArgument();
					else
						/* do this as default, 'CUT' will cut the selected command */
						CutCommand();
					break;
				case AREXX_PASTE:
					if(ARG(c,1))
						/*	paste argument */
						PasteArgument();
					else
						/* do this as default, 'PASTE' will paste the a command */
						PasteCommand();
					break;
				case AREXX_RENAME:
					if(ARG(c,1))
						/*	rename argument */
						RenameNode(argumentnode, ARexxInput(ARGSTRING(c,2)));
					else
						/* do this as default, 'RENAME <name>' will rename the selected command */
						RenameNode((struct Node *)commandnode, ARexxInput(ARGSTRING(c,2)));
					UpdateMainTask();
					break;
				case AREXX_MOVE:
					if(ARG(c,1))
					{
						if(ARG(c,2))
							/*	move argument up */
							MoveArgumentUp();
						else if(ARG(c,3))
							/*	move argument down */
							MoveArgumentDown();
					}
					else
					{
						/* do this as default, 'MOVE up/down' will move the selected command */
						if(ARG(c,2))
							/*	move command up */
							MoveCommandUp();
						else if(ARG(c,3))
							/*	move command down */
							MoveCommandDown();
					}
					break;
				case AREXX_ACTIVATE:
					{
						register UWORD number=(UWORD)ARGNUMBER(c,2)-1;

						if(ARG(c,1))
						{
							/* make sure the number is valid */
							resultlong=number=MAX(0, MIN(number, arguments->max));

							/* select argument */
							GetSelectedArgument(number);
						}
						else
						{
							/* make sure the number is valid */
							resultlong=number=MAX(0, MIN(number, commands->max));

							/* do this as default: 'SELECT n' will select command number n */
							GetSelectedCommand(number);
						}
					}
					break;
				case AREXX_WINDOW:
					if(ARG(c,4) || ARG(c,6))
					{
						/* open window */
						if(ARG(c,0))
							OpenMainTask(NULL, NULL, NULL);
						else if(ARG(c,1))
							OpenCodeTask(NULL, NULL, NULL);
						else if(ARG(c,2))
							OpenAssignTask(NULL, NULL, NULL);
						else if(ARG(c,3))
							OpenAboutTask(NULL, NULL, NULL);
					}
					if(ARG(c,5))
					{
						/* close window */
						if(ARG(c,1))
							egCloseTask(&codeTask);
						else if(ARG(c,2))
							egCloseTask(&assignTask);
						else if(ARG(c,3))
							egCloseTask(&aboutTask);
					}
					if(ARG(c,7) || ARG(c,8))
					{
						register struct Window *window=NULL;

						/* zoom/zip window */
						if(ARG(c,0))
							window=mainTask.window;
						else if(ARG(c,1))
							window=codeTask.window;
						else if(ARG(c,2))
							window=assignTask.window;
						else if(ARG(c,3))
							window=aboutTask.window;

						if(window)
						{
							ZipWindow(window);
							RefreshWindowFrame(window);
						}
					}
					if(ARG(c,9))
					{
						register struct Window *window=NULL;

						/* window to front*/
						if(ARG(c,0))
							window=mainTask.window;
						else if(ARG(c,1))
							window=codeTask.window;
						else if(ARG(c,2))
							window=assignTask.window;
						else if(ARG(c,3))
							window=aboutTask.window;

						if(window)
							WindowToFront(window);
					}
					if(ARG(c,10))
					{
						register struct Window *window=NULL;

						/* window to front*/
						if(ARG(c,0))
							window=mainTask.window;
						else if(ARG(c,1))
							window=codeTask.window;
						else if(ARG(c,2))
							window=assignTask.window;
						else if(ARG(c,3))
							window=aboutTask.window;

						if(window)
							WindowToBack(window);
					}
					break;
				case AREXX_GETATTR:
					if(ARG(c,0))
						resultlong=(LONG)ISBITSET(flags, ALWAYS);
					else if(ARG(c,1))
						resultstring=(argumentnode ? argumentnode->ln_Name: NOT_AVAILABLE);
					else if(ARG(c,2))
						resultstring=code.author;
					else if(ARG(c,3))
						resultstring=(commandnode ? commandnode->nn_Node.ln_Name: NOT_AVAILABLE);
					else if(ARG(c,4))
						resultstring=code.copyright;
					else if(ARG(c,5))
						resultlong=(LONG)ISBITSET(flags, FINAL);
					else if(ARG(c,6))
						resultlong=(LONG)code.arexxhandler;
					else if(ARG(c,7))
						resultlong=(LONG)code.handle;
					else if(ARG(c,8))
						resultlong=(LONG)ISBITSET(flags, KEYWORD);
					else if(ARG(c,9))
						resultlong=(LONG)code.main;
					else if(ARG(c,10))
						resultlong=(LONG)ISBITSET(flags, MULTIPLE);
					else if(ARG(c,11))
						resultlong=(LONG)ISBITSET(flags, NUMBER);
					else if(ARG(c,12))
						resultstring=code.portname;
					else if(ARG(c,13))
						resultlong=(LONG)ISBITSET(flags, SWITCH);
					else if(ARG(c,14))
						resultlong=(LONG)code.templates;
					else if(ARG(c,15))
						resultlong=(LONG)ISBITSET(flags, TOGGLE);
					else if(ARG(c,16))
						resultstring=code.version;
					break;
				case AREXX_SETATTR:
					{
						if(ARG(c,0))
							IFTRUESETBIT(ARGNUMBER(c,0), flags, ALWAYS);
						if(ARG(c,1))
							strcpy(code.author, ARGSTRING(c,1));
						if(ARG(c,2))
							strcpy(code.copyright, ARGSTRING(c,2));
						if(ARG(c,3))
							IFTRUESETBIT(ARGNUMBER(c,3), flags, FINAL);
						if(ARG(c,4))
							code.arexxhandler=(BYTE)ARGNUMBER(c,4);
						if(ARG(c,5))
							code.handle=(BYTE)ARGNUMBER(c,5);
						if(ARG(c,6))
							IFTRUESETBIT(ARGNUMBER(c,6), flags, KEYWORD);
						if(ARG(c,7))
							code.main=(BYTE)ARGNUMBER(c,7);
						if(ARG(c,8))
							IFTRUESETBIT(ARGNUMBER(c,8), flags, MULTIPLE);
						if(ARG(c,9))
							IFTRUESETBIT(ARGNUMBER(c,9), flags, NUMBER);
						if(ARG(c,10))
							strcpy(code.portname, ARGSTRING(c,10));
						if(ARG(c,11))
							IFTRUESETBIT(ARGNUMBER(c,11), flags, SWITCH);
						if(ARG(c,12))
							code.templates=(BYTE)ARGNUMBER(c,12);
						if(ARG(c,13))
							IFTRUESETBIT(ARGNUMBER(c,13), flags, TOGGLE);
						if(ARG(c,14))
							strcpy(code.version, ARGSTRING(c,14));
						if(ARG(c,15) && ARG(c,16))
							EnterMacroName((BYTE)MAX(0, MIN(MAXMACROS, ARGNUMBER(c,15)-1)), ARGSTRING(c,16));

						if(argumentnode)
						{
							argumentnode->ln_Pri=flags;
							PutFlags(argumentnode);
						}
						if(	ARG(c,0) | ARG(c,3)	 | ARG(c,6)  | ARG(c,8)  |
								ARG(c,9) | ARG(c,11) | ARG(c,13))
							UpdateMainTask();

						if(	ARG(c,1) | ARG(c,2)	 | ARG(c,4)  | ARG(c,5)  | ARG(c,7) |
								ARG(c,10)| ARG(c,12) | ARG(c,14))
							UpdateCodeTask();
					}
					break;
				case AREXX_HELP:
					egShowAmigaGuide(eg, ARGSTRING(c,0));
					break;
				case AREXX_QUIT:
					if(ARG(c,0))
						/* supress change-requester */
						env.acknowledge=FALSE;
					/* close all windows in the application and free all resources */
					egCloseAllTasks(eg);
					break;
			}
			ReplyARexxMsg(c,
										ER_ReturnCode,	RC_OK,
										(resultlong!=~0 ? ER_ResultLong		:TAG_IGNORE),	resultlong,
										(resultstring		?	ER_ResultString	:TAG_IGNORE),	resultstring,
										TAG_DONE);
		}
		record=oldrecord;
	}
}

/*** MACRO FILE IN/OUT **************************************************************/
LONG ReadMacros(struct Macro *macros, UBYTE *file)
{
	struct IFFHandle		*iff;
	struct ContextNode	*cn;
	struct PrefHeader		header;
	LONG								error=IFFERR_EOF;

#ifdef MYDEBUG_H
	DebugOut("ReadMacros");
#endif

	if(iff=AllocIFF())
	{
		if(iff->iff_Stream=Open(file, MODE_OLDFILE))
		{
			InitIFFasDOS (iff);
			if(!(error=OpenIFF(iff, IFFF_READ)))
			{
				ParseIFF(iff, IFFPARSE_RAWSTEP);
				if(cn=CurrentChunk(iff))
				{
					if(cn->cn_ID!=ID_FORM & cn->cn_Type!=ID_PREF)
						error=IFFERR_NOTIFF;
					else
					{
						ParseIFF(iff, IFFPARSE_RAWSTEP);
						cn=CurrentChunk(iff);
						if(cn->cn_ID!=ID_PRHD)
							error=IFFERR_NOTIFF;
						else
						{
							register BYTE i=0;

							ReadChunkBytes(iff, (APTR)&header, cn->cn_Size);

							while(i<MAXMACROS)
							{
								error=ParseIFF(iff, IFFPARSE_RAWSTEP);
								if(error==IFFERR_EOC)
									continue;
								else if(error)
									break;

								if(cn=CurrentChunk(iff))
								{
									switch(cn->cn_ID)
									{
										case ID_MACR:
											ReadChunkBytes(iff, (APTR)&macros[i].fullname, cn->cn_Size);
											if(0==Stricmp(macros[i].fullname, NOT_ASSIGNED))
												strcpy(macros[i].fullname, egGetString(MSG_NOTASSIGNED));
											strcpy(macros[i].name, FilePart(macros[i].fullname));
											++i;
											break;
									}
								}
							}
						}
					}
				}
				else
					error=IFFERR_NOTIFF;
				CloseIFF(iff);
			}
			Close(iff->iff_Stream);
		}
		else
			FailRequest(mainTask.window, MSG_NOTFOUND, (APTR)file, NULL);
		FreeIFF(iff);
	}
	if(error==IFFERR_NOTIFF)
		FailRequest(mainTask.window, MSG_IFFERROR2, NULL);
	else if(error<IFFERR_NOMEM)
		FailRequest(mainTask.window, MSG_IFFERROR1, NULL);
	return error;
}

LONG WriteMacros(struct Macro *macros, UBYTE *file)
{
	struct IFFHandle	*iff;
	LONG							error;
	register BYTE			i;

#ifdef MYDEBUG_H
	DebugOut("WriteMacros");
#endif

	if(iff=AllocIFF())
	{
		if(iff->iff_Stream=Open(file, MODE_NEWFILE))
		{
			InitIFFasDOS(iff);
			if(!(error=OpenIFF(iff, IFFF_WRITE)))
			{
				struct PrefHeader PrefHdrChunk={1,0,0};

				PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN);

				myWriteChunkStruct(iff, ID_PRHD, (APTR)&PrefHdrChunk, sizeof(struct PrefHeader));

				for(i=0; i<MAXMACROS; i++)
				{
					if(0==Stricmp(macros[i].fullname, egGetString(MSG_NOTASSIGNED)))
						myWriteChunkText(iff, ID_MACR, NOT_ASSIGNED);
					else
						myWriteChunkText(iff, ID_MACR, macros[i].fullname);
				}

				PopChunk(iff);
				CloseIFF(iff);
			}
			Close(iff->iff_Stream);
		}
		FreeIFF(iff);
	}
	return error;
}

LONG OpenMacros(struct Macro *macros, UBYTE *file)
{
	LONG	error=IFFERR_EOF;

#ifdef MYDEBUG_H
	DebugOut("OpenMacros");
#endif

	egLockAllTasks(eg);
	if(FileRequest(	mainTask.window,
									MSG_OPENMACROS,
									file,
									NULL,
									NULL,
									MSG_OPEN))
	{
		ReadMacros(macros, file);
		UpdateAssignTask();
		UpdateMainMenu();

		if(record)
			AddARexxMacroCommand(	macro,
														ER_Command,		"OPEN MACROS '%s'",
														ER_Argument, (KeepContents() ? file:NULL),
														TAG_DONE);
	}
	egUnlockAllTasks(eg);
	return error;
}

LONG SaveMacros(struct Macro *macros, UBYTE *file)
{
	LONG error;

#ifdef MYDEBUG_H
	DebugOut("SaveMacros");
#endif

	egLockAllTasks(eg);
	error=WriteMacros(macros, file);
	if(record)
		AddARexxMacroCommand(	macro,
													ER_Command,		"SAVE MACROS",
													TAG_DONE);
	egUnlockAllTasks(eg);

	return error;
}

LONG SaveMacrosAs(struct Macro *macros, UBYTE *file)
{
	LONG error;

#ifdef MYDEBUG_H
	DebugOut("SaveMacrosAs");
#endif

	egLockAllTasks(eg);
	if(FileRequest(	mainTask.window,
									MSG_SAVEMACROS,
									file,
									FRF_DOSAVEMODE,
									NULL,
									MSG_SAVE))
	{
		error=WriteMacros(macros, file);
		if(record)
			AddARexxMacroCommand(	macro,
														ER_Command,		"SAVE MACROS AS '%s'",
														ER_Argument, (KeepContents() ? file:NULL),
														TAG_DONE);
	}
	egUnlockAllTasks(eg);
	return error;
}

/*	Small function which asks the user if he/she wants to store the
**	contents of a requester in the macro.
*/
LONG KeepContents(void)
{
#ifdef MYDEBUG_H
	DebugOut("KeepContents");
#endif
	return egRequest(	mainTask.window,
										egGetString(MSG_MACROGENERATION),
										egGetString(MSG_STORECONTENTS),
										egGetString(MSG_YESNO),
										NULL);
}

__asm UBYTE *ARexxInput(register __a0 UBYTE *string)
{
	register UBYTE *c=string, *newstring=string;

#ifdef MYDEBUG_H
	DebugOut("ARexxInput");
#endif

	if(string)
		while(*c!='\0')
		{
			if(*c<'0' || (*c>'9' & *c<'A') || (*c>'Z' & *c<'_') || (*c=='`') || *c>'z')
				*string='_';
			*c++=ToUpper(*string++);
		}
	return newstring;
}

#endif
