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

#define MAX_LINE_LEN    256

#define KEYMAP_STRING           "keymap"
#define KEYMAP_NAME_STRING      "name"

enum {
	THAI_DEFAULT_SECTION = 0,
	THAI_KEYMAP_SECTION,
};

/**************************************************************
The format of Thai configure file as follow:

[keymap name="ThaiKeymapName"]
key     ThaiSymbol_Lower  ThaiSymbol_Upper

**************************************************************/

#define THAI_STANDARD_KEYMAP_NUM  3

# if 0
/* Thai Keymap on Solaris 8 */
unsigned char _Thai_Enhanced_Kedmanee_Keymap[97] = {
/*        !     "     #     $     %     &     '     (     )     *     +     ,     -     .     /      */
/*        +     .     ò     ó     ô     ß     §     ö     ÷     õ     ù     Á     ¢     ã     ½      */
    0x20, 0x2b, 0x2e, 0xf2, 0xf3, 0xf4, 0xdf, 0xa7, 0xf6, 0xf7, 0xf5, 0xf9, 0xc1, 0xa2, 0xe3, 0xbd, 
/*  0     1     2     3     4     5     6     7     8     9     :     ;     <     =     >     ?      */
/*  ¨     å     /     -     À     ¶     Ø     Ö     ¤     µ     «     Ç     ²     ª     Ì     Æ      */
    0xa8, 0xe5, 0x2f, 0x2d, 0xc0, 0xb6, 0xd8, 0xd6, 0xa4, 0xb5, 0xab, 0xc7, 0xb2, 0xaa, 0xcc, 0xc6, 
/*  @     A     B     C     D     E     F     G     H     I     J     K     L     M     N     O      */
/*  ñ     Ä     Ú     ©     ¯     ®     â     ¬     ç     ³     ë     É     È     ?     ì     Ï      */
    0xf1, 0xc4, 0xda, 0xa9, 0xaf, 0xae, 0xe2, 0xac, 0xe7, 0xb3, 0xeb, 0xc9, 0xc8, 0x3f, 0xec, 0xcf, 
/*  P     Q     R     S     T     U     V     W     X     Y     Z     [     \     ]     ^     _      */
/*  ­     ð     ±     ¦     ¸     ê     Î     "     )     í     (     º     _     Å     Ù     ø      */
    0xad, 0xf0, 0xb1, 0xa6, 0xb8, 0xea, 0xce, 0x22, 0x29, 0xed, 0x28, 0xba, 0x5f, 0xc5, 0xd9, 0xf8, 
/*  `     a     b     c     d     e     f     g     h     i     j     k     l     m     n     o      */
/*  £     ¿     Ô     á     ¡     Ó     ´     à     é     Ã     è     Ò     Ê     ·     ×     ¹      */
    0xa3, 0xbf, 0xd4, 0xe1, 0xa1, 0xd3, 0xb4, 0xe0, 0xe9, 0xc3, 0xe8, 0xd2, 0xca, 0xb7, 0xd7, 0xb9, 
/*  p     q     r     s     t     u     v     w     x     y     z     {     |     }     ~            */
/*  Â     æ     ¾     Ë     Ð     Õ     Í     ä     »     Ñ     ¼     °     %     ,     ¥            */
    0xc2, 0xe6, 0xbe, 0xcb, 0xd0, 0xd5, 0xcd, 0xe4, 0xbb, 0xd1, 0xbc, 0xb0, 0x25, 0x2c, 0xa5, 0x7f, 
};
#endif

