#include <exec/memory.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include "launch.h"

main(ac, av)
int ac;
char **av;
{
	click(av[1]);
}

UBYTE *AllocMem();
struct SegList *LoadSeg();
struct MsgPort *CreateProc(), *CreatePort();
struct WBStartup *BuildStartup();

struct MsgPort *rport;
struct WBStartup *startup;

cleanup(msg, name)
char *msg;
char *name;
{
	if(msg && name)
		printf("click: %s: %s\n", name, msg);
	if(startup)
		FreeStartup(startup);
	if(rport) DeletePort(rport);
}

click(name)
char *name;
{
	rport = NULL;

	rport = CreatePort(0, 0);
	if(!rport) {
		cleanup("Can't create reply port", name);
		exit(20);
	}

	startup = BuildStartup(name);
	if(!startup) {
		cleanup("Can't load", name);
		exit(20);
	}

	startup->sm_Message.mn_ReplyPort = rport;
	startup->sm_Message.mn_Length = sizeof(struct WBStartup);
	startup->sm_Message.mn_Node.ln_Type = NT_MESSAGE;

	PutMsg(startup->sm_Process, startup);
	WaitPort(rport);

	cleanup(0, 0);
	exit(0);
}

FreeStartup(msg)
struct WBStartup *msg;
{
	if(msg->sm_ArgList) {
		int i;
		for(i = 0; i < msg->sm_NumArgs; i++) {
			if(msg->sm_ArgList[i].wa_Lock)
				UnLock(msg->sm_ArgList[i].wa_Lock);
			if(msg->sm_ArgList[i].wa_Name)
				FreeMem(msg->sm_ArgList[i].wa_Name,
					strlen(msg->sm_ArgList[i].wa_Name)+1);
		}
		FreeMem(msg->sm_ArgList,
			sizeof(struct WBArg) * msg->sm_NumArgs);
	}
	if(msg->sm_Segment)
		UnLoadSeg(msg->sm_Segment);
	if(msg->sm_ToolWindow)
		FreeMem(msg->sm_ToolWindow,
			strlen(msg->sm_ToolWindow)+1);
	FreeMem(msg, sizeof(struct WBStartup));
}

struct WBStartup *
BuildStartup(name)
char *name;
{
	ULONG flock;
	struct WBStartup *msg;
	char *s, *namep;

	msg = (struct WBStartup *)
		AllocMem(sizeof(struct WBStartup), MEMF_PUBLIC|MEMF_CLEAR);
	if(!msg)
		return 0;

	msg->sm_Segment = LoadSeg(name);
	if(!msg->sm_Segment) {
		FreeStartup(msg);
		return 0;
	}

	msg->sm_ToolWindow = 0;

	msg->sm_ArgList = (struct WBArg *)
		AllocMem(sizeof(struct WBArg), MEMF_PUBLIC | MEMF_CLEAR);
	if(!msg->sm_ArgList) {
		FreeStartup(msg);
		return 0;
	}

	msg->sm_NumArgs = 1;

	flock = Lock(name);
	if(!flock) {
		FreeStartup(msg);
		return 0;
	}
	msg->sm_ArgList[0].wa_Lock = ParentDir(flock);
	UnLock(flock);
	if(!msg->sm_ArgList[0].wa_Lock) {
		FreeStartup(msg);
		return 0;
	}

	namep = name;
	for(s = name; *s; s++)
		if(*s=='/' || *s==':')
			namep = s+1;
	msg->sm_ArgList[0].wa_Name = AllocMem(strlen(namep)+1, MEMF_PUBLIC);
	if(!msg->sm_ArgList[0].wa_Name) {
		FreeStartup(msg);
		return 0;
	}
	strcpy(msg->sm_ArgList[0].wa_Name, namep);

	msg->sm_Process =
		CreateProc(msg->sm_ArgList[0].wa_Name, 0, msg->sm_Segment, 8192);
	if(!msg->sm_Process) {
		FreeStartup(msg);
		return 0;
	}

	return msg;
}
