/*************************************************************************************************************
* This file contains accepting conections and disconecting client
* 2012/8 by Dlxko
* Version 3.0
**************************************************************************************************************/
#include "AcpDisClient.h"

// Local variables
static int counter;
static bool found;

// Signal if sth come to server def sock
void signal_accept_client()
{
	// If empty slots for connection continue
	if (clients_connected > (MAX_CLIENTS-1))
	{
		function_show_warning("Maximum clients connected!");
		return;
	}

	// Find empty client
	counter = RESET;
	found = false;
	do
	{
		if(!client[counter].connected)
		{
			found = true;
			break;
		}
		else ++counter;
	}
	while (counter < MAX_CLIENTS);

	// If no position break
	if (found == false)
	{
		function_show_error("Cant find empty position!");
		return;
	}

	// Get socket
	client[counter].socket = accept(server_socket, NULL, NULL);

	// No data in socket
	if (client[counter].socket == INVALID_SOCKET || client[counter].socket == SOCKET_ERROR)
	{
		function_show_error("Socket accept error!");
		return;
	}

	// Define as connected
	client[counter].connected = TRUE;

	//Make a new channel
	client[counter].client_gich = g_io_channel_win32_new_socket (client[counter].socket);
	if (!client[counter].client_gich)
	{
		function_show_error("Can't create channel for client!");
		return;
	}

	// Set encoding
	if(g_io_channel_set_encoding(client[counter].client_gich, NULL, NULL) != G_IO_STATUS_NORMAL)
	{
		function_show_error("Can't change coding for channel of client");
		return;
	}

	// Set closing
	g_io_channel_set_close_on_unref(client[counter].client_gich, TRUE);

	// Add watchdog
	client[counter].client_event_id = g_io_add_watch_full(client[counter].client_gich, 0, G_IO_IN, (GIOFunc)signal_receive_data, (gint*) client[counter].socket, NULL );
	if (!client[counter].client_event_id)
	{
		function_show_error("Can't create watchdog!");
		return;
	}

	// Write message
	memset(warnings_tmp, 0, WARNING_TMP_SIZE);
	sprintf_s(warnings_tmp, WARNING_TMP_SIZE, "Accept cln connect with sock [%d]", client[counter].socket);
	function_show_info(warnings_tmp);

	// Increase number of connected clients
	++clients_connected;

	// Update progress bar
	function_update_progress_clients();
}

// Function to disconnect some client
void function_disconnect_client ( _client *current_client )
{
	// Get buddy number
	counter = function_get_buddy_number(current_client->nick_name);

	// Only if connected
	if ( current_client->connected == TRUE )
		closesocket ( current_client->socket );

	// Update client state
	current_client->connected = FALSE;

	// Clear the address length
	current_client->return_value = -1;

	// Decrease number of connected clients
	clients_connected--;

	// Cleaup structure
	current_client->client_acess = 0;

	// Broad offline state
	function_buddy_status_update(counter, 2);

	//Clean name
	memset(current_client->nick_name, 0, DATA_ONE_SIZE);

	// Write message
	memset(warnings_tmp, 0, WARNING_TMP_SIZE);
	sprintf_s(warnings_tmp, WARNING_TMP_SIZE, "Disconnect cln with sock [%d]", current_client->socket);
	function_show_info(warnings_tmp);

	// Update progress bar
	function_update_progress_clients();
}