/*************************************************************************************************************
This file contains buddy functions
2012/6 by Dlxko
**************************************************************************************************************/
#include "Buddyactions.h"

// Buddy numbers for each stage
static int deleting_buddy;
static int newing_buddy;

// GTK variables
static GtkTreeIter iter;
static gint sortid;
static GtkSortType order;

static int counter;
static bool handler;

// Buffer for sending packets
static char sending_text[BUF_SIZE];
static int sending_text_len;
static char sending_text_len_char[LENGHT_SIZE+1];

// For nickname
static const gchar *entry_text_user;

// For pixmap error
static GError *px_error;

// For avatar file name
static gchar *file_avatar;

// Avatar handler
static GdkPixbuf *buddy_pixbuf;

// Event images variables
static GtkImage *px_event_00;
static GtkImage *px_event_01;
static GtkImage *px_event_02;
static GtkImage *px_event_03;
static GtkImage *px_event_04;
static GtkImage *px_event_05;
static GtkImage *px_event_06;
static GtkImage *px_event_07;
static GtkImage *px_event_08;
static GtkImage *px_event_09;

/******************************** Create new buddy in buddylist ***********************************/
int function_make_online(char nick_name[10])
{
	// Get buddy number
	newing_buddy = function_get_buddy_number(nick_name);

	// If some problem while searching for buddy
	if (newing_buddy == (MAX_BUDDIES + 1))
	{
		function_show_warning("Wrong buddy number for creating new online buddy!");
		buddy[newing_buddy].listed = false;
		return (MAX_BUDDIES + 1);
	}
	else
	{
		// Destroy old widget
		if (strlen(buddy[newing_buddy].nick_name) > 0)
			gtk_list_store_remove(buddy_tree_view, buddy[newing_buddy].tree_iter);
		else
			function_show_warning("Proble with buddy want's to do action but name doesnt exist?");

		// Create new row with this avatar
		file_avatar = g_strconcat("avatars/", buddy[newing_buddy].nick_name, ".png", NULL);
		buddy_pixbuf = gdk_pixbuf_new_from_file_at_scale(file_avatar, 25, 25, FALSE, &px_error);
		if (px_error)
		{
			function_show_warning("Can't load avatar for new online buddy - loading default!");
			buddy_pixbuf = default_buddy_pixbuf;
			g_error_free (px_error);
		}

		// Insert in the list
		gtk_list_store_append(buddy_tree_view, &buddy_iter);
		gtk_list_store_set(buddy_tree_view, &buddy_iter, PIXBUF_COL, buddy_pixbuf, TEXT_COL, buddy[newing_buddy].nick_name, TEXT_COL2, "Online", -1);
		buddy[newing_buddy].tree_iter = gtk_tree_iter_copy (&buddy_iter);

		// Sort list
		gtk_tree_sortable_set_sort_column_id(buddy_sortable_model, TEXT_COL2, GTK_SORT_DESCENDING);

		// Update buddy struct info
		buddy[newing_buddy].online = true;
		buddy[newing_buddy].listed = true;

		// Return its number
		return newing_buddy;
	}
}

/******************************** Buddy is offline action ***********************************/
bool function_make_offline(char nick_name[10])
{
	// Already existing buddy
	if (function_get_buddy_number(nick_name) != (MAX_BUDDIES + 1))
	{
		// Get buddy number
		deleting_buddy = function_get_buddy_number(nick_name);

		// Remove previous row
		if (strlen(buddy[deleting_buddy].nick_name) > 0)
			gtk_list_store_remove(buddy_tree_view, buddy[deleting_buddy].tree_iter);
		else
		{
			function_show_warning("Proble with buddy want's to do action but name doesnt exist?");
			return false;
		}

		// Create new row if showing offlines
		if (hidden_offlines == false)
		{
			// Create new row with this avatar
			file_avatar = g_strconcat("avatars/", buddy[deleting_buddy].nick_name, ".png", NULL);
			buddy_pixbuf = gdk_pixbuf_new_from_file_at_scale(file_avatar, 25, 25, FALSE, &px_error);
			if (px_error)
			{
				function_show_warning("Can't load avatar for new online->offline buddy - loading default!");
				buddy_pixbuf = default_buddy_pixbuf;
				g_error_free (px_error);
			}

			// Insert into list
			gtk_list_store_append(buddy_tree_view, &buddy_iter);
			gtk_list_store_set(buddy_tree_view, &buddy_iter, PIXBUF_COL, buddy_pixbuf, TEXT_COL, buddy[deleting_buddy].nick_name, TEXT_COL2, "Offline", -1);
			buddy[deleting_buddy].tree_iter = gtk_tree_iter_copy (&buddy_iter);
			buddy[deleting_buddy].listed = true;
		}
		else buddy[deleting_buddy].listed = false;

		// Update buddy struct info
		buddy[deleting_buddy].online = false;

		// Sort list
		gtk_tree_sortable_set_sort_column_id(buddy_sortable_model, TEXT_COL2, GTK_SORT_DESCENDING);

		// Return its number
		return true;
	}

	else // If new buddy comming set offline for default
	{
		// Next buddy
		++current_buddy;

		if(current_buddy > MAX_BUDDIES)
		{
			function_show_warning("Reached maximum limit of showed buddies!");
			return false;
		}

		// Create new row if showing offlines
		if (hidden_offlines == false)
		{
			// Create new row with this avatar
			file_avatar = g_strconcat("avatars/", nick_name, ".png", NULL);
			buddy_pixbuf = gdk_pixbuf_new_from_file_at_scale(file_avatar, 25, 25, FALSE, &px_error);
			if (px_error)
			{
				function_show_warning("Can't load avatar for new offline buddy - loading default!");
				buddy_pixbuf = default_buddy_pixbuf;
				g_error_free (px_error);
			}

			// Insert into list
			gtk_list_store_append(buddy_tree_view, &buddy_iter);
			gtk_list_store_set(buddy_tree_view, &buddy_iter, PIXBUF_COL, buddy_pixbuf, TEXT_COL, nick_name, TEXT_COL2, "Offline", -1);
			buddy[current_buddy].tree_iter = gtk_tree_iter_copy (&buddy_iter);
			buddy[current_buddy].listed = true;
		}
		else buddy[current_buddy].listed = false;

		// Update buddy struct info
		buddy[current_buddy].online = false;
		strcpy_s(buddy[current_buddy].nick_name, 10, nick_name);

		// Check name
		if (strlen(buddy[current_buddy].nick_name) < 0 || strlen(buddy[current_buddy].nick_name) > 10)
			function_show_warning("Saved wrong buddy name!");

		// Sort list
		gtk_tree_sortable_set_sort_column_id(buddy_sortable_model, TEXT_COL2, GTK_SORT_DESCENDING);

		// Return true
		return true;
	}
}

/******************************** Action after clicked buddy button ***********************************/
void function_create_chat(gint buddy_number)
{
	// if only hidden only show
	if(buddy[buddy_number].buddy_chat == true)
		gtk_widget_show(buddy[buddy_number].window);

	else // Other way is create new one
	{
		if (!(create_buddy_chat(buddy_number)))
			function_show_warning("Cant't create chat for this buddy!");
	}
}

