/*
	language.c
	Routines for language-handling.
	14.3.99 tn
	18.11.01 rewrote to support apple mac osX 
	(osX malloc is buggy and I have to alloate static buffers to
	 avoid random core dumps)
*/

#include "largefile.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <glib.h>
#include <gtk/gtk.h>
#include "xcdrdata.h"
#include "xcdroast.h"
#include "main.h"

/* size of static text buffer (guess of size) */
#define ALLTEXTSSIZE MAXLANG*MAXENTRIES*64

/* global language setting */
gint language;

language_list_t **langarray;

gchar *mesgarray[MAXENTRIES*MAXLANG];
gchar *helparray[MAXENTRIES*MAXLANG];
gchar alltexts[ALLTEXTSSIZE];
gint alltextscounter;

/* returns the text-string for the current selected language */

gchar *text(gint string_id) {
gchar *tmppnt;

	tmppnt = mesgarray[MAXLANG*string_id+language];

	if (tmppnt == NULL || strlen(tmppnt) == 0) {
		tmppnt = mesgarray[MAXLANG*string_id+0];
	}
	if (tmppnt == NULL) {
		return "- N.A. -";
	} else {
		return tmppnt;
	}
}


/* return the english text string */

gchar *text0(gint string_id) {
gchar *tmppnt;

	tmppnt = mesgarray[MAXLANG*string_id];

	if (tmppnt == NULL) {
		return "- N.A. -";
	} else {
		return tmppnt;
	}
}


/* returns the text-string for the current selected language */

gchar *help(gint string_id) {
gchar *tmppnt;

	tmppnt = helparray[MAXLANG*string_id+language];

	if (tmppnt == NULL || strlen(tmppnt) == 0) {
		/* if no mesg found, try default language 0 */
		tmppnt = helparray[MAXLANG*string_id+0];
	}
	if (tmppnt == NULL) {
		return "";
	} else {
		return tmppnt;
	}
}


/* takes the lines from the lang.defs-file and sorts them into a
   memory structure */

void parse_line(gchar *line) {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar *tmppnt;
gchar *tmppnt2;
gint langid, msgid;

	strip_string(line);

	/* skip comments and empty lines */
	if (line[0] == '#') return;
	if (line[0] == '\0') return;
	
	if (strncmp(line,"LANG",4) == 0) {
		strcpy(tmp,line);
		tmppnt = strtok(tmp,"_");
		if (tmppnt == NULL) return;
		tmppnt = strtok(NULL,":");
		if (tmppnt == NULL) return;
		langid = atoi(tmppnt);
		tmppnt = strtok(NULL,";");
		if (tmppnt == NULL) return;
		strcpy(tmp,tmppnt);
		strip_string(tmp);

		if (langid >= MAXLANG) {
			g_warning("maximal number of language definitions hit. Aborting...\n");
			gtk_exit(1);
		}	
		
		/* now we have found a language string */
		langarray[langid]=g_new0(language_list_t,1);
		langarray[langid]->langstring = g_strdup(tmp);
		langarray[langid]->codes = NULL;

		/* now look for the iso-language-codes */
		tmppnt = strtok(NULL, "");
		if (tmppnt != NULL) {
			strcpy(tmp,tmppnt);
			strip_string(tmp);
			tmppnt = strtok(tmp,",");
			while (tmppnt != NULL) {
				strcpy(tmp2, tmppnt);
				strip_string(tmp2);
				langarray[langid]->codes = g_list_append(langarray[langid]->codes, g_strdup(tmp2));
				tmppnt = strtok(NULL,",");
			}	
		}

		return;
	}

	/* all strings now are message-definitions */
	
	strcpy(tmp,line);
	tmppnt = strtok(tmp,"_:");
	if (tmppnt == NULL) return;
	msgid = atoi(tmppnt);
	tmppnt = strtok(NULL,"_:");
	if (tmppnt == NULL) return;
	langid = atoi(tmppnt);
	strcpy(tmp,tmppnt);

	if (msgid >= MAXENTRIES) {
		g_warning("maximal number of text definitions hit. Aborting...\n");
		gtk_exit(1);
	}	

	tmppnt = strtok(NULL,"");
	if (tmppnt == NULL) return;
	strcpy(tmp,tmppnt);
	strip_string(tmp);

	/* now strip quotes from string */	
	if (*tmp == '\"') {
		tmppnt2 = tmp+1;
	} else {
		tmppnt2 = tmp;
	} 
	if (tmp[strlen(tmp)-1] == '\"') {
		tmp[strlen(tmp)-1] = '\0';
	}
	strcpy(tmp2,tmppnt2);
	escape_parse(tmp2);

	/* already a translation for this found? Must be an error */
	if (mesgarray[msgid*MAXLANG+langid] != NULL) {
		g_warning("Sequence error in language.def at %04d_%d\n", 
			msgid, langid);
	}

/* 	mesgarray[msgid*MAXLANG+langid]=g_strdup(tmp2); */

	strcpy(alltexts+alltextscounter, tmp2);
	mesgarray[msgid*MAXLANG+langid]=alltexts+alltextscounter;
	alltextscounter += strlen(tmp2)+1;
	if (alltextscounter > ALLTEXTSSIZE) {
		g_warning("Buffer for textstrings exhausted. Aborting...\n");
		gtk_exit(1);
	}
}


/* takes the lines from the lang.defs-file and sorts them into a
   memory structure */

void parse_helpline(gchar *line) {
gchar tmp[MAXLINE];
gchar tmp2[MAXLINE];
gchar *tmppnt;
gchar *tmppnt2;
gint langid, msgid;

	strip_string(line);

	/* skip comments and empty lines */
	if (line[0] == '#') return;
	if (line[0] == '\0') return;
	
	/* all strings are help-definitions */
	
	strcpy(tmp,line);
	tmppnt = strtok(tmp,"_:");
	if (tmppnt == NULL) return;
	msgid = atoi(tmppnt);
	tmppnt = strtok(NULL,"_:");
	if (tmppnt == NULL) return;
	langid = atoi(tmppnt);

	strcpy(tmp,tmppnt);

	if (msgid >= MAXENTRIES) {
		g_warning("maximal number of help texts hit. Aborting...\n");
		gtk_exit(1);
	}	

	tmppnt = strtok(NULL,"");
	if (tmppnt == NULL) return;
	strcpy(tmp,tmppnt);
	strip_string(tmp);

	/* now strip quotes from string */	
	if (*tmp == '\"') {
		tmppnt2 = tmp+1;
	} else {
		tmppnt2 = tmp;
	} 
	if (tmp[strlen(tmp)-1] == '\"') {
		tmp[strlen(tmp)-1] = '\0';
	}
	strcpy(tmp2,tmppnt2);
	escape_parse(tmp2);

	/* already a translation for this found? Must be an error */
	if (helparray[msgid*MAXLANG+langid] != NULL) {
		g_warning("Sequence error in langhelp.def at %04d_%d\n", 
			msgid, langid);
	}

/*	helparray[msgid*MAXLANG+langid]=g_strdup(tmp2); */
	strcpy(alltexts+alltextscounter, tmp2);
	helparray[msgid*MAXLANG+langid]=alltexts+alltextscounter;
	alltextscounter += strlen(tmp2)+1;
	if (alltextscounter > ALLTEXTSSIZE) {
		g_warning("Buffer for textstrings exhausted. Aborting...\n");
		gtk_exit(1);
	}
}


/* load language-definitions into memory */

void load_langfile(gchar *filename) {
FILE *fd;
gchar line[MAXLINE];
int i;

	/* allocate memory */
/*	use static buffers instead for osX
	mesgarray = g_new0(gchar *,(MAXENTRIES*MAXLANG));
	alltexts = g_new0(gchar,ALLTEXTSSIZE);
*/
	memset(mesgarray,0x0,MAXENTRIES*MAXLANG*sizeof(gchar *));
	memset(alltexts,0x0,ALLTEXTSSIZE);
	alltextscounter = 0;

	langarray = g_new0(language_list_t *,MAXLANG+1);

	dodebug(1,"Opening language file %s\n", filename);
	if ((fd = fopen(filename,"r")) == NULL) {
		g_warning("Error opening %s\n", filename);
		g_warning("Without language file X-CD-Roast cannot be started - aborting\n");
		gtk_exit(1);
	}

	for (;;) {
		if (fgets(line,MAXLINE,fd) == NULL)
			break;
		dodebug(11,"language: %s",line);
		parse_line(line);
	}		

	/* This is for setup... so that for all languages the array
	   got valid values. */
	for(i=0; i<MAXLANG; i++) {
		if (langarray[i] == NULL) {	
			langarray[i]=g_new0(language_list_t,1);
			langarray[i]->langstring = NULL;
			langarray[i]->codes = NULL;
		}
	}	

	fclose(fd);
}


/* load language-definitions into memory */

void load_helpfile(gchar *filename) {
FILE *fd;
gchar line[MAXLINE];

	/* allocate memory */
/*
	helparray = g_new0(gchar *,(MAXENTRIES*MAXLANG));
*/
	memset(helparray,0x0,MAXENTRIES*MAXLANG*sizeof(gchar *));

	dodebug(1,"Opening language help file %s\n", filename);
	if ((fd = fopen(filename,"r")) == NULL) {
		g_warning("Error opening %s\n", filename);
		g_warning("Without language help file X-CD-Roast cannot be started - aborting\n");
		gtk_exit(1);
	}

	for (;;) {
		if (fgets(line,MAXLINE,fd) == NULL)
			break;
		dodebug(11,"language.help: %s",line);
		parse_helpline(line);
	}		
	
	fclose(fd);
}


/* scan the LC_ALL/LANG-environment variable and find matching language */
/* otherwise set to english */

void scan_lang() {
gchar *lang;
GList *iso;
gint i;

	/* init language */
	language = -1;

	/* check LC_ALL first */
	lang = getenv("LC_ALL");
	if (lang == NULL) {
		/* fall back to alternative var */
		lang = getenv("LC_MESSAGES");
		if (lang == NULL) {
			/* fall back again */
			lang = getenv("LANG");
		}
	}
	if (lang != NULL) {
		/* now scan for id string */
		i = 0;
		while(langarray[i] != NULL) {
			iso = g_list_first(langarray[i]->codes);
			while (iso) {
				if (strncasecmp(lang, (gchar *)iso->data, 
				    strlen((gchar *)iso->data)) == 0) {
					/* found match */
					language = i;
					dodebug(1, "Enabling language setting: %s (can be overidden by configfile)\n", lang);
					break;
				}
				iso = iso->next;
			}
			i++;
		}
	}

	/* no match found? */
	if (language == -1) {
		/* use english as default */
		language = 0;
	}
}

