/**
*
*
* RENDERER
*
*
**/

/*

It receives abstract showData requests and updates htmlSections on client browser.

It uses the translator module.

*/

internal_renderer = {};

// kernel language / game language
ludi_language.kernel_lanIndex = -1; 
ludi_language.lanIndex = -1; 

ludi_renderer.currentItem= -1;

// --------------------------- panel 1 elements, by view (end of definitions) ******************************

ludi_renderer.generalContext = "loadingGame"; // "loadingGame" or "playing" 

ludi_renderer.showKernelMSG_html = true;

// graphic environment
ludi_renderer.mainTab = 0; // playing
ludi_renderer.mainPanel = 0; // exits, direct-actions, items or actions of selected item
ludi_renderer.subPanel = 0; // which items: here, carried, on, or not here
ludi_renderer.itemInPanel = -1;

// click handlers: tricks rilating reference mapping
ludi_renderer.handlerToOnClick_addACTION = 'ludi' + '_play.clickAddACTION';
ludi_renderer.handlerToOnClick_executeButton = 'ludi' + '_play.executeButton';
ludi_renderer.handlerToOnClick_showItemGroup = 'ludi' + '_play.showItemGroup';
ludi_renderer.handlerToOnClick_showImage = 'ludi' + '_play.showImage';
ludi_renderer.handlerToOnClick_panelAction = 'ludi' + '_play.panelAction';
ludi_renderer.handlerToOnClick_showIActions = 'ludi' + '_play.showIActions';
ludi_renderer.handlerToOnClick_sendMessage = 'ludi' + '_play.sendMessage';
ludi_renderer.handlerToOnClick_menuSelected = 'ludi' + '_play.menuSelected';
ludi_renderer.handlerToOnChange_changeFunc = 'ludi' + '_play.changeFunc';


ludi_renderer.addLogedUserInUserList = function () { 
	defaultUser = new ludi_renderer.menu.MI_Player(
		ludi_renderer.userState.data, {}
	);
	
	defaultUser.data = ludi_renderer.userState.data;
	// defaultUser.data.idPlayer = 'anonymous';
	
	if (ludi_renderer.userState.id == "anonymous") {
		ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu.push (defaultUser);
	}
}

ludi_renderer.initialization = function  (userState) {
	ludi_renderer.userGameCodeLoaded = 0;
	
	ludi_renderer.userState = userState;
	ludi_renderer.userState.id = 'anonymous';
	ludi_renderer.addLogedUserInUserList();
	ludi_renderer.userState.profile = {markedItem: -1};


}

// distribute players in panel lists: here/game/online/offline, without overlapping

ludi_renderer.reassignPlayers = function  () {
	ludi_renderer.panelOptions[ludi_root.p1Def.HerePlayers.value].menu = [];
	ludi_renderer.panelOptions[ludi_root.p1Def.GamePlayers.value].menu = [];
	// ludi_renderer.panelOptions[ludi_root.p1Def.OfflinePlayers.value].menu = [];

	var onlinePlayers = ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value];
	
	for (var index=0; index< onlinePlayers.menu.length; index++) {
		if (onlinePlayers.menu[index].type == 0) continue;
		
		// same game
		if (onlinePlayers.menu[index].data.game == ludi_renderer.userState.data.gamename 
			&& ludi_renderer.userState.data.gamename != "" && ludi_renderer.userState.data.gamename != undefined) {
			
			var it = new ludi_renderer.menu.MI_Player(
				onlinePlayers.menu[index].data.idPlayer,
				onlinePlayers.menu[index].data );
			it.type = ludi_root.p1Def.GamePlayers.value;
			it.viewType = ludi_root.panel1ViewEnum.Players.value;
				
			ludi_renderer.panelOptions[ludi_root.p1Def.GamePlayers.value].menu.push (it);

			// same location
			if (onlinePlayers.menu[index].data.loc == ludi_renderer.userState.data.loc && onlinePlayers.menu[index].data.loc != -1) {
				it = new ludi_renderer.menu.MI_Player(
					onlinePlayers.menu[index].data.idPlayer,
					onlinePlayers.menu[index].data );
				it.type = ludi_root.p1Def.HerePlayers.value;

				ludi_renderer.panelOptions[ludi_root.p1Def.HerePlayers.value].menu.push (it);
			}

			continue;
		}

		// to-do: offline players

	}
}


 // ************************************************************************************************ 

 // here! to-do: add submenus too!
ludi_renderer.panel1Initialization = function () {
	ludi_renderer.panelOptions = [];
	ludi_renderer.mainPanel = 1; // exits

	// array initialization with viewTypes
	for (var index=0;index<ludi_root.panelInfo.length; index++) {
			ludi_renderer.panelOptions[index]= { 
			viewType: ludi_root.panelInfo[index].viewType,
			menu: []
		};
	}

	// buttons	
	ludi_renderer.menu.button=[
	    // new ludi_renderer.menu.Button (1, "PlayTab", true, 'play.jpg');
		// main buttons
		new ludi_renderer.menu.Button(1, 'PlayTab', true, 'play.jpg'),	
		new ludi_renderer.menu.Button(1, 'SocialTab', true, 'social.jpg'),
		new ludi_renderer.menu.Button(1, 'HelpView', true, 'help.jpg'),	
		new ludi_renderer.menu.Button(1, 'ChatView', false, 'chat.jpg'),

		// play buttons
		new ludi_renderer.menu.Button(2, 'GamesView', false, 'load.jpg'),	
		new ludi_renderer.menu.Button(2, 'Game', false, 'game.jpg'),
		new ludi_renderer.menu.Button(2, 'Here', false, 'here.jpg'),
		
		new ludi_renderer.menu.Button(2, 'Panels', false, 'panels.jpg'),	

		new ludi_renderer.menu.Button(2, 'SwitchOrientation', false),	// now, automatic resize instead of button
		new ludi_renderer.menu.Button(2, 'Restart', false, 'restart.png'),
		new ludi_renderer.menu.Button(2, 'SwitchView', false),
		new ludi_renderer.menu.Button(2, 'Undo', false),
		new ludi_renderer.menu.Button(2, 'ClearHistory', false),

		// network group
		new ludi_renderer.menu.Button(2, 'ActivityView', false, 'log.jpg'),	
		new ludi_renderer.menu.Button(2, 'MsgView', false, 'messages.png'),	
		new ludi_renderer.menu.Button(2, 'BoardView', false, 'board.jpg'),	

		// help group
		new ludi_renderer.menu.Button(2, 'About', true, 'about.png'),	
		new ludi_renderer.menu.Button(2, 'Instructions', true, 'question.jpg'),
		new ludi_renderer.menu.Button(2, 'GameHelp', false, 'game_help.jpg'),	
		
		// chat group
		new ludi_renderer.menu.Button(2, 'ChatGlobal', false, 'chat.jpg'),	
		new ludi_renderer.menu.Button(2, 'ChatGame', false, 'chat_game.jpg'),	
		new ludi_renderer.menu.Button(2, 'ChatLocation', false, 'chat_here.jpg'),	
		new ludi_renderer.menu.Button(2, 'ChatPrivate', false, 'chat_private.jpg'),	
		
		// profile group
		new ludi_renderer.menu.Button(2, 'GeneralSettings', false, 'config-app.png'),
		new ludi_renderer.menu.Button(2, 'MyLanguages', false, 'world.jpg'),
		new ludi_renderer.menu.Button(2, 'Login', true, 'login.jpg'),	
		new ludi_renderer.menu.Button(2, 'Logout', false, 'quit.jpg'),
		
		// secondary buttons
		new ludi_renderer.menu.Button (4, "SetLanguagePreferences", true),
		new ludi_renderer.menu.Button (4, "ShowLanguagePreferences", true),
		new ludi_renderer.menu.Button (4, "Input", true),
		new ludi_renderer.menu.Button (4, "Redescribe", true, "redescribe.png"),
		new ludi_renderer.menu.Button (4, "Save", true),
		new ludi_renderer.menu.Button (4, "Mark", true),
		new ludi_renderer.menu.Button (4, "Unmark", true),
		new ludi_renderer.menu.Button (4, "PressKey", true),
		new ludi_renderer.menu.Button (4, "Input", true),
		new ludi_renderer.menu.Button (4, "ChangeChatTo", true),
		new ludi_renderer.menu.Button (4, "ChangeChatText", true),
		new ludi_renderer.menu.Button (4, "SetFilter", true),
		new ludi_renderer.menu.Button (4, "QuitGame", true),
		new ludi_renderer.menu.Button (4, "ShowAbout", true),

		// contextual button (they require dynamic parameter/s):
		new ludi_renderer.menu.Button (4, "To", true),
		new ludi_renderer.menu.Button (4, "Text", true),
		new ludi_renderer.menu.Button (4, "RemoveLanguage", true), 
		new ludi_renderer.menu.Button (4, "UpLanguage", true),
		new ludi_renderer.menu.Button (4, "DownLanguage", true),
		new ludi_renderer.menu.Button (4, "AddLanguage", true),
		new ludi_renderer.menu.Button (4, "ChangeProfileStatus", true), 
		new ludi_renderer.menu.Button (4, "ChangeProfileMail", true),
		new ludi_renderer.menu.Button (4, "DoThis", true, 'again.png'),
		new ludi_renderer.menu.Button (4, "AboutUser", true, 'about.png'),
		new ludi_renderer.menu.Button (4, "MessageToUser", true, 'chat.jpg'),
		new ludi_renderer.menu.Button (4, "LoadGame", true, 'download.jpg'),
		new ludi_renderer.menu.Button (4, "LoadGameFromStart", false, 'download0.jpg'),
		new ludi_renderer.menu.Button (4, "LoadSavedGame", false, 'download1.jpg'),
		new ludi_renderer.menu.Button (4, "SaveGame", true, 'save.png'),
		new ludi_renderer.menu.Button (4, "AboutGame", true, 'about.png'),

	];
	
	// preloaded MI values
	// ludi_renderer.addAnonymousInUserList(); //??
	/*
	ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu=[
		ludi_renderer.userState
	];
	*/

	ludi_renderer.panelOptions[ludi_root.p1Def.PublicGames.value].menu=[
		new ludi_renderer.menu.MI_Game("tresfuentes", {type:0} ), 
		new ludi_renderer.menu.MI_Game("texel", {type:0} ), 
		// new ludi_renderer.menu.MI_Game("game1", {type:0} ),
	];
	
	ludi_renderer.panelOptions[ludi_root.p1Def.UserGames.value].menu = [
		// new ludi_renderer.menu.MI_Game("game1", {type:2, baseurl:"https://asdasdas/"} )
	];
	
	// Activity
	ludi_renderer.panelOptions[ludi_root.p1Def.GameActivity.value].menu = [];
	ludi_renderer.panelOptions[ludi_root.p1Def.LocationActivity.value].menu= [];
	ludi_renderer.panelOptions[ludi_root.p1Def.PrivateActivity.value].menu= [];

	// demo: boards (global, game, location, private)
	ludi_renderer.panelOptions[ludi_root.p1Def.GlobalBoard.value].menu = [
		new ludi_renderer.menu.MI_Board("2", {from:"admin", text: "ekzempla teksto en globala forumo", lan:"EO"} ),
		new ludi_renderer.menu.MI_Board("1", {from:"admin", text: "texto de demo en tablero global", lan:"ES"} ),
		new ludi_renderer.menu.MI_Board("0", {from:"admin", text: "demo text in global board ", lan:"EN"} ),
	];

	ludi_renderer.panelOptions[ludi_root.p1Def.GameBoard.value].menu = [
		new ludi_renderer.menu.MI_Board("2", {from:"admin", text: "ekzempla teksto en forumo de elektita ludo", lan:"EO"} ),
		new ludi_renderer.menu.MI_Board("1", {from:"admin", text: "texto de demo en tablero del juego", lan:"ES"} ),
		new ludi_renderer.menu.MI_Board("0", {from:"admin", text: "demo text in game board ", lan:"EN"} ),
	];

	// setting p1 type
	for (var index=0;index<ludi_root.panelInfo.length; index++) {
		for (var index2 in ludi_renderer.panelOptions[index].menu) {
			ludi_renderer.panelOptions[index].menu[index2].type = index;
			ludi_renderer.panelOptions[index].menu[index2].viewType = ludi_renderer.panelOptions[index].viewType;
		}
	}
	
}

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