/******************************** Hide offline buddies after signal ***********************************/
void function_buddy_hide()
{
	// Refresh counter
	counter = 0;

	do
	{
		// Of hiddening isn't online and want to hide and is also in buddy list
		if (hidden_offlines == false && buddy[counter].online == false && buddy[counter].listed == true && strlen(buddy[counter].nick_name))
		{
			// Remove row, change listed to false and set handler
			gtk_list_store_remove(buddy_tree_view, buddy[counter].tree_iter);
			buddy[counter].listed = false;
			handler = true;
		}
		// Else if hiddening isn't online and want to show and isn't in list
		else if (hidden_offlines == true && buddy[counter].listed == false && buddy[counter].online == false && strlen(buddy[counter].nick_name))
		{
			// Create new row with this avatar
			file_avatar = g_strconcat("avatars/", buddy[counter].nick_name, ".png", NULL);
			buddy_pixbuf = gdk_pixbuf_new_from_file_at_scale(file_avatar, 25, 25, FALSE, &px_error);
			if (px_error)
			{
				function_show_warning("Can't load avatar for new offline buddy - loading default!");
				buddy_pixbuf = default_buddy_pixbuf;
				g_error_free (px_error);
			}

			// Insert into list
			gtk_list_store_append(buddy_tree_view, &buddy_iter);
			gtk_list_store_set(buddy_tree_view, &buddy_iter, PIXBUF_COL, buddy_pixbuf, TEXT_COL, buddy[counter].nick_name, TEXT_COL2, "Offline", -1);
			buddy[counter].tree_iter = gtk_tree_iter_copy (&buddy_iter);

			// Sort list and update listed to true with handler
			gtk_tree_sortable_set_sort_column_id(buddy_sortable_model, TEXT_COL2, GTK_SORT_DESCENDING);
			buddy[counter].listed = true;
			handler = false;
		}

		++counter;
	}
	while (counter < MAX_BUDDIES);

	// Set global handler from local
	if (handler == true)
		hidden_offlines = true;
	else
		hidden_offlines = false;
}

/******************************** Adding new friend action ***********************************/
void signal_new_friend()
{
	entry_text_user = gtk_entry_get_text (GTK_ENTRY (new_friend_username));

	if(strlen(gtk_entry_get_text (GTK_ENTRY (new_friend_username))) > 0)
	{
		// Count lenght
		sending_text_len = LENGHT_SIZE + DATA_ONE_SIZE + OPCODE_SIZE;
		sprintf_s(sending_text_len_char, LENGHT_SIZE, "%d", sending_text_len);

		// Update text for server with "DX_OPCODE_SNT" and name datas
		memset(sending_text,0,BUF_SIZE);
		memcpy(sending_text, sending_text_len_char, LENGHT_SIZE);
		memcpy(&sending_text[LENGHT_SIZE], DX_OPCODE_NFR, OPCODE_SIZE);
		memcpy(&sending_text[LENGHT_SIZE+OPCODE_SIZE], entry_text_user, strlen(entry_text_user));

		// Send socket
		function_send_data(sending_text, sending_text_len);
	}
	else function_show_warning("Nothing entered or can't get text!");
}

/******************************** Creating buddy add window ***********************************/
void signal_create_buddy_adder()
{
	// New window, parameters, title, closing
	new_friend_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	if (!new_friend_window) function_show_warning("Can't create buddy adder window");
	gtk_widget_set_size_request (GTK_WIDGET (new_friend_window), 300, 50);
	gtk_window_set_title (GTK_WINDOW (new_friend_window), "Add friend");
	gtk_window_set_icon(GTK_WINDOW(new_friend_window), default_icon);

	// Create new box and container and show
	new_friend_vbox = gtk_vbox_new (FALSE, 0);
	if (!new_friend_vbox) function_show_warning("Can't create buddy adder vbox");
	gtk_container_add (GTK_CONTAINER (new_friend_window), new_friend_vbox);
	gtk_widget_show (new_friend_vbox);

	// Create text entry widget for username, lenght, set text, position, editable, pack, show
	new_friend_username = gtk_entry_new ();
	if (!new_friend_username) function_show_warning("Can't create buddy adder entry");
	gtk_entry_set_max_length (GTK_ENTRY (new_friend_username), 30);
	gtk_entry_set_text (GTK_ENTRY (new_friend_username), "Username");
	g_signal_connect (new_friend_username, "activate", G_CALLBACK (signal_new_friend), new_friend_username);
	gtk_editable_select_region (GTK_EDITABLE (new_friend_username), 0, GTK_ENTRY (new_friend_username)->text_length);
	gtk_box_pack_start (GTK_BOX (new_friend_vbox), new_friend_username, TRUE, TRUE, 0);
	gtk_widget_show (new_friend_username);

	// Create label, wrapping, pack, show
	new_friend_label = gtk_label_new ("");
	if (!new_friend_label) function_show_warning("Can't create buddy adder label");
	gtk_label_set_justify (GTK_LABEL (new_friend_label), GTK_JUSTIFY_FILL);
	gtk_label_set_line_wrap (GTK_LABEL (new_friend_label), TRUE);
	gtk_box_pack_start (GTK_BOX (new_friend_vbox), new_friend_label, FALSE, TRUE, 5);
	gtk_widget_show (new_friend_label);

	gtk_widget_show (new_friend_window);
}

