CTask		*chat_display_task	= NULL;
CTask		*chat_message_task	= NULL;
CTCPSocket	*tcp = TCPSocket(AF_INET);

U0 ChatDisplayTask(I64)
{ // display received messages.
	DocTermNew;
	DocCursor;
	DocPrint(, "$$WW,1$$");

	while (TaskValidate(chat_message_task))
	{
		Refresh;
	}
}

U0 ChatMessageTask(I64)
{ // take in text.
	U8	*message;

	DocTermNew;
	DocPrint(, "$$WW,1$$");

	while (message = StrGet("> ",, SGF_SHIFT_ESC_EXIT))
	{
		DocBottom(chat_display_task->put_doc);
		DocPrint(chat_display_task->put_doc,
				 "$$BG,BLUE$$$$BLACK$$<local>$$FG$$$$BG$$ %s\n", message);

		TCPSocketSendString(tcp, message);

		DocClear;
		DocPrint(, "$$WW,1$$");

	}
}

U0 ChatInit()
{
	chat_message_task = Spawn(&ChatMessageTask, NULL, "TCP Chat Message");
	chat_display_task = Spawn(&ChatDisplayTask, NULL, "TCP Chat");
	chat_message_task->win_inhibit = WIG_USER_TASK_DEFAULT;
	chat_display_task->win_inhibit = WIG_USER_TASK_DEFAULT;
	LBts(&chat_message_task->display_flags, DISPLAYf_SHOW);
	LBts(&chat_display_task->display_flags, DISPLAYf_SHOW);

	WinFocus(chat_display_task);
	WinFocus(chat_message_task);

	chat_display_task->win_top		= 2;
	chat_display_task->win_bottom	= TEXT_ROWS / 3;
	chat_display_task->win_left		= TEXT_COLS / 3;
	chat_display_task->win_right	= TEXT_COLS / 3 * 2;

	chat_message_task->win_top		= chat_display_task->win_bottom + 2;
	chat_message_task->win_bottom	= chat_message_task->win_top + 3;
	chat_message_task->win_left		= chat_display_task->win_left;
	chat_message_task->win_right	= chat_display_task->win_right;

}

U0 Chat()
{
	CSocketAddressIPV4	 socket_addr;
	CIPV4Address		 ip_addr;
	U8					*ip_string	 = StrGet("Server IPV4: ");
	U8					*port_string = StrGet("Server Port: ");
	I64					 port		 = Str2I64(port_string);
	U8					*buffer[ETHERNET_FRAME_SIZE];
	I64					 receive_val;

	while (PresentationToNetwork(AF_INET, ip_string, &ip_addr) == -1)
	{
		"\nERROR: Bad IP entered. Retry.\n";
		ip_string = StrGet("Server IPV4: ");
	}


	Free(ip_string);
	Free(port_string);

	socket_addr.port			= EndianU16(port);
	socket_addr.family			= AF_INET;
	socket_addr.address.address	= ip_addr.address;

	tcp->timeout = TCP_TIMEOUT; // use normal timeout for connect()

	"\nConnecting to server...\n";
	if (TCPSocketConnect(tcp, &socket_addr) != 0)
	{
		"\nFailed to connect to server.\n";
		TCPSocketClose(tcp);
		return;
	}
	else
		"\nSuccessfully connected.\n";

	ChatInit;

	tcp->timeout = 0;

	while (TaskValidate(chat_message_task))
	{

		if ((receive_val = TCPSocketReceive(tcp, buffer, ETHERNET_FRAME_SIZE)) != -1)
		{
			if (receive_val == 0)
			{
				"\nServer closed the connection.\n";
				Kill(chat_message_task);
				break;
			}
			else if (receive_val > 0)
			{
				DocBottom(chat_display_task->put_doc);
				DocPrint(chat_display_task->put_doc,
						 "%s\n", buffer);
				MemSet(buffer, 0, ETHERNET_FRAME_SIZE);
			}
		}

		Refresh;

	}

	tcp->timeout = TCP_TIMEOUT;

	"\nClosing connected socket...\n";
	if (TCPSocketClose(tcp) == 0)
		"\nSocket closed.\n";
	else
		"\nSocket failed to close.\n";
}

Chat;