#include <stdio.h>
#include <locale.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "hzinput.h"
#include "encode.h"

#define MAX_LINE_LEN	256

/*  Auxiliary Window User Input Method Information  */
IMEListRec	AllIMEList, SelectedIMEList;

extern char 	gLocaleID;

IMEBaseRec *IMEItem_Malloc()
{
	IMEBaseRec *pIME_Base;

	pIME_Base = (IMEBaseRec *)calloc(1, sizeof(IMEBaseRec));
	if (pIME_Base == NULL) return(NULL);

	pIME_Base->ename = NULL;
	pIME_Base->cname = NULL;

	return(pIME_Base);
}

void IMEItem_Free(IMEBaseRec *pIME_Base)
{
	if (pIME_Base == NULL) return;

	if (pIME_Base->ename) free((char *)pIME_Base->ename);
	if (pIME_Base->cname) free((char *)pIME_Base->cname);

	free((char *)pIME_Base);
}

void IMEList_Init()
{
	int i;

	AllIMEList.nIME_Num = 0;
	SelectedIMEList.nIME_Num = 0;

	for (i = 0 ; i < MAX_ENGINE_NUM ; i++) {
		AllIMEList.arrIME_Base[i] = NULL;
		SelectedIMEList.arrIME_Base[i] = NULL;
	}
}

void IMEList_Free()
{
	int i;

	for (i = 0 ; i < MAX_ENGINE_NUM ; i++) {
		if (AllIMEList.arrIME_Base[i] != NULL) {
			IMEItem_Free(AllIMEList.arrIME_Base[i]);
			AllIMEList.arrIME_Base[i] = NULL;
		}
	}

	AllIMEList.nIME_Num = 0;
	SelectedIMEList.nIME_Num = 0;
}

void Add_IME_To_AllList(IMEBaseRec *baseinfo)
{
	int engine_num, engine_locale_id, system_locale_id, encode_id;
	int ilen, olen, ret, nIME_Num;
	char *engine_cname, *ime_cname, tmp_name[256];
	IMEBaseRec *pIME_Base;

	engine_locale_id = baseinfo->locale_id;
	system_locale_id = gLocaleID;

	logf("locale_id:%d, engine_id:%d, status:%d, ename:%s, cname:%s\n",
		baseinfo->locale_id,
		baseinfo->engine_id,
		baseinfo->status,
		baseinfo->ename,
		baseinfo->cname);
	
	/* if is ENCODES_NUM, means this engine is a common engine for this language. */
	if (engine_locale_id != system_locale_id && engine_locale_id != ENCODES_NUM)
		return;

	if (baseinfo->status == ENGINE_NOT_INSTALLED)
		return;

	nIME_Num = AllIMEList.nIME_Num;
	pIME_Base = AllIMEList.arrIME_Base[nIME_Num];
	if (pIME_Base != NULL) IMEItem_Free(pIME_Base);
	AllIMEList.arrIME_Base[nIME_Num] = NULL;

	pIME_Base = (IMEBaseRec *)IMEItem_Malloc();
	if (pIME_Base == NULL) return;

	pIME_Base->engine_id = baseinfo->engine_id;
	pIME_Base->locale_id = baseinfo->locale_id;
	pIME_Base->encode_id = baseinfo->encode_id;
	pIME_Base->status = baseinfo->status;
	pIME_Base->ename = (char *)strdup(baseinfo->ename);
	
	/* convert IME name to native encoding. */
	/* Usually: IME name is in UTF-8 or native encoding */
	encode_id = pIME_Base->encode_id;
	if (encode_id == ENCODE_UTF8) {
		engine_cname = (char *)baseinfo->cname;
		ilen = strlen((char *)engine_cname);
		ime_cname = tmp_name;
		olen = 256;
		memset(ime_cname, 0, olen);
		ret = Convert_UTF8_To_Native(system_locale_id, engine_cname, ilen, &ime_cname, &olen);
		logf("ret:%d, ime_cname:%s, olen:%d\n", ret, ime_cname, olen);
		if (ret == 0)
			pIME_Base->cname = (char *)strdup(tmp_name);
		else
			pIME_Base->cname = (char *)strdup(baseinfo->ename);
	} else {
		pIME_Base->cname = (char *)strdup(baseinfo->cname);
	}

	AllIMEList.arrIME_Base[nIME_Num] = pIME_Base;
	nIME_Num ++;
	AllIMEList.nIME_Num = nIME_Num;
}

