/*
 *  FM_ARexx_Misc.c
 *
 *  functions for reaction-arexx.
 *
 *  $VER: V1.1, 19.2.2002
 *  Coded by Edgar Schwan
 */

#include <exec/types.h>
#include <exec/tasks.h>
#include <libraries/asl.h>
#include <libraries/locale.h>
#include <iffp/ilbmapp.h>
#include <graphics/text.h>
#include <intuition/classusr.h>
#include <reaction/reaction.h>
#include <classes/arexx.h>

#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/asl_protos.h>
#include <clib/icon_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/locale_protos.h>

#include <pragmas/dos_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/asl_pragmas.h>
#include <pragmas/icon_pragmas.h>
#include <pragmas/gadtools_pragmas.h>
#include <pragmas/locale_pragmas.h>

#include <stdio.h>
#include <string.h>

#include "FM_ARexx_Misc.h"
#include "FlashMandel.h"
#include "FM_ReactionCD.h"
#include "FM_ReactionBasics.h"

#ifdef FM_AREXX_SUPPORT

/* external vars */
extern Object *ARexxObj;
extern struct TextAttr MYFONTSTRUCT;
extern struct Catalog *CatalogPtr;

/* local prototypes */
//static void LaunchIt(struct ILBMInfo *Ilbm, char *cmd, char *dir);

/* LaunchARexxScript(): Launch an arexx-script.

		SYNOPSIS: BOOL  = LaunchARexx
						(
						struct ILBMInfo  *Ilbm;
						);

		INPUTS:		Ilbm:
							Pointer to the ILBMInfo-structure.

		RETURNS:		result:
							Is TRUE if successfull.
*/

BOOL LaunchARexxScript(struct ILBMInfo *Ilbm)
{
static char ARexxDir[MAX_DIRLEN] = "FLASHMANDEL:arexx";
static char ARexxFilename[MAX_FILELEN] = {0};
struct FileRequester *ARexxFileReq;
BOOL Success = FALSE;

if (ARexxObj) {
	if (ARexxFileReq = AllocAslRequest(ASL_FileRequest, 0)) {
		if (AslRequestTags(ARexxFileReq, ASLFR_Window, Ilbm->win,
													ASLFR_InitialLeftEdge, Ilbm->win->LeftEdge + 25,
													ASLFR_InitialTopEdge, Ilbm->win->TopEdge + 35,
													ASLFR_InitialWidth, 300,
													ASLFR_InitialHeight, ((Ilbm->win->Height) * 7) >> 3,
													ASLFR_SleepWindow, TRUE,
													ASLFR_TextAttr, &MYFONTSTRUCT,
													ASLFR_TitleText, CATSTR(TXT_SelectRxScript),
													ASLFR_InitialDrawer, &ARexxDir,
													ASLFR_InitialFile, &ARexxFilename,
													ASLFR_DoSaveMode, FALSE,
													ASLFR_RejectIcons, TRUE,
													TAG_END)) {
			strncpy(ARexxFilename, ARexxFileReq->rf_File, MAX_FILELEN);
			strncpy(ARexxDir, ARexxFileReq->rf_Dir, MAX_DIRLEN);

			LaunchIt(Ilbm, ARexxFilename, ARexxDir);
			Success = TRUE;
			}
		FreeAslRequest (ARexxFileReq);
		}
	}
return(Success);
}

/* CreateARexxMenu(): Create ARexx-menu.

		SYNOPSIS: BOOL  = CreateARexxMenu
						(
						struct DiskObject *dobj;
						);

		INPUTS:		dobj:
							Pointer to the DiskObject-structure or NULL.

		RETURNS:		result:
							Is TRUE if successfull.
*/
struct NewMenu *ARexxNewMenu = NULL;

