ludi_language = {};

// language-dependent section; only for texts.
ludi_language.lastLoadedLanguages = [];

ludi_language.lanList = []; // kernelMessages
// to-do: add libMessages:[], gameMessages[], items: [],	attributes: [],	actions: [], directions:[] ???

ludi_language.allLanguages = ["EN", "ES", "EO"]; // in the future, from external file
ludi_language.defaultLanguage = ["EN"]; // first time using LUDI; sort matters

ludi_language.showInternalItemByLan = [];


// ----------------------------------------------------------------------------------------

ludi_language.message_LongId_Exists  = function (longId) {
	if (typeof  ludi_language.lanList[ludi_language.lanIndex].gameMes[longId] != 'undefined'){
		return true;
	} else if (typeof  ludi_language.lanList[ludi_language.lanIndex].libMes[longId] != 'undefined'){
		return true;
	}
	return false;
}

ludi_language.message_LongId_ExistsByLan  = function (longId) {
	
	if (typeof  ludi_language.lanList[ludi_language.lanIndex].gameMesByLan  == 'undefined') {
		// to-do: error loading ByLan data
		console.log ("gameMesByLan table was not loaded for this language");
		return false;
	}
	
	if (typeof  ludi_language.lanList[ludi_language.lanIndex].gameMesByLan[longId] != 'undefined'){
		return true;
	} else if (typeof  ludi_language.lanList[ludi_language.lanIndex].libMesByLan[longId] != 'undefined'){
		return true;
	}
	return false;
}	




ludi_language.generalInstructionsMsg = function() {

	var txt = "";

	if (ludi_language.kernel_lanIndex <0)  {
		txt = "<h3>" + "Instructions" + "</h3>";

		txt += "<p>Error: missing language</p>";
		
		return txt;
	}
	
	if (ludi_language.lanList[ludi_language.kernel_lanIndex].code == "EN") {
		
		txt = "<h3>" + "Instructions" + "</h3>";

		txt += "<p>Modify your preferred languages: Profile / Set your language preferences / Apply changes</p>";

		txt += "<p>Choose your game: Games / Public games / game1 / Load game from start / add or remove languages / Apply  changes</p>";

		txt += "<p>Online interaction with another players: Profile / Set nick name / write your nick name and push intro</p>";		
		txt += "<p>When you log on with a nick name you can send public or private messages to the other players, share your actions with them and see their actions. You can read and write messages on boards as well. At any moment, you can log out from the server.</p>";
		
		txt += "<p>Playability</p>";
		txt += "<ul>";
		txt += "<li>For two-item actions, you must first mark the second item, generally a container or a character.</li>";
		txt += "<li>For instance, to put X into Y: first mark Y and when you click on X, you\'ll be able to choose \'put into\'</li>";
		txt += "<li>Similarly, to use X on Y: first mark Y and when you click on X, you\'ll be able to choose \'use on\'</li>";
		txt += "<li>When you choose to talk to a character, a list of senteces will be shown. You\'ll have to choose one of them.</li>";
		txt += "</ul>";		
		
	} else 	if (ludi_language.lanList[ludi_language.kernel_lanIndex].code == "ES") {
	
		txt = 	"<h3>" + "Instrucciones" + "</h3>";
		
		txt += "<p>Modifica tus idiomas preferidos: Perfil / Elige tus idiomas preferidos / Aplica cambios</p>";

		txt += "<p>Elige tu juego: Juegos / Juegos públicos / game1 / Carga juego desde cero</p>";

		txt += "<p>Para interactuar con otros jugadores: Perfil / Ponte un apodo / escribir tu apodo y aceptar.</p>";
		txt += "<p>Cuando se inicia sesión con un apodo se puede enviar mensajes públicos o privados a los otros jugadores, compartir tus acciones con ellos y ver sus acciones. También podrás leer y escribir mensajes en los foros. En cualquier momento, puedes cerrar la sesión con el servidor.</p>";

		txt += "<p>Jugabilidad</p>";
		txt += "<ul>";
		txt += "<li>Para acciones con dos objetos, hay que marcar uno de ellos, generalmente un contenedor o un personaje.</li>";
		txt += "<li>Por ejemplo, para meter X en Y: primero se marca Y y luego al pulsar en X aparecerá disponible la acción 'meter dentro de'.</li>";
		txt += "<li>De igual manera, para usar X en Y: primero se marca Y y luego al pulsar en X aparecerá disponible la acción 'usar en'.</li>";
		txt += "<li>Al seleccionar la acción hablar con un personaje aparecerá una lista de frases entre las que elegir.</li>";
		txt += "</ul>";			
		
	} else 	if (ludi_language.lanList[ludi_language.kernel_lanIndex].code == "EO") {
	
		txt = "<h3>" + "Instrukcioj" + "</h3>";
		
		txt += "<p>Elektu viajn preferatajn lingvojn: Profilo / Elektu viajn preferatajn lingvojn / Efektivigu ŝanĝojn </p>";

		txt += "<p>Elektu vian ludo: Ludoj / Publikaj ludoj / game1 / Rekuperi ludon ekde nulo </p>";

		txt += "<p>Por interagado kun alia ludantoj: Profilo / Elektu vian komnomon / skribu vian komnomon kaj konfirmu.</p>";
		txt += "<p>Kiam vi ensalutas kun komnomo vi povas sendi publikajn aŭ privatajn mesaĝojn al la aliaj ludantoj, havebligi viajn agojn kun ili kaj vidi iliajn agojn. Vi ankaŭ povos legi kaj skribi mesaĝojn en forumoj. Ĉiumomente, vi povos elsaluti el la servilo. </p>";

		txt += "<p>Ludeco</p>";
		txt += "<ul>";
		txt += "<li>Por agoj kun du objektoj, vi devas unue marki la duan objekton, ĝenerale ujo aŭ gravulo.</li>";
		txt += "<li>Ekzemple, por meti X en Y: unue marku Y-on kaj kiam vi klaku sur X, vi povos elekti \'enmeti en\'</li>";
		txt += "<li>Simile, uzi X sur Y: unue marku Y-on kaj kiam vi klaku sur X, vi povos elekti 'uzi sur'.</li>";
		txt += "<li>Kiam vi elektas paroli al iu karaktero, estos montrita listo de eblecoj. Vi devos elekti unu el ili.</li>";
		txt += "</ul>";		

	}
	
	return txt;
}