unsigned char _Thai_Enhanced_Kedmanee_Keymap[97] = {
/*        !     "     #     $     %     &     '     (     )     *     +     ,     -     .     /      */
/*        å     .     ò     ó     ô     î     §     ö     ÷     õ     ù     Á     ¢     ã     ½      */
    0x20, 0xe5, 0x2e, 0xf2, 0xf3, 0xf4, 0xee, 0xa7, 0xf6, 0xf7, 0xf5, 0xf9, 0xc1, 0xa2, 0xe3, 0xbd, 
/*  0     1     2     3     4     5     6     7     8     9     :     ;     <     =     >     ?      */
/*  ¨     ß     /     -     À     ¶     Ø     Ö     ¤     µ     «     Ç     ²     ª     Ì     Æ      */
    0xa8, 0xdf, 0x2f, 0x2d, 0xc0, 0xb6, 0xd8, 0xd6, 0xa4, 0xb5, 0xab, 0xc7, 0xb2, 0xaa, 0xcc, 0xc6, 
/*  @     A     B     C     D     E     F     G     H     I     J     K     L     M     N     O      */
/*  ñ     Ä     Ú     ©     ¯     ®     â     ¬     ç     ³     ë     É     È     ?     ì     Ï      */
    0xf1, 0xc4, 0xda, 0xa9, 0xaf, 0xae, 0xe2, 0xac, 0xe7, 0xb3, 0xeb, 0xc9, 0xc8, 0x3f, 0xec, 0xcf, 
/*  P     Q     R     S     T     U     V     W     X     Y     Z     [     \     ]     ^     _      */
/*  ­     ð     ±     ¦     ¸     ê     Î     "     )     í     (     º     ¥     Å     Ù     ø      */
    0xad, 0xf0, 0xb1, 0xa6, 0xb8, 0xea, 0xce, 0x22, 0x29, 0xed, 0x28, 0xba, 0xa5, 0xc5, 0xd9, 0xf8, 
/*  `     a     b     c     d     e     f     g     h     i     j     k     l     m     n     o      */
/*  ï     ¿     Ô     á     ¡     Ó     ´     à     é     Ã     è     Ò     Ê     ·     ×     ¹      */
    0xef, 0xbf, 0xd4, 0xe1, 0xa1, 0xd3, 0xb4, 0xe0, 0xe9, 0xc3, 0xe8, 0xd2, 0xca, 0xb7, 0xd7, 0xb9, 
/*  p     q     r     s     t     u     v     w     x     y     z     {     |     }     ~            */
/*  Â     æ     ¾     Ë     Ð     Õ     Í     ä     »     Ñ     ¼     °     £     ,     û            */
    0xc2, 0xe6, 0xbe, 0xcb, 0xd0, 0xd5, 0xcd, 0xe4, 0xbb, 0xd1, 0xbc, 0xb0, 0xa3, 0x2c, 0xfb, 0x7f, 
};

unsigned char _Thai_Kedmanee_Keymap[97] = {
/*        !     "     #     $     %     &     '     (     )     *     +     ,     -     .     /      */
/*        +     .     ò     ó     ô     ß     §     ö     ÷     õ     ù     Á     ¢     ã     ½      */
    0x20, 0x2b, 0x2e, 0xf2, 0xf3, 0xf4, 0xdf, 0xa7, 0xf6, 0xf7, 0xf5, 0xf9, 0xc1, 0xa2, 0xe3, 0xbd, 
/*  0     1     2     3     4     5     6     7     8     9     :     ;     <     =     >     ?      */
/*  ¨     å     /     -     À     ¶     Ø     Ö     ¤     µ     «     Ç     ²     ª     Ì     Æ      */
    0xa8, 0xe5, 0x2f, 0x2d, 0xc0, 0xb6, 0xd8, 0xd6, 0xa4, 0xb5, 0xab, 0xc7, 0xb2, 0xaa, 0xcc, 0xc6, 
/*  @     A     B     C     D     E     F     G     H     I     J     K     L     M     N     O      */
/*  ñ     Ä     Ú     ©     ¯     ®     â     ¬     ç     ³     ë     É     È     ?     ì     Ï      */
    0xf1, 0xc4, 0xda, 0xa9, 0xaf, 0xae, 0xe2, 0xac, 0xe7, 0xb3, 0xeb, 0xc9, 0xc8, 0x3f, 0xec, 0xcf, 
/*  P     Q     R     S     T     U     V     W     X     Y     Z     [     \     ]     ^     _      */
/*  ­     ð     ±     ¦     ¸     ê     Î     "     )     í     (     º     £     Å     Ù     ø      */
    0xad, 0xf0, 0xb1, 0xa6, 0xb8, 0xea, 0xce, 0x22, 0x29, 0xed, 0x28, 0xba, 0xa3, 0xc5, 0xd9, 0xf8, 
/*  `     a     b     c     d     e     f     g     h     i     j     k     l     m     n     o      */
/*  _     ¿     Ô     á     ¡     Ó     ´     à     é     Ã     è     Ò     Ê     ·     ×     ¹      */
    0x5f, 0xbf, 0xd4, 0xe1, 0xa1, 0xd3, 0xb4, 0xe0, 0xe9, 0xc3, 0xe8, 0xd2, 0xca, 0xb7, 0xd7, 0xb9, 
/*  p     q     r     s     t     u     v     w     x     y     z     {     |     }     ~            */
/*  Â     æ     ¾     Ë     Ð     Õ     Í     ä     »     Ñ     ¼     °     ¥     ,     %            */
    0xc2, 0xe6, 0xbe, 0xcb, 0xd0, 0xd5, 0xcd, 0xe4, 0xbb, 0xd1, 0xbc, 0xb0, 0xa5, 0x2c, 0x25, 0x7f, 
};