// store message in internal cliente data
// to-do: FiltredMessages
ludi_renderer.storeMessage = function (dataFromMessage) {
	
	var messageLimit = 20;
	
	
	// always: store in AllMessages
	var it = new ludi_renderer.menu.MI_Message( 	"" + ludi_renderer.panelOptions[ludi_root.p1Def.AllMessages.value].menu.length, dataFromMessage);
		
	// ludi_root.p1Def.AllMessages.value
	it.type = ludi_root.p1Def.AllMessages.value;
	it.viewType = ludi_root.panel1ViewEnum.Messages.value;
	ludi_renderer.panelOptions[ludi_root.p1Def.AllMessages.value].menu.unshift (it);
	
	ludi_renderer.panelOptions[ludi_root.p1Def.AllMessages.value].menu = ludi_renderer.panelOptions[ludi_root.p1Def.AllMessages.value].menu.slice(0, messageLimit);	
	
	var p1Types = []; 
	
	// specific store
	if (dataFromMessage.scope == "game") { // store in GameMessages
		p1Types.push (ludi_root.p1Def.GameMessages.value);
	} else if (dataFromMessage.scope == "loc") { // store in LocationMessages
		p1Types.push (ludi_root.p1Def.LocationMessages.value);
	} else if (dataFromMessage.scope == "private") { // to-do: store in PrivateMessages
		p1Types.push (ludi_root.p1Def.PrivateMessages.value);
	}  else if (dataFromMessage.scope == "global") { // store in GlobalMessages
		p1Types.push (ludi_root.p1Def.GlobalMessages.value);
	} else if (dataFromMessage.scope == "system") { // store in GlobalMessages
		p1Types.push (ludi_root.p1Def.SystemMessages.value);
	}

	for (var i=0;i<p1Types.length;i++) {
		var it2 = new ludi_renderer.menu.MI_Message(
			"" + ludi_renderer.panelOptions[p1Types[i]].menu.length,
			it.data);
		it2.type = p1Types[i];
		ludi_renderer.panelOptions[p1Types[i]].menu.unshift (it2);
		ludi_renderer.panelOptions[p1Types[i]].menu = ludi_renderer.panelOptions[p1Types[i]].menu.slice(0, messageLimit);	
	}
	
}

ludi_renderer.setButtonVisible = function  (idSysAction, visible) {
	var saIndex = arrayObjectIndexOf(ludi_renderer.menu.button, "id", idSysAction);
	ludi_renderer.menu.button[saIndex].visible = visible;
}

ludi_renderer.setButtonParameters = function  (idName, parameters) {
	var button = ludi_renderer.getButton (idName);
	if (button) button.parameters = parameters;
}

ludi_renderer.renderer = {};

internal_renderer = {};

/* ---------------------------------------------------------------------------------------------------------------------

MENU

---------------------------------------------------------------------------------------------------------------------*/

/* Menus items for: GameItem, Player,  Game, Message, Board and Activity */

ludi_renderer.menu = {};

// Button class (start) *************************************
ludi_renderer.menu.Button = function (section, id, visible, icon, altText) { //constructor
	this.section = section;
	this.id = id;
	this.visible = visible;
	if (icon) this.icon = icon;
	
	 this.functionCall = "javascript:" + ludi_renderer.handlerToOnClick_executeButton;
}

ludi_renderer.menu.Button.prototype.getHTML = function(displayOption, altText){

	var classSection;
	var iconHTML = ludi_root.getIconHTML (this.icon,displayOption);
	// tricky: altText=='x' means no text
	var text = "";
	
	if (typeof altText === 'undefined') 
		text = ludi_renderer.showKernelMSG(this.id);
	else if (altText != 'x') 
		text = ludi_renderer.showKernelMSG(altText);

	return ludi_renderer.htmlURLBasic (
		iconHTML + text, 
		this.functionCall + "('" + this.id + "'" + ((this.parameters)? "," + this.parameters : "") + ")", 
		this.id, 
		"horiz"
	);

};


// Button class (end) *************************************

// MenuItem class (start) *************************************

ludi_renderer.menu.MenuItem = function (id) { //constructor
	this.id = id;
	this.type = -1;
}

ludi_renderer.menu.MenuItem.prototype.getHTML = function(classId){

	return this.textToShow();
	
	// to-delete:
	//var classSection;
	//if (classId !== "") classSection	= " class = \"" + classId + "\""; else classSection = "";
	
	var txt = "<li " + classSection + ">";
	txt += this.textToShow();
	txt += "</li>";
	return txt;

};

ludi_renderer.menu.MenuItem.prototype.textToShow = function(){
	return this.id;
}

ludi_renderer.menu.MenuItem.prototype.onSelected = function(){
  return "id: " + this.id;
};

ludi_renderer.menu.MenuItem.prototype.getOptionsTable = function(){
	return [{text:"back", action:-1}]; 
}

ludi_renderer.menu.MenuItem.prototype.getHeader = function(){
	return ludi_renderer.showKernelMSG(ludi_root.panelInfo[this.type].text); 
}

