/*
** Amster - ARexx support
** Copyright © 1999-2000 by Gürer Özen & Jacob Laursen
**
** Maintained by Jacob Laursen <laursen@myself.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "include/config.h"

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

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/rexxsyslib.h>
#include <rexx/storage.h>

#include "include/msg.h"
#include "include/mui.h"
#include "include/search.h"
#include "include/gui.h"
#include "include/rexx.h"
#include "include/panel.h"
#include "include/upload.h"
#include "amster_Cat.h"

MUIF rexx_con(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array);
MUIF rexx_dis(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array);
MUIF rexx_ison(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array);
MUIF rexx_search(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array);
MUIF rexx_sstat(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array);
MUIF rexx_whois(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array);
MUIF rexx_download(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array);
MUIF rexx_serverstat(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array);
MUIF rexx_window(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array);

struct Hook rexx_conHook = { {0,0}, &rexx_con, NULL, NULL };
struct Hook rexx_disHook = { {0,0}, &rexx_dis, NULL, NULL };
struct Hook rexx_isonHook = { {0,0}, &rexx_ison, NULL, NULL };
struct Hook rexx_searchHook = { {0,0}, &rexx_search, NULL, NULL };
struct Hook rexx_sstatHook = { {0,0}, &rexx_sstat, NULL, NULL };
struct Hook rexx_whoisHook = { {0,0}, &rexx_whois, NULL, NULL };
struct Hook rexx_downloadHook = { {0,0}, &rexx_download, NULL, NULL };
struct Hook rexx_serverstatHook = { {0,0}, &rexx_serverstat, NULL, NULL };
struct Hook rexx_windowHook = { {0,0}, &rexx_window, NULL, NULL };

struct MUI_Command rexx_cmds[] = {
	{ "connect", "SERVER/K,PORT/K/N", 2, &rexx_conHook },
	{ "disconnect", NULL, 0, &rexx_disHook },
	{ "isonline", NULL, 0, &rexx_isonHook },
	{ "search", "TITLE/A,STEM/A,MAXRESULTS/K/N", 3, &rexx_searchHook },
	{ "searchstate", NULL, 0, &rexx_sstatHook },
	{ "whois", "USER/A,STEM/A", 2, &rexx_whoisHook },
	{ "download", "NUM/A/N", 1, &rexx_downloadHook },
	{ "getserverstats", "STEM/A", 1, &rexx_serverstatHook },
	{ "window", "NAME/A,OPEN/S,CLOSE/S", 3, &rexx_windowHook },
	{ NULL, NULL, 0, NULL }
};

ULONG gRC;
enum RexxCommand gRexxCommand = NONE;
char *gSTEM;


MUIF rexx_con(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array)
{
    if (gui_onlinestate > OFFLINE) nap_logout();
	if (array[0] == NULL || array[1] == NULL) nap_login();
	else nap_login_fromlist(array[0], *(long *)array[1]);

	return(0);
}


MUIF rexx_dis(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array)
{
	nap_logout();
	set(gui->stat, MUIA_Text_Contents, MSG_STATUS2_NOTCONNECTED);
	return(0);
}


MUIF rexx_ison(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array)
{
	if (gui_onlinestate == ONLINE) return 1;
	else return 0;
}


MUIF rexx_search(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array)
{
	struct SearchArgs args;

	gRC = 0;
	gRexxCommand = SEARCH;

	if (gui_onlinestate < ONLINE) return 15;

	args.String = array[0];
	if (array[2]) args.MaxResults = *(long *)array[2];
	else args.MaxResults = -1;

	DoMethod(gui->searchpanel, SEARCH_GO, &args);
	DoMethod(gui->searchpanel, SEARCH_GETSTATE);
	if (search_state == 1) do {
		nap_listen();
		DoMethod(gui->searchpanel, SEARCH_GETSTATE);
	} while (search_state == 1);

	if (search_state == 2) DoMethod(gui->searchpanel, SEARCH_FILLSTEM, array[1]);
	else gRC = 10;
	gRexxCommand = NONE;

	return gRC;
}


MUIF rexx_sstat(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array)
{
	DoMethod(gui->searchpanel, SEARCH_GETSTATE);
	return (ULONG)search_state;
}


MUIF rexx_whois(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array)
{
	if (gui_onlinestate < ONLINE) return 10;

	gRC = 0;
	gRexxCommand = WHOIS;
	gSTEM = array[1];

	nap_sendbuf(NAPC_WHOIS, array[0]);
	do {
		nap_listen();
	} while (gRexxCommand == WHOIS);

	return gRC;
}


MUIF rexx_download(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array)
{
	gRC = 0;

	DoMethod(gui->searchpanel, SEARCH_DOWNLOAD, *(long *)array[0]);

	return gRC;
}


MUIF rexx_serverstat(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array)
{
	struct Message *m;
	u_long tmp;
	char buf1[64], buf2[64];

	GetAttr(MUIA_Application_RexxMsg, gui->app, &tmp);
	m = (struct Message *)tmp;

	sprintf(buf1, "%s.USERS", array[0]);
	sprintf(buf2, "%ld", gui->Libraries);
	SetRexxVar(m, buf1, buf2, strlen(buf2));

	sprintf(buf1, "%s.SONGS", array[0]);
	sprintf(buf2, "%ld", gui->Songs);
	SetRexxVar(m, buf1, buf2, strlen(buf2));

	sprintf(buf1, "%s.GIGABYTES", array[0]);
	sprintf(buf2, "%ld", gui->Gigabytes);
	SetRexxVar(m, buf1, buf2, strlen(buf2));

	sprintf(buf1, "%s.SERVER", array[0]);
	SetRexxVar(m, buf1, nap_server, strlen(nap_server));

	sprintf(buf1, "%s.PORT", array[0]);
	sprintf(buf2, "%d", nap_port);
	SetRexxVar(m, buf1, buf2, strlen(buf2));

	sprintf(buf1, "%s.CONNECTTIME", array[0]);
	sprintf(buf2, "%ld", gui->OnlineSince);
	SetRexxVar(m, buf1, buf2, strlen(buf2));

	if (gui_onlinestate < ONLINE) return 5;
	else return 0;
}


MUIF rexx_window(REG(a0) struct Hook *h,REG(a2) Object *app, REG(a1) char **array)
{
	if (stricmp(array[0], "upload") == 0) {
		if (array[1]) DoMethod(gui->uwin, UPLOAD_OPEN);
		else if (array[2]) DoMethod(gui->uwin, UPLOAD_CLOSE);
	}
	else if (stricmp(array[0], "download") == 0) {
		if (array[1]) DoMethod(gui->iconpanel, PANEL_OPENDL);
		else if (array[2]) DoMethod(gui->iconpanel, PANEL_CLOSEDL);
	}
	else if (stricmp(array[0], "debug") == 0) {
		if (array[1]) DoMethod(gui->iconpanel, PANEL_OPENDEBUG);
		else if (array[2]) DoMethod(gui->iconpanel, PANEL_CLOSEDEBUG);
	}
	else if (stricmp(array[0], "library") == 0) {
		if (array[1]) DoMethod(gui->iconpanel, PANEL_OPENSHARE);
		else if (array[2]) DoMethod(gui->iconpanel, PANEL_CLOSESHARE);
	}
	else if (stricmp(array[0], "hotlist") == 0) {
		if (array[1]) set(gui->WI_Hotlist, MUIA_Window_Open, TRUE);
		else if (array[2]) set(gui->WI_Hotlist, MUIA_Window_Open, FALSE);
	}
	else if (stricmp(array[0], "message") == 0) {
		if (array[1]) set(gui->mwin, MUIA_Window_Open, TRUE);
		else if (array[2]) set(gui->mwin, MUIA_Window_Open, FALSE);
	}

	return 0;
}


u_long rexx_sendcommand(char *port, char *com)
{
	struct MsgPort *me,*him;
	struct RexxMsg *rmsg;
	u_long rc=0;

	if (me = CreateMsgPort()) {
		if (rmsg = CreateRexxMsg(me,NULL,NULL)) {
			if (rmsg->rm_Args[0] = CreateArgstring(com, strlen(com))) {
				rmsg->rm_Action = RXCOMM;
				Forbid();
				him = FindPort(port);
				Permit();
				if (him) {
					PutMsg(him, (struct Message *)rmsg);
					WaitPort(me);
					GetMsg(me);
					rc = rmsg->rm_Result1;
/*					if (!rc && rmsg->rm_Result2) DeleteArgstring(rmsg->rm_Result2);*/
				}
				DeleteArgstring(rmsg->rm_Args[0]);
			}
			DeleteRexxMsg(rmsg);
		}
		DeleteMsgPort(me);
	}
	return rc;
}


void rexx_execute(char *com, char *argfmt, ...)
{
	static char buf[1024];
	char *p;
	va_list ap;

	p = buf + sprintf(buf,"Run <>NIL: RexxC:RX %s ",com);
	if(argfmt) {
		va_start(ap,argfmt);
		vsprintf(p,argfmt,ap);
		va_end(ap);
	}

	Execute(buf, 0, 0);
}