ludi_language.pendingKernelMessages = function () {

	var pendingLoading = false;
	for (var ilan=0;ilan<ludi_language.lanList.length;ilan++) {
		if (ludi_language.lanList[ilan].toLoad_Kernel && !ludi_language.lanList[ilan].kernelLoaded) {
			pendingLoading = true;
			break;
		}
	}
	
	return pendingLoading;
	
}


/*

Translation:
It receives an abstract (language-independent) msgId with parameters, and returns a fullMessage (language-dependent)

*/



ludi_language.translateKernelMSG = function  (mesIn, param) {

	return ludi_language.expandMSG(mesIn, param);

}

ludi_language.translateMSG = function (mesIn, param) {

	return ludi_language.expandMSG(mesIn, param);

}


//-------------------------------------------------------------------------------------------------------------------------
/*
	%: escape char
	Format: %LetterNumberWhatever%
	
	Where:
		Letter: type of element: [o: item short text; v: verb; s: string]
		Number: index of the element in the sentence (provisional use, can be depreciated later)
		Whatever: language-dependent modulaton. Samples:
		- english short name as subject %o1nas% -> he/she/it
		- english pronoun as object %o2pao% -> him/her/it
		- spanish verb conjugation : %v1ms% ->  como
		
	From generic "%o1 %v2 %o3 %s4 times!" we can get several language versions:
		a) English: "%o1nas% %v23ps% %o3pao% %s4% times!" -> "The cat gets it 3 times!"
		b) Spanish: "¡%o1pas% %v23ps% %o3pao% %s4% veces!"-> "¡El gato lo coge 4 veces!"

	Each language library must have a function Locatize (type, param, modulation, context)
	Examples: 
		Locatize ("EN", "o", "cat", "nas") -> "the cat" // as subject
		Locatize ("EN", "o", "cat", "pao") -> "it" // as object
		Locatize ("EN", "o", "cat", "ap") -> "its" // as possesive
		Locatize ("EN", "v", "eat", "3ps") -> "eats" // as verb in present for 3rd person
		
	"Context" is an way to provide eventual aditional information, who can be needed to expand the text.
	
	to-think: syntax alternatives: %o1nas% 
		alt1: [o:n,s] is easier to read
		alt2: [o:[n,s]] maybe... JSON.parse() could be used there

*/

ludi_language.expandMSG = function  (mesIn, param) {

	if (typeof param != 'object') return mesIn;
	var txt = mesIn;
	var currentToken;
	var allTokens = ["o", "i", "v", "s", "d"];
	
	for (var iParam =0; iParam<param.length; iParam++) {
		if (typeof param[iParam] == 'undefined') continue;
		
		for (tType in allTokens) {
			currentToken = "%" + allTokens[tType] + (iParam+1); // + "%"
			
			if (txt.indexOf(currentToken) !=-1) { // token found
				
				// depending of element nature: item, verb, number, string
				if (allTokens[tType] == "o") { // short item description
					// previous version: var res = txt.replace(currentToken, ludi_language.getMessage_LongId (param[iParam].longId));
					var res = txt.replace(currentToken, ludi_language.showItemIdByLan (param[iParam].id) );
					txt = res;
				} else if (allTokens[tType] == "s") { // text as is
					// to-do: param[iParam].item or .id??
					var res = txt.replace(currentToken, param[iParam].id);
					txt = res;
				} else if (allTokens[tType] == "v") { // verb
					var res = txt.replace(currentToken, ludi_language.getMessageByLan_LongId ("actions." + param[iParam] + ".txt"));
					txt = res;
				} else if (allTokens[tType] == "d") { // direction
					var res = txt.replace(currentToken, ludi_language.getMessage_LongId (param[iParam].longId));
					txt = res;
				} else { // debug in case of missing tokenType
					var res = txt.replace(currentToken, "[" + allTokens[tType] + ":" + param[iParam] + "]");
					txt = res;
				}
				
				break; // allTokens
			}
		}
	}
	
	// language-dependent corrections
	return ludi_language.textCorrectionsByLan (txt);
	
}

ludi_language.textCorrectionsByLan = function (txtIn) {
	
	if (ludi_language.kernel_lanIndex == -1 ) return txtIn;
	
	var language = ludi_language.lanList[ludi_language.kernel_lanIndex].code;
	
	var txtOut = txtIn;
	if (language == "ES") {
		txtOut = txtOut.replace(" de el ", " del "); // contractions
		txtOut = txtOut.replace(" a el ", " al "); // contractions
	}

	// capitalize the first letter
	 return txtOut.charAt(0).toUpperCase() + txtOut.slice(1);
	
}


ludi_language.showItemIdByLan = function (itemId, connector, displaymode) {

	if (typeof itemId == 'undefined') {
		console.log ("Undefined itemId in ludi_language.showItemIdByLan");
		return "Undefined itemId"
	}

	var language = ludi_language.lanList[ludi_language.kernel_lanIndex].code; // what about ludi_language.lanIndex?? 

	// from relative loadLanguages to absolute allLanguages
	for (var ilan=0; ilan<ludi_language.allLanguages.length;ilan++) {
		if (ludi_language.allLanguages[ilan] == language)
			return ludi_language.showInternalItemByLan[ilan](itemId, connector, displaymode);
	}
	
	return "Error showing item " + itemId;
}


/*

	ES: 
		el: artículo determinado
		al: a + artículo determinado
		del: de + artículo determinado
		un: artículo indeterminado
		cd: complemento directo
		ci: complemento indirecto
		Ejemplos: 
			("Le das %o1:el %o2:al", i1, i2) -> Le das el hueso al perro  / Le dar la pelota a María
			("Le das %o1:un %o2:al", i1, i2) -> Le das un hueso al perro  / Le dar una pelota a María
			("%o1:cd coges", i1) -> Lo coges / La coges
			("%o1:pron te mira", i1) -> Ella te mira / Él te mira.
			
	EO: akuzativo ( + n)
	EN: you verb _it_  -> ES: _lo_ verb
- Flexiones de los verbos (algo similar a los casos en ruso: el usuario debería currarse metar tablas de las palabras sobre las que quiera tener esta funcionalidad; o funciones de usuario en el caso de esperanto o para el caso general)

dos maneras:
	simplemente: "%v" (usa default para ese idioma)
	con argumentos: "%v:" flag [,flag]* "%"
	más argumentos para verbos: tuteo/usted, el aspecto

Ejemplos (input: IndexAction de "look"):
	EO: %v:is% -> is(rigardi) -> rigardis 
	ES: %v:2,s,p% -> (2,s,p=2a persona del singular en presente)(mirar) -> miras
	EN: %v:3,s,p% -> (3,s,p=3a persona singular en presente)(look) -> looks
	EN: %v:ing% -> (ing)(look) -> looking	

*/

// 0: english
ludi_language.showInternalItemByLan[0] = function (itemId, connector, displaymode) { 

	var txt = "";

	if (connector) txt +=connector + " ";
		
	if (ludi_language.message_LongId_ExistsByLan  ("items." + itemId + ".article")) {
		txt += ludi_language.getMessageByLan_LongId  ("items." + itemId + ".article") + " ";
	} else {
		txt += "the ";
	}
	txt += ludi_language.getMessage_LongId ("items." + itemId + ".txt");
	
	return txt;
};

// 1: spanish
// displaymode: 1: first letter is upcase; 2: all in capitals
ludi_language.showInternalItemByLan[1] = function (itemId, connector, displaymode) { 

	/* to-do:
	
	contractions: 
		connector "a" + articulo == "el" -> "al" 
		connector "de" + articulo == "el" -> "del"
	*/
	
	var txt = "";

	if (connector) txt +=connector + " ";
		
	if (ludi_language.message_LongId_ExistsByLan  ("items." + itemId + ".articulo")) {
		txt += ludi_language.getMessageByLan_LongId  ("items." + itemId + ".articulo") + " ";
	}
	txt += ludi_language.getMessage_LongId ("items." + itemId + ".txt");

	return txt;
				
};

// 2: esperanto
// displaymode: 1: first letter is upcase; 2: all in capitals
ludi_language.showInternalItemByLan[2] = function (itemId, connector, displaymode) { 

	var txt = "";

	if (connector) txt +=connector + " ";
		
	if (ludi_language.message_LongId_ExistsByLan  ("items." + itemId + ".artikolo")) {
		txt += ludi_language.getMessageByLan_LongId  ("items." + itemId + ".artikolo") + " ";
	} else {
		txt += "la ";
	}
	
	txt += ludi_language.getMessage_LongId ("items." + itemId + ".txt");

	return txt;
				
};

ludi_language.getMessage_LongId  = function (longId) {
	var msg = "";
	var bad = false;
	
	if (typeof  ludi_language.lanList[ludi_language.lanIndex].gameMes[longId] != 'undefined'){
		msg = ludi_language.lanList[ludi_language.lanIndex].gameMes[longId].message;
	} else if (typeof  ludi_language.lanList[ludi_language.lanIndex].libMes[longId] != 'undefined'){
		msg = ludi_language.lanList[ludi_language.lanIndex].libMes[longId].message;
	} else {
		msg = longId;
		bad = true;
	}
	
	if (msg.substring(0, 1) == "@") {
		msg = ludi_language.getMessage_LongId (msg.substring(1)); // recursive
	} else if (bad){
		// to-do: check @@ behaviour after add these lines
		console.log ("Undefined longId: " + longId);
		return "";
	}
	
	return msg;
}

ludi_language.getMessageByLan_LongId  = function (longId) {
	var msg = "";
	
	if (typeof  ludi_language.lanList[ludi_language.lanIndex].gameMesByLan[longId] != 'undefined'){
		msg =  ludi_language.lanList[ludi_language.lanIndex].gameMesByLan[longId].message;
	} else if (typeof  ludi_language.lanList[ludi_language.lanIndex].libMesByLan[longId] != 'undefined'){
		msg =  ludi_language.lanList[ludi_language.lanIndex].libMesByLan[longId].message;
	} else {
		msg = longId;		
	}
	if (msg.substring(0, 1) == "@") {
		msg = ludi_language.getMessageByLan_LongId (msg.substring(1)); // recursive
	}
	return msg;
}
	
