#include "ofTCPServer.h"
#include "ofTCPClient.h"

//--------------------------
ofTCPServer::ofTCPServer(){
	verbose		= true;
	connected	= false;
	count		= 0;
	port		= 0;
	str			= "";
	
	TCPConnections = new ofTCPClient[TCP_MAX_CLIENTS];
}

//--------------------------
ofTCPServer::~ofTCPServer(){
	close();
}

//--------------------------			
void ofTCPServer::setVerbose(bool _verbose){
	verbose = _verbose;
}

//--------------------------	
bool ofTCPServer::setup(int _port){
	if( !TCPServer.Create() ){
		if(verbose)printf("ofTCPServer: create() failed\n");
		return false;
	}
	if( !TCPServer.Bind(_port) ){
		if(verbose)printf("ofTCPServer: bind(port = %i) failed\n", _port);
		return false;
	}
	
	connected = true;
	port	  = _port;
	
	startThread(true, false);
	return true;
}

//--------------------------
bool ofTCPServer::close(){
	
	if(!connected) return true;
	
	for(int i = 0; i < count; i++){
		TCPConnections[i].close();
	}
	
	stopThread(); //stop the thread
	
	if( !TCPServer.Close() ){
		if(verbose)printf("ofTCPServer: unable to close connection\n");
		return false;
	}else{
		connected = false;
		return true;
	}
}

//--------------------------
bool ofTCPServer::disconnectClient(int clientID){
	if( !isClientSetup(clientID) ){
		if(verbose)printf("ofTCPServer: client %i doesn't exist\n", clientID);
		return false;
	}
	else if(TCPConnections[clientID].close()){
		return true;
	}
	return false;
}

//--------------------------
bool ofTCPServer::send(int clientID, string message){
	if( !isClientSetup(clientID) ){
		if(verbose)printf("ofTCPServer: client %i doesn't exist\n", clientID);
		return false;
	}
	else{
		TCPConnections[clientID].send(message);
		return true;
	}
}

//--------------------------
bool ofTCPServer::sendToAll(string message){
	if(count == 0) return false;

	for(int i = 0; i < count; i++){
		if(TCPConnections[i].isConnected())TCPConnections[i].send(message);
	}
	return true;
}

//--------------------------
string ofTCPServer::receive(int clientID){
	if( !isClientSetup(clientID) ){
		if(verbose)printf("ofTCPServer: client %i doesn't exist\n", clientID);
		return "client doesn't exist";
	}
	
	return TCPConnections[clientID].receive();
}		

//--------------------------
bool ofTCPServer::sendRawBytes(int clientID, const char * rawBytes, const int numBytes){
	if( !isClientSetup(clientID) ){
		if(verbose)printf("ofTCPServer: client %i doesn't exist\n", clientID);
		return false;
	}
	else{
		return TCPConnections[clientID].sendRawBytes(rawBytes, numBytes);
	}
}

//--------------------------
bool ofTCPServer::sendRawBytesToAll(const char * rawBytes, const int numBytes){
	if(count == 0 || numBytes <= 0) return false;

	for(int i = 0; i < count; i++){
		if(TCPConnections[i].isConnected())TCPConnections[i].sendRawBytes(rawBytes, numBytes);
	}
	return true;
}

//--------------------------
int ofTCPServer::getNumReceivedBytes(int clientID){
	if( !isClientSetup(clientID) ){
		if(verbose)printf("ofTCPServer: client %i doesn't exist\n", clientID);
		return 0;
	}
	
	return TCPConnections[clientID].getNumReceivedBytes();
}

//--------------------------
char * ofTCPServer::receiveRawBytes(int clientID){
	if( !isClientSetup(clientID) ){
		if(verbose)printf("ofTCPServer: client %i doesn't exist\n", clientID);
		return "client doesn't exist";
	}
	
	return TCPConnections[clientID].receiveRawBytes();
}		

//--------------------------
int ofTCPServer::receiveRawBytes(int clientID, char * receiveBytes){
	if( !isClientSetup(clientID) ){
		if(verbose)printf("ofTCPServer: client %i doesn't exist\n", clientID);
		return 0;
	}
	
	return TCPConnections[clientID].receiveRawBytes(receiveBytes);	
}

//--------------------------
int ofTCPServer::getClientPort(int clientID){
	if( !isClientSetup(clientID) ){
		if(verbose)printf("ofTCPServer: client %i doesn't exist\n", clientID);
		return 0;
	}
	else return TCPConnections[clientID].getPort();
}

//--------------------------
string ofTCPServer::getClientIP(int clientID){
	if( !isClientSetup(clientID) ){
		if(verbose)printf("ofTCPServer: client %i doesn't exist\n", clientID);
		return "000.000.000.000";
	}
	else return TCPConnections[clientID].getIP();
}

//--------------------------
int ofTCPServer::getNumClients(){
	return count;
}

//--------------------------
int ofTCPServer::getPort(){
	return port;
}	

//--------------------------
bool ofTCPServer::isConnected(){
	return connected;
}

//--------------------------		
bool ofTCPServer::isClientSetup(int clientID){
	return (clientID < count && clientID < TCP_MAX_CLIENTS); 
}

//--------------------------		
bool ofTCPServer::isClientConnected(int clientID){
	return isClientSetup(clientID) && TCPConnections[clientID].isConnected(); 
}

//don't call this
//--------------------------
void ofTCPServer::threadedFunction(){
				
	while( isThreadRunning() ){
		
		if(count == TCP_MAX_CLIENTS){
			if(verbose)printf("ofTCPServer: reached max connected clients! \nofTCPServer: no more connections accepted\n");
			break;
		}
		
		if( !TCPServer.Listen(TCP_MAX_CLIENTS) ){
			if(verbose)printf("ofTCPServer: Listen() failed\n");
		}
		
		if( !TCPServer.Accept(TCPConnections[count].TCPClient) ){
			if(verbose)printf("ofTCPServer: Accept() failed\n");
			continue;
		}else{
			TCPConnections[count].setup(count);
			count++;
			if(verbose)printf("ofTCPServer: client %i connected on port %i\n", count, TCPConnections[count].getPort());
		}
	}
	if(verbose)printf("ofTCPServer: listen thread ended\n");
}

	



