#include "../inc/swilib.h"
#include "siejc_ipc.h"
#include "smiles.h"

S_SMILES* s_top = 0;

DYNPNGICONLIST* SmilesImgList;

int smiles_max;
int smiles_loaded;

extern const char SMILE_FILE[];
extern const char SMILE_PATH[];
extern const char ipc_my_name[32];

static IPC_REQ gipc;
static char* p_buf;
static char* s_buf;
static S_SMILES* s_bot;
static int n_pic;

S_SMILES* FindSmileById(int n)
{
	int i = 0;
	S_SMILES* sl = (S_SMILES*)s_top;
	while(sl && i != n)
	{
		sl = sl->next;
		i++;
	}
	return sl;
}

S_SMILES* FindSmileByUni(int wchar)
{
	S_SMILES* sl = (S_SMILES*)s_top;
	while(sl)
	{
		if (sl->uni_smile == wchar) return (sl);
		sl = sl->next;
	}
	return (0);
}

void FreeSmiles(void)
{
	S_SMILES* s_smile;
	STXT_SMILES* n;
	STXT_SMILES* st;
	DYNPNGICONLIST* d;
	DYNPNGICONLIST* nd;
	LockSched();
	smiles_loaded = 0;
	smiles_max = 0;
	s_smile = (S_SMILES*)s_top;
	s_top = 0;
	s_bot = 0;
	UnlockSched();
	while(s_smile)
	{
		S_SMILES* s;
		s = s_smile;
		st = s->lines;
		while(st)
		{
			n = st->next;
			mfree(st);
			st = n;
		}
		s_smile = (S_SMILES*)(s_smile->next);
		mfree(s);
	}
	LockSched();
	d = SmilesImgList;
	SmilesImgList = 0;
	UnlockSched();
	while(d)
	{
		if (d->img)
		{
			mfree(d->img->bitmap);
			mfree(d->img);
		}
		nd = d->next;
		mfree(d);
		d = nd;
	}
	mfree(s_buf);
}

void CheckSmiles(void)
{
	int f;
	unsigned int err;
	int fsize;
	char* buf, *p_buf;
	FSTATS stat;

	if (GetFileStats(SMILE_FILE, &stat, &err) == -1)
		return;

	if ((fsize = stat.size) <= 0)
		return;

	if ((f = fopen(SMILE_FILE, A_ReadOnly + A_BIN, P_READ, &err)) == -1)
		return;

	buf = p_buf = malloc(fsize + 1);
	buf[fread(f, buf, fsize, &err)] = 0;
	fclose(f, &err);

	f = smiles_max;
	for(buf = p_buf; *buf; buf++)
		if(*buf == ':')
		{
			buf++;
			while(*buf && *buf != 0x0D) buf++;
			smiles_max++;
		}
	mfree(p_buf);
}

void InitSmiles(void)
{
	int f;
	unsigned int err;
	int fsize;
	char* buf;
	FSTATS stat;

	FreeSmiles();
	CheckSmiles();

	n_pic = FIRST_UCS2_BITMAP;
	if (GetFileStats(SMILE_FILE, &stat, &err) == -1)
		return;

	if ((fsize = stat.size) <= 0)
		return;

	if ((f = fopen(SMILE_FILE, A_ReadOnly + A_BIN, P_READ, &err)) == -1)
		return;

	buf = s_buf = p_buf = malloc(fsize + 1);
	buf[fread(f, buf, fsize, &err)] = 0;
	fclose(f, &err);

	gipc.name_to = ipc_my_name;
	gipc.name_from = ipc_my_name;
	gipc.data = 0;
	GBS_SendMessage(MMI_CEPID, MSG_IPC, IPC_SMILE_PROCESSED, &gipc);
}

void ProcessNextSmile(void)
{
	int c;
	char fn[128];
	DYNPNGICONLIST* dp;
	S_SMILES* si;
	STXT_SMILES* st;
	char* buf = p_buf;
	if (!buf) return;
	while ((c = *buf))
	{
		char* p;
		if ((c == 10) || (c == 13))
		{
			buf++;
			gipc.name_to = ipc_my_name;
			gipc.name_from = ipc_my_name;
			gipc.data = 0;
			GBS_SendMessage(MMI_CEPID, MSG_IPC, IPC_SMILE_PROCESSED, &gipc);
			p_buf = buf;
			return;
		}
		p = strchr(buf, ':');
		if (!p) break;
		zeromem(fn, 128);
		strcpy(fn, SMILE_PATH);
		if (fn[strlen(fn) - 1] != '\\') strcat(fn, "\\");
		c = p - buf;
		if (c > (127 - strlen(fn))) break;
		strncpy(fn + strlen(fn), buf, c);
		buf = p;
		dp = malloc(sizeof(DYNPNGICONLIST));
		zeromem(dp, sizeof(DYNPNGICONLIST));
		dp->icon = GetPicNByUnicodeSymbol(n_pic);
		dp->img = CreateIMGHDRFromPngFile(fn, 0);
		LockSched();
		if (SmilesImgList)
		{
			dp->next = SmilesImgList;
		}
		SmilesImgList = dp;
		UnlockSched();
		si = malloc(sizeof(S_SMILES));
		si->next = NULL;
		si->lines = NULL;
		si->botlines = NULL;
		si->uni_smile = n_pic;
		if (s_bot)
		{
			//Не первый
			s_bot->next = si;
			s_bot = si;
		}
		else
		{
			//Первый
			s_top = si;
			s_bot = si;
		}
		n_pic++;
		while (*buf != 10 && *buf != 13 && *buf != 0)
		{
			buf++;
			int i = 0;
			while (buf[i] != 0 && buf [i] != ',' && buf [i] != 10 && buf[i] != 13)  i++;
			st = malloc(sizeof(STXT_SMILES) + i);
			strncpy(st->text, buf, i);
			st->text[i] = 0;

			st->next = NULL;
			st->key = *((unsigned long*)st->text);
			st->mask = ~(0xFFFFFFFFUL << (8 * i));
			st->key &= st->mask;
			if (si->botlines)
			{
				si->botlines->next = st;
				si->botlines = st;
			}
			else
			{
				si->lines = st;
				si->botlines = st;
			}
			buf += i;
		}
		smiles_loaded++;
	}
	p_buf = NULL;
	mfree(s_buf);
	s_buf = NULL;
	REDRAW();
}