void get_ime_line(FILE *fd, char *line)
{
	int line_ptr;
	char line_buf[256], *ptr;

	line_ptr = 0;
	line[0] = '\0';

	/* get line with no space */
 	while(fgets(line_buf, 255, fd) != NULL) {
		ptr = line_buf;

		/* skip space keys */
		while(*ptr && isspace(*ptr)) ptr++;

		/* if is space line, get new line */
		if (*ptr == '\n' || *ptr == '\0')
			continue;

		while(*ptr != '\n' && *ptr != '\0' && line_ptr < MAX_LINE_LEN) 
			line[line_ptr++] = *ptr++;

		/* trim right space */
		while (isspace(line[line_ptr-1])) line_ptr--;
		line[line_ptr] = '\0';

		/* if the line end with '\', then continue read the next line */
		if (line[line_ptr-1] == '\\') {
			line_ptr--;
			line[line_ptr] = '\0';
			continue;
		}

		break;
	}
}

void Select_IMEs_From_Profile()
{
    	char            file_name[256], line[MAX_LINE_LEN]; 
	int 		i, nInstalledIME;
    
	register char 	*ptr, *ime_name;
	FILE 		*fd;

	char 		*locale_name;

	if (AllIMEList.nIME_Num == 0) return;

	locale_name = setlocale(LC_CTYPE, NULL);

	/* read profile from file to memory buffer  */ 
	sprintf(file_name, "%s/%s/%s/%s", getenv("HOME"), 
		USER_PROFILE_PATH, locale_name, USER_PROFILE_NAME);
	logf("file name :%s\n",file_name);

	fd = fopen(file_name, "r");
	if (! fd) {
		SelectedIMEList = AllIMEList;
		return;
	}

	nInstalledIME = 0;
	do {
		get_ime_line(fd, line);

		if (line[0] == '\0') break;
		if (line[0] == '#') continue;

		/* get IME language engine name */
		ime_name = line;

		logf("IME Name:%s\n", ime_name);
		for (i=0; i<AllIMEList.nIME_Num; i++) {
			if (strcasecmp(ime_name, AllIMEList.arrIME_Base[i]->ename)) {
				continue;
			} else {
				SelectedIMEList.arrIME_Base[nInstalledIME] = AllIMEList.arrIME_Base[i];
				nInstalledIME ++;
				break;
			}
		}
	} while (1);

	fclose(fd);
	
	if (nInstalledIME == 0) 
		SelectedIMEList = AllIMEList;
	else
		SelectedIMEList.nIME_Num = nInstalledIME;

	for (i=0; i<SelectedIMEList.nIME_Num; i++) {
		logf("localeid:%d, ename:%s, cname:%s, imid:%d, status:%d\n", 
			SelectedIMEList.arrIME_Base[i]->locale_id,
			SelectedIMEList.arrIME_Base[i]->ename,
			SelectedIMEList.arrIME_Base[i]->cname,
			SelectedIMEList.arrIME_Base[i]->engine_id,
			SelectedIMEList.arrIME_Base[i]->status);
	}

    	return;
}

void Save_IMEList_To_Profile(IMEListRec *imelist)
{
	FILE *fd;
	int ret, i;
	struct stat file_stat;
	char path_name[256], tmp_name[256];
	char *locale_name;

	/* Create Path $(HOME)/.Xlocale */
	sprintf(path_name, "%s/%s", (char *)getenv("HOME"), USER_PROFILE_PATH);
	logf("path_name: %s\n", path_name);

	ret = stat(path_name, &file_stat);
	if (ret == -1) {
		logf("%s not exist\n", path_name);
		ret = mkdir(path_name, 0777);
		if (ret == -1) {
			logf("can not create path %s\n", path_name);
			return;
		}
	}

	/* Create Path $(HOME)/.Xlocale/<locale> */
	locale_name = setlocale(LC_CTYPE, NULL);

	sprintf(tmp_name, "%s/%s", path_name, locale_name);
	strcpy(path_name, tmp_name);

	ret = stat(path_name, &file_stat);
	if (ret == -1) {
		logf("%s not exist\n", path_name);
		ret = mkdir(path_name, 0777);
		if (ret == -1) {
			logf("can not create path %s\n", path_name);
			return;
		}
	}

	/* Create File $(HOME)/.Xlocale/<locale>/ime.cfg */
	sprintf(tmp_name, "%s/%s", path_name, USER_PROFILE_NAME);
	strcpy(path_name, tmp_name);
	logf("path_name: %s\n", path_name);
	fd = fopen(path_name, "wb");
	if (! fd) {
		logf("unable open the file: %s\n", path_name);
		return;
	}

	for (i=0; i<imelist->nIME_Num; i++) {
		fprintf(fd, "%s\n", imelist->arrIME_Base[i]->ename);
	}

	fclose(fd);
}
