#include <stdio.h>
#include "thai_keymap.h"

int ThaiKeymapList_Init(TThaiKeymapList *pThaiKeymapList)
{
	pThaiKeymapList->nNum_Keymaps = 0;
	pThaiKeymapList->nNum_Keymaps_Alloced = 0;
	pThaiKeymapList->pKeymaps = NULL;

	return(THAI_KEYMAP_OK);
}

int ThaiKeymapList_Free(TThaiKeymapList *pThaiKeymapList)
{
	int i;

	if (pThaiKeymapList->pKeymaps == NULL) {
		return(0);
	}

	for(i=0; i<pThaiKeymapList->nNum_Keymaps_Alloced; i++) {
		if (pThaiKeymapList->pKeymaps[i]== NULL)
			continue;

		if (pThaiKeymapList->pKeymaps[i]->pName) {
			free((char *)pThaiKeymapList->pKeymaps[i]->pName);
		}

		if (pThaiKeymapList->pKeymaps[i]->pKeymap) {
			free((char *)pThaiKeymapList->pKeymaps[i]->pKeymap);
		}

		free((char *)pThaiKeymapList->pKeymaps[i]);
	}

	free((char *)pThaiKeymapList->pKeymaps);

	pThaiKeymapList->nNum_Keymaps = 0;
	pThaiKeymapList->nNum_Keymaps_Alloced = 0;
	pThaiKeymapList->pKeymaps = NULL;

	return(THAI_KEYMAP_OK);
}

int ThaiKeymapList_Alloc(TThaiKeymapList *pThaiKeymapList, int nNum_Alloced)
{
	int i;

	pThaiKeymapList->nNum_Keymaps_Alloced = 0;
	pThaiKeymapList->pKeymaps = (PThaiKeymap*)malloc(nNum_Alloced*sizeof(PThaiKeymap));
	if (pThaiKeymapList->pKeymaps == NULL) {
		return(THAI_KEYMAP_ERROR);
	}

	for (i=0; i<nNum_Alloced; i++)
		pThaiKeymapList->pKeymaps[i] = NULL;

	pThaiKeymapList->nNum_Keymaps_Alloced = nNum_Alloced;

	return(THAI_KEYMAP_OK);
}

int ThaiKeymapList_ReAlloc(TThaiKeymapList *pThaiKeymapList, int nNum_ReAlloced)
{
	int i;

	pThaiKeymapList->pKeymaps = (PThaiKeymap*)realloc(pThaiKeymapList->pKeymaps,
					nNum_ReAlloced * sizeof(PThaiKeymap));
	if (pThaiKeymapList->pKeymaps == NULL) {
		pThaiKeymapList->nNum_Keymaps = 0;
		pThaiKeymapList->nNum_Keymaps_Alloced = 0;
		return(THAI_KEYMAP_ERROR);
	}

	for (i=pThaiKeymapList->nNum_Keymaps_Alloced; i<nNum_ReAlloced; i++)
		pThaiKeymapList->pKeymaps[i] = NULL;

	pThaiKeymapList->nNum_Keymaps_Alloced = nNum_ReAlloced;

	return(THAI_KEYMAP_OK);
}

int ThaiKeymapList_Print(TThaiKeymapList *pThaiKeymapList)
{
	int nKeymap_ID, idx, key;

	printf("nNum_Keymaps: %d\n", pThaiKeymapList->nNum_Keymaps);
	for(nKeymap_ID = 0; nKeymap_ID < pThaiKeymapList->nNum_Keymaps; nKeymap_ID ++) {
		if (pThaiKeymapList->pKeymaps[nKeymap_ID] == NULL) {
			return(THAI_KEYMAP_ERROR);
		}

		if (pThaiKeymapList->pKeymaps[nKeymap_ID]->pName == NULL) {
			return(THAI_KEYMAP_ERROR);
		}

		if (pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap == NULL) {
			return(THAI_KEYMAP_ERROR);
		}

		printf("Name: %s\n", pThaiKeymapList->pKeymaps[nKeymap_ID]->pName);

		printf("Keymap: \n");
		for (idx = 1; idx <= THAI_KEYMAP_LEN; idx++) {
			key = pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap[idx];
			if (key != 0) {
				printf("%c:  %c  0x%x\n", idx + 0x20, key, key);
			}
		}
	}

	return(THAI_KEYMAP_OK);
}

int ThaiKeymapList_Item_Prepare(TThaiKeymapList *pThaiKeymapList, int nKeymap_ID)
{
	int ret;

	if (nKeymap_ID < 0 || nKeymap_ID >= pThaiKeymapList->nNum_Keymaps_Alloced + NUM_KEYMAPS_ALLOC)
		return(THAI_KEYMAP_ERROR);

	if (pThaiKeymapList->nNum_Keymaps_Alloced == 0) {
		ret = ThaiKeymapList_Alloc(pThaiKeymapList, NUM_KEYMAPS_ALLOC);
		if (ret == THAI_KEYMAP_ERROR)
			return(THAI_KEYMAP_ERROR);
	}

	if (nKeymap_ID >= pThaiKeymapList->nNum_Keymaps_Alloced) {
		int nNum_Alloc = pThaiKeymapList->nNum_Keymaps_Alloced + NUM_KEYMAPS_ALLOC;
		ret = ThaiKeymapList_ReAlloc(pThaiKeymapList, nNum_Alloc);
		if (ret == THAI_KEYMAP_ERROR)
			return(THAI_KEYMAP_ERROR);
	}

	if (pThaiKeymapList->pKeymaps[nKeymap_ID] == NULL) {
		pThaiKeymapList->pKeymaps[nKeymap_ID] = (TThaiKeymap *)calloc(1, sizeof(TThaiKeymap));
		if (pThaiKeymapList->pKeymaps[nKeymap_ID] == NULL)
			return(THAI_KEYMAP_ERROR);
	}

	if (pThaiKeymapList->pKeymaps[nKeymap_ID]->pName != NULL) {
		free((char *)pThaiKeymapList->pKeymaps[nKeymap_ID]->pName);
		pThaiKeymapList->pKeymaps[nKeymap_ID]->pName = NULL;
	}

	if (pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap != NULL) {
		free((char *)pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap);
		pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap = NULL;
	}
		
	return(THAI_KEYMAP_OK);
}

