/*************************************************************************************************************
This file contains channel functions
2012/6 by Dlxko
**************************************************************************************************************/
#include "Channel.h"

// For getting packets lenght
static char char_packet_lenght[LENGHT_SIZE+1];
static int int_packet_lenght;

// For GIOchannel
static GIOStatus giostat;
static gchar gio_buffer[BUF_SIZE];
static gchar gio_buffer2[BUF_SIZE];
static gsize read_size;

// For actual position in buffer
static int position;

/********** Create channel ********/
bool create_channel()
{
	// Get channel
	gich = g_io_channel_win32_new_socket (s);
	if (!gich)
		return false;

	// Set encoding
	if(g_io_channel_set_encoding(gich, NULL, NULL) != G_IO_STATUS_NORMAL)
	{
		printf("GIOChannel initialization: can't change coding.\n");
		return false;
	}

	g_io_channel_set_close_on_unref(gich, TRUE);

	// Add watchdog
	event_id = g_io_add_watch_full( gich, 0, G_IO_IN, (GIOFunc)function_receive_socket, NULL, NULL );
	if (!event_id)
		return false;

	return true;
}

/************************ RECEIVE DATA ******************************/
gboolean function_receive_socket( GIOChannel   *channel, GIOCondition  cond)
{
	// Set looking packet position to null
	position = 0;

	// Clean sock_buffer and read incomming data from it
	memset(gio_buffer, 0, BUF_SIZE);
	giostat = g_io_channel_read_chars(gich, gio_buffer, sizeof(gio_buffer), &read_size, NULL);

	if (giostat == G_IO_STATUS_ERROR)
		function_show_warning ("Error while reading packet data!");

	// Get expected first lenght
	memset(char_packet_lenght, 0, LENGHT_SIZE+1);
	function_midcopy(gio_buffer, char_packet_lenght, 0, LENGHT_SIZE);
	int_packet_lenght = function_convert_packet_lenght(char_packet_lenght);

	// Only if some lenght found
	if(int_packet_lenght != 0)
	{
		// Process first packet
		memset(gio_buffer2, 0, BUF_SIZE);
		function_midcopy(gio_buffer, gio_buffer2, 0, int_packet_lenght);
		function_process_packet(gio_buffer2, int_packet_lenght);

		// Check if some data missing
		if (int_packet_lenght != (int)read_size)
		{
			// Set second position in buffer
			position = int_packet_lenght;

			// Process all packets
			do
			{
				// Get new buffer from new position
				memset(gio_buffer2, 0, BUF_SIZE);
				function_midcopy(gio_buffer, gio_buffer2, position, BUF_SIZE-position);

				// Get expected lenght again
				memset(char_packet_lenght, 0, LENGHT_SIZE+1);
				function_midcopy(gio_buffer2, char_packet_lenght, 0, LENGHT_SIZE);
				int_packet_lenght = function_convert_packet_lenght(char_packet_lenght);

				// If nothing in new buffer break
				if (int_packet_lenght != 0)
				{
					// Process datas or report error
					if (!function_process_packet(gio_buffer2, int_packet_lenght))
						function_show_warning("Error while processing packet");

					// Update position
					position = position + int_packet_lenght;
				}
			}
			while (int_packet_lenght != 0);
		}
	}

	return true;
}