26a27
> #define DEBUG 1
36,41c37,61
< #define LETTERS_ARRAY_LENGTH 3
< static char *letters_array[LETTERS_ARRAY_LENGTH] = {
<   "0123456789",
<   G_CSET_A_2_Z,
<   G_CSET_a_2_z
< };
---
> /* both letters_array and keymap should be read in
>  * dynamically at run-time from files based on 
>  * user locale
>  */
> 
> /* letters_array contains letters you want shown
>  * on each play level
>  * there appear to be 6 levels, apparently hard-coded
>  * somewhere in the program
>  */
> 
> #define MAXLEVEL 6
> char *letters_array[MAXLEVEL];
> 
> /* keymap contains pairs of chars. The first char is the ASCII
>  * on the keyboard map, the second is the unichar that 
>  * is also represented by that key.  That way, if there is more
>  * than one character represented by a key, the user doesn't
>  * have to use alternate input methods.
>  * both chars are packed into the same string; this makes it
>  * easier to deal with.
>  */
> 
> int keyMapSize;
> char **keyMap;
109a130,148
> 
> static void level_set_score() {
>    int l;
> 
> 
> #ifdef DEBUG
> g_message("letters_array length for level %d is %d\n",gcomprisBoard->level,
>    g_utf8_strlen(letters_array[gcomprisBoard->level-1],-1));
> #endif
>    l = g_utf8_strlen(letters_array[gcomprisBoard->level-1],-1)/3;
>    gcomprisBoard->number_of_sublevel=(8>l?8:l);
> 
>    gcompris_score_start(SCORESTYLE_NOTE, 
> 			   gcomprisBoard->width - 220, 
> 			   gcomprisBoard->height - 50, 
> 			   gcomprisBoard->number_of_sublevel);
>    gcompris_bar_set(GCOMPRIS_BAR_LEVEL);
>    }
> 
129a169
>       level_set_score();
142a183,289
> 
> 
> 
> 
> int fill_letters(char **letterString,char *buffer) {
> #ifdef DEBUG
> g_message("in fill_letters\n");
> #endif
>    *letterString = g_malloc(strlen(buffer)+1);
>    sprintf(*letterString,"%s",buffer);
>    }
> 
> int load_default_charset() {
> #ifdef DEBUG
>    g_message("in load_default_charset\n");
> #endif
>    fill_letters(&letters_array[0],"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
>    fill_letters(&letters_array[1],"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
>    fill_letters(&letters_array[2],"abcdefghijklmnopqrstuvwxyz");
>    fill_letters(&letters_array[3],"abcdefghijklmnopqrstuvwxyz0123456789");
>    fill_letters(&letters_array[4],"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
>    fill_letters(&letters_array[5],"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
>    keyMapSize = 0;
>    return TRUE;
>    }
> 
> int load_charset_from_file(FILE *fp) {
>    int level, fp_ret_code, currKeyMap;
>    char lineBuffer[4096], strBuffer[4096], charBuffer[8];
> 
>    /* keymap size is dynamically allocated */
> #ifdef DEBUG
>    g_message("scanning line\n");
> #endif
>    keyMapSize = 64;
>    currKeyMap = 0;
>    keyMap = (char **)g_malloc((sizeof (char *))*keyMapSize);
>    
> 
>    printf("in load_charset_from_file\n");
> 
>    /* first read each line into a buffer */
>    while( fgets(lineBuffer,4095,fp) ) {
>       /* if it's a comment or blank (empty), skip line */
>       if ( lineBuffer[0] == '#' || lineBuffer[0] == '\0' ) continue;
>       /* if it's not a comment, it can only be one of 2 things
>        * a level string, where it starts with "level "
>        * and the format is "level %d %s" or
>        * a keymap which starts with "key" and the format is "key %c%lc"
>        */
> #ifdef DEBUG
>    g_message("scanning line\n");
> #endif
>       if( sscanf(lineBuffer,"level %d %s",&level, strBuffer) == 2 ) {
>          /* we have a level charset */
>          if (level > MAXLEVEL || level < 1) {
>             g_message("level %d outside range of 1 to %s in line %s ",level,MAXLEVEL,lineBuffer);
>             return FALSE;
>             }
>          fill_letters(&letters_array[level-1],strBuffer);
>          }
>       else if( sscanf(lineBuffer,"key %7s",charBuffer) == 1) {
>          /* we potentially have a keymap */
>          if( !g_utf8_validate(charBuffer,-1,(void *)NULL) ) {
>             /* it's not a valid UTF-8 string */
>             g_message("malformed UTF-8 character string >%s< ",charBuffer);
>             return FALSE;
>             }
>          keyMap[currKeyMap] = (char *)g_malloc((sizeof (char))*8);
>          sprintf(keyMap[currKeyMap],"%s",charBuffer);
>          currKeyMap++;
>          if(currKeyMap ==  keyMapSize) {
>             keyMapSize *= 2;
>             keyMap = (char **)realloc(keyMap,(sizeof(char *))*keyMapSize);
>             }
>          }
>      else
>        g_message("unknown command in file: %s",lineBuffer);
>    }
>    keyMapSize = currKeyMap;
>    return TRUE;
> }   
> 
> int get_charset(char *locale) {
>   char *filename;
>   FILE *charsfd = NULL;
>                                                                                                                      
>   /* First Try to find a file matching the level and the locale */
>   filename = g_strdup_printf("%s%s.%.2s",
>                              PACKAGE_DATA_DIR, "/gletters/gletters",
>                              locale);
>   g_message("Trying to open file %s ", filename);
>   charsfd = fopen (filename, "r");
>   g_free(filename);
>                                                                                                                      
>   if (charsfd == (FILE *)NULL) {
>       g_message("failed to open file.\n");
>       load_default_charset();
>       }
>   else if (load_charset_from_file(charsfd))
>       g_message("loaded charset from file.\n");
>    else {
>       g_message("failed to load charset from file - using defaults.\n");
>       load_default_charset();
>    }
> }
> 
151c298
< 
---
>       gcomprisBoard->maxlevel=MAXLEVEL;
153,160c300,301
<       gcomprisBoard->maxlevel=6;
<       gcomprisBoard->number_of_sublevel=10; /* Go to next level after this number of 'play' */
<       gcompris_score_start(SCORESTYLE_NOTE, 
< 			   gcomprisBoard->width - 220, 
< 			   gcomprisBoard->height - 50, 
< 			   gcomprisBoard->number_of_sublevel);
<       gcompris_bar_set(GCOMPRIS_BAR_LEVEL);
< 
---
>       get_charset(gcompris_get_locale());
>       level_set_score();
162d302
< 
167a308,309
> 
> 
186a329
>       level_set_score();
197,200c340,355
< gint key_press(guint keyval)
< {
<   gchar *old_value;
<   gchar *old_name;
---
> gint is_falling_letter(char *utfchar) {
>    gchar *old_value;
>    gchar *old_name;
> 
>    if (g_hash_table_lookup_extended (letters_table,
>                                     utfchar,
>                                     (gpointer) &old_name,
>                                     (gpointer) &old_value))
>        {
>        player_win(item_find_by_title(utfchar));
>        return TRUE;
>        }
>    return FALSE;
>    }
> 
> gint key_press(guint keyval) {
202c357,363
<   char str[2];
---
>   char lcStr[6],ucStr[6], *str;
>   char utf8char[6];
>   int i;
> 
> #ifdef DEBUG
> g_message("in key_press\n");
> #endif
269,296c430,495
<   c = tolower(keyval); 
<   str[0] = c;
<   str[1] = '\0';
<   if (g_hash_table_lookup_extended (letters_table,
< 				    (char *)&str,
< 				    (gpointer) &old_name,
< 				    (gpointer) &old_value))
<     {
< 
<       player_win(item_find_by_title((char *)&str));
< 
<     }
<   else
<     {
<       gchar *list_of_letters[255];
< 
<       list_of_letters[0] = '\0';
< 
<       /* We have to loop to concat the letters */
<       g_hash_table_foreach (letters_table,
< 			    (GHFunc) add_char,
< 			    list_of_letters);
< 
<       /* Log what happened, what was expected, what we got */
<       gcompris_log_set_comment(gcomprisBoard, list_of_letters, str);
< 
<       player_loose();
<     }
---
> /* first check the obvious - simple keystrokes 
>    check for keymap 
>    convert to unichar/utf8
>    set to lower case
>    check direct match
>    check upper case match
>  */
> #ifdef DEBUG
> g_message("checking keymap: %d\n",keyMapSize);
> #endif
> 
>   for(i = 0; i < keyMapSize; ++i) {
> #ifdef DEBUG
> g_message("keymap: %d: %s\n",i,keyMap[i]);
> #endif
>      if (keyval == keyMap[i][0]) {
> 
>         /* match in keymap */
>         sprintf(utf8char, "%s", keyMap[i]+1);
>         if( is_falling_letter(utf8char) ) {
>             str = utf8char;
>             break;
>             }
>         }
>      }
> 
> #ifdef DEBUG
> g_message("no match-moving on\n");
> #endif
> 
>       /* no match in keymap */
>     if (i == keyMapSize) {
> 
>        sprintf(utf8char, "%c", gdk_keyval_to_unicode(keyval));
>        g_unichar_to_utf8 (gdk_keyval_to_unicode(keyval),utf8char);
> 
>        sprintf(lcStr,"%s",g_utf8_strdown(utf8char,-1));
>        sprintf(ucStr,"%s",g_utf8_strup(utf8char,-1));
> 
>        if ( is_falling_letter(lcStr) ) {
>               str = lcStr;
>               }
>        else if( is_falling_letter(ucStr) ) {
>               str = ucStr;
>               }
>        else {
>           str = utf8char;
>           player_loose();
>           }
>      }
> 
>      gchar *list_of_letters[255];
>      list_of_letters[0] = '\0';
> 
>      /* We have to loop to concat the letters */
>      g_hash_table_foreach (letters_table,
>          (GHFunc) add_char,
>          list_of_letters);
> 
>      /* Log what happened, what was expected, what we got */
> 
>      gcompris_log_set_comment(gcomprisBoard, list_of_letters, str);
> 
> #ifdef DEBUG
> g_message("leaving key_press\n");
> #endif
428c627
<   int i;
---
>   int i,j,k;
430c629
<   char *lettersItem;
---
>   char *lettersItem, *str_p;
437c636
<   lettersItem = g_malloc (2);
---
>   lettersItem = g_malloc (6);
443a643,648
> 
> #ifdef DEBUG
>   printf("dump: %d, %s\n",gcomprisBoard->level,letters_array[gcomprisBoard->level-1]);
> #endif
> 
>   k=g_utf8_strlen(letters_array[gcomprisBoard->level-1],-1);
445,451c650,651
<     i=rand()%strlen(letters_array[gcomprisBoard->level%LETTERS_ARRAY_LENGTH]);
<     sprintf(lettersItem, "%c",
< 	    letters_array[gcomprisBoard->level%LETTERS_ARRAY_LENGTH][i]);
< 
<     /* Changing the letter to lower case : should be easier but these works */
<     c = tolower(lettersItem[0]); 
<     sprintf(lettersItem, "%c", c);
---
>     str_p=letters_array[gcomprisBoard->level-1];
>     i=1+(int)((float)k*rand()/(RAND_MAX+1.0));
453c653,657
<   } while(item_find_by_title(lettersItem)!=NULL);
---
>     for( j = 0; j < i; j++) {
>         str_p=g_utf8_find_next_char(str_p,NULL);
>        }
>     sprintf(lettersItem, "%lc",
> 	    g_utf8_get_char(str_p));
455c659
<   lettersItem[1] = '\0';
---
>   } while(item_find_by_title(lettersItem)!=NULL);
464d667
< 
472c675
<   x = 80 + (rand()%(gcomprisBoard->width-160));
---
>   x = 80 + (int)((float)(gcomprisBoard->width-160)*rand()/(RAND_MAX+1.0));
497a701,704
> #ifdef DEBUG
>   printf("done\n");
> #endif
> 
520a728,731
> #ifdef DEBUG
> g_message("in player_win\n");
> #endif
> 
526c737
<   if(gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel)
---
>   if(gcomprisBoard->sublevel > gcomprisBoard->number_of_sublevel)
557a769,771
> #ifdef DEBUG
>   printf("leaving player_win\n");
> #endif
561a776,779
> #ifdef DEBUG
>   printf("entering player_loose\n");
> #endif
> 
562a781,783
> #ifdef DEBUG
>   printf("leaving player_loose\n");
> #endif