unsigned char _Thai_Pattachote_Keymap[97] = {
/*        !     "     #     $     %     &     '     (     )     *     +     ,     -     .     /      */
/*        +     .     ò     ó     ô     ß     §     ö     ÷     õ     ù     Á     ¢     ã     ½      */
    0x20, 0x2b, 0x2e, 0xf2, 0xf3, 0xf4, 0xdf, 0xa7, 0xf6, 0xf7, 0xf5, 0xf9, 0xc1, 0xa2, 0xe3, 0xbd, 
/*  0     1     2     3     4     5     6     7     8     9     :     ;     <     =     >     ?      */
/*  ¨     å     /     -     À     ¶     Ø     Ö     ¤     µ     «     Ç     ²     ª     Ì     Æ      */
    0xa8, 0xe5, 0x2f, 0x2d, 0xc0, 0xb6, 0xd8, 0xd6, 0xa4, 0xb5, 0xab, 0xc7, 0xb2, 0xaa, 0xcc, 0xc6, 
/*  @     A     B     C     D     E     F     G     H     I     J     K     L     M     N     O      */
/*  "     Ä     Ú     ©     ¯     ®     â     ¬     ç     ³     ë     É     È     ?     ì     Ï      */
    0x22, 0xc4, 0xda, 0xa9, 0xaf, 0xae, 0xe2, 0xac, 0xe7, 0xb3, 0xeb, 0xc9, 0xc8, 0x3f, 0xec, 0xcf, 
/*  P     Q     R     S     T     U     V     W     X     Y     Z     [     \     ]     ^     _      */
/*  ­     ð     ±     ¦     ¸     ê     Î     "     )     í     (     º     _     Å     Ù     ø      */
    0xad, 0xf0, 0xb1, 0xa6, 0xb8, 0xea, 0xce, 0x22, 0x29, 0xed, 0x28, 0xba, 0x5f, 0xc5, 0xd9, 0xf8, 
/*  `     a     b     c     d     e     f     g     h     i     j     k     l     m     n     o      */
/*  £     ¿     Ô     á     ¡     Ó     ´     à     é     Ã     è     Ò     Ê     ·     ×     ¹      */
    0xa3, 0xbf, 0xd4, 0xe1, 0xa1, 0xd3, 0xb4, 0xe0, 0xe9, 0xc3, 0xe8, 0xd2, 0xca, 0xb7, 0xd7, 0xb9, 
/*  p     q     r     s     t     u     v     w     x     y     z     {     |     }     ~            */
/*  Â     æ     ¾     Ë     Ð     Õ     Í     ä     »     Ñ     ¼     °     %     ,     ¥            */
    0xc2, 0xe6, 0xbe, 0xcb, 0xd0, 0xd5, 0xcd, 0xe4, 0xbb, 0xd1, 0xbc, 0xb0, 0x25, 0x2c, 0xa5, 0x7f, 
};

/*
TThaiKeymap Thai_Standard_Keymaps[THAI_STANDARD_KEYMAP_NUM] = {
	{ (unsigned char *)"à¡ÉÁ³Õ (ÁÍ¡.øòð-òõóø)",  _Thai_Enhanced_Kedmanee_Keymap},
	{ (unsigned char *)"à¡ÉÁ³Õ",                 _Thai_Kedmanee_Keymap         },
	{ (unsigned char *)"»ÑµµÐâªµÔ",               _Thai_Pattachote_Keymap        }
};
*/

TThaiKeymap Thai_Standard_Keymaps[THAI_STANDARD_KEYMAP_NUM] = {
	{ (unsigned char *)"Enhanced Kedmanee(TIS820-2538)",     _Thai_Enhanced_Kedmanee_Keymap},
	{ (unsigned char *)"Kedmanee(TIS820-2531)",     _Thai_Kedmanee_Keymap         },
	{ (unsigned char *)"Pattachote",  _Thai_Pattachote_Keymap       }
};

char get_upper_key(char ch)
{
	static char lower_keys[] = "`1234567890-=qwertyuiop[]\\asdfghjkl;\'zxcvbnm,./";
	static char upper_keys[] = "~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?";

	int i, len;

	ch = tolower(ch);

	len = strlen(lower_keys);
	for (i=0; i< len; i++) {
		if (ch == lower_keys[i]) {
			return(upper_keys[i]);
		}
	}

	return(0);
}

char *skip_space(char *s)
{
        while (*s && (*s == ' ' || *s == '\t')) s++;
        return s;
}

char *to_space(char *s)
{
	while (*s && !(*s == ' ' || *s == '\t')) s++;
        return s;
}

char *trim_string(char *s)
{
	char *head_ptr, *tail_ptr;

	if (!s || !*s) return(s);

	head_ptr = s;

	/* trim left space */
	while(*head_ptr && (*head_ptr == ' ' || *head_ptr == '\t' || *head_ptr == '\n'))
		head_ptr ++;

	if (!*head_ptr) return(head_ptr);

	/* trim right space */
	tail_ptr = head_ptr + strlen(head_ptr) - 1;
	
	while(*tail_ptr && (*tail_ptr == ' ' || *tail_ptr == '\t' || *tail_ptr == '\n')) {
		*tail_ptr = '\0';
		tail_ptr --;
	}

	return(head_ptr);
}

int parse_line_for_pair(char *line_buf, char **key_ptr, char **value_ptr)
{
	char *ptr;

	*key_ptr = ptr = skip_space(line_buf);

	while(*ptr && !(*ptr==' ' || *ptr=='\t' || *ptr=='\n' || *ptr=='=' || *ptr==':')) ptr++;

	if (*ptr=='=' || *ptr==':') {
		*ptr = '\0';
		ptr = skip_space(ptr+1);
	} else if (*ptr==' ' || *ptr=='\t') {
		*ptr = '\0';
		ptr = skip_space(ptr+1);
		if (*ptr=='=' || *ptr==':') {
			ptr = skip_space(ptr+1);
		}
	} else if (*ptr=='\n') {
		*ptr = '\0';
	}

	/* skip " */
	if (*ptr == '\"') {
		ptr++;
		if (*(ptr + strlen(ptr) - 1) == '\"')
			*(ptr + strlen(ptr) - 1) = '\0';
	}

	*value_ptr = ptr;
	
	return(0);
}

int parse_line_for_tripple(char *line_buf, char **key_ptr, char **value1_ptr, char **value2_ptr)
{
	char *ptr;

	*key_ptr = ptr = skip_space(line_buf);

	while(*ptr && !(*ptr==' ' || *ptr=='\t' || *ptr=='\n')) ptr++;

	if (*ptr==' ' || *ptr=='\t' || *ptr=='\n') {
		*ptr = '\0';
		ptr = skip_space(ptr+1);
	}

	*value1_ptr = ptr;

	while(*ptr && !(*ptr==' ' || *ptr=='\t' || *ptr=='\n')) ptr++;

	if (*ptr==' ' || *ptr=='\t' || *ptr=='\n') {
		*ptr = '\0';
		ptr = skip_space(ptr+1);
	}

	*value2_ptr = ptr;

	while(*ptr && !(*ptr==' ' || *ptr=='\t' || *ptr=='\n')) ptr++;

	if (*ptr==' ' || *ptr=='\t' || *ptr=='\n') {
		*ptr = '\0';
	}

	return(0);
}

