

/* language.cpp

   Written by Roger Nelson

		 Biological Systems Engr. Dept.
       Washington State University
       Pullman, WA 99164-6120

       rnelson@wsuaix.csc.wsu.edu

   See header file for additional documentation

*/

#define LANGUAGE_THE_TRANSLATIONS
#include <rlib/language.h>
#undef LANGUAGE_THE_TRANSLATIONS

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#if defined(_DCC) || defined(__SASC)
#include <stdlib.h>
#else
#include <malloc.h>
#endif


#ifdef __MSDOS__
#include <dir.h>           /* <- MS-DOS */
#endif
#if defined(_DCC) || defined(__SASC) || defined(UNIX)
#define MAXPATH 255
#define MAXFILE 32
#endif

char language_full_phrase_filename[MAXPATH];
int language_curr_number = 0;

struct language_available *languages_available=0;  /* List of available langs */
char *language_current_code=0;                     /* active language */


/*
#define USEFSCANF
*/
/*
ISO standard language codes ISO639

The list was extracted from an Internet draft,
"Characters and character sets for various languages"
by Harald.Alvestrand@delab.sintef.no.

*/
/*
	 ?? Gaelic
    ?? Rhaetian
    ?? Sami/
    ?? Sorbian

    lowercase letters must be used because thats the standard
*/
#define NUM_ISO2_CODES 135
struct ISO2coding ISO2codes[NUM_ISO2_CODES] =
{
{"aa","Afar"            /*,"Somalia, Ethiopia, Djibouti"  Latin*/},
{"ab","Abkhazian"       /*,"Georgia"                      Cyrillic*/},
{"af","Afrikaans"       /*,"South Africa"*/},
{"am","Amharic"         /*,"Ethiopia"                     Ethiopic*/},
{"ar","Arabic"          /*,"Arabia"                       ISO-8859-6*/},
{"as","Assamese"        /*,"India, Nepal"                 Bengali*/},
{"ay","Aymara"          /*,"Bolivia, Peru, Chile"         Latin*/},
{"az","Azerbaijani"     /*,"SNC, Iran, Iraq, Turkey"      Cyrillic, Arabic*/},
{"ba","Bashkir"         /*,"SNC"                          Cyrillic*/},
{"be","Byelorussian"    /*,"?"                            ISO-8859-5*/},
{"bg","Bulgarian"       /*,"Bulgaria"                     ISO-8859-5*/},
{"bh","Bihari"          /*,"India"                        Gujarati (or Kaithi)*/},
{"bi","Bislama"         /*,"Vanuatu, New Caledonia"       Latin*/},
{"bn","Bengali"         /*,"India"                        Bengali*/},
{"bo","Tibetan"         /*,"Tibet" */},
{"br","Breton"          /*,"Britania"*/},
{"ca","Catalan"         /*,"Spain"*/},
{"co","Corsican"        /*,"France"                       Latin*/},
{"cs","Czech"           /*,"Czech republic"*/},
{"cy","Welsh"           /*,"Wales"*/},
{"da","Danish"          /*,"Denmark"*/},
{"de","German"          /*,"Germany"*/},
{"dz","Bhutani"         /*,"Bhutan?"*/},
{"el","Greek"           /*,"Greece"                      ISO-8859-7*/},
{"en","English"         /*,"various"                     USASCII*/},
{"eo","Esperanto"       /*,"artificial"*/},
{"es","Spanish"         /*,"various"*/},
{"et","Estonian"        /*,"Estonia"*/},
{"eu","Basque"          /*,"?"*/},
{"fa","Persian"         /*,"Persian countries"            ISO-8859-6*/},
{"fi","Finnish"         /*,"Finland"*/},
{"fj","Fiji"            /*,"Fiji"                         Latin*/},
{"fo","Faeroese"        /*,"Faeroe Islands"*/},
{"fr","French"          /*,"various"*/},
{"fy","Frisian"         /*,"?"*/},
{"ga","Irish"           /*,"      'Ireland"*/},
{"gd","Scots"           /*,"UK"                           Latin*/},
{"gl","Galician"        /*,"?"*/},
{"gn","Guarani"         /*,"Paraguay"                     Latin*/},
{"gu","Gujarati"        /*,"India"                        Gujarati*/},
{"ha","Hausa"           /*,"Nigeria, Niger,Chad,Sudan,..."  Latin*/},
{"hi","Hindi"           /*,"India"                        Devanagari*/},
{"hr","Croatian"        /*,"Croatia"*/},
{"hu","Hungarian"       /*,"Hungary"*/},
{"hy","Armenian"        /*,"Armenia"                      Armenian*/},
{"ia","Interlingua"     /*,"artificial"                   Latin*/},
{"ie","Interlingue"     /*,"artificial"                   Latin*/},
{"ik","Inupiak"         /*,"USA, Cannada"                 Latin, Cree*/},
{"in","Indonesian"      /*,"Indonesia"                    Latin*/},
{"is","Icelandic"       /*,"Iceland"*/},
{"it","Italian"         /*,"Italy"*/},
{"iw","Hebrew"          /*,"Israel"                       ISO-8859-8*/},
{"ja","Japanese"        /*,"Japan"                        ISO-IR-87 (Japanese JIS C6226-1983)*/},
{"ji","Yiddish"         /*,"Germany, USA, SNC, Israel"    Hebrew*/},
{"jw","Javanese"        /*,"Indonesia, Malaysia"          Latin, Javanese*/},
{"ka","Georgian"        /*,"Georgia"                      Georgian*/},
{"kk","Kazakh"          /*,"SNC, Afghanistan"             Cyrillic, Arabic*/},
{"kl","Greenlandic"     /*,"Greenland"*/},
{"km","Cambodian"       /*,"Cambodia"                     Khmer*/},
{"kn","Kannada"         /*,"India"                        Kannada*/},
{"ko","Korean"          /*,"Korea"                        ISO-IR-149 (Korean KS C 5601-1989)*/},
{"ks","Kashmiri"        /*,"India, Pakistan"              Arabic*/},
{"ku","Kurdish"         /*,"SNC, Turkey, Iraq, Iran"      Cyrillic, Arabic*/},
{"ky","Kirghiz"         /*,"SNC, China, Afghanistan"      Cyrillic, Arabic*/},
{"la","Latin"           /*,"none"                         USASCII*/},
{"ln","Lingala"         /*,"CAR, Congo, Zaire"            Latin*/},
{"lo","Laotian"         /*,"Laos"                         ISO-IR-166*/},
{"lt","Lithuanian"      /*,"Lithuania"*/},
{"lv","Latvian, Lettish"/*,"Latvia"*/},
{"mg","Malagasy"        /*,"Madagascar, Comoro Islands"   Latin, Arabic*/},
{"mi","Maori"           /*,"New Zealand"                  Latin*/},
{"mk","Macedonian"      /*,"Greece, Yugoslavia"           Greek, Cyrillic*/},
{"ml","Malayalam"       /*,"India"                        Malayalam*/},
{"mn","Mongolian"       /*,"Mongolia"                     Cyrillic, Mongolian*/},
{"mo","Moldavian"       /*,"Romania"                      Latin*/},
{"mr","Marathi"         /*,"India"                        Devanagari*/},
{"ms","Malay"           /*,"Malaysia, Thailand"           Latin*/},
{"mt","Maltese"         /*,"Malta"*/},
{"my","Burmese"         /*,"Myanmar"                      Burmese*/},
{"na","Nauru"           /*,"Nauru"                        Latin*/},
{"ne","Nepali"          /*,"Nepal"                        Devanagari*/},
{"nl","Dutch"           /*,"Holland"*/},
{"no","Norwegian"       /*,"Norway"*/},
{"oc","Occitan"         /*,"France"                       Latin*/},
{"or","Oriya"           /*,"India"                        Oriya*/},
{"pa","Punjabi"         /*,"India"                        Gurmukhi*/},
{"pl","Polish"          /*,"Poland"                      */},
{"ps","Pashto (W.)"     /*,"Afghanistan, Iran"            Arabic*/},
{"pt","Portuguese"      /*,"Portugal"*/},
{"qu","Quechua"         /*,"Peru"                         Latin*/},
{"rm","Rhaeto"          /*,"Swizerland"                   Latin*/},
{"rn","Kirundi"         /*,"Burundi, Uganda"              Latin*/},
{"ro","Romanian"        /*,"Romania"*/},
{"ru","Russian"         /*,"Russia"                       ISO-8859-5*/},
{"rw","Kinyarwanda"     /*,"Rwanda, Uganda, Zaire"        Latin*/},
{"sa","Sanskrit"        /*,"India"                        Devanagari*/},
{"sd","Sindhi"          /*,"Pakistan,India,Afghanistan"   Arabic, Gurmukhi*/},
{"sg","Sangro"          /*,"Central African Republic"     Latin*/},
{"sh","Serbo-Croatian"  /*,"Serbia,Croatia"*/},
{"si","Singhalese"      /*,"Sri Lanka"                    Sinhalese*/},
{"sk","Slovak"          /*,"Slovakia"*/},
{"sl","Slovenian"       /*,"Slovenia"*/},
{"sm","Samoan"          /*,"Samoa, USA, New Zealand"      Latin*/},
{"sn","Shona"           /*,"Zimbabwe,Zambia,Mozambique"   Latin*/},
{"so","Somali"          /*,"Somalia, Ethiopia, Djibouti"  Latin*/},
{"sq","Albanian"        /*,"Albania"*/},
{"sr","Serbian"         /*,"former Yugoslavia"            Cyrillic*/},
{"ss","Siswati"         /*,"S. Africa, Swaziland"         Latin*/},
{"st","Sesotho"         /*,"S. Africa, Lesotho"           Latin*/},
{"su","Sudanese"        /*,"Sudan"                        Latin*/},
{"sv","Swedish"         /*,"Sweden"*/},
{"sw","Swahili"         /*,"Africa"                       USASCII*/},
{"ta","Tamil"           /*,"India, Malaysia"              Tamil*/},
{"te","Tegulu"          /*,"India"                        Telugu*/},
{"tg","Tajik"           /*,"Tajikistan"                   Arabic*/},
{"th","Thai"            /*,"Thailand"                     ISO-IR-166*/},
{"ti","Tigrinya"        /*,"Ethiopia"                     Latin, Ethiopic*/},
{"tk","Turkmen"         /*,"SNC, Iran, Afghanistan"       Cyrillic, Arabic*/},
{"tl","Tagalog"         /*,"Phillipines"                  Latin*/},
{"tn","Setswana"        /*,"S.Africa, Botswana, Namibia"  Latin*/},
{"to","Tonga (3)"       /*,"Mozambique"                   Latin*/},
{"tr","Turkish"         /*,"Turkey"*/},
{"ts","Tsonga"          /*,"Mozambique, Swaziland"        Latin*/},
{"tt","Tatar"           /*,"SNC"                          Cyrillic*/},
{"tw","Twi (Ewe)"       /*,"Ghana"                        Latin*/},
{"uk","Ukrainian"       /*,"Ukrain"                       ISO-8859-5*/},
{"ur","Urdu"            /*,"Pakistan"                     ISO-8859-6*/},
{"uz","Uzbek (S.)"      /*,"Afghanistan, Turkey"          Arabic*/},
{"vi","Vietnamese"      /*,"Vietnam, Cambodia, China"     Latin*/},
{"vo","Volapuk"         /*,"?"                            ISO-8859-1*/},
{"wo","Wolof"           /*,"Senegal, Mauritania"          Latin*/},
{"xh","Xhosa"           /*,"S. Africa"                    Latin*/},
{"yo","Yoruba"          /*,"Nigeria, Togo, Benin"         Latin*/},
{"zh","Chinese"         /*,"China"                        ISO-IR-58 (Chinese GB 2312-80)*/},
{"zu","Zulu"            /*,"S. Africa, Lesotho, Malawi"   Latin*/},
};

struct language_node
{
  long phrase_ID;
  char *phrase;
  struct language_node *right;
};

struct language_node *language_list = 0;

/* This function takes the fully qualified program name
	Ie C:\PATHA\MYAPP.EXE
   it returns the path: C:\PATHA  and the
   program name without the extension: MYAPP

   This function is used internally, but may be useful to the programmer.
*/
#ifdef HARDCODE_PHRASES
#if defined(__STDC__) || defined(__cplusplus)
int language_set(char *language_name)
#else
int language_set(language_name)
char *language_name;
#endif
{
  int i;
  for (i = 0; i < language_num_languages;i++)
    if (strcmp(language_codes[i], language_name) == 0)
    {
       language_curr_number = i;
       return(1);
    };
  return(0);
}

#if defined(__STDC__) || defined(__cplusplus)
char *translate_to(long phrase_ID,int language_number)
#else
char *translate_to(phrase_ID,language_number)
long phrase_ID;
int language_number;
#endif
{
   /* With this, we now support recursive dialect definitions! */

   /* Case where there is no translation for the language,
		return the first translation (usually english). */
	if (language_translations[phrase_ID][language_number] == 0)
		return(language_translations[phrase_ID][0]);

	/* Case where the translation is the same as a base language
		this case will only occur in languages which are dialects
		The entry in the table is actually the number of the base language. */
	if ((long)(language_translations[phrase_ID][language_number]) <= language_num_languages)
		return(translate_to(phrase_ID,(int)(long)(language_translations[phrase_ID][language_number])));

   /* Case where the translation is the character string */
   return(language_translations[phrase_ID][language_number]);
}
#else
/*
#if defined (__BCPLUSPLUS__) || defined(__BORLANDC)
#  define strupper(x) strupr(x)
#else
*/
#  if defined(__STDC__) || defined(__cplusplus)
      char_8bit *strupper(char_8bit *str)
#  else
		char_8bit *strupper(str);
      char_8bit *str;
#  endif
{
  int i;
  for (i = 0 ; i < strlen(str);i++)
    str[i] = toupper(str[i]);
  return(str);
}
/*#endif */
/* This function deallocates the linked list of phrases
   This function should not be called externally.
*/
#if defined(__STDC__) || defined(__cplusplus)
void clear_language_list(struct language_node *langlist)
#else
void clear_language_list(langlist)
struct language_node *langlist;
#endif
{
	struct language_available *lang;
	struct language_available *next_lang = 0;
	struct language_node *node;
	struct language_node *nextnode = 0;
	for (node = langlist; node; node = nextnode)
	{ if (node->phrase)
		  free(node->phrase);
	  nextnode = node->right;
	  free(node);
	};

	for (lang = languages_available; lang; lang = next_lang)
	{ next_lang = lang->next;
	  free(lang->name);
	  free(lang->desc);
	  free(lang);
	};
	languages_available = 0;


}

/* This function reads a phrase entry from the phrases file.
   It is used internally and is probably of no use to the programmer.
*/
#if defined(__STDC__) || defined(__cplusplus)
int language_read_phrase
 (FILE *phrase_file,
  char *phrase,         /* Where to put the read phrase. */
  char *language_name_code,  /* The language to read. */
  char *base_language_name_code,
  char *used_by         /* This list of programs using this phrase */
 )
#else
int language_read_phrase(phrase_file,phrase,language_name_code,base_language_name_code,used_by)
FILE *phrase_file;
char *phrase;         /* Where to put the read phrase. */
char *language_name_code;  /* The language to read. */
char *base_language_name_code;
char *used_by;        /* This list of programs using this phrase */
#endif
  /* Returns true is the next phrase was read successfully. */
{
	char phrase_ID_str[255];
	char language_name_code_to_read[255];
	char language_name_code_in[255];
	int read_complete;
	char line_in[255];
	char phrase_in[255];

   if (feof(phrase_file))  /* If at eof then phrase not read */
      return(0);

   fgets(phrase_ID_str,255,phrase_file);  /* get the phrase ID (not used) */
#ifdef DEBUG
printf("%s\n",phrase_ID_str);
#endif
	if ((phrase_ID_str[0] == 0) || (feof(phrase_file)))
      return(0);

#ifdef USEFSCANF
   fscanf(phrase_file,"%[^\n]\n",used_by);
#else
   fgets(used_by,255,phrase_file);
#endif

   read_complete = 0;
   phrase[0] = 0;      /* Clear the phrase */
   do
	{
     strcpy(language_name_code_to_read,language_name_code);
#ifdef USEFSCANF
     fscanf(phrase_file,"%[^\n]\n",line_in);
#else
     fgets(line_in,255,phrase_file);
#endif
     if (line_in[0] == '*')
        read_complete = 1;
     else
     {
#ifdef USEFSCANF
       sscanf(line_in,"%s %[^\n]\n",language_name_code_in,phrase_in);
#else
       { int i;
         int j =0;
         int k =0;
         int incode = 1;
         for (i = 0; i < strlen(line_in); i++)
           if (incode)
              if (line_in[i] == ' ')
                 incode = 0;
              else
					  language_name_code_in[j++] = line_in[i];
           else
              if (line_in[i] != '\n')
                phrase_in[k++] = line_in[i];
         language_name_code_in[j] = 0;
         phrase_in[k] = 0;
       };
#endif
       if (phrase_in[0] == '=')
          strcpy(language_name_code_to_read,&(phrase_in[1]));
       if (strcmp(language_name_code_in,language_name_code_to_read) == 0)
			 strcpy(phrase,phrase_in);
       else
          if ((strcmp(language_name_code_in,base_language_name_code) == 0) &&
               (phrase[0] == 0))
              strcpy(phrase,phrase_in);
           /* Use english if translation not provided
           if ((strcmp(language_name_code_in,"en") == 0) &&
               (phrase[0] == 0))
              strcpy(phrase,phrase_in);
           */
	  };
   } while (!read_complete);
	return(1);
}
/* Some UNIXes may not have strstr defined in string.h */
#ifdef SYSV
char *strstr(str1,str2)
char *str1;
char *str2;
{
  int i,j;
  j = 0;
  for (i = 0; i < strlen(str1); i++)
	  if (str1[i] == str2[i+j])
     { j += 1;
		 if (j == strlen(str2))
         return (&(str1[i-j]));
     }
     else
     {  j = 0;
        i = i - j + 1;
     };
}
#endif

