// localizedtexts.cpp
 
 
 
#include "common.h"
 
 
 
 
 
void LocalizedTexts_Init (void)
 
{
 
   // this function opens and parses the INI files containing the localized texts and fills the
 
   // global language_t structure.
 
 
 
   static wchar_t lngfile_pattern[MAX_PATH];
 
   static wchar_t lngfile_pathname[MAX_PATH];
 
   void *inifile;
 
   text_t *text;
 
   int text_index;
 
   wchar_t *id_string;
 
   wchar_t *filter_char;
 
   WIN32_FIND_DATA wfd;
 
   HANDLE hFind;
 
 
 
   language_count = 0;
 
   swprintf_s (lngfile_pattern, sizeof (lngfile_pattern), L"%s\\data\\languages\\*.ini", app_path); // build the search pattern string out of the path
 
   hFind = FindFirstFile (lngfile_pattern, &wfd); // initiate search from that point
 
   if (hFind != INVALID_HANDLE_VALUE)
 
   {
 
      // start examining search results...
 
      do
 
      {
 
         // open the INI file
 
         swprintf_s (lngfile_pathname, WCHAR_SIZEOF (lngfile_pathname), L"%s\\data\\languages\\%s", app_path, wfd.cFileName);
 
         inifile = INIFile_LoadINIFile (lngfile_pathname);
 
 
 
         // consistency check (FIXME: this should never happen)
 
         if (inifile == NULL)
 
            continue;
 
 
 
         // file successfully opened, reallocate languages structure to hold one language more
 
         languages = (language_t *) SAFE_realloc (languages, language_count, language_count + 1, sizeof (language_t), false);
 
 
 
         // read the number of known localized texts and mallocate enough space for them
 
         languages[language_count].text_count = INIFile_GetNumberOfEntries (inifile, L"texts");
 
         languages[language_count].texts = (text_t *) SAFE_malloc (languages[language_count].text_count, sizeof (text_t), true);
 
 
 
         // now read all of them
 
         for (text_index = 0; text_index < languages[language_count].text_count; text_index++)
 
         {
 
            text = &languages[language_count].texts[text_index]; // quick access to text
 
 
 
            id_string = INIFile_GetEntryName (inifile, L"texts", text_index); // read this entry
 
            if (id_string == NULL)
 
            {
 
               MessageBox (NULL, L"There is an inconsistency in Chess Giants's language file.\n\nPlease reinstall the program to fix the problem.", L"Chess Giants", MB_ICONERROR | MB_OK);
 
               continue; // consistency check
 
            }
 
 
 
            text->id_string = _wcsdup (id_string); // have a copy of ID string and save it
 
            text->localized_string = (wchar_t *) SAFE_malloc (65536, sizeof (wchar_t), false); // allocate big space for localized string...
 
            wcscpy_s (text->localized_string, 65536, INIFile_ReadEntryAsString (inifile, L"texts", text->id_string, text->id_string)); // ... read it...
 
            text->localized_string = (wchar_t *) SAFE_realloc (text->localized_string, 65536, wcslen (text->localized_string) + 1, sizeof (wchar_t), false); // and resize correctly
 
 
 
            // conventionally, all texts whose ID end in "FileFilter" are file filters. Convert them for Windows API.
 
            // Reminder: INI file key entries are LOWERCASE.
 
            if (wcsistr (text->id_string, L"FileFilter") != NULL)
 
            {
 
               filter_char = text->localized_string; // convert vertical bars into string terminator characters
 
               while (*filter_char != 0) { if (*filter_char == L'|') *filter_char = 0; filter_char++; }
 
            }
 
         }
 
 
 
         // close the INI file
 
         INIFile_FreeINIFile (inifile);
 
 
 
         // save the language name (and chop off the trailing ".ini" suffix)
 
         wcscpy_s (languages[language_count].name, WCHAR_SIZEOF (languages[language_count].name), wfd.cFileName);
 
         languages[language_count].name[wcslen (languages[language_count].name) - 4] = 0;
 
 
 
         language_count++; // we've identified one language more
 
      } while (FindNextFile (hFind, &wfd)); // ...and don't stop as long as there are files to go
 
 
 
      FindClose (hFind); // close the search handle
 
   }
 
 
 
   return; // finished loading texts
 
}
 
 
 
 
 
void LocalizedTexts_Shutdown (void)
 
{
 
   // this function unloads all the contents of the localized texts array, freeing
 
   // the associated memory space, and resets the text_count variable to zero.
 
 
 
   int language_index;
 
   int text_index;
 
 
 
   // cycle through all the localized texts and free their mallocated space
 
   for (language_index = 0; language_index < language_count; language_index++)
 
   {
 
      for (text_index = 0; text_index < languages[language_index].text_count; text_index++)
 
      {
 
         SAFE_free ((void **) &languages[language_index].texts[text_index].id_string);
 
         SAFE_free ((void **) &languages[language_index].texts[text_index].localized_string);
 
      }
 
      SAFE_free ((void **) &languages[language_index].texts); // free the texts array themselves
 
      languages[language_index].text_count = 0; // reset the localized texts count
 
   }
 
   SAFE_free ((void **) &languages); // free the languages array themselves
 
   language_count = 0; // and reset the languages count
 
 
 
   return; // finished unloading texts
 
}
 
 
 
 
 
wchar_t *LocalizedTexts_GetLocalizedTextFor (wchar_t *id_string)
 
{
 
   // this function returns the localized text corresponding to a given id string
 
 
 
   language_t *language;
 
   int text_index;
 
 
 
   language = &languages[language_id]; // quick access to language
 
 
 
   // cycle through all the localized texts and find the one we want
 
   // NOTE: case-insensitive comparison mandatory, for dictionary entries are lowercase.
 
   for (text_index = 0; text_index < language->text_count; text_index++)
 
      if (_wcsicmp (language->texts[text_index].id_string, id_string) == 0)
 
         return (language->texts[text_index].localized_string); // when found, return a pointer to it
 
 
 
   Debug_Log (L"===WARNING: translation missing for string ID [%s]!===\n", id_string);
 
   return (id_string); // when not found, return the ID string itself
 
}