#include <classes/DOS/Notify.h>

#include <exec/memory.h>
#include <string.h>

#pragma -
#include <pragma/dos_lib.h>
#include <pragma/exec_lib.h>
#pragma +

NotifyC::NotifyC()
{
	memset(&nreq,0,sizeof(struct NotifyRequest));
	outstanding = FALSE;
	inited = FALSE;
}

NotifyC::NotifyC(const NotifyC &s)
{
	memset(&nreq,0,sizeof(struct NotifyRequest));
	nreq.nr_Name = s.nreq.nr_Name;
	nreq.nr_UserData = s.nreq.nr_UserData;
	nreq.nr_Flags = s.nreq.nr_Flags & 0x01b;
	if (nreq.nr_Flags & NRF_SEND_MESSAGE)
	{
		nreq.nr_stuff.nr_Msg.nr_Port = s.nreq.nr_stuff.nr_Msg.nr_Port;
	};
	if (nreq.nr_Flags & NRF_SEND_SIGNAL)
	{
		nreq.nr_stuff.nr_Signal.nr_Task = s.nreq.nr_stuff.nr_Signal.nr_Task;
		nreq.nr_stuff.nr_Signal.nr_SignalNum =
			s.nreq.nr_stuff.nr_Signal.nr_SignalNum;
	};
	inited = TRUE;
	outstanding = FALSE;
}

NotifyC::~NotifyC()
{
	end();
}

NotifyC &NotifyC::operator= (const NotifyC &s)
{
	if (this != &s)
	{
		end();
		memset(&nreq,0,sizeof(struct NotifyRequest));
		nreq.nr_Name = s.nreq.nr_Name;
		nreq.nr_UserData = s.nreq.nr_UserData;
		nreq.nr_Flags = s.nreq.nr_Flags & 0x01b;
		if (nreq.nr_Flags & NRF_SEND_MESSAGE)
		{
			nreq.nr_stuff.nr_Msg.nr_Port = s.nreq.nr_stuff.nr_Msg.nr_Port;
		};
		if (nreq.nr_Flags & NRF_SEND_SIGNAL)
		{
			nreq.nr_stuff.nr_Signal.nr_Task = s.nreq.nr_stuff.nr_Signal.nr_Task;
			nreq.nr_stuff.nr_Signal.nr_SignalNum =
				s.nreq.nr_stuff.nr_Signal.nr_SignalNum;
		};
		inited = TRUE;
		outstanding = FALSE;
	};
	return *this;
}

BOOL NotifyC::start(STRPTR name, PortC &port, APTR userData,
	BOOL wait, BOOL initial)
{
	if (!outstanding)
	{
		memset(&nreq,0,sizeof(struct NotifyRequest));
		nreq.nr_Name = name;
		nreq.nr_UserData = (ULONG) userData;
		nreq.nr_Flags = NRF_SEND_MESSAGE;
		if (wait)
			nreq.nr_Flags |= NRF_WAIT_REPLY;
		if (initial)
			nreq.nr_Flags |= NRF_NOTIFY_INITIAL;
		nreq.nr_stuff.nr_Msg.nr_Port = port.port();
		inited = TRUE;
		return (outstanding = (BOOL) StartNotify(&nreq));
	};
	return FALSE;
}

BOOL NotifyC::start(STRPTR name, struct Task *task, UBYTE signal,
		APTR userData, BOOL initial)
{
	if (task && !outstanding)
	{
		memset(&nreq,0,sizeof(struct NotifyRequest));
		nreq.nr_Name = name;
		nreq.nr_UserData = (ULONG) userData;
		nreq.nr_Flags = NRF_SEND_SIGNAL;
		if (initial)
			nreq.nr_Flags |= NRF_NOTIFY_INITIAL;
		nreq.nr_stuff.nr_Signal.nr_Task = task;
		nreq.nr_stuff.nr_Signal.nr_SignalNum = signal;
		inited = TRUE;
		return (outstanding = (BOOL) StartNotify(&nreq));
	};
	return FALSE;
}

BOOL NotifyC::restart()
{
	if (inited && !outstanding)
	{
		return (outstanding = (BOOL) StartNotify(&nreq));
	};
	return FALSE;
}

VOID NotifyC::end()
{
	if (outstanding)
	{
		EndNotify(&nreq);
		outstanding = FALSE;
	};
}