int ThaiKeymapList_Item_Set_Name(TThaiKeymapList *pThaiKeymapList, int nKeymap_ID, unsigned char *pName)
{
	if (!pName || !*pName) 
		return(THAI_KEYMAP_ERROR);

	if (nKeymap_ID < 0 || nKeymap_ID >= pThaiKeymapList->nNum_Keymaps_Alloced)
		return(THAI_KEYMAP_ERROR);

	if (pThaiKeymapList->pKeymaps[nKeymap_ID] == NULL) {
		return(THAI_KEYMAP_ERROR);
	}

	if (pThaiKeymapList->pKeymaps[nKeymap_ID]->pName != NULL) {
		free((char *)pThaiKeymapList->pKeymaps[nKeymap_ID]->pName);
	}

	pThaiKeymapList->pKeymaps[nKeymap_ID]->pName = (unsigned char *)strdup((char *)pName);
	if (pThaiKeymapList->pKeymaps[nKeymap_ID]->pName == NULL)
		return(THAI_KEYMAP_ERROR);

	return(THAI_KEYMAP_OK);
}

int ThaiKeymapList_Item_Set_KeymapValue(TThaiKeymapList *pThaiKeymapList, int nKeymap_ID, unsigned char key, unsigned char key_value)
{
	int idx;

	if (!key_value)
		return(THAI_KEYMAP_ERROR);

	if (key < 0x20 || key >= 0x80) 
		return(THAI_KEYMAP_ERROR);

	if (nKeymap_ID < 0 || nKeymap_ID >= pThaiKeymapList->nNum_Keymaps_Alloced)
		return(THAI_KEYMAP_ERROR);

	if (pThaiKeymapList->pKeymaps == NULL) {
		return(THAI_KEYMAP_ERROR);
	}

	if (pThaiKeymapList->pKeymaps[nKeymap_ID] == NULL) {
		return(THAI_KEYMAP_ERROR);
	}

	if (pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap == NULL) {
		pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap = (unsigned char *)calloc(THAI_KEYMAP_LEN + 1, sizeof(char));
		if (pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap == NULL)
			return(THAI_KEYMAP_ERROR);
		for (idx = 0; idx < THAI_KEYMAP_LEN; idx ++) {
			pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap[idx] = idx+0x20;
		}
	}
		
	pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap[key - 0x20] = key_value;
	return(THAI_KEYMAP_OK);
}

int ThaiKeymapList_Item_Add_Keymap(TThaiKeymapList *pThaiKeymapList, unsigned char *pName, unsigned char *pKeymap)
{
	int idx, ret;
	int nKeymap_ID;

	if (!pName || !*pName) 
		return(THAI_KEYMAP_ERROR);

	if (!pKeymap) 
		return(THAI_KEYMAP_ERROR);

	nKeymap_ID = pThaiKeymapList->nNum_Keymaps;
	ret = ThaiKeymapList_Item_Prepare(pThaiKeymapList, nKeymap_ID);
	if (ret == THAI_KEYMAP_ERROR)
		return(THAI_KEYMAP_ERROR);

	if (pThaiKeymapList->pKeymaps[nKeymap_ID]->pName != NULL) {
		free((char *)pThaiKeymapList->pKeymaps[nKeymap_ID]->pName);
	}

	pThaiKeymapList->pKeymaps[nKeymap_ID]->pName = (unsigned char *)strdup((char *)pName);
	if (pThaiKeymapList->pKeymaps[nKeymap_ID]->pName == NULL)
		return(THAI_KEYMAP_ERROR);

	if (pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap == NULL) {
		pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap = (unsigned char *)calloc(THAI_KEYMAP_LEN + 1, sizeof(char));
		if (pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap == NULL)
			return(THAI_KEYMAP_ERROR);
		for (idx = 0; idx < THAI_KEYMAP_LEN; idx ++) {
			pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap[idx] = idx+0x20;
		}
	}
		
	for (idx = 1; idx <= THAI_KEYMAP_LEN; idx++) {
		pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap[idx] = pKeymap[idx];
	}

	pThaiKeymapList->nNum_Keymaps ++;

	return(THAI_KEYMAP_OK);
}

int ThaiKeymapList_Item_Get_Symbol(TThaiKeymapList *pThaiKeymapList, int nKeymap_ID, int key)
{
	if (nKeymap_ID < 0 || nKeymap_ID >= pThaiKeymapList->nNum_Keymaps)
		return(key);

	if (key <= 0x20 || key >= 0x80) 
		return(key);

	if (pThaiKeymapList->pKeymaps == NULL ||
	    pThaiKeymapList->pKeymaps[nKeymap_ID] == NULL ||
	    pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap == NULL)
		return(key);

	return(pThaiKeymapList->pKeymaps[nKeymap_ID]->pKeymap[key - 0x20]);
}