/******************************** Show avivable requests in event window ***********************************/
void signal_show_requests()
{
	gtk_widget_show_all(requests_window);
}

void signal_requests_shut(GtkWidget *button, gint event_id)
{
	// Destroy event and clean name in memory
	gtk_widget_destroy(req_events[event_id].ok_button);
	gtk_widget_destroy(req_events[event_id].shut_button);
	gtk_widget_destroy(req_events[event_id].label);
	gtk_widget_destroy(req_events[event_id].hbox);
	gtk_widget_destroy(req_events[event_id].vbox);
	memset(req_events[event_id].nick_name, 0, DATA_ONE_SIZE);

	// Make inactive also decrease counter
	req_events[event_id].active = false;
	--activated_events;

	// Destroy previous button
	gtk_widget_destroy(buddy_requests);

	// Show requests
	if (activated_events == 0)
	{
		// Create new button
		buddy_requests = gtk_button_new_with_label("X");

		// If can't create report
		if(!buddy_requests)
			function_show_warning("Can't update events button!");
		else
			// Resize it!
			gtk_widget_set_size_request(buddy_requests, 35, 26);

		if(requests_window)
			gtk_widget_hide(requests_window);
		else
			function_show_warning("Can't hide requests window!");
	}
	else
	{
		// Create new button
		buddy_requests = gtk_button_new();

		// If can't create report
		if(!buddy_requests)
		{
			function_show_warning("Can't update events button with image!");
		}
		else
		{
			// Resize it!
			gtk_widget_set_size_request(buddy_requests, 35, 26);

			// Load event images - don't have to protect this already default image included
			px_event_00 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_00.png");
			px_event_01 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_01.png");
			px_event_02 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_02.png");
			px_event_03 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_03.png");
			px_event_04 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_04.png");
			px_event_05 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_05.png");
			px_event_06 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_06.png");
			px_event_07 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_07.png");
			px_event_08 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_08.png");
			px_event_09 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_09.png");

			// Get image of button
			if (activated_events == 1)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_01));
			else if (activated_events == 2)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_02));
			else if (activated_events == 3)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_03));
			else if (activated_events == 4)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_04));
			else if (activated_events == 5)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_05));
			else if (activated_events == 6)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_06));
			else if (activated_events == 7)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_07));
			else if (activated_events == 8)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_08));
			else if (activated_events == 9)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_09));
			else
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_00));

			// Attach signal
			g_signal_connect (G_OBJECT(buddy_requests), "clicked", G_CALLBACK (signal_show_requests), NULL);
		}
	}

	if (buddy_requests)
	{
		// Pack button into footer
		gtk_box_pack_start(GTK_BOX(buddy_hfooter), buddy_requests, FALSE, FALSE, 0);
		gtk_widget_show(buddy_requests);
	}

	// Count lenght
	sending_text_len = LENGHT_SIZE + 100 + OPCODE_SIZE;
	sprintf_s(sending_text_len_char, LENGHT_SIZE, "%d", sending_text_len);

	// Update text for server with "DX_OPCODE_DEV" and name datas
	memset(sending_text,0,BUF_SIZE);
	memcpy(sending_text, sending_text_len_char, LENGHT_SIZE);
	memcpy(&sending_text[LENGHT_SIZE], DX_OPCODE_DEV, OPCODE_SIZE);
	memcpy(&sending_text[LENGHT_SIZE+OPCODE_SIZE], req_events[event_id].id, strlen(req_events[event_id].id));

	// Send socket
	function_send_data(sending_text, sending_text_len);
}

