/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2008.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: src/drivers/wintel32/network/sdlnetconnection.cpp

*/

#include "sgx/core/core.hpp"
#include "sgx/network/network.hpp"
#include "sgx/system/system.hpp"
#include "drivers/wintel32/network/network.hpp"


/*
** Client code
*/
CSDLNetConnectionClient::CSDLNetConnectionClient(CNetMachine *pServer, int flags)
{
	SDLNet_ResolveHost(&serverAddress, pServer->address.c_str(), pServer->port);
	serverSocket = SDLNet_TCP_Open(&serverAddress);
}

/*
** Server code
*/

static size_t monitor_connections(CThread *pThread) 
{
	CSDLNetConnectionServer *pServer = SGX_STATIC_CAST(CSDLNetConnectionServer *, pThread->m_pUserData);
	return pServer->MonitorConnections(pThread); 
}

static size_t monitor_messages(CThread *pThread) 
{
	CSDLNetConnectionServer *pServer = SGX_STATIC_CAST(CSDLNetConnectionServer *, pThread->m_pUserData);
	return pServer->MonitorMessages(pThread); 
}

tMEM_SIZE CSDLNetConnectionServer::MonitorConnections(CThread *pThread)
{

	while(TRUE) {
		sgxYieldWait(1.0f);

		SDLNet_CheckSockets(socketset, ~0);	// blocking function

		// Also poll
		if (SDLNet_SocketReady(serverSocket)) {

			CSGXNetworkManager::get()->dispatchControl(NET_CONNECTION_REQUESTED, (void *)0);

			TCPsocket clientSocket = SDLNet_TCP_Accept(serverSocket);
			SDLNet_TCP_AddSocket(socketset, clientSocket);

			// add to server
			ClientMachine *cm = new ClientMachine(clientSocket);
			clients.push_back(cm);


			CSGXNetworkManager::get()->dispatchControl(NET_CONNECTION_ESTABLISHED, SGX_STATIC_CAST(void *, cm));
		}
	}

	return 0;
}

tMEM_SIZE CSDLNetConnectionServer::MonitorMessages(CThread *pThread) 
{
	while(TRUE) {
		sgxYieldWait(1.0f);

		sgxVector<ClientMachine *>::iterator it = clients.begin();

		while(it != clients.end()) {
			// Poll for messages (from each client)
			int length = SDLNet_TCP_Recv((*it)->socket, &(*it)->messageBuffer[(*it)->idx], 512);

			if (length > 0) {

				// TODO Build a list of client and server instances on
				// each machine
				if (cbStreamHandler) {
					tUINT32 swallowSize = (*cbStreamHandler)(NULL, (*it)->messageBuffer, length); 
// sunb and copy
				} 
#if 0
				if (size > 0 && size <= idx) {
			CSGXNetworkManager::get()->dispatchPacket(*new CPacketType("text"), buffer, size);
			sgxMemmove(buffer, &buffer[size], idx-size);
			idx -= size;
				
					// TODO TEST
					messageBuffer
#endif			

			} else if (length < 0) {
			   // error 
			}
		}
	}
	return 0;
}

CSDLNetConnectionServer::CSDLNetConnectionServer(tUINT16 port, int flags)
{
	SDLNet_ResolveHost(&serverAddress, NULL, port);
	serverSocket = SDLNet_TCP_Open(&serverAddress);

	socketset = SDLNet_AllocSocketSet(2);
	SDLNet_TCP_AddSocket(socketset, serverSocket);


	pServerThread = CThreadManager::get()->create(monitor_connections, SGX_STATIC_CAST(void *, this)); 
	pServerThread->resume();

	CThreadManager::get()->create(monitor_messages, SGX_STATIC_CAST(void *, this)); 
}



// videos
// Talk - coldplay text
// Prez - islandin the stream, halle berry?
// sing for the moment - eminem - lyrics:carrera? that hit you
// naughty by nature - opp???