/*********************
*   ScrShuffle 1.0   *
*********************/

#include <exec/types.h>
#include <devices/input.h>
#include <intuition/intuitionbase.h>
#include <libraries/dos.h>
#include <exec/memory.h>
#include <libraries/dosextens.h>
#include <string.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>

#include "ScrShuffle.h"

struct myHandlerInfo *info = NULL;
struct MsgPort *port = NULL, *inputport = NULL;
struct IOStdReq *inputreq = NULL;
UBYTE inputopen = FALSE;
BPTR out;

char noinputdev[] = "Can't open input.device !\n";
char nomem[] = "Out of memory !\n", handlername[] = "l:ScrShuffle-handler";
char copyright[] = "\2331mScrShuffle 1.0 \2330m\23333mby Nico François, Jorrit Tyberghein (PowerPeak)\2330m\n";

void _main (char *line)
{
	out = Output();
	myPutStr (copyright);
	if (port = FindPort (PORTNAME)) {
		info = (struct myHandlerInfo *)port->mp_SigTask;
		RemoveHandler();
		}
	else {
		if (!(info = AllocMem ((ULONG)sizeof(*info), MEMF_PUBLIC)))
			FreeExit (nomem);
		strcpy (info->portname, PORTNAME);
		if (!(port = CreatePort (info->portname, 0L))) FreeExit (nomem);
		port->mp_SigTask = (struct Task *)info;
		LoadHandler();
		OpenInputStuff();
		inputreq->io_Command = IND_ADDHANDLER;
		inputreq->io_Data = (APTR)&info->myhandler;
		DoIO (inputreq);
		myPutStr ("ScrShuffle-Handler installed.\n");
		CloseInputStuff();
		}
}

FreeExit (str)
char *str;
{
	if (str) myPutStr (str);
	if (port) DeletePort (port);
	if (info) FreeMem (info, (ULONG)sizeof(*info));
	CloseInputStuff();
	XCEXIT(0);
}

CloseInputStuff()
{
	if (inputopen) CloseDevice (inputreq);
	if (inputreq) DeleteStdIO (inputreq);
	if (inputport) DeletePort (inputport);
}

OpenInputStuff()
{
	if (!(inputport = CreatePort (0L, 0L))) FreeExit (noinputdev);
	if (!(inputreq = CreateStdIO (inputport))) FreeExit (noinputdev);
	if (!(inputopen = !OpenDevice ("input.device", 0L, inputreq, 0L)))
		FreeExit (noinputdev);
}

RemoveHandler()
{
	OpenInputStuff();
	inputreq->io_Command = IND_REMHANDLER;
	inputreq->io_Data = (APTR)&info->myhandler;
	DoIO (inputreq);
	UnLoadSeg (info->seglist);
	FreeExit ("ScrShuffle-Handler removed.\n");
}

LoadHandler()
{
	if (!(info->seglist = LoadSeg (handlername + 2)))
		if (!(info->seglist = LoadSeg (handlername)))
			FreeExit ("Can't load 'L:ScrShuffle-Handler' !\n");
	info->myhandler.is_Code = 
		(void (*)())((APTR (*)())(((ULONG)info->seglist << 2) + 4))();
	info->myhandler.is_Data = (APTR)info;
	info->myhandler.is_Node.ln_Pri = 52;
}

myPutStr (str)
char *str;
{
	Write (out, str, (ULONG)strlen (str));
}

void MemCleanup() {}
