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

#define _MESSAGES_CC_
#include <cstring>
#include <ctime>
#include <cstdio>
#include "messages.h"

Messages::Messages(void)
{
	for(int i = 0; i < CHANNELS_MAX; i++)
	{
		for(int ii = 0; ii < NUM_LINES; ii++)
		{
			channel_messages[i][ii] = NULL;
			has_format_chars[i][ii] = 0;
		}
		which_start_message[i] = NUM_LINES;
		how_many_entrys[i] = 0;
		has_changed[i] = 0;
	}
	return;
}

Messages::~Messages(void)
{
	for(int i = 0; i < CHANNELS_MAX; i++)
        {
                for(int ii = 0; ii < NUM_LINES; ii++)
                {
                        if(channel_messages[i][ii] != NULL) {
				delete[] channel_messages[i][ii];
				channel_messages[i][ii] = NULL;
			}
                }
        }
	return;
}

void Messages::SetMessage(int channel_num, char * new_message)
{
	int len = strlen(new_message);
	if(len > LINEBUF_LEN-1) {
		len = LINEBUF_LEN;
	} else {
		len++;
	}
	/* return when an impossible channel is queried */
	if((channel_num < 0) || (channel_num > CHANNELS_MAX-1)) return;
	has_changed[channel_num] = 1;
	
	/* find the position where we have to write */
	if(which_start_message[channel_num] > NUM_LINES-2) {
		which_start_message[channel_num] = 0;
	} else {
		which_start_message[channel_num]++;
	}
	/* delete the old allocated memory and write our
	 * entry in a new allocated memory               */
	int message = which_start_message[channel_num];
	if(channel_messages[channel_num][message] != NULL) {
		delete[] channel_messages[channel_num][message];
		channel_messages[channel_num][message] = NULL;
	}
	channel_messages[channel_num][message] = new char[len+1];
	strncpy(channel_messages[channel_num][message], new_message, len);
	channel_messages[channel_num][message][len] = '\0';

	has_format_chars[channel_num][message] = check_for_format_chars(channel_messages[channel_num][message]);

	/* count the entrys */
	how_many_entrys[channel_num]++;
	if(how_many_entrys[channel_num] > NUM_LINES) how_many_entrys[channel_num] = NUM_LINES;
	return;
}

int Messages::check_for_format_chars(char * string)
{
	if(string == NULL) return 0;
	if(string[0] == '\0') return 0;
	char *x = string;
	while(*x)
	{
		switch((unsigned int)*x) {
			case FORMAT_BOLD_NUM:
				return 1;
			case FORMAT_COLOR_NUM:
				return 1;
			case FORMAT_UNDERLINE_NUM:
				return 1;
			case FORMAT_RESET_NUM:
				return 1;
			default:
				break;
		}
		x++;
	}
	return 0;
}

char * Messages::GetMessage(int channel_num, int position)
{
	/* return NULL when an impossible channel or position is queried */
	if((channel_num < 0) || (channel_num > CHANNELS_MAX-1)) return NULL;
	if((position < 0) || (position > NUM_LINES-1)) return NULL;
	int our_position = which_start_message[channel_num] - position;
	if(our_position < 0)
		our_position += NUM_LINES;
	return channel_messages[channel_num][our_position];
}

int Messages::GetFormatOptions(int channel_num, int position)
{
	if((channel_num < 0) || (channel_num > CHANNELS_MAX-1)) return 0;
	if((position < 0) || (position > NUM_LINES-1)) return 0;
	int our_position = which_start_message[channel_num] - position;
	if(our_position < 0)
		our_position += NUM_LINES;
	return has_format_chars[channel_num][our_position];
}

int Messages::GetLinesNum(int channel_num)
{
	return how_many_entrys[channel_num];
}

void Messages::SetIrcChatMessage(int channel_num, char * nickname, char * message)
{
	if((channel_num < 0) || (channel_num >= CHANNELS_MAX)) return;
	long unix_time = time(NULL);
	struct tm * time_settings;
	time_settings = localtime((const time_t *)&unix_time);
	char tmp_msg[LINEBUF_LEN];
	char tmp_time[TIME_AND_NICKLEN]; /* [xx:xx]\0 */
	snprintf(tmp_time, TIME_AND_NICKLEN, "[%.2i:%.2i]", time_settings->tm_hour, time_settings->tm_min);
	int timelen = strlen(tmp_time);
	int num_spaces = TIME_AND_NICKLEN - (timelen + text_strlen(nickname));
	for(int i = 0; i < num_spaces; i++) strncat(tmp_time, " ", 1);
	snprintf(tmp_msg, LINEBUF_LEN, "%s %s> %s", tmp_time, nickname, message);
	SetMessage(channel_num, tmp_msg);
	return;
}

void Messages::EmptyMessages(int channel_num)
{
	if((channel_num < 0) || (channel_num > (CHANNELS_MAX-1))) return;
	if(how_many_entrys[channel_num] == 0) return;
	has_changed[channel_num] = 1;
	for(int i = 0; i < NUM_LINES; i++)
	{
		if(channel_messages[channel_num][i] != NULL) {
			delete[] channel_messages[channel_num][i];
			channel_messages[channel_num][i] = NULL; }
			has_format_chars[channel_num][i] = 0;
	}
	which_start_message[channel_num] = NUM_LINES;
	how_many_entrys[channel_num] = 0;
	return;
}

void Messages::SetChange(int tmp_channel, bool value)
{
	if((value != 0) && (value != 1)) return;
	if((tmp_channel < 0) || (tmp_channel > CHANNELS_MAX-1)) return;
	has_changed[tmp_channel] = value;
	return;
}

bool Messages::GetChange(int tmp_channel)
{
	if((tmp_channel < 0) || (tmp_channel > CHANNELS_MAX-1)) return 1;
	return has_changed[tmp_channel];
}

#undef _MESSAGES_CC_
