/*
 *      Code from:              Philipp Meinen
 *      Copyright (C):          2003-2004 Philipp Meinen
 *
 *      Email:                  lancelot@lancelot2k.dyndns.org
 *      Homepage:               http://lancelot2k.dyndns.org
 *      License:                GPL
 *                                                      */

#define _USERDB_CC_
#include <cstdio>
#include <cstring>
#include "userdb.h"

UserDB::UserDB(void)
{
	users = NULL;
	users = new Parameter * [CHANNELS_MAX];
	for(int i = 0; i < CHANNELS_MAX; i++)
	{
		users[i] = NULL;
		channel[i][0] = '\0';
	}
	return;
}

UserDB::~UserDB(void)
{
	if(users) {
		for(int i = 0; i < CHANNELS_MAX; i++)
			if(users[i]) delete users[i];
		delete[] users;
	}
	return;
}

void UserDB::Reset_UserDB(char * tmp_channel)
{
	string_tolower(tmp_channel); /* channelnames are stores lowercase */
	int index = Get_Index_for_Channel(tmp_channel);
	if((index < 0) || (index >= CHANNELS_MAX)) return;
	if(users[index]) {
		delete users[index];
		users[index] = NULL;
	}
	channel[index][0] = '\0';
	return;
}

void UserDB::Reset_All_UserDB(void)
{
	for(int i = 0; i < CHANNELS_MAX; i++)
		Reset_UserDB(i);
	return;
}

void UserDB::Init_UserDB(char * new_channel)
{
	if(new_channel == NULL) return;
	if(new_channel[0] == '\0') return;
	string_tolower(new_channel); /* channelnames are stores lowercase */
	/* is there allready a channel with this name? */
	int index = Get_Index_for_Channel(new_channel);
	if(index != -1) return;
	/* search for a left slot */
	index = -1;
	int i;
	int len = (signed)strlen(new_channel);
	if(len < 1) return;
	for(i = 0; i < CHANNELS_MAX; i++)
	{
		if((users[i] == NULL) && (channel[i][0] == '\0')) {
			index = i;
			break;
		}
	}
	if(index == -1) return;
	snprintf(channel[index], CHANNELS_NAME_LEN, "%s", new_channel);
	users[index] = new Parameter;
	return;
}

void UserDB::Add_User(char * new_user, char * tmp_channel)
{
	if(new_user == NULL || tmp_channel == NULL) return;
	if(new_user[0] == '\0' || tmp_channel[0] == '\0') return;
	string_tolower(tmp_channel); /* channelnames are stores lowercase */
	if(Is_User_in_Channel(new_user, tmp_channel) != -1) return; /* this user is allready in this channel */
	int index = Get_Index_for_Channel(tmp_channel);
	if(index == -1) return;
	users[index]->Add_Parameter(new_user);
	return;
}

void UserDB::Remove_User_from_Channel(char * tmp_user, char * tmp_channel)
{
	if(tmp_user == NULL || tmp_channel == NULL) return;
	if(tmp_user[0] == '\0' || tmp_channel[0] == '\0') return;
	string_tolower(tmp_channel); /* channelnames are stores lowercase */
	int index = Get_Index_for_Channel(tmp_channel);
	if(index == -1) return;
	int user_index = Is_User_in_Channel(tmp_user, tmp_channel);
	if(user_index == -1) return;
	users[index]->Remove_Parameter(user_index);
	return;
}

void UserDB::Remove_User_from_Channel(int user_index, char * tmp_channel)
{
	if(tmp_channel == NULL) return;
	if(tmp_channel[0] == '\0') return;
	string_tolower(tmp_channel); /* channelnames are stores lowercase */
	int index = Get_Index_for_Channel(tmp_channel);
	if(index == -1) return;
	users[index]->Remove_Parameter(user_index);
	return;
}

void UserDB::Remove_User_from_all_Channels(char * tmp_user)
{
	for(int i = 0; i < CHANNELS_MAX; i++)
	{
		if(channel[i][0] != '\0')
			Remove_User_from_Channel(tmp_user, channel[i]);
	}
	return;
}