ludi_renderer.menu.MenuItem.prototype.getOptionsHTML = function(){

	var txt = this.getHeader();

	var table = this.getOptionsTable();

	var idName, indexList = -1;
	var idClass = "horiz"; // testing, it was "vert"
	
	if (this.viewType == ludi_root.panel1ViewEnum.Playing.value) {
		idName = "IdAction";
		indexList = 0;
	} 

	txt += "<ul class=\"" + idClass + "\">";
	
	for (var index in table) {
		txt += "<li class=\"" + idClass + "\">";
		
		if (
			this.viewType == ludi_root.panel1ViewEnum.Activity.value ||
			this.viewType == ludi_root.panel1ViewEnum.Boards.value  ||
			this.viewType == ludi_root.panel1ViewEnum.Messages.value  ||
			this.viewType == ludi_root.panel1ViewEnum.Players.value ||
			this.viewType == ludi_root.panel1ViewEnum.Games.value 
		) {
			txt += ludi_renderer.showURLGeneralOption (table[index].text, this.type, "" +  this.id, table[index].action, idName, idClass);		
		} else {
			txt += ludi_renderer.showURLGeneralAction(table[index].text, table[index].action, this.id, -1, -1, idName, idClass) 
		}
	
		txt += "</li>";
	} 
	
	txt += "</ul>";
	return txt;
}


// MenuItem class (end) *************************************

// child prototypes

ludi_renderer.menu.MI_GameItem = function (id, data) {   ludi_renderer.menu.MenuItem.call(this, id);  this.data = data; };
ludi_renderer.menu.MI_GameItem.prototype = Object.create(ludi_renderer.menu.MenuItem.prototype); 
ludi_renderer.menu.MI_GameItem.prototype.constructor = ludi_renderer.menu.MI_GameItem; 

// MI_GameItem (start) *************************************
// MI_GameItem (end) *************************************

ludi_renderer.menu.MI_Player = function (id, data) {   ludi_renderer.menu.MenuItem.call(this, id);  this.data = data; };
ludi_renderer.menu.MI_Player.prototype = Object.create(ludi_renderer.menu.MenuItem.prototype); 
ludi_renderer.menu.MI_Player.prototype.constructor = ludi_renderer.menu.MI_Player; 

ludi_renderer.menu.MI_Game = function (id, data) {   ludi_renderer.menu.MenuItem.call(this, id);  this.data = data; };
ludi_renderer.menu.MI_Game.prototype = Object.create(ludi_renderer.menu.MenuItem.prototype); 
ludi_renderer.menu.MI_Game.prototype.constructor = ludi_renderer.menu.MI_Game; 

ludi_renderer.menu.MI_Message = function (id, data) {   ludi_renderer.menu.MenuItem.call(this, id);  this.data = data; };
ludi_renderer.menu.MI_Message.prototype = Object.create(ludi_renderer.menu.MenuItem.prototype); 
ludi_renderer.menu.MI_Message.prototype.constructor = ludi_renderer.menu.MI_Message; 

ludi_renderer.menu.MI_Board = function (id, data) {   ludi_renderer.menu.MenuItem.call(this, id);  this.data = data; };
ludi_renderer.menu.MI_Board.prototype = Object.create(ludi_renderer.menu.MenuItem.prototype); 
ludi_renderer.menu.MI_Board.prototype.constructor = ludi_renderer.menu.MI_Board; 

ludi_renderer.menu.MI_Activity = function (id, data) {   ludi_renderer.menu.MenuItem.call(this, id);  this.data = data; };
ludi_renderer.menu.MI_Activity.prototype = Object.create(ludi_renderer.menu.MenuItem.prototype); 
ludi_renderer.menu.MI_Activity.prototype.constructor = ludi_renderer.menu.MI_Activity; 

// CHILD METHODS (start) ************************************************************************** 


// MI_Player (start) *************************************

ludi_renderer.menu.MI_Player.prototype.textToShow = function(classId){
	var txt;
				
	txt = "<p class=\"msg\">";
	// txt += this.id;
	// link to send message
	ludi_renderer.setButtonParameters ("MessageToUser", "'" + this.id + "'");
	txt += ludi_renderer.htmlOfButtonAs("MessageToUser", "x");

	// about user
	ludi_renderer.setButtonParameters ("AboutUser", "'" + this.id + "'");
	txt += ludi_renderer.htmlOfButtonAs("AboutUser", "x");
	
	txt += this.id;
	
	/*
	table.push ({text:ludi_renderer.showKernelMSG('GeneralSettings'), action:1});
	//table.push ({text:ludi_renderer.showKernelMSG("Ignore for 5 minutes"), action:4});
	//table.push ({text:ludi_renderer.showKernelMSG("Add to black list"), action:5});
	//table.push ({text:ludi_renderer.showKernelMSG("Rremove from black list"), action:6});
	//table.push ({text:ludi_renderer.showKernelMSG("Add to friend list"), action:7});	
	//table.push ({text:ludi_renderer.showKernelMSG("Remove from friend list"), action:8});	
	//table.push ({text:ludi_renderer.showKernelMSG("Send my game state"), action:9});	
	*/
	
	txt += "</p>";
	
	return txt;

}

ludi_renderer.menu.MI_Player.prototype.getHeader = function () {

	var txt = "";
	if (this.id != ludi_renderer.userState.data.idPlayer) {
		txt += ludi_renderer.showKernelMSG("Actions on player") + " " + this.id;	
		return txt;
	}

	// own profile
	txt += "<h4>" + ludi_renderer.showKernelMSG("Your profile") + "</h4>";
		
	txt += "<table COLS=\"2\">";
	txt += "<tr>";
		txt += "<td>";
		txt += ludi_renderer.showKernelMSG("nick") + ": " + ludi_renderer.userState.data.idPlayer;
		txt += "</td>";
	txt += "</tr>";
	
	// clickable settings
	var msgIdSettings = [];
	
	msgIdSettings.push ({title: "MessagesHidden",options: ["true", "false"]});
	msgIdSettings.push ({title: "ActivityHidden",options: ["true", "false"]});
	msgIdSettings.push ({title: "SpeechOn",options: ["true", "false"]});

	if (this.id != "anonymous") {

		txt += "<tr>";
			txt += "<td>";
			txt += ludi_renderer.showKernelMSG("mail") + ": ";
			txt += "</td>";
			txt += "<td>";
			txt += ludi_renderer.htmlOfButtonAs("ChangeProfileMail", "Text");
			txt += "<b>" + ludi_renderer.userState.data.profile.email + "</b>";
			txt += "</td>"
		txt += "</tr>";

		// typeable settings
		txt += "<tr>";
			txt += "<td>";
			txt += ludi_renderer.showKernelMSG("status") + ": ";	
			txt += "</td>";
			txt += "<td>";
			txt += ludi_renderer.htmlOfButtonAs("ChangeProfileStatus", "Text");
			txt += "<b>" + ludi_renderer.userState.data.profile.status + "</b>";
			txt += "</td>";
		txt += "</tr>";
		
		// more clickable settings
		msgIdSettings.push(	{title: "IncomingLanguages", options: ["all", "preferedLanguages", "myGame"]});
		msgIdSettings.push( {title: "BroadcastFrom",options: [ "everywhere", "myGame", "myLocation"]});
		msgIdSettings.push(	{title: "ActivityFrom", options: ["myGame", "myLocation", "none"]});
		msgIdSettings.push(	{title: "ActivityTo", options: ["myGame", "myLocation", "none"]	});
	}
	
	// values
	for (var i=0;i<msgIdSettings.length;i++) {
		txt += "<tr>";
			txt += "<td>";
			txt += ludi_renderer.showKernelMSG (msgIdSettings[i].title) + ": ";
			txt += "</td>";
			for (var j=0;j<msgIdSettings[i].options.length;j++) {
				txt += "<td>";
				if (j == ludi_renderer.userState.data.profile.filters[i]) {
					txt += "<b>" + ludi_renderer.showKernelMSG(msgIdSettings[i].options[j]) + "</b>";
				} else {
				
					ludi_renderer.setButtonParameters ("SetFilter", "'" + i +"', '" + j + "'");
					
					// txt += ludi_renderer.htmlURLsysAction (msgIdSettings[i].options[j], "SetFilter", "SetFilter", "horiz", "'" + i +"', '" + j + "'");
					
					txt += ludi_renderer.htmlOfButtonAs("SetFilter", msgIdSettings[i].options[j]);
				}
				txt += "</td>";
			}
		txt += "</tr>";
	}

	txt += "</table>";
	
	return txt;

}
// MI_Player (end) *************************************

// MI_Game (start) *************************************
ludi_renderer.menu.MI_Game.prototype.getOptionsTable = function(classId){

	var table = [];
	
	if (ludi_renderer.generalContext == "loadingGame") {
		table.push ({text:ludi_renderer.showKernelMSG("Load game from start"), action:0});
	}
	table.push ({text:ludi_renderer.showKernelMSG("About game"), action:1});
	if (ludi_renderer.userState.data.idPlayer != 'anonymous') {
		table.push ({text:ludi_renderer.showKernelMSG("Who are playing now"), action:2});
	} 
	return table;
	
}