int parse_line_for_keymap_name(TThaiKeymapList *pThaiKeymapList, char *line_buf)
{
	char *key_ptr, *value_ptr;
	int ret, nKeymap_ID;

	parse_line_for_pair(line_buf, &key_ptr, &value_ptr);
	if (strcasecmp(key_ptr, KEYMAP_NAME_STRING)) {
		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);

	ret = ThaiKeymapList_Item_Set_Name(pThaiKeymapList, nKeymap_ID, (unsigned char *)value_ptr);
	if (ret == THAI_KEYMAP_ERROR)
		return(THAI_KEYMAP_ERROR);

	pThaiKeymapList->nNum_Keymaps ++;
	return(THAI_KEYMAP_OK);
}

int parse_line_for_keymap_section(TThaiKeymapList *pThaiKeymapList, char *line_buf)
{
	char *key_ptr, *value1_ptr, *value2_ptr, ch;
	int nKeymap_ID;

	nKeymap_ID = pThaiKeymapList->nNum_Keymaps - 1;
	if (nKeymap_ID < 0)
		return(THAI_KEYMAP_ERROR);

	parse_line_for_tripple(line_buf, &key_ptr, &value1_ptr, &value2_ptr);

	ch = tolower(*key_ptr);
	ThaiKeymapList_Item_Set_KeymapValue(pThaiKeymapList, nKeymap_ID, ch, *value1_ptr);

	ch = get_upper_key(*key_ptr);
	ThaiKeymapList_Item_Set_KeymapValue(pThaiKeymapList, nKeymap_ID, ch, *value2_ptr);

	return(THAI_KEYMAP_OK);
}

int parse_line_for_section_flag(TThaiKeymapList *pThaiKeymapList, char *line_buf)
{
	char *flag_section_str;

	int flag_section = THAI_DEFAULT_SECTION;

	/* Extract the name of section */
	line_buf[strlen(line_buf) - 1] = '\0';
	flag_section_str = trim_string(line_buf+1);

	if (!*flag_section_str) return(THAI_DEFAULT_SECTION);

	/* get flag_section */
	if (!(strncasecmp(flag_section_str, KEYMAP_STRING, strlen(KEYMAP_STRING)))) {
		flag_section = THAI_KEYMAP_SECTION;
		parse_line_for_keymap_name(pThaiKeymapList, flag_section_str + strlen(KEYMAP_STRING));
	}

	return(flag_section);
}

int Thai_Read_Config(char *file_name, TThaiKeymapList *pThaiKeymapList)
{
	FILE *ifile;
	char line_buf[MAX_LINE_LEN], *line_ptr;
	int flag_section;
	int idx;

	for (idx = 0; idx < THAI_STANDARD_KEYMAP_NUM - 1; idx++) {
		ThaiKeymapList_Item_Add_Keymap(pThaiKeymapList,  Thai_Standard_Keymaps[idx].pName, Thai_Standard_Keymaps[idx].pKeymap);
	}

	ifile = fopen(file_name, "r");
	if (ifile == NULL) {
		fprintf(stderr, "Error: open file %s\n", file_name);
		return(THAI_KEYMAP_ERROR);
	}

	while(fgets(line_buf, MAX_LINE_LEN, ifile) != NULL) {
		line_ptr = trim_string(line_buf);

		if (*line_ptr && line_ptr[0] == '[' && line_ptr[strlen(line_ptr)-1] == ']') {
			flag_section = parse_line_for_section_flag(pThaiKeymapList, line_ptr);
			continue;
		}

		/* If space line or comment line */
		if (*line_ptr == '\0' || *line_ptr == '#') continue;

		switch (flag_section) {
			case THAI_DEFAULT_SECTION:
				break;

			case THAI_KEYMAP_SECTION:
				parse_line_for_keymap_section(pThaiKeymapList, line_ptr);
				break;
		}
	}

	fclose(ifile);

	return(THAI_KEYMAP_OK);
}