BOOL CreateARexxMenu(struct DiskObject *dobj)
{
BOOL success = FALSE;
char ttnamebuf[50];
const char title_txt[] = "ARexx";
const char *launch_txt = (const char *) CATSTR(TXT_Launch);
int numcmds = 0;
ULONG i;
size_t nm_size = 0, string_size = 0;
struct DiskObject *cli_dobj = NULL, *act_dobj = NULL;
struct Task *own_task = FindTask(NULL);

if (ARexxObj) {
	if (dobj) act_dobj = dobj;
	else {
		if (cli_dobj = GetDiskObject(own_task->tc_Node.ln_Name)) act_dobj = cli_dobj;
		else return(success);
		}

	while(1) {
		STRPTR value;
		sprintf((STRPTR) &ttnamebuf, "REXXCMD%d", numcmds + 1);
		if (!(value = FindToolType(act_dobj->do_ToolTypes, (STRPTR) &ttnamebuf))) break;
		string_size += strlen(value) + 1;
		numcmds++;
		}
	string_size += strlen((const char *) &title_txt) + 1;
	string_size += strlen(launch_txt) + 1;
	if (numcmds) numcmds++;
	nm_size = ((numcmds + 3) * sizeof(struct NewMenu));

	if (ARexxNewMenu = (struct NewMenu *) AllocVec((ULONG) (nm_size + string_size), MEMF_PUBLIC|MEMF_CLEAR)) {
		char *string = (char *) ((ULONG) ARexxNewMenu) + nm_size, *tmp;
		struct NewMenu *act_nm = ARexxNewMenu;

		strcpy(string, title_txt);		/* initialize menu-title */
		act_nm->nm_Type = NM_TITLE;
		act_nm->nm_Label = string;
		act_nm->nm_CommKey = NULL;
		act_nm->nm_Flags = 0;
		act_nm->nm_MutualExclude = 0;
		act_nm->nm_UserData = (APTR) (REXX_MENU_ID);
		string = (char *) ((ULONG) string + strlen(string)) + 1;
		act_nm++;

		if (numcmds) {		/* initialize command-items */
			for (i = 0; i < (numcmds - 1); i++) {
				sprintf((STRPTR) &ttnamebuf, "REXXCMD%d", i + 1);
				strcpy(string, (const char *) FindToolType(act_dobj->do_ToolTypes, (STRPTR) &ttnamebuf));
				tmp = string;
				string = (char *) ((ULONG) string + strlen(string)) + 1;
				if (tmp[strlen(tmp) -1] == '"') tmp[strlen(tmp) -1] = 0;		/* delete " */
				if (tmp[0] == '"') {tmp[0] = 0; tmp++;}
				act_nm->nm_Type = NM_ITEM;
				act_nm->nm_Label = tmp;
				act_nm->nm_CommKey = NULL;
				act_nm->nm_Flags = 0;
				act_nm->nm_MutualExclude = 0;
				act_nm->nm_UserData = (APTR) (REXX_MENU_ID + i + 1);

				act_nm++;
				}
			act_nm->nm_Type = NM_ITEM;		/* initialize barlabel */
			act_nm->nm_Label = NM_BARLABEL;
			act_nm->nm_CommKey = NULL;
			act_nm->nm_Flags = 0;
			act_nm->nm_MutualExclude = 0;
			act_nm->nm_UserData = NULL;
			act_nm++;
			}

		strcpy(string, launch_txt);		/* initialize launch-item */
		act_nm->nm_Type = NM_ITEM;
		act_nm->nm_Label = string;
		act_nm->nm_CommKey = NULL;
		act_nm->nm_Flags = 0;
		act_nm->nm_MutualExclude = 0;
		act_nm->nm_UserData = (APTR) REXX_MENUITEM_LAUNCH;
		act_nm++;

		act_nm->nm_Type = NM_END;		/* initialize menu-end */
		act_nm->nm_Label = NULL;
		act_nm->nm_CommKey = NULL;
		act_nm->nm_Flags = 0;
		act_nm->nm_MutualExclude = 0;
		act_nm->nm_UserData = NULL;
		success = TRUE;
		}

	if (cli_dobj) {FreeDiskObject(cli_dobj); cli_dobj = NULL;}
	}
return(success);
}

/* SetARexxMenu(): Activate menu-items for ARexx-menu in main-window.

		SYNOPSIS: BOOL  = SetARexxMenu
						(
						struct ILBMInfo  *Ilbm;
						);

		INPUTS:		Ilbm:
							Pointer to the ILBMInfo-structure.

		RETURNS:		result:
							Is TRUE if successfull.
*/
struct Menu *ARexxMenu = NULL;

BOOL SetARexxMenu(struct ILBMInfo *Ilbm)
{
BOOL success = FALSE;
struct Menu *win_menu = Ilbm->win->MenuStrip, *last_menu = NULL;
APTR vi = NULL;

if (ARexxObj) {
	if (vi = GetVisualInfoA(Ilbm->scr, NULL)) {
		if (ARexxNewMenu) {
			if (ARexxMenu = CreateMenusA(ARexxNewMenu, NULL)) {
				last_menu = win_menu;
				while (last_menu->NextMenu) {
					last_menu = last_menu->NextMenu;
					}
				ModifyIDCMP(Ilbm->win, NULL);
				ClearMenuStrip(Ilbm->win);
				last_menu->NextMenu = ARexxMenu;
				LayoutMenus(win_menu, vi, GTMN_TextAttr, &MYFONTSTRUCT, GTMN_NewLookMenus, TRUE, TAG_END);
				SetMenuStrip(Ilbm->win, win_menu);
				ModifyIDCMP(Ilbm->win, IDCMP_STANDARD);
				success = TRUE;
				}
			}
		FreeVisualInfo(vi);
		}
	}
return(success);
}