void signal_requests_ok(GtkWidget *button, gint event_id)
{
	// Count lenght
	sending_text_len = LENGHT_SIZE + DATA_ONE_SIZE + OPCODE_SIZE;
	sprintf_s(sending_text_len_char, LENGHT_SIZE, "%d", sending_text_len);

	if (strlen(req_events[event_id].nick_name) > 0)
	{
		// Update text for server with "DX_OPCODE_NAR" and name datas
		memset(sending_text,0,BUF_SIZE);
		memcpy(sending_text, sending_text_len_char, LENGHT_SIZE);
		memcpy(&sending_text[LENGHT_SIZE], DX_OPCODE_NAR, OPCODE_SIZE);
		memcpy(&sending_text[LENGHT_SIZE+OPCODE_SIZE], req_events[event_id].nick_name, strlen(req_events[event_id].nick_name));

		// Send socket
		function_send_data(sending_text, sending_text_len);
	}

	// Destroy event widgets and clean name in memory
	gtk_widget_destroy(req_events[event_id].ok_button);
	gtk_widget_destroy(req_events[event_id].shut_button);
	gtk_widget_destroy(req_events[event_id].label);
	gtk_widget_destroy(req_events[event_id].hbox);
	gtk_widget_destroy(req_events[event_id].vbox);
	memset(req_events[event_id].nick_name, 0, DATA_ONE_SIZE);

	// Make non-active and decrease counter
	req_events[event_id].active = false;
	--activated_events;

	// Destroy previous button
	gtk_widget_destroy(buddy_requests);

	// Show requests
	if (activated_events == 0)
	{
		buddy_requests = gtk_button_new_with_label("X");
		if (!buddy_requests)
			function_show_warning("Can't update events button!");
		else
			gtk_widget_set_size_request(buddy_requests, 35, 26);

		if(requests_window)
			gtk_widget_hide(requests_window);
		else
			function_show_warning("Can't hide requests window!");
	}
	else
	{
		// Create new button
		buddy_requests = gtk_button_new();
		if (!buddy_requests)
		{
			function_show_warning("Can't update events button with image!");
		}
		else
		{
			// Resize
			gtk_widget_set_size_request(buddy_requests, 35, 26);

			// Load event images
			px_event_00 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_00.png");
			px_event_01 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_01.png");
			px_event_02 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_02.png");
			px_event_03 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_03.png");
			px_event_04 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_04.png");
			px_event_05 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_05.png");
			px_event_06 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_06.png");
			px_event_07 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_07.png");
			px_event_08 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_08.png");
			px_event_09 = (GtkImage *) gtk_image_new_from_file("images/core/px_event_09.png");

			// Get image of button
			if (activated_events == 1)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_01));
			else if (activated_events == 2)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_02));
			else if (activated_events == 3)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_03));
			else if (activated_events == 4)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_04));
			else if (activated_events == 5)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_05));
			else if (activated_events == 6)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_06));
			else if (activated_events == 7)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_07));
			else if (activated_events == 8)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_08));
			else if (activated_events == 9)
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_09));
			else
				gtk_button_set_image(GTK_BUTTON(buddy_requests), GTK_WIDGET(px_event_00));

			// Attach signal
			g_signal_connect (G_OBJECT(buddy_requests), "clicked", G_CALLBACK (signal_show_requests), NULL);
		}
	}

	// Pack button into footer
	if (buddy_requests)
	{
		gtk_box_pack_start(GTK_BOX(buddy_hfooter), buddy_requests, FALSE, FALSE, 0);
		gtk_widget_show(buddy_requests);
	}

	// Count lenght
	sending_text_len = LENGHT_SIZE + 100 + OPCODE_SIZE;
	sprintf_s(sending_text_len_char, LENGHT_SIZE, "%d", sending_text_len);

	// Update text for server with "DX_OPCODE_DEV" and name datas
	memset(sending_text,0,BUF_SIZE);
	memcpy(sending_text, sending_text_len_char, LENGHT_SIZE);
	memcpy(&sending_text[LENGHT_SIZE], DX_OPCODE_DEV, OPCODE_SIZE);
	memcpy(&sending_text[LENGHT_SIZE+OPCODE_SIZE], req_events[event_id].id, strlen(req_events[event_id].id));

	// Send socket
	function_send_data(sending_text, sending_text_len);

}