#include	"multix.h"

#include	<stdio.h>
#include	<stdlib.h>

#include	<string.h>
#include	<time.h>

#include	"appl.h"
TMdxProcId	MyId;

void	ApplDataReplyReceived(
TMdxEvent	*Event
)
{
	TMdxSRMsgInfo	*MsgInfo;

	/*
	"Event->Data"	holds the information abount the new message.
	*/

	MsgInfo =	(TMdxSRMsgInfo	*)Event->Data;

	/*	First	thing is to check MsgCode of the new message	*/

	switch(MsgInfo->Received.MsgCode)
	{
		case	ApplGetTimeReplyCode	:
		{
			TMdxTime	MdxTime	=	0;
			MdxMsgRead(MsgInfo->Received.Msg,(UInt8Ptr)&MdxTime,sizeof(MdxTime));
			MdxTime =	MdxTimeTo_time_t(MdxTime);
			printf("(%ld) Time Received From %ld - %s",MdxGetCurrTimerValue(),Event->ProcId,ctime((time_t *)&MdxTime));
			MdxReply(MsgInfo,MdErrNoError);
		}
		break;
		default 					:	break;
	}
}


void	ApplCallCompleted(
TMdxEvent	*Event
)
{
	printf("(%ld) Call Completed to Process (%ld)\n",MdxGetCurrTimerValue(),Event->ProcId);
}


void	ApplInitReceived(void)
{

	TMdxProcessParams	ProcessParams;
	TMdxLinkParams	LinkParams;

	/*
	You may choose to use onw or more links of the types specified.
	Un comment the relevent "MdxOpenLink()".

	You may change the parameters for the links.
	*/


	memset(&LinkParams,0,sizeof(LinkParams));
	strcpy(LinkParams.LinkName.Byte,"com2");
	LinkParams.LinkType				=	MdxLinkTypeAsyncLocal;
	LinkParams.ConnectMode			=	MdxConnectModeCall;
	LinkParams.ConnectTimeout		=	0x7fffffff;
	LinkParams.MaxConnectRetries	=	-1;
	LinkParams.ConnectRetriesDelay	=	200;
	LinkParams.LinkBaud 			=	19200;
	LinkParams.UseDlcFraming		=	True;
	LinkParams.ImAliveInterval		=	400l;
	LinkParams.MaxPollRetries		=	2;
	LinkParams.L1MaxSendSize		=	256;
	/*
	MdxOpenLink(&LinkParams);
	*/
	memset(&LinkParams,0,sizeof(LinkParams));
	strcpy(LinkParams.LinkName.Byte,"MdxFs");
	LinkParams.LinkType				=	MdxLinkTypeSpxIpx;
	LinkParams.ConnectMode			=	MdxConnectModeCall;
	LinkParams.ConnectTimeout		=	1000;
	LinkParams.MaxConnectRetries	=	-1;
	LinkParams.ConnectRetriesDelay	=	200;
	LinkParams.UseDlcFraming		=	True;
	LinkParams.MaxPollRetries		=	10;
	LinkParams.L1MaxSendSize		=	500;
	/*
	MdxOpenLink(&LinkParams);
	*/

	memset(&LinkParams,0,sizeof(LinkParams));
	strcpy(LinkParams.LinkName.Byte,"MdxFs");
	LinkParams.LinkType				=	MdxLinkTypeNetBios;
	LinkParams.ConnectMode			=	MdxConnectModeCall;
	LinkParams.ConnectTimeout		=	0x7fffffffl;
	LinkParams.ConnectRetriesDelay	=	300l;
	LinkParams.L1MaxSendSize		=	1024;
	LinkParams.MaxConnectRetries	=	-1l;
	/*
	MdxOpenLink(&LinkParams);
	*/


	memset(&ProcessParams,0,sizeof(ProcessParams));
	ProcessParams.ProcId					=	CallId;
	ProcessParams.InactivityTimer			=	6000;
	ProcessParams.ConnectRetriesInterval	=	200;
	MdxConnectProcess(&ProcessParams);
	printf("(%ld) Calling %ld\n",MdxGetCurrTimerValue(),ProcessParams.ProcId);

	MdxSetApplTimer(ApplTimerDisplayTimer,1000,CallId,0,0,-1);
}


void	ApplSendMsgCompleted(
TMdxEvent	*Event
)
{
	TMdxSRMsgInfo		*MsgInfo;

	/*
	"Event->Data"	holds the information abount the Message we sent.
	*/

	MsgInfo =	(TMdxSRMsgInfo	*)Event->Data;
	switch(MsgInfo->Sent.MsgCode)
	{
		case	ApplGetTimeMsgCode	:
		{
			printf("(%ld) Time Sent - Error = %d\n",MdxGetCurrTimerValue(),Event->Error);
		}
		break;
		default 					:	break;
	}
}


void	ApplSendGetTimeReq(
TMdxProcId	ProcId
)
{
	if (	MdxSendData(ProcId,		/*	Target Process	*/
					(UInt8Ptr)" ",		/*	Data			*/
					1,					/*	Data Size		*/
					ApplGetTimeMsgCode,	/*	Msg Code		*/
					0,					/*	Priority		*/
					MdxSendReliable,	/*	Send Attributes	*/
										/*	Success/Failure	*/
										/*	Report			*/
					0,					/*	No ReqSeq		*/
					1000					/*	3 Secs	Timeout	*/
					)	!=	MdErrNoError	)
	{
		FatalErrorHandler("Mdx Send Error");
	}
	printf("(%ld) Sending Time Req To %ld\n",MdxGetCurrTimerValue(),ProcId);
}

void	ApplTimerEvent(
TMdxEvent	*Event
)
{
	TMdxApplTimerInfo	TimerInfo;

	/*
	"Event->Data"	holds the information abount the timer.
	We use	"MdxGetApplTimerInfo()" to extract that info.
	*/

	MdxGetApplTimerInfo(Event->Data,&TimerInfo);

	switch(TimerInfo.Code)
	{
		case	ApplTimerDisplayTimer	:
		{
			ApplSendGetTimeReq(TimerInfo.Tag1);
		}
		break;
		default :	break;
	}
}


void	cdecl	ApplEventHandler(
TMdxEvent	*Event
)
{
	switch(Event->Code)
	{
		case	MdxTimerEvent					:
		{
			ApplTimerEvent(Event);
		}
		break;
		case	MdxEvSendMsgCompleted		:
		{
			ApplSendMsgCompleted(Event);
		}
		break;
		case	MdxEventApplInit				:
		{
			ApplInitReceived();
		}
		break;
		case	MdxEvCallCompleted			:
		case	MdxEvCallRejected			:
		{
			ApplCallCompleted(Event);
		}
		break;
		case	MdxEvDataReplyReceived		:
		{
			ApplDataReplyReceived(Event);
		}
		break;
		case	MdxStdInAvailable				:
		{
			ApplShutdown	=	True;
		}
		break;
		default 								:	break;
	}
}


Int cdecl	main(
Int 	Argc,
Int8Ptr *Argv
)
{
	if (	Argc	<	3	)
	{
		printf("Usage : client <MyId> <Node Id To Call>\n");
		return(5);
	}
	MyId	=	atol(Argv[1]);
	CallId	=	atol(Argv[2]);

	MultiXStart(MyId,"Client",0,ApplEventHandler);

	printf("Type any key to stop the program...\n");
	while (	ApplShutdown	==	False	)
	{
		MultiXWaitEvent();
	}
	return(0);
}