int UserDB::Is_User_in_Channel(char * tmp_user, char * tmp_channel)
{
	if(tmp_user == NULL || tmp_channel == NULL) return -1;
	if(tmp_user[0] == '\0' || tmp_channel[0] == '\0') return -1;
	string_tolower(tmp_channel); /* channelnames are stores lowercase */
	int index = Get_Index_for_Channel(tmp_channel);
	if(index == -1) return -1;
	int num_users = users[index]->Get_Num_Parameter();
	/* read the first parameter */
	char * tmp_ptr = users[index]->GetFirstElement();
	if(tmp_ptr != NULL) {
		if(strcmp(tmp_ptr, tmp_user) == 0)
			return users[index]->Get_Last_Parameter();;
	}
	for(int i = 0; i <= num_users; i++)
	{
		tmp_ptr = users[index]->GetNextElement();
		if(tmp_ptr == NULL) continue;
		if(strcmp(tmp_ptr, tmp_user) == 0)
			return users[index]->Get_Last_Parameter();
	}
	return -1; /* name not found :.( */
}

int UserDB::Get_Index_for_Channel(char * tmp_channel)
{
	if(tmp_channel == NULL) return -1;
	if(tmp_channel[0] == '\0') return -1;
	string_tolower(tmp_channel); /* channelnames are stores lowercase */
	for(int i = 0; i < CHANNELS_MAX; i++) {
		if(strcmp(channel[i], tmp_channel) == 0) return i;
	}
	return -1;
}

void UserDB::Reset_UserDB(int index)
{
	if((index < 0) || (index >= CHANNELS_MAX)) return;
	if(users[index]) {
		delete users[index];
		users[index] = NULL;
	}
	channel[index][0] = '\0';
	return;
}

int UserDB::Get_Num_Users_in_Channel(char * tmp_channel)
{
	if(tmp_channel == NULL) return 0;
	if(tmp_channel[0] == '\0') return 0;
	string_tolower(tmp_channel); /* channelnames are stores lowercase */
	int index = Get_Index_for_Channel(tmp_channel);
	if(index == -1) return 0;
	return users[index]->Get_Num_Parameter();
}

void UserDB::ListUsersToScreen(char * search_pattern)
{
	int active_channel = Classes.IrcScreen->GetActiveChannel();
	int screen_type = Classes.IrcScreen->GetScreenType(active_channel);
	int screen_use = Classes.IrcScreen->GetScreenUse(active_channel);
	if(!active_channel || screen_type || !screen_use) {
		help_me("who");
		return;
	}
	int num_users_on_one_line = (((Classes.IrcScreen->GetScreenCols() - TIME_AND_NICKLEN) / NICKNAME_LEN));
	if(num_users_on_one_line < 1) num_users_on_one_line = 1;
	int bufferlen = (num_users_on_one_line * (NICKNAME_LEN+1)) + 1;
	char tmp_names[bufferlen];
	tmp_names[0] = '\0';
	int num_spaces = 0;
	char * nickname;
	char * channelname = Classes.IrcScreen->GetChannelName(active_channel);
	int index = Get_Index_for_Channel(channelname);
	if(index == -1) return; /* no such channel */
	int entrys = users[index]->Get_Num_Parameter();
	int allready_in_buffer = 0;
	int i, ii;
	int with_searchpattern = 0;
	if(search_pattern != NULL) {
		if(search_pattern[0] != '\0')
			with_searchpattern = 1;
	}
	for(i = 0; i < entrys; i++) {
		if(i == 0)
			nickname = users[index]->GetFirstElement();
		else
			nickname = users[index]->GetNextElement();
		if(!nickname) { /* end reached */
			if(tmp_names[0] != '\0') {
				Classes.MsgDB->SetIrcChatMessage(active_channel, DISPLAY_USERLIST, tmp_names);
			}
			break;
		}
		if(with_searchpattern) {
			if(!does_match_case_insensitive(nickname, search_pattern)) {
				goto dont_display;
			}
		}
		num_spaces = NICKNAME_LEN - strlen(nickname);
		if(num_spaces < 1) num_spaces = 1;
		strncat(tmp_names, nickname, NICKNAME_LEN);
		allready_in_buffer++;
		if(allready_in_buffer < num_users_on_one_line) {
			for(ii = 0; ii < num_spaces; ii++)
			{
				strcat(tmp_names, " ");
			}
		}
dont_display:
		if(((allready_in_buffer) == num_users_on_one_line) || (i == (entrys-1))) {
			Classes.MsgDB->SetIrcChatMessage(active_channel, DISPLAY_USERLIST, tmp_names);
			tmp_names[0] = '\0';
			allready_in_buffer = 0;
		}
	}
}

#undef _USERDB_CC_