ludi_renderer.menu.MI_Game.prototype.textToShow = function(classId){
	var txt;
	
	txt = "<table><tr>";
	txt += "<td>" + this.id + "</td>";

	// about game
	ludi_renderer.setButtonParameters ("AboutGame", "'" + this.id + "'");
	txt += "<td>" + ludi_renderer.htmlOfButtonAs("AboutGame", "x")  + "</td>";
	
	// load game from file
	ludi_renderer.setButtonParameters ("LoadGame", "'" + this.id + "'");
	txt += "<td>" + ludi_renderer.htmlOfButtonAs("LoadGame", "x")  + "</td>";

	// load game from localStorage
	// to-do: ludi_renderer.setButtonParameters ("LoadGameFromStart", "'" + this.id + "'");
	// to-do: txt += "<td>" + ludi_renderer.htmlOfButtonAs("LoadGameFromStart", "x")  + "</td>";

	// load saved game from localStorage
	// to-do: ludi_renderer.setButtonParameters ("LoadSavedGame", "'" + this.id + "'");
	// to-do: txt += "<td>" + ludi_renderer.htmlOfButtonAs("LoadSavedGame", "x")  + "</td>";

	txt += "</tr></table>";

	return txt;

}

ludi_renderer.menu.MI_Game.prototype.getHeader = function () {
	
	var txt = "<H4>";
	txt += ludi_renderer.showKernelMSG("Actions on game") + " " + this.id;
		
	txt += "</H4>";
	
	return txt;
	
};
// MI_Game (end) *************************************

// MI_ Message (start) *************************************
ludi_renderer.menu.MI_Message.prototype.getOptionsTable = function(classId){

	var table = [];
	
	table.push ({text:ludi_renderer.showKernelMSG("Write message to sender"), action:0});
	
	return table;
	
}


ludi_renderer.menu.MI_Message.prototype.getHeader = function () {
	var txt = "<H4>";
	txt += ludi_renderer.showKernelMSG("Actions on message") + " " + this.id;
		
	txt += "</H4>";
	
	return txt;

};

ludi_renderer.menu.MI_Message.prototype.textToShow = function(classId){
	var txt;
				
	txt = "<p class=\"msg\">";
	
	//txt += this.id + "#"; 
	txt += this.data.from;
	if (this.data.lan != "*" && this.data.from != "web browser") {
		txt += "(" + this.data.lan + ")"; 
		
		// here!! indeed!
		
		// link to user (sender)
		ludi_renderer.setButtonParameters ("AboutUser", "'" + this.data.from + "'");
		// txt += ludi_renderer.htmlOfButtonAs("AboutUser", "x");
		txt += ludi_renderer.htmlOfButtonAs("AboutUser", this.data.from, 2); // 2: no icon
		
		// link to send message
		ludi_renderer.setButtonParameters ("MessageToUser", "'" + this.data.from + "'");
		txt += ludi_renderer.htmlOfButtonAs("MessageToUser", "x");
				
	}
	txt += ": "; 	
	txt += this.data.txt; 
	txt += "</p>";
	
	return txt;

}

// MI_ Message (end) *************************************
 
// MI_ Board (start) *************************************
ludi_renderer.menu.MI_Board.prototype.getOptionsTable = function(classId){

var table = [];
	
	table.push ({text:ludi_renderer.showKernelMSG("Send message to the sender"), action:0});
	table.push ({text:ludi_renderer.showKernelMSG("Resend as a message"), action:1});
	table.push ({text:ludi_renderer.showKernelMSG("Add comment in current language"), action:2});
	
	if (this.data.from == ludi_renderer.userState.data.idPlayer) {
		table.push ({text:ludi_renderer.showKernelMSG("Delete comment"), action:2});
	}
	
	return table;
	
}

ludi_renderer.menu.MI_Board.prototype.getHeader = function () {
	
	var txt = "<H4>";
	txt += ludi_renderer.showKernelMSG("Actions on selected item");
	//txt += ludi_renderer.showKernelMSG( ludi_root.panelInfo[this.type].text);
	txt += " " + this.id;
		
	txt += "</H4>";
	
	return txt;

};

ludi_renderer.menu.MI_Board.prototype.textToShow = function(classId){


	var txt;
	
	txt = "<p class=\"msg\">";
	// txt += this.id + ": "; 

	// link to user (sender)
	ludi_renderer.setButtonParameters ("AboutUser", "'" + this.data.from + "'");
	txt += ludi_renderer.htmlOfButtonAs("AboutUser", "x");
	// link to send message
	ludi_renderer.setButtonParameters ("MessageToUser", "'" + this.data.from + "'");
	txt += ludi_renderer.htmlOfButtonAs("MessageToUser", "x");

	// link to delete own message
	if (this.data.from == ludi_renderer.userState.data.idPlayer) {
		ludi_renderer.setButtonParameters ("DeleteMessageOnBoard", "'" + this.id + "','" + this.data.from + "'");
		txt += ludi_renderer.htmlOfButtonAs("DeleteMessageOnBoard", "delete");
	}

	// to-do: as a general command:	"Add comment in current language"

	txt += this.data.from;
	txt += "(" + this.data.lan + "): "; 
	txt += this.data.text; 
	txt += "</p>";

	return txt;

}
 // MI_ Board (end) *************************************
 
// MI_ Activity (start) *************************************
ludi_renderer.menu.MI_Activity.prototype.getOptionsTable = function(classId){

	var table = [];
	
	if (ludi_renderer.userState.data.idPlayer != "anonymous") {
		table.push ({text:ludi_renderer.showKernelMSG("Private message"), action:0});
	}

	table.push ({text:ludi_renderer.showKernelMSG("Do the same action"), action:1});
	
	return table;
	
}

ludi_renderer.menu.MI_Activity.prototype.getHeader = function () {
	
	
	var txt = "<H4>";
	// txt += ludi_renderer.showKernelMSG("Actions on activity") + " " + this.id;

	txt += this.data.idPlayer + ": ";
	txt += ludi_renderer.getEcho (this.data.par_c, true);
	txt += "</H4>";
	
	return txt;
	
};

ludi_renderer.menu.MI_Activity.prototype.textToShow = function(classId){
	var txt;
	
	txt = "<p class=\"activity\">";

	// link to user (sender)
	ludi_renderer.setButtonParameters ("AboutUser", "'" + this.data.idPlayer + "'"); 
	txt += ludi_renderer.htmlOfButtonAs("AboutUser", this.data.idPlayer, 2);

	txt += this.data.idPlayer;
	txt += " > ";
	
	// to-do: verify (assumes par_c was already expanded
	// txt += ludi_renderer.getEcho (this.data.par_c, false); // really false??
	txt += ludi_renderer.getEcho (this.data.par_c, false); // really false??
	
	// button to redo this action
	ludi_renderer.setButtonParameters ("DoThis", [this.data.par_c.action, this.data.par_c.item1, this.data.par_c.item2, this.data.par_c.direction]); 
	txt += ludi_renderer.htmlOfButtonAs("DoThis", "x");
		
	// to-do: mensage-to , if it's another user
		
	txt += "." + "</p>";

	return txt;

}

 // MI_ Activity (end) *************************************
 
 // CHILD METHODS (end) 
 



/* ---------------------------------------------------------------------------------------------------------------------

RENDER CORE
---------------------------------------------------------------------------------------------------------------------*/

ludi_renderer.getEcho = function (par_c, isOwn) {
	
	var echo="";
	
	if (!isOwn) echo += "(" + ludi_language.getMessage_LongId ("items." + par_c.locId + ".txt") + ")";
	
	echo += ludi_language.getMessage_LongId ("actions." + par_c.actionId + ".txt");

	if (par_c.item1>=0) 
		echo += " " + ludi_root.echoSeparator + " " + 
			    ludi_language.getMessage_LongId ("items." + par_c.item1Id + ".txt");
	
	if (par_c.item2>=0) 
		echo += " " + ludi_root.echoSeparator + " " + 
			    ludi_language.getMessage_LongId ("items." + par_c.item2Id + ".txt");

	if (par_c.direction>=0) 
		echo += " " + ludi_root.echoSeparator + " " + 
				ludi_language.getMessage_LongId ("directions." + par_c.directionId + ".txt");
				
	echo += ".";
	
	return echo;
	
}

internal_renderer.createMenu_ViewButtons = function  (sectionId, classId) {

	var classId = classId || "horiz";
	var txt = "";
	var sysActionId = "";
	
	txt += "<ul class =\"classId\"";
	for (var saIndex in ludi_renderer.menu.button) {
		if (ludi_renderer.menu.button[saIndex].section != sectionId) continue;
		sysActionId = ludi_renderer.menu.button[saIndex].id;
		txt += "<li class=\"" + classId + "\">";
		txt += ludi_renderer.htmlOfButton(sysActionId, classId);
		txt += "</li> ";	
	}
	txt +="</ul>";
	
	return txt;
}

ludi_renderer.showURLGeneralOption = function   (txt, type, objectId, idAction, idClass) {
	
	idClass = idClass || "horiz";

	var idName = "suboption";
	var url = 'javascript:' + ludi_renderer.handlerToOnClick_panelAction + '(' + type + ", '" + objectId + "', " + idAction + ');';
	return ludi_renderer.htmlURLBasic (txt, url, idName, idClass);
}

ludi_renderer.showURLGeneralAction = function   (txt, indexAction, indexItem1, indexItem2, direction, idName, idClass) {
	
	idClass = idClass || "horiz";
	
	var url = 'javascript:' + ludi_renderer.handlerToOnClick_addACTION;
	var txt2 = txt;
	
	var par = indexAction;
	par += ',' + indexItem1;
	par += ',' + indexItem2;
	par += ',' + direction;
	if ((indexItem2!= -1) && (indexAction != ludi_root.actEnum.LOOK_DIR.value)) { 
		txt2 = txt + "(2)";
	}

	url += '(' + par + ');'
	
	return ludi_renderer.htmlURLBasic (txt2, url, idName, idClass);
}

ludi_renderer.htmlPanelView = function  (panel1View) {

	var txt = "<H3>" + ludi_renderer.showKernelMSG(ludi_root.panel1ViewMessages[panel1View].text) + "</H3> ";

	if (panel1View == ludi_root.panel1ViewEnum.Playing.value) {
		txt += ludi_renderer.htmlAvailableUserActions();
		return txt;
	}
	
	var classId = "";
	var classSection ="";
	if (classId != "") classSection	= " class = \"" + classId + "\""; else classSection = "";

	
	txt += "<ul class=\"vert\">";
	
	for (var option in ludi_renderer.panelOptions) {
		if (ludi_renderer.panelOptions[option].menu.length > 0) {

			if (ludi_renderer.panelOptions[option].viewType != panel1View ) continue;

			if ((ludi_renderer.panelOptions[option].viewType ==  ludi_root.panel1ViewEnum.Players.value) &&
				 (ludi_renderer.userState.data.idPlayer == 'anonymous') )
				 continue;

			// only show private activity if offline
			if ((ludi_renderer.panelOptions[option].viewType ==  ludi_root.panel1ViewEnum.Activity.value) &&
				 (ludi_renderer.userState.data.idPlayer == 'anonymous') ) {
				 if (option != ludi_root.p1Def.PrivateActivity.value) continue;
			}
			
			txt += "<li " + classSection + " >" ;
			txt += internal_renderer.showButtonToItemGroup (option);
			txt += 	"</li>";			
		}	
	}
				
	// back button
	if ((ludi_renderer.mainTab == 0) && !ludi_root.visiblePanels) {
			
		txt += "<li" + classSection + ">" ;
		txt +=  ludi_renderer.htmlURLsysAction(ludi_renderer.showKernelMSG ("Back"), "PlayTab", "PlayTab");
		txt += 	"</li>";			
	}
	txt += "</ul>";
	return txt;

}

ludi_renderer.getPanel2_Generic = function  (table) {

	var line="";
	var classId = "horiz"; // testing, it was "vert"
	var classSection;
	
	if (classId != "") classSection	= " class = \"" + classId + "\""; else classSection = "";
	
	var txt ="";
	//var txt = "<ul " + classSection + ">";
	// here!! indeed!
	
	for (var index in table) {
		//txt += "<li" + classSection + ">" ;
		txt += table[index].getHTML(classId) + "<br/>";
		//txt += 	"</li>";
	}
	
	//txt +="</ul>";

	if (table.length>0) return txt;
	return "";	
}

ludi_renderer.getActionsOnItem = function   () {

	var actionsOfItem;

	if (ludi_renderer.itemInPanel == -1) return;
	
	if ((ludi_renderer.subPanel >= ludi_root.p1Def.Here.value) && (ludi_renderer.subPanel <= ludi_root.p1Def.NotHere.value) &&
		(ludi_renderer.itemInPanel < ludi_renderer.panelOptions[ludi_renderer.subPanel].menu.length)) // case in multiple action selection
	{ 
		actionsOfItem = ludi_renderer.panelOptions[ludi_renderer.subPanel].menu[ludi_renderer.itemInPanel].data; 
	} else return;
	
	ludi_renderer.currentItem = actionsOfItem.item;
	ludi_renderer.currentItemId = actionsOfItem.itemId;
	return actionsOfItem.actions;
	
}


ludi_renderer.getCommonActions  = function  () {
	
	var tableItems = ludi_renderer.panelOptions[ludi_renderer.subPanel].menu;
	
	var counters = [];
	var actionsId = [];
	
	// for each item, increment count on its actions
	for (i in tableItems) {
		for (a in tableItems[i].data.actions) {
			if (counters [tableItems[i].data.actions[a].action] == undefined) {
				counters [tableItems[i].data.actions[a].action] = 1;
				actionsId [tableItems[i].data.actions[a].action] = tableItems[i].data.actions[a].actionId;
			} else {
				counters [tableItems[i].data.actions[a].action] ++;
			}
		}
	}

	var commonActions = [];
	// only actions with maximum counter will be shown
	for (c in counters) {
		if (counters[c] == tableItems.length) {
			// to-do: do not push "mark" action 
			commonActions.push({action: c, actionId:actionsId[c]});
		}
	}
	
	return commonActions;
	
}

ludi_renderer.getPanel2_ItemsIn = function  (table) {
	
	var line="";
	var classId = "horiz"; // testing, it was "vert"
	var classSection;

	if (classId != "") classSection	= " class = \"" + classId + "\""; else classSection = "";
	
	var txt = "<ul " + classSection + ">";
	
	for (var index in table) {
		var idText =  ludi_language.showItemIdByLan (table[index].data.itemId);
		line = "<li " + classSection + ">" + ludi_renderer.htmlURLBasic (idText, 'javascript:' + ludi_renderer.handlerToOnClick_showIActions + '(' + index + ');', "idName", classId) + "</li>";
		txt +=line;
	}

	// multiple actions with a click (index: -2)
	if (table.length > 1) {
		var lineAll = ""; 
		txt += "<li " + classSection + ">" + ludi_renderer.htmlURLBasic ("(" + ludi_renderer.showKernelMSG("All of them") + ")", 'javascript:' + ludi_renderer.handlerToOnClick_showIActions + '(' + "-2" + ');',  "idName", classId) + "</li>";
	}
		
	txt +="</ul>";

	if (table.length>0) return txt;
	return "";

}

ludi_renderer.htmlPanelConnections = function  (table, world) {

	var txt ="";
	
	if (table.length == 0)  {
		txt = txt  + ludi_renderer.showKernelMSG("nowhere") ;
		return txt;
	}

	txt +="<ul>";
	for(var i = 0; i < table.length ; i++) {
		if (table[i].data.dir <0) continue; // preventive
		var dirId = world.directions[table[i].data.dir].id;
		
		var connection = ludi_language.getMessage_LongId ("directions." +  dirId + ".txt");
		
		// only if item is in a known place: show taget name (maye customizable option in the future)
		if (typeof world.items[ludi_renderer.userState.profile.indexPC].state.itemsMemory[table[i].data.target] != "undefined") {
			
			var idText =  ludi_language.showItemIdByLan (table[i].data.targetId);

			connection =  connection + ": " + idText;
		}

		// considering table[i].data.actions (if look-dir exists)
		if (typeof table[i].data.actions != "undefined") {
			
			for (var j=0;j<table[i].data.actions.length;j++) {
				var actionIndex = table[i].data.actions[j];
				var actionId = table[i].data.actionsId[j];
				
				if (actionIndex == ludi_root.actEnum.GO.value) {
					// going to direction
					
					txt += "<li class=\"horiz\">" + 
					ludi_renderer.showURLGeneralAction(connection, actionIndex, -1, -1, table[i].data.dir, "IdGo") +
					"</li>";
				} else if (actionIndex == ludi_root.actEnum.LOOK_DIR.value) {
					// description in that direction
					
					txt += "<li class=\"horiz\">";
					
					txt += ludi_renderer.showURLGeneralAction(
						connection + "(" + ludi_language.getMessage_LongId ("actions." + actionId + ".txt") + ")", 
						actionIndex, -1, -1, table[i].data.dir,  "IdLook_Dir");
						
					txt += "</li>";
				}
			}
			
			
		}
	}

	txt +="</ul>";
	return txt;
}

ludi_renderer.getPanel2_DirectActions = function   (table) {

	var txt = "<ul>";

	for (var index in table) {
		var actionIndex = table[index].data.action;
		var actionId = ludi_routing.getIdFromTypeAndIndex ("actions", table[index].data.action);
		
		txt += "<li class=\"horiz\">" + 
			   ludi_renderer.showURLGeneralAction(ludi_language.getMessage_LongId ("actions." + actionId + ".txt"), actionIndex,  -1, -1, -1, "IdAction") + 
			   "</li>";
	} 
	
	return txt + "</ul>";
}

ludi_renderer.showLanguagePreferences = function  (tempUserLanguages, lanList) {

	var txt = "<table border = \"1\">";
	
	txt += "<tr>";

	txt +="<td>" + ludi_renderer.showKernelMSG("MyLanguages") + "</td>";
	txt += "<td>" + ludi_renderer.showKernelMSG("Available languages") + "</td>";
	txt += "</tr>";
	
	txt += "<tr>";

	var side = ["",""];
		
	for (var ilan=0;ilan<tempUserLanguages.length;ilan++) {
		side[0] += "<div><p>" + tempUserLanguages[ilan] + "</p>";
		ludi_renderer.setButtonParameters ("RemoveLanguage", "'" + tempUserLanguages[ilan] + "'"
		);
		side[0] += ludi_renderer.htmlOfButtonAs("RemoveLanguage", "remove");
		if (ilan>0) {
			ludi_renderer.setButtonParameters ("UpLanguage", "'" + tempUserLanguages[ilan] + "'"
			);
			side[0] += ludi_renderer.htmlOfButtonAs("UpLanguage", "up");
		}
		if (ilan<tempUserLanguages.length-1) {
			ludi_renderer.setButtonParameters ("DownLanguage", "'" + tempUserLanguages[ilan] + "'"
			);
			side[0] += ludi_renderer.htmlOfButtonAs("DownLanguage", "down");
		}
		side[0] += "</div><br/>"
	}
		
	for (var ilan=0;ilan<lanList.length;ilan++) {
		if (!lanList[ilan].isUserPreference) {
			side[1] += "<div><p>" + lanList[ilan].code + "</p>";
			
			ludi_renderer.setButtonParameters ("AddLanguage", "'" + lanList[ilan].code + "'"
			);
			side[1] += ludi_renderer.htmlOfButtonAs("AddLanguage", "add");
			
			
			side[1] += "</div><br/>"
		}
	}	
	
	txt += "<td>" + side[0] + "</td>";
	txt += "<td>" + side[1] + "</td>";
	
	txt += "</tr>";
	txt += "</table>";

	txt += "<p>";
	txt += ludi_renderer.htmlOfButtonAs("SetLanguagePreferences", "Apply changes");
	txt += "</p>";

	return txt;
	
	
}

ludi_renderer.getButton = function  (idName) {
	var indexButton =  arrayObjectIndexOf (ludi_renderer.menu.button, "id", idName);
	if (indexButton>=0) return ludi_renderer.menu.button[indexButton];
	return null;
}

ludi_renderer.htmlOfButton = function  (idName, displayOption) {  

	var button = ludi_renderer.getButton (idName);
	if (button) return button.getHTML (displayOption);
	console.log ("Alert: missing button creation: " + idName);
	return "";
}

ludi_renderer.htmlOfButtonAs = function  (idName, txt, displayOption) {  

	var button = ludi_renderer.getButton (idName);
	if (button) return button.getHTML (displayOption, txt);
	return "";
}

internal_renderer.showButtonToItemGroup = function  (itemGroupId, displayOption) {

	displayOption = (displayOption || 0);

	var counter = 	ludi_renderer.panelOptions[itemGroupId].menu.length;
	if (counter == 0) return "";
	
	var label = "", size;
	if (displayOption == 0) {
		label= ludi_renderer.showKernelMSG(ludi_root.panelInfo[itemGroupId].text);
		size=32;
	} else {
		size=20;
	}
	
	var funcName = ludi_renderer.handlerToOnClick_showItemGroup + "(" + itemGroupId + ")";
	
	var icon = "";
	if (typeof ludi_root.panelInfo[itemGroupId].icon !== 'undefined') {
		icon ="<IMG src='";
		icon += './client/icons/' + ludi_root.panelInfo[itemGroupId].icon;
		icon += "' ";
		icon += "alt='config'  height='" + size + "' width='" + size + "'>" ;
	}
	
	return 	ludi_renderer.htmlURLBasic ( 
			icon + label + " (" + counter + ")", 
			"javascript:" + funcName  + ";",
			"idName", "horiz"
	);
}

ludi_renderer.messageInput_html = function () {
 
	var txt = "<p id='lblChat'></P>";

	txt += "<table>";
	
	txt += "<tr><td>";
	txt += ludi_renderer.showKernelMSG ("Language") + ": <select name='cmbMsgLan' id='cmbMsgLan' onchange='" + ludi_renderer.handlerToOnChange_changeFunc + "(\"cmbMsgLan\");'></select> ";
	txt += "</td></tr>";

	txt += "<tr><td>";
	txt += "<span id='spanMsgTo'>"
		txt += ludi_renderer.htmlOfButtonAs("ChangeChatTo", "To");
		txt += "<b><span id='lblMsgTo'></span></b>";
	txt += "</span>"
	txt += "</td></tr>";
			
	txt += "<tr><td>";
	txt += ludi_renderer.htmlOfButtonAs("ChangeChatText", "Text");
	txt += "<b><span id='lblMsgText'></span></b>";
	txt += "</td></tr>";

	txt += "<tr><td>";
	txt += '<button id="button_sendMsg" onclick="' + ludi_renderer.handlerToOnClick_sendMessage + '();">send</button>';

	txt += "</td></tr>";

	txt += "</table>";
	return txt;
	
}

ludi_renderer.getMessage_HTML = function (data) {

	var lanCode;

	lanCode = (ludi_language.lanIndex>=0) ? ludi_language.lanList[ludi_language.lanIndex].code : ludi_language.lanList[0].code;

	// incoming messages hiden till logon
	// if (ludi_renderer.userState.data.idPlayer == "anonymous") return "";

	var txt = "<p class='";
	if (data.from == ludi_renderer.userState.data.idPlayer) { // echo
		txt += "own_"; 
	}
	txt += "msg'>";
	
	txt += "(" + data.scope + ")"; 
	
	txt += data.from;

	if (data.lan != '*'  && data.lan != lanCode) {
		txt += "(" + data.lan + ")"
	}
	txt += ": " + data.txt + "</p>";
	
	return txt;

}

// displayOption: 0 normal, 1 short
ludi_renderer.htmlAvailableUserActions = function  (displayOption) {  
	
	displayOption = (displayOption || 0);

	var txt = "";
	if (displayOption ==0) {
		var idText =  ludi_language.showItemIdByLan (ludi_renderer.userState.profile.currentLocId);
		
		txt += "<p>" + ludi_renderer.showKernelMSG("Location") + ":" + idText + "</p>";
		txt += ludi_renderer.htmlOfButton ("Redescribe", "horiz", displayOption);
	}

	txt += internal_renderer.showButtonToItemGroup (ludi_root.p1Def.Carried.value, displayOption);
	txt += internal_renderer.showButtonToItemGroup (ludi_root.p1Def.On.value, displayOption);
	txt += internal_renderer.showButtonToItemGroup (ludi_root.p1Def.Exit.value, displayOption);
	txt += internal_renderer.showButtonToItemGroup (ludi_root.p1Def.Here.value, displayOption);
	txt += internal_renderer.showButtonToItemGroup (ludi_root.p1Def.DirectAction.value, displayOption);
	txt += internal_renderer.showButtonToItemGroup (ludi_root.p1Def.NotHere.value, displayOption);
	
	if (ludi_renderer.userState.profile.markedItem >=0) { 
		txt += internal_renderer.showButtonToItemGroup (ludi_root.p1Def.Marked.value, displayOption);
	} 

	// social buttons
	if (ludi_renderer.userState.data.idPlayer != "anonymous") {
		txt += internal_renderer.showButtonToItemGroup (ludi_root.p1Def.HerePlayers.value, displayOption);
		txt += ludi_renderer.htmlOfButton ("ChatLocation", "horiz", displayOption);
	}
	
	return txt;
	
}



ludi_renderer.htmlIActions = function  (actionList) {

	// if ((ludi_renderer.subPanel < ludi_root.p1Def.Here.value) || (ludi_renderer.subPanel > ludi_root.p1Def.NotHere.value)) return ;

	var txt = "";
	
	if (index == -2) { // all actions
		txt = ludi_renderer.getPanel2_CommonActions (ludi_renderer.panelOptions[ludi_renderer.subPanel].menu);
	} else {
		ludi_renderer.itemInPanel = index;
		txt = ludi_renderer.getPanel2_ActionsOnItem();
		// mark button
		txt +=  ludi_renderer.htmlURLsysAction (ludi_renderer.showKernelMSG ("Mark"), "Mark", "Mark", "horiz", index);
	}
	
	// back button
	txt +=  ludi_renderer.htmlURLBasic (
		ludi_renderer.showKernelMSG("Back"), 
		'javascript:' + ludi_renderer.handlerToOnClick_showItemGroup + '(' + ludi_renderer.subPanel  + ');', 
		this.id, 
		"horiz"
	);
	
	return txt;
	
	
}