#if defined(__STDC__) || defined(__cplusplus)
void language_get_available(FILE *phrases_file)
#else
void language_get_available(phrases_file)
FILE *phrases_file;
#endif
{
	 struct language_available *lang =0;
	 char nameline[255];
	 char name[255];
	 char desc[255];

	 do
		 fgets(nameline,255,phrases_file);
	 while (strncmp(nameline,"LINGVO,",7) != 0);

	 fgets(nameline,255,phrases_file); /* ignore the program line */
	 fgets(nameline,255,phrases_file); /* ignore the program line */

	 while (nameline[0] != '*')   /* first char of comment token */
	 {
		if ((lang = (struct language_available *)malloc(sizeof(struct language_available))) != 0)
		{
		  sscanf(nameline,"%s %[^\n]",name,desc);   /* the first language line */
		  lang->name = (char *)malloc(strlen(name)+1);
		  strcpy(lang->name,name);
		  lang->desc = (char *)malloc(strlen(desc)+1);
		  strcpy(lang->desc,desc);
		  lang->next = languages_available;
		  languages_available = lang;
		};
		fgets(nameline,255,phrases_file); /* ignore the program line */
	 };
}

#if defined(__STDC__) || defined(__cplusplus)
void language_load_dialects(FILE *phrases_file,char *language_name_code,char *base_language_name_code)
#else
void language_load_dialects(phrases_file,language_name_code,base_language_name_code)
FILE *phrases_file;
char *language_name_code;
char *base_language_name_code;
#endif
{
   char dialects[256];
#ifdef USEFSCANF
   fscanf(phrases_file,"%[^\n]\n",dialects);  /* Read the DIALEKTOJ */
	fscanf(phrases_file,"%[^\n]\n",dialects);
#else
	fgets(dialects,255,phrases_file);
   fgets(dialects,255,phrases_file);
#endif
	while (dialects[0] != '*')
   {
	  if (strstr(dialects,language_name_code) != NULL)
		  sscanf(dialects,"%s ",base_language_name_code);
#ifdef USEFSCANF
     fscanf(phrases_file,"%[^\n]\n",dialects);
#else
	  fgets(dialects,255,phrases_file);
#endif
   };
}


/* This function is usually used internally by language_init(),
	but may be used by the programmer to allow the user to change the
   language on the fly.

   language_load returns 1 if the translations loaded successfully
	0 if the file is not found or corrupt.
*/

#if defined(__STDC__) || defined(__cplusplus)
int language_load(char *language_name_code,char *program_name,char *program_dir, char *phrases_filename)
#else
int language_load(language_name_code,program_name,program_dir,phrases_filename)
char *language_name_code;
char *program_name;
char *program_dir;
char *phrases_filename;
#endif
{
   FILE *phrase_file;
/*    char phrase_directory[MAXPATH]; */
   struct language_node *node = 0;
   long phrase_ID;  /* long may be int depending on implementation of enum */
   struct language_node *last_node = 0;
	char phrase[256];
	char used_by[256];
   char base_language_name_code[256];


	if (language_list)
		clear_language_list(language_list);
	language_list = 0;

	if (strcmp(language_name_code,"") == 0)
		strcpy(language_name_code,"en");

	if (language_current_code)  free(language_current_code);
	language_current_code = (char *)malloc(strlen(language_name_code) +1);
	strcpy(language_current_code,language_name_code);

	phrase_ID = LINGVO;
	sprintf(language_full_phrase_filename,"%s%s",program_dir,phrases_filename);

	if ((phrase_file = fopen(language_full_phrase_filename,"rt")) == NULL)
		return(0);  /* Unable to open phrases file. */

	language_get_available(phrase_file);
	rewind(phrase_file);

	language_load_dialects(phrase_file,language_name_code,base_language_name_code);

	for (phrase_ID = LINGVO ; phrase_ID < LANGUAGE_END_PHRASES; phrase_ID++)
	{
	  if (!language_read_phrase(phrase_file,phrase,
			 language_name_code,base_language_name_code,used_by))
	  {  fclose(phrase_file);
		  return(0);   /* language read failed. */
	  };
	  if (strstr((char_8bit *)strupper((char_8bit *)used_by),
                (char_8bit *)strupper((char_8bit *)program_name)))
	  {
		  node = (struct language_node *)malloc(sizeof(struct language_node));

		  language_list = language_list ? language_list : node;
		  node->phrase_ID = phrase_ID;
		  node->phrase = (char *)malloc(strlen(phrase)+1);
		  strcpy(node->phrase,phrase);
		  node->right = 0;
		  if (last_node) last_node->right = node;
		  last_node = node;
	  }
	};
	fclose(phrase_file);
	return(1);
}


/* This function should be called near the beginning of the program.
   None of the other functions must be called before this function.
*/
#if defined(__STDC__) || defined(__cplusplus)
int language_init(char *language_name_code,char *program_name,char *program_dir, char *phrases_filename)
#else
int language_init(language_name_code,program_name,program_dir,phrases_filename)
char *language_name_code;
char *program_name;
char *program_dir;
char *phrases_filename;
#endif
{
	int langloadresult;
	language_list = 0;
	langloadresult = language_load( language_name_code, program_name,program_dir,phrases_filename);
	return(langloadresult);
}

/* This function should be called near the end of the program.
   It deallocates the memory used by the translation list.
*/
#if defined(__STDC__) || defined(__cplusplus)
void language_end(void)
#else
void language_end()
#endif
{
	clear_language_list(language_list);
}

#endif


static char L_unable_to_translate_str[] = "???";
static char L_blank_str[] = " ";

/* translate() is used in place of literal strings.
   The programmer should not modify the returned string; if the string
	must be modified, strcpy the string into a separate buffer.
*/


#if defined(__STDC__) || defined(__cplusplus)
char *translate(long phrase_ID)
#else
char *translate(phrase_ID)
long phrase_ID;
#endif
{
#ifdef HARDCODE_PHRASES
   return(translate_to(phrase_ID,language_curr_number));
#else
   struct language_node *curr;
   static char *translation;

	for (curr = language_list;
        curr && (curr->phrase_ID != phrase_ID);
        curr = curr->right) ;  /*  <- Yes semicolon here! */

   if (curr)
      translation = curr->phrase;
   else
      translation = L_unable_to_translate_str;
   if (translation[0] == '_')
      translation = L_blank_str;
   return(translation);
#endif
}


/*Remove_tilde removes tilde characters from the phrase string.
  and places the result in newphrase.
  A pointer to newphrase is returned.
  The program must provide a sufficiently sized buffer to store newphrase.
  Tilde characters are used in TurboVision to highlight text in gadgets.
*/
#if defined(__STDC__) || defined(__cplusplus)
char *remove_tilde(char *phrase, char *newphrase)
#else
char *remove_tilde(phrase, newphrase)
char *phrase;
char *newphrase;
#endif
{
  int i;
  int j = 0;
  for (i = 0; i < strlen(phrase);i++)
     if (phrase[i] != '~')
       newphrase[j++] = phrase[i];
  newphrase[j] = 0;
  return(newphrase);
}


#if defined(__STDC__) || defined(__cplusplus)
void language_list_available(FILE *dest)
#else
void language_list_available(dest)
FILE *dest;
#endif
{

#ifdef HARDCODE_PHRASES
   int i;
   for (i = 0; i < language_num_languages; i++)
     fprintf(dest,"%s %s\n",language_codes[i],language_translations[0][i]);

#else
   char in_line[255];
   FILE *phrase_file;
   if ((phrase_file = fopen(language_full_phrase_filename,"r")) != NULL)
   {
     do
     {
       fgets(in_line,254,phrase_file);
     } while ((!feof(phrase_file)) ||
              (strncmp(in_line,"LINGVO",6) != 0));
     do
     {
       fgets(in_line,254,phrase_file);
       if (strncmp(in_line,"*/",2) != 0)
          fprintf(dest,"%s\n",in_line);
     } while ((!feof(phrase_file)) ||
              (strncmp(in_line,"*/",2) != 0));
   };
#endif
}

/* Given an ISO standard 2 letter language code, return the
   English name of the language
*/
#if defined(__STDC__) || defined(__cplusplus)
char *language_name(char *language_name_code)
#else
char *language_name(language_name_code)
char *language_name_code;
#endif
{
  int i;
  for (i = 0; i < NUM_ISO2_CODES; i++)
     if (strcmp(ISO2codes[i].code,language_name_code) == 0)
        return(ISO2codes[i].language);
  return(0);
}


#ifdef _Windows

char MSW2ISO2[][3] =
{
  "??","ar","bg","ca","zh","cs","da","de","el","en",
  "es","fi","fr","iw","hu","is","it","ja","ko","nl",
  "no","pl","pt","rm","ro","ru","sh","hr","sq","sv",
  "th","tu","ur","??","zh","de","en","es","fe","it",
  "nl","no","pt","sk","fr","fr"
};
/* Given an MS Window language code, return the two digit ISO language code.
*/
#if defined(__STDC__) || defined(__cplusplus)
char *language_MSWindows2ISO2(unsigned int windowscode)
#else
char *language_MSWindows2ISO2(windowscode)
unsigned int windowscode;
#endif
{  int ndx;
   switch (windowscode)
   {
	  case 0x0401 : ndx =  1; break; /*arabic*/
	  case 0x0402 : ndx =  2; break; /*bulgarian*/
	  case 0x0403 : ndx =  3; break; /*catalan*/
	  case 0x0404 : ndx =  4; break; /*chinese (traditional)*/
	  case 0x0405 : ndx =  5; break; /*czech*/
	  case 0x0406 : ndx =  6; break; /*danish*/
	  case 0x0407 : ndx =  7; break; /*german*/
	  case 0x0408 : ndx =  8; break; /*greek*/
	  case 0x0409 : ndx =  9; break; /*english (US)*/
	  case 0x040A : ndx = 10; break; /*spanish (Castilian)*/
	  case 0x040B : ndx = 11; break; /*finnish*/
	  case 0x040C : ndx = 12; break; /*french*/
	  case 0x040D : ndx = 13; break; /*hebrew*/
	  case 0x040E : ndx = 14; break; /*hungarian*/
	  case 0x040F : ndx = 15; break; /*icelandic*/
	  case 0x0410 : ndx = 16; break; /*italian*/
	  case 0x0411 : ndx = 17; break; /*japanese*/
	  case 0x0412 : ndx = 18; break; /*korean*/
	  case 0x0413 : ndx = 19; break; /*dutch*/
	  case 0x0414 : ndx = 20; break; /*norwegian (bokmal)*/
	  case 0x0415 : ndx = 22; break; /*portuguese(brazil)*/
	  case 0x0417 : ndx = 23; break; /*rhaeto*/
	  case 0x0418 : ndx = 24; break; /*romanian*/
	  case 0x0419 : ndx = 25; break; /*russian*/
	  case 0x041A : ndx = 26; break; /*croato-serbian*/
	  case 0x041B : ndx = 27; break; /*slovak*/
	  case 0x041C : ndx = 28; break; /*albanian*/
	  case 0x041D : ndx = 29; break; /*swedish*/
	  case 0x041E : ndx = 30; break; /*thai*/
	  case 0x041F : ndx = 31; break; /*turkish*/
	  case 0x0420 : ndx = 32; break; /*urdu*/
	  case 0x0421 : ndx = 33; break; /*bahasa*/
	  case 0x0804 : ndx = 34; break; /*chinese (simplified)*/
	  case 0x0807 : ndx = 35; break; /*german (swiss)*/
	  case 0x0809 : ndx = 36; break; /*english (UK)*/
	  case 0x080A : ndx = 37; break; /*spanish (mexican)*/
	  case 0x080C : ndx = 38; break; /*french (belgian)*/
	  case 0x0810 : ndx = 39; break; /*italian (swiss)*/
	  case 0x0813 : ndx = 40; break; /*dutch (belgian)*/
	  case 0x0814 : ndx = 41; break; /*norwegian (Nynorsk)*/
	  case 0x0816 : ndx = 42; break; /*portuguese*/
	  case 0x081A : ndx = 43; break; /*serbo-croatian*/
	  case 0x0C0C : ndx = 44; break; /*french (canadian)*/
	  case 0x100C : ndx =45; break; /*french (swiss)*/
	  default : ndx = 0; break;
   };
	return(MSW2ISO2[ndx]);
}
#endif