/* RemoveARexxMenu(): Remove and free menu-items for ARexx-menu.

		SYNOPSIS: void  = RemoveARexxMenu
						(
						struct ILBMInfo  *Ilbm;
						);

		INPUTS:		Ilbm:
							Pointer to the ILBMInfo-structure.

		RETURNS:		result: -
*/

void RemoveARexxMenu(struct ILBMInfo *Ilbm)
{
struct Menu *win_menu = Ilbm->win->MenuStrip, *act_menu = NULL, *prev_menu = NULL;
APTR vi = NULL;

if (ARexxMenu) {
	if (vi = GetVisualInfoA(Ilbm->scr, NULL)) {
		act_menu = win_menu;
		while (act_menu) {
			if (act_menu == ARexxMenu) {
				ModifyIDCMP(Ilbm->win, NULL);
				ClearMenuStrip(Ilbm->win);
				if (prev_menu) prev_menu->NextMenu = ARexxMenu->NextMenu;
				LayoutMenus(win_menu, vi, GTMN_TextAttr, &MYFONTSTRUCT, GTMN_NewLookMenus, TRUE, TAG_END);
				SetMenuStrip(Ilbm->win, win_menu);
				ModifyIDCMP(Ilbm->win, IDCMP_STANDARD);

				FreeMenus(ARexxMenu); ARexxMenu = NULL;
				break;
				}
			prev_menu = act_menu;
			act_menu = act_menu->NextMenu;
			}
		FreeVisualInfo(vi);
		}
	}
}

/* FreeARexxMenu(): Free menu-items of arexx-menu.

		SYNOPSIS: void  = FreeARexxMenu
						(
						void
						);

		INPUTS:		-

		RETURNS:		result: -
*/

void FreeARexxMenu(void)
{
if (ARexxNewMenu) {FreeVec((APTR) ARexxNewMenu); ARexxNewMenu = NULL;}
}

/* HandleARexxMenu(): Handle all events on the arexx-menu.

		SYNOPSIS: void  = HandleARexxMenu
						(
						struct ILBMInfo *Ilbm;
						UWORD MenuCode;
						);

		INPUTS:		Ilbm:
							Pointer to the ILBMInfo-structure.

						MenuCode:
							Code, that specifies the selected menu-item.

		RETURNS:		result: -
*/

void HandleARexxMenu(struct ILBMInfo *Ilbm, UWORD MenuCode)
{
struct MenuItem *SelectedItem = ItemAddress(Ilbm->win->MenuStrip, MenuCode);
ULONG id = (ULONG) GTMENUITEM_USERDATA(SelectedItem);

if (ARexxObj) {
	if (id) {
		if (id & REXX_MENU_CMD_MASK) {
			struct IntuiText *it = (struct IntuiText *) SelectedItem->ItemFill;
			char *command = it->IText;

			LaunchIt(Ilbm, command, "FLASHMANDEL:arexx");
			}
		else {
			switch(id) {
				case REXX_MENUITEM_LAUNCH:
					LaunchARexxScript(Ilbm);
					break;
				default:
					DisplayBeep(Ilbm->scr);
				}
			}
		}
	}
}

/* LaunchIt(): Launch an arexx-script.

		SYNOPSIS: static void  = LaunchIt
						(
						struct ILBMInfo *Ilbm;
						char *cmd;
						char *dir;
						);

		INPUTS:		Ilbm:
							Pointer to the ILBMInfo-structure.

						cmd:
							Pointer to the command-string.

						dir:
							Pointer to the directory-string.

		RETURNS:		result: -
*/

void LaunchIt(struct ILBMInfo *Ilbm, char *cmd, char *dir)
{
STRPTR hostname;
char cmd_string[300];
BPTR OldDir, NewDir, Script;

if (ARexxObj) {
	GetAttr(AREXX_HostName, ARexxObj, (ULONG *) &hostname);

	sprintf((STRPTR) &cmd_string, "%s %s", cmd, hostname);
	if (NewDir = Lock(dir, SHARED_LOCK)) {
		OldDir = CurrentDir(NewDir);
		if (Script = Lock(cmd, SHARED_LOCK)) {
			LONG result1, result2, result;
			STRPTR result_str;
			struct apExecute ape = {
				AM_EXECUTE,
				(STRPTR) cmd_string,
				NULL,
				&result1,
				&result2,
				&result_str,
				NULL};
			UnLock(Script);
			result = DoMethodA(ARexxObj, (Msg) &ape);
			}
//		else DisplayBeep(Ilbm->scr);
		CurrentDir(OldDir);
		UnLock(NewDir);
		}
	}
}

#else /* FM_AREXX_SUPPORT */
extern struct Library *ResourceBase;  /* dummy */
#endif /* FM_AREXX_SUPPORT */