ludi_renderer.htmlCommonActions  = function  (commonActions) {

	var txt = "<H4>" + ludi_renderer.showKernelMSG("Common Actions") + "</H4><ul>";
	ludi_renderer.currentItem = -2;
	for (var index in commonActions) {
		
		// to-do: pending to generate outside
		var actionIndex = commonActions[index].action;
		var actionId = commonActions[index].actionId;
		
		txt += "<li class=\"horiz\">" + 
		       ludi_renderer.showURLGeneralAction(	ludi_language.getMessage_LongId ("actions." + actionId + ".txt") , actionIndex, ludi_renderer.currentItem, -1, -1, "IdAction") + 
			   "</li>";	
	} 
	
	txt += "</ul>";	
	
	return txt;
	
}

ludi_renderer.htmlActionsOnItem = function   (actionNames, table) {
	
	var txt = "<H4>" + ludi_renderer.showKernelMSG("Actions on o1", [ludi_renderer.currentItemId]) + "</H4><ul>";
	var indexAct;

	for (var index in table) {
		indexAct = table[index].action;
		if (ludi_renderer.userState.profile.markedItem == -1 && table[index].numPars == 2) continue; // ignore 2-parameters actions
		if (table[index].numPars == 1) { // just obj1
			txt += "<li class=\"horiz\">" + ludi_renderer.showURLGeneralAction(actionNames[index], indexAct, ludi_renderer.currentItem, -1, -1, "IdAction") + "</li>";
		} else if (ludi_renderer.userState.profile.markedItem != -1 & table[index].numPars == 2) { // obj1 and obj2
			txt += "<li class=\"horiz\">" + ludi_renderer.showURLGeneralAction(actionNames[index], indexAct, ludi_renderer.currentItem, ludi_renderer.userState.profile.markedItem , -1,"IdAction") + "</li>";
		} else { // instransitive
			txt += "<li class=\"horiz\">" + ludi_renderer.showURLGeneralAction(actionNames[index], indexAct, -1, -1, -1, "IdAction") + "</li>";
		}
	} 
	
	return txt + "</ul>";
}

ludi_renderer.htmlMenuEnvironment = function  () {
	var txt = "";
	var sysActionId = "";

	
	txt += "<table>";
		txt += "<tr>";
		
			// main buttons
			txt += "<td>";
				txt += internal_renderer.createMenu_ViewButtons (1, "horiz"); 
			txt += "</td>";

			// language
			txt += "<td>";
				//txt +="<span id='languageLbl'>" + ludi_renderer.showKernelMSG("Language") + "</span>" + ": ";
				txt +="<select name='cmbKLan' id='cmbKLan' onchange='" + ludi_renderer.handlerToOnChange_changeFunc + "(\"cmbKLan\");'></select>";
				txt +="<select name='cmbGLan' id='cmbGLan' onchange='" + ludi_renderer.handlerToOnChange_changeFunc + "(\"cmbGLan\");'></select>";
			txt += "</td>";
			txt += "<td>";

				txt +="<IMG onclick='" + ludi_renderer.handlerToOnClick_executeButton + "(\"GeneralSettings\")' src='";
				txt += './client/';
				txt += "icons//config-app.png' alt='config'  height='42' width='42'>" ;
				// file:///C:/Users/paco/Google%20Drive/nodejs/ludi/client//icons//config-app.png
				// http://localhost:8080/client//icons//config-app.png
				
			txt += "</td>";
		
		txt += "</tr>";
	txt += "</table>";
	
	txt += "<hr/>";
	
	txt += "<table>";
		
		txt += "<tr>";
			txt += "<td>";
				// second level buttons
				txt += internal_renderer.createMenu_ViewButtons (2, "horiz"); 
								
			txt += "</td>";
				
		txt += "</tr>";
		
	txt += "</table>";

	return txt;
	
}
 
ludi_renderer.welcomeMsg = function(lanList) {

	if (ludi_language.kernel_lanIndex <0) {
		var txt = "<h3>" + "Welcome to LUDI!" + "</h3>";
		txt += "<p>LUDI (Language-Unaffiliated Delightful Interactivity)... nevertheless the acronym itself is quite irrelevant: ludi also means to play in esperanto and games in latin.</p>";

		txt += "<p>Error: missing language</p>";
		
		return;
	}
	
	if (lanList[ludi_language.kernel_lanIndex].code == "EN") {
		
		var txt = "<h3>" + "Welcome to LUDI!" + "</h3>";
		txt += "<p>LUDI means to play in Esperanto, games in Latin and people in Russian... so it's an under-construction environment to play multilingual interactive fiction games in a tiny collaborative network.</p>";
		txt += "<p>It is being developed by Francisco Orta (mail: ludi.ludon at gmail.com). You can contact me if you want to collaborate somehow.</p>";

		txt += "<p>With LUDI you can play offline or login to interact with another players. You will also be able to share your game actions and see what the other people do in the game.</p>";
		
	} else 	if (lanList[ludi_language.kernel_lanIndex].code == "ES") {
	
		var txt = 	"<h3>" + "¡Bienvenido a LUDI!" + "</h3>";
		txt += "<p>LUDI significa jugar en esperanto, juegos en latín y gente en ruso... se trata de un entorno en desarrollo para jugar aventuras  multilingües de ficción interactiva en una pequeña red colaborativa.</p>";
		txt += "<p>Está siendo desarrollado por Francisco Orta (mail: ludi.ludon at gmail.com). Me puedes escribir si quieres colaborar de alguna manera.</p>";
		
		txt += "<p>LUDI permite jugar de manera aislada o bien conectarte e interactuar con otros jugadores. También podrás hacer público qué acciones realizas en el juego y ver qué hacen los otros jugadores.</p>";
		
	} else 	if (lanList[ludi_language.kernel_lanIndex].code == "EO") {
	
		var txt = 	"<h3>" + "Estu bonvena en LUDI!" + "</h3>";
		txt += "<p>LUDI signifas ludi en Esperanto, ludoj en la latina kaj personoj en la rusa ... do temas pri konstruanta medio por ludi plurlingvajn interaga-fikciajn ludojn en eta kunlabora reto.</p>";
		
		txt += "<p>Ĝi estas evoluinta por Francisko Orta (poŝto: ludi.ludon ĉe gmail.com). Vi povas kontakti min se vi volas kunlabori iel ajn.</p>";

		txt += "<p>Per LUDI vi povas ludi izole aŭ ensaluti por interagi kun alia ludantoj. Vi ankaŭ povos dividi vian ludajn agojn kaj vidi kion faras la aliaj ludantoj en la ludo.</p>";
	}
	
	return txt;
}


ludi_renderer.showKernelMSG = function  (mesId, param) {

	var txt = "";

	if ((ludi_language.kernel_lanIndex <0) || 
	    (ludi_language.lanList[ludi_language.kernel_lanIndex].kernelMessages[mesId] == undefined)) {
		if (ludi_renderer.showKernelMSG_html) {
			txt+= "<span class=\"wrong-msg\">";
		}
		txt += mesId;
		if (ludi_renderer.showKernelMSG_html)	txt+= "</span>";
		if (ludi_root.debugMode>1) 
			console.log("wrong showKernelMSG: " + mesId)
	} else {
		txt = ludi_language.lanList[ludi_language.kernel_lanIndex].kernelMessages[mesId].message;
	}

	var expandedParam = ludi_renderer.expandParam(txt, param);
	return ludi_language.translateKernelMSG(txt, expandedParam);

}

ludi_renderer.showMSG = function (mesId, param) {

	var txt;
	
	if (ludi_language.message_LongId_Exists ("messages." + mesId + ".txt")) {
		txt = ludi_language.getMessage_LongId ("messages." + mesId + ".txt");
	} else {
		if ((mesId == "") || (mesId == " ")) return mesId;
		txt = "<span class=\"wrong-msg\">[" + mesId + "]</span>";
		if (ludi_root.debugMode>1) 
			console.log("wrong showMSG: " + mesId)
	}
			
	var expandedParam = ludi_renderer.expandParam(txt, param);
	return ludi_language.translateMSG(txt, expandedParam);

}


//-------------------------------------------------------------------------------------------------------------------------
/*
	%: 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_renderer.expandParam = function  (mesIn, paramIn) {

	var paramOut = [];

	if (typeof paramIn != 'object') return paramOut;
	var txt = mesIn;
	var currentToken;
	var allTokens = ["o", "i", "v", "s", "d", "u["]; 
	
	// to-do: %u[blabla1, blabla2] -> link to blabla2 showing blabla1
	
	for (var iParam =0; iParam<paramIn.length; iParam++) {
		if (typeof paramIn[iParam] == 'undefined') continue;
		
		for (tType in allTokens) {
			currentToken = "%" + allTokens[tType] + (iParam+1); // + "%"
			
			if (txt.indexOf(currentToken) !=-1) { // token found
				var res = "";
				var longId = "";
				var type;
				
				// depending of element nature: item, verb, number, string
				if ( (allTokens[tType] == "o") ||
				     (allTokens[tType] == "v")  ) {
						 
					if (allTokens[tType] == "o") type = "items";
				    else if (allTokens[tType] == "s") type = "texts";
				    else if (allTokens[tType] == "v") type = "verbs";

					longId = type + "." + paramIn[iParam] + ".txt";
					
					res = txt.replace(currentToken, ludi_language.getMessage_LongId (longId) );
					txt = res;
					
					paramOut.push ({type:type, id:paramIn[iParam], longId:longId});
				
				} else if (allTokens[tType] == "d") { //directions
					type = "directions";
				
					longId = type + "." + paramIn[iParam] + ".desc";
					
					res = txt.replace(currentToken, ludi_language.getMessage_LongId (longId) );
					txt = res;
					
					paramOut.push ({type:type, id:paramIn[iParam], longId:longId});

				} else if (allTokens[tType] == "s") { // text as is
					var res = txt.replace(currentToken, paramIn[iParam]);
					txt = res;
					
					longId = "texts." + paramIn[iParam] + ".txt";
					
					paramOut.push ({type:"texts", id:paramIn[iParam], longId:longId});
					
				} else if (allTokens[tType] == "u") { // url  %u[text%url]
				
					// here!!
					
					var res = txt.replace(currentToken, "[" + allTokens[tType] + ":" + paramIn[iParam] + "]");
					txt = res;
					
					longId = paramIn[iParam]; // as is
					
					paramOut.push ({type:"asIs", id:paramIn[iParam], longId:longId});
				} else { // debug in case of missing tokenType
					var res = txt.replace(currentToken, "[" + allTokens[tType] + ":" + paramIn[iParam] + "]");
					txt = res;
					
					longId = paramIn[iParam]; // as is
					
					paramOut.push ({type:"asIs", id:paramIn[iParam], longId:longId});
				}
				break; // allTokens
			}
			// else error ?
		}
	}
	
	return paramOut;

}

ludi_renderer.gameInstructionsMsg = function(about) {

	var txt = "<h3>" + ludi_renderer.showMSG ("Game Instructions") + "</h3>";

	// to-do: by language
	txt += about.translation[0].introduction;

	return txt;

}

ludi_renderer.recalculeButtonVisibility = function  () {

	// first, all invisible
	for (var i=0;i<ludi_renderer.menu.button.length;i++) {
		if (ludi_renderer.menu.button[i].section > 1) {
			ludi_renderer.menu.button[i].visible = false;
		}
	}
	
	// then, activating necesary
	if (ludi_renderer.mainTab == 0) { // game tab

		if (ludi_renderer.generalContext == "loadingGame") {
			ludi_renderer.setButtonVisible ("GamesView", true);
		} else { // playing
			ludi_renderer.setButtonVisible ("Panels", true);
			ludi_renderer.setButtonVisible ("Game", true);
			ludi_renderer.setButtonVisible ("Here", true);
		}
		
	} else if (ludi_renderer.mainTab == 1) { // social tab
		if (ludi_renderer.userState.data.idPlayer != "anonymous") {
			ludi_renderer.setButtonVisible ("ActivityView", true);
			ludi_renderer.setButtonVisible ("MsgView", true);
			ludi_renderer.setButtonVisible ("BoardView", true);
			ludi_renderer.setButtonVisible ("ChatView", true);
		} else {
			ludi_renderer.setButtonVisible ("ChatView", false);
		}
	} else if (ludi_renderer.mainTab == 2) { // help tab	
		ludi_renderer.setButtonVisible ("About", true);
		ludi_renderer.setButtonVisible ("Instructions", true);
		if (ludi_renderer.generalContext == "playing") {
			ludi_renderer.setButtonVisible ("GameHelp", true);
		}
	
	} else if (ludi_renderer.mainTab == 3) { // chat tab	
		ludi_renderer.setButtonVisible ("ChatGlobal", true);
		ludi_renderer.setButtonVisible ("ChatPrivate", true);
		if (ludi_renderer.generalContext == "playing") {
			ludi_renderer.setButtonVisible ("ChatGame", true);
			ludi_renderer.setButtonVisible ("ChatLocation", true);
		}
	
	} else if (ludi_renderer.mainTab == 4) { // profile tab	
		ludi_renderer.setButtonVisible ("MyLanguages", true);
		ludi_renderer.setButtonVisible ("GeneralSettings", true);
		if (ludi_renderer.userState.data.idPlayer == "anonymous") 
			ludi_renderer.setButtonVisible ("Login", true);
		else
			ludi_renderer.setButtonVisible ("Logout", true);
	}
}

ludi_renderer.htmlURLsysAction = function   (txt, saId, idName, className, parameters) {
 
    var url = "javascript:" + ludi_renderer.handlerToOnClick_executeButton + "('" + saId + "'";

	if (parameters != undefined) {
		url += ", " + parameters;
	}
	url += ");";
	return ludi_renderer.htmlURLBasic (txt, url, idName, className);

}

ludi_renderer.htmlURLBasic = function  (txt, url, idName, className) {

	var txt2;
	//txt2 = txt.link(url);
 	txt2 = "<a href=\"" + url + "\" ";
	txt2 = txt2 + " id=\"" + idName + "\"";
	if (className != "") txt2 = txt2 + " class=\"" + className + "\"";
	txt2 = txt2 + ">"+ txt + "</a>"
	
	return txt2;

}

ludi_renderer.htmlURLMenu = function  (txt, option, idName, className) {

    var url = "javascript:" + ludi_renderer.handlerToOnClick_menuSelected + "('" + option + "');";
	return ludi_renderer.htmlURLBasic (txt, url, idName, className);
}


ludi_renderer.htmlAllActions = function  (item, actionList, actionNames) {
	
	var txt="";
	
	// Marked Item / unmark button
	if (ludi_routing.userState.profile.markedItem >=0) { 
		txt += "<p>" + ludi_renderer.showKernelMSG("Marked item is o1", [ludi_routing.getIdFromTypeAndIndex ("items", ludi_runner.userState.profile.markedItem)]);
		txt += ludi_renderer.htmlOfButtonAs("Unmark");
		txt += "</p>"
		ludi_renderer.setButtonVisible ("Unmark", true);
	} 
	
	if (item == -2) { // all actions
		txt += ludi_renderer.htmlCommonActions (actionList);
	} else {
		txt += ludi_renderer.htmlActionsOnItem (actionNames, actionList);
		// mark button
		txt +=  ludi_renderer.htmlURLsysAction (ludi_renderer.showKernelMSG ("Mark"), "Mark", "Mark", "horiz", item);
	}
	
	// back button 
	txt +=  ludi_renderer.htmlURLBasic (
		ludi_renderer.showKernelMSG("Back"), 
		'javascript:' + ludi_renderer.handlerToOnClick_showItemGroup +'(' + ludi_renderer.subPanel  + ');', 
		this.id, //????
		"horiz"
	);
		
	return txt;
}

ludi_renderer.expandText = function(txtIn) {
	// %u for links . Format %utextToShow_|_url%
	// %n for new_line, must be rendered

	if (typeof txtIn == "undefined") return "";
	
	//return txtIn; // by now
	
	// sample: blabla1%utext1__url1%blabla2%n%blabla2%utext2__url2%blabla3";

	var re = txtIn.match("(.*)%u(.*)__(.*)%(.*)");
	// re: ["blabla1%utext1__url1%blabla2%n%blabla2%utext2__url2%blabla3", "blabla1%utext1__url1%blabla2%n%blabla2", "text2", "url2", "blabla3"]
	
	// re[0]: source text:				"blabla1%utext1__url1%blabla2%n%blabla2%utext2__url2%blabla3"
	// re[1]: pending to analyze		"blabla1%utext1__url1%blabla2%n%blabla2"
	// re[2]: text to show in link		"text2"
	// re[3]: url in link				"url2"
	// re[4]: remain text to show
	
	// using recursivity
	
	if (re != null) {
		var txtOut =  ludi_renderer.expandText (re[1]) + 
				"<A HREF='" + re[3] + "' class='embedded' target=\"_blank\" >" +
				re[2] +
				"</A>" +
				re[4];
		
		return txtOut;
	}
	
	return txtIn;

}
		
