/*
/*

It receives interactive requests (clicks), transforms them in a stardarized request and resend to the specialized controller.

Standarization is needed because in the future, packets withs these requests will be sended to server.

*/

ludi_routing = {};

ludi_routing.afterLoadKernelLanguages = [];

ludi_routing.tempUserLanguages = [];

ludi_routing.runningDialogMenu = false;
ludi_routing.pendingAnswer = {};
ludi_routing.pendingToSpeech = []; // buffer to speech
ludi_routing.caList = [];
ludi_routing.pendingCA = 0; // initial CA to be inserted there
ludi_routing.initialLoad = true;

ludi_routing.linkTable = [];

ludi_routing.userState = {
	data: {
		idPlayer: 'anonymous',
		game: '',
		loc: -1, // current location?
		profile: {
			status: '',
			email: '',
			// default filters and preferences, as defined  ludi_root.filterEnum []:
			// MessagesHidden, ActivityHidden, SpeechOn, IncomingLanguages, BroadcastFrom, ActivityFrom, ActivityTo
			filters: [0, 0, 1, 0, 0, 0, 0], 
			userLanguages: [],
			currentLoc: -1,
			score: 0,
			turnCounter: 0,
			indexPC: 0,
			markedItem: -1
		}	
	}
}

ludi_renderer.presskeyActive = false; // true, when "press any key to continue" is shown


internal_routing = {};

internal_routing.pendingRequests = [];

ludi_routing.internal = {};

/*
	item1 == -1: intransitive action (no object)
	item1 == -2: "all" action (more than one objects)
*/
ludi_routing.addACTION = function  (action, item1, item2, direction, option) {
	
	
	var addOnTop = (typeof option != 'undefined') && (option>=0);
	
	if (ludi_renderer.presskeyActive) return;
	
	if (ludi_routing.runningDialogMenu) {
		alert ("Select menu option first");
		return;
	}
	
	var request = {
		type: ludi_root.requestEnum.game, 
		id: 'gameAction',
		par: {
			pc: ludi_routing.userState.profile.indexPC,
			loc: ludi_routing.userState.profile.currentLoc,
			action:action, 
			item1:item1, 
			item2:item2, 
			direction:direction, 
			option:option,
			freeText:''}
	};
	
	item2 = item2 || -1;
	
	if (request.par.item1 !== -2) {
		internal_routing.addSingleAction (request, addOnTop);
	} else { // multiple actions
		internal_routing.addMultipleAction (request);
	} 
	
	ludi_routing.executePendingRequests();
	
}

internal_routing.addSingleAction = function (request, addOnTop) {
	if (!addOnTop) // ordinary case
		internal_routing.pendingRequests.push (request); 
	else
		internal_routing.pendingRequests.unshift (request); // on top 
	
}

internal_routing.addMultipleAction = function (request) {
	
	var table = ludi_renderer.panelOptions[ludi_renderer.subPanel].menu;
	for (i in table) {
		var requestClone = JSON.parse(JSON.stringify(request));
		requestClone.par.item1 = table[i].data.item;
		internal_routing.pendingRequests.push (requestClone);
	}

}

ludi_routing.executePendingRequests = function() {
	
	var previousLoc = ludi_routing.userState.profile.currentLoc;

	for (var request = internal_routing.pendingRequests.shift(); request != undefined; request = internal_routing.pendingRequests.shift()) {
		ludi_routing.executeRequest (request);	
	}
	
	// refresh environment			
	if (!ludi_root.visiblePanels) { // if no panel, show game zone
		ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.AllActions, "", true, true);
	} else { 
		// if panel and same location, redraw current item subpanel
		if (previousLoc == ludi_routing.userState.profile.currentLoc) {
			ludi_routing.updateItemInPanel(ludi_renderer.currentItem);
		}
		ludi_routing.showDefaultInfo();
	}

}

ludi_routing.executeRequest = function(request) {
	
	
	if (request.type == ludi_root.requestEnum.game && 
		request.id == 'gameAction') {
		
		ludi_routing.expandParC(request.par);

		ludi_routing.savePrivateActivity (request.par);

		if (typeof request.par.option  == 'undefined') // if the second phase in a menu decistion, it is not necessary
			ludi_runner.clientAction.push ({type:ludi_root.caEnum.SHOW_ECHO.value, par_c:request.par}); // echo as a clientAction
		var result = ludi_runner.executeActionRequest (request.par);
		
		// processing and result
		for (var i in result.clientAction) {
			ludi_routing.caList.push (result.clientAction[i]);
		}
		ludi_routing.userState = result.userState;

		ludi_routing.getMenuCache();
		
		ludi_routing.userChatReallocation ();

		ludi_routing.createMenu(ludi_language.lanList, ludi_language.lanList[ludi_language.lanIndex].code);
		ludi_routing.updateItemInPanel(ludi_renderer.currentItem);
		ludi_routing.showDefaultInfo();
		ludi_routing.processClientActionList();
		internal_routing.refreshAfterAction(request.par);
		
		
		// update loc in network
		if (typeof ludi_comm !== 'undefined') {
			ludi_comm.leaveLoc ({gameName:ludi_routing.userState.data.gamename, loc:ludi_routing.userState.data.loc});
			ludi_routing.userState.data.loc = ludi_routing.userState.profile.currentLoc;
			ludi_comm.joinLoc ({gameName:ludi_routing.userState.data.gamename, loc:ludi_routing.userState.data.loc});
		}
		
		
	} else if (request.type == ludi_root.requestEnum.game && 
		request.id == 'showActionsOnItem') {
		
		// 1. get data
		// to-do: if needed, ge data from DB instead from cache
		var actionList;
		var actionNames;
			
		if (request.par.item == -2) { // all actions
			actionList = ludi_renderer.getCommonActions ();
		} else {
			ludi_renderer.itemInPanel = request.par.item;
			actionList = ludi_renderer.getActionsOnItem ();
			actionNames = ludi_routing.actionDisambiguation (actionList);
		}

		// 2. renderer
		var txt = ludi_renderer.htmlAllActions (request.par.item, actionList, actionNames);

		// 3. display
		ludi_display.showMappedPanel (ludi_root.enumPanels.Panel1, txt);
	
	}
	
	// not implemented requests

}

ludi_routing.actionDisambiguation = function  (table) {
	// disambiguation
	var actionNames = [];
    var counteraction = [];
	for (var index in table) {
		actionNames[index] = ludi_routing.getActionDesc(table[index].action);
		counteraction[index]=1;
	}
	for (var index in actionNames) {
		for (var index2 in actionNames) {
			if (index > index2) {
				if ( actionNames[index] == actionNames[index2]) {
					counteraction[index]++;
					counteraction[index2]++;
				} 
			}
		}
	}
	for (var index in actionNames) {
		if (counteraction[index] > 1) {

			// here!?
			var actionId = ludi_routing.getIdFromTypeAndIndex ("actions", table[index].action);
			if (ludi_language.message_LongId_Exists ("actions." + actionId + ".disambiguator")) {
				actionNames[index] += "(" + ludi_language.getMessage_LongId ("actions." + actionId + ".disambiguator");
			} else {
				actionNames[index] += "(!)";
			}
		}
	}
	return actionNames;
}

// when menuOption is selected
// dialog/phase 2: clean previous menu, show the selected alternative (echo) and launch action
ludi_routing.menuSelected = function  (option)  {
	
	if (!ludi_routing.runningDialogMenu) return;
	if (option<0) return;
	
	ludi_display.replaceMenuBySelectedOption(ludi_renderer.showMSG ("You selected"), option); // to-do: it must be a CA
	ludi_routing.pendingAnswer.option = option;
	ludi_routing.runningDialogMenu = false;
	
	ludi_routing.addACTION (ludi_routing.pendingAnswer.action, ludi_routing.pendingAnswer.item1, ludi_routing.pendingAnswer.item2, ludi_routing.pendingAnswer.direction, option);
	
}



ludi_routing.showIActions = function  (item) {

	var request = {
		type: ludi_root.requestEnum.game, 
		id: 'showActionsOnItem',
		par: {
			item:item
		}
	};

	ludi_routing.executeRequest (request);
	
}


ludi_routing.showItemGroup = function  (option) {
	
	if (option == undefined) return "";
	
	// 1: get data
	var table = ludi_renderer.panelOptions[option].menu;
	
	// 2: render
	var txt = "";
	var title = ludi_root.panelInfo[option].text;
	
	var txt2="";
	
	if (option == ludi_root.p1Def.Exit.value)	{ 
		txt += ludi_language.getMessage_LongId ("items." +  ludi_runner.world.items[ludi_routing.userState.profile.currentLoc].id + ".txt") +  ". ";
    }
	
	if (ludi_renderer.panelOptions[option].viewType ==  ludi_root.panel1ViewEnum.Playing.value) {  // to-do: provisional
		if (option == ludi_root.p1Def.Exit.value)	{ 
			txt2 = ludi_renderer.htmlPanelConnections(table, ludi_runner.world);
		} else if ((option >= ludi_root.p1Def.Here.value) && (option <= ludi_root.p1Def.NotHere.value)){ 
			txt2 = ludi_renderer.getPanel2_ItemsIn(table);
		} else if (option == ludi_root.p1Def.DirectAction.value)	{
			txt2 = ludi_renderer.getPanel2_DirectActions(table);
		}
	} else {
		txt2 = ludi_renderer.getPanel2_Generic(table);
	}
	
	// back button
	if (ludi_root.visiblePanels) {
		// txt2 += ludi_renderer.htmlOfButtonAs ("PlayTab", ludi_renderer.showKernelMSG("Back"), "horiz");  
		txt2 += ludi_renderer.htmlOfButtonAs ("PlayTab", "Back", "horiz");  // translated inside
	} else {
		if (ludi_renderer.panelOptions[option].viewType ==  ludi_root.panel1ViewEnum.Playing.value) {
			txt2 += ludi_renderer.htmlURLsysAction(ludi_renderer.showKernelMSG ("Back"), "Input", "Input", "horiz");
		} else {
			txt2 += ludi_renderer.htmlURLsysAction(ludi_renderer.showKernelMSG ("Back"), "GamesView", "GamesView", "horiz");		
		}
	}

	// if data, show title and data
	if (txt2 != "") txt +="<h4>" + ludi_renderer.showKernelMSG(title) + ":" + "</h4>" + txt2;
		
	// 3: display
	if (ludi_root.visiblePanels) {
		ludi_display.showMappedPanel (ludi_root.enumPanels.Panel1, txt);
	} else {
		ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);
	}
	
	ludi_renderer.subPanel = option;
	
}

ludi_routing.executeButton = function  (saId, p0, p1, p2, p3) {
	var button = ludi_renderer.getButton (saId);
	if (!button) {
		alert ("Alert: missing button: " + saId);
		return;
	} 
	
	if (ludi_routing.actionButton [saId] === undefined) {
		alert ("Alert: missing button action: " + saId);
		return;
	} 
	ludi_routing.actionButton [button.id](p0, p1, p2, p3);
	ludi_routing.screenResizeHandler();

}

ludi_routing.getMenuCache = function () { 

	// refresh data in ludi_runner
	ludi_runner.updateBaseMenus();
	
	// set place as known
	if (typeof ludi_runner.world.items[ludi_routing.userState.profile.indexPC].state.itemsMemory[ludi_routing.userState.profile.currentLoc] == "undefined") {
		ludi_runner.world.items[ludi_routing.userState.profile.indexPC].state.itemsMemory[ludi_routing.userState.profile.currentLoc] = {};
	}
	
	// update menus in ludi_renderer
	ludi_routing.refreshMenuCache();
}

ludi_routing.refreshMenuCache = function () { 

	// interface between ludi_renderer and ludi_runner: 
	// get menu tables from ludi_runner and get transformed ones in ludi_renderer

	var tableTypes = [
		ludi_root.p1Def.DirectAction.value, 
		ludi_root.p1Def.Exit.value,
		ludi_root.p1Def.NotHere.value,
		ludi_root.p1Def.Here.value,
		ludi_root.p1Def.On.value,
		ludi_root.p1Def.Carried.value,
		ludi_root.p1Def.Marked.value
	];
	
	for (var i in tableTypes) {
		var type = tableTypes[i];
		
		ludi_renderer.panelOptions[type].menu = [];
		
		var tableIn = ludi_runner.panelOptionsCache[type].menu;
		
		for (var el in tableIn) {
			var data = {};
		
			if (type == ludi_root.p1Def.DirectAction.value) {
				data.action =  tableIn[el].action;
			} else if (type == ludi_root.p1Def.Exit.value) {
				data.dir =  tableIn[el].dir;
				data.target = tableIn[el].target;
				data.targetId = ludi_routing.getIdFromTypeAndIndex("items", tableIn[el].target);	
				if (typeof tableIn[el].actions != "undefined") {
					data.actions =  tableIn[el].actions;
					
					// to-do: pending to improve
					data.actionsId = [];
					
					for (var a in data.actions) {
						data.actionsId[a] = ludi_routing.getIdFromTypeAndIndex("actions", data.actions[a]);	
					}
				}
			} else {
				data.item = tableIn[el].item;
				data.itemId = ludi_routing.getIdFromTypeAndIndex("items", tableIn[el].item);	
				
				data.actions =  tableIn[el].actions;
				for (var a in data.actions) {
					data.actions[a].actionId = ludi_routing.getIdFromTypeAndIndex("actions", data.actions[a].action);	
				}
			}

			var it = new ludi_renderer.menu.MI_GameItem(el, data );
			it.type = type;
			it.viewType = ludi_root.panel1ViewEnum.Playing.value;
		
			ludi_renderer.panelOptions[type].menu.push (it);
		}
	}
	
}

ludi_routing.updateItemInPanel = function  (item) {

	if (item < 0 ) return;
	
	for (var option = ludi_root.p1Def.Here.value; option <= ludi_root.p1Def.NotHere.value; option++) { 
		for (var i=0; i<ludi_renderer.panelOptions[option].menu.length;i++) {
			if (+ludi_renderer.panelOptions[option].menu[i].data.item == +item) {	// numbers!
				ludi_renderer.subPanel = option;
				ludi_renderer.itemInPanel = +i;
			}
		}
	}
	return;
}

internal_routing.refreshAfterAction = function  (par_c) {
	if (ludi_routing.runningDialogMenu) {
		ludi_routing.pendingAnswer = par_c;
	} else {
		//txt += "</p> <hr/>"
		// if subPanel is being used now
		if (ludi_root.visiblePanels) {
			if (par_c.action == ludi_root.actEnum.GO.value) {
				// refresh "exits from here"
				ludi_routing.showItemGroup(ludi_root.p1Def.Exit.value);
			}  else if (ludi_renderer.itemInPanel >= 0) { // refresh available actions
				ludi_routing.showIActions (ludi_renderer.itemInPanel); 
			}
		}
	}

}

//**********************************************************************************************
//         Actions on buttons 
//**********************************************************************************************

ludi_routing.actionButton = [];

// main buttons
ludi_routing.actionButton['PlayTab'] = function  () {
	ludi_renderer.mainTab = 0;
	ludi_renderer.recalculeButtonVisibility();
	ludi_routing.createMenu(ludi_language.lanList, ludi_language.lanList[ludi_language.lanIndex].code);
	ludi_routing.showDefaultInfo();
	if (ludi_root.visiblePanels) {
		ludi_routing.showPanelView(ludi_root.panel1ViewEnum.Playing.value);
	}
}

ludi_routing.actionButton['SocialTab'] = function  () {
	ludi_renderer.mainTab = 1;
	ludi_routing.interactionPanel_SetVisible (false);		
	ludi_renderer.recalculeButtonVisibility();
	ludi_routing.createMenu(ludi_language.lanList, ludi_language.lanList[ludi_language.lanIndex].code);
	ludi_routing.showDefaultInfo();
	ludi_renderer.setButtonVisible ("Panels", false);
}

ludi_routing.actionButton['HelpView'] = function  () {
	ludi_renderer.mainTab = 2;
	ludi_routing.interactionPanel_SetVisible (false);		
	ludi_renderer.recalculeButtonVisibility();
	ludi_routing.createMenu(ludi_language.lanList, ludi_language.lanList[ludi_language.lanIndex].code);
	ludi_routing.showDefaultInfo();
	ludi_renderer.setButtonVisible ("Panels", false);
}

ludi_routing.actionButton['ChatView'] = function  () {
	ludi_renderer.mainTab = 3;
	ludi_routing.interactionPanel_SetVisible (false);		
	ludi_renderer.recalculeButtonVisibility();
	ludi_routing.createMenu(ludi_language.lanList, ludi_language.lanList[ludi_language.lanIndex].code);
	ludi_routing.showDefaultInfo();
	ludi_renderer.setButtonVisible ("Panels", false);
}

// about, instructions and Game Help
ludi_routing.actionButton['About'] = function  () {
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, ludi_renderer.welcomeMsg(ludi_language.lanList), true);
	ludi_display.goTopInMainPanel();
}

ludi_routing.actionButton['Instructions'] = function  () {
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, ludi_language.generalInstructionsMsg(), true);
	ludi_display.goTopInMainPanel();
}

ludi_routing.actionButton['GameHelp'] = function  () {
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, ludi_renderer.gameInstructionsMsg(ludi_renderer.about), true);
	ludi_display.goTopInMainPanel();
}

// settings
ludi_routing.actionButton['GeneralSettings'] = function  () {
	ludi_renderer.mainTab = 4;
	ludi_routing.interactionPanel_SetVisible (false);		
	ludi_renderer.recalculeButtonVisibility();
	ludi_routing.createMenu(ludi_language.lanList, ludi_language.lanList[ludi_language.lanIndex].code);
	ludi_routing.showDefaultInfo();
	ludi_renderer.setButtonVisible ("Panels", false);
}

// login, logout
ludi_routing.actionButton['Login'] = function  () {
	var person=prompt("Please enter your nick name");
	if (person!=null) {
		
		if ((typeof socket != "undefined") && (ludi_routing.userState.data.idPlayer == 'anonymous')){
			if (typeof user != 'undefined') 
				user.setName(person);
		}
		ludi_routing.userState.id = person;
		ludi_routing.userState.data.idPlayer = person;

	}

	ludi_renderer.recalculeButtonVisibility();
	
	if (ludi_routing.userState.data.idPlayer != "anonymous")
		ludi_display.showHTMLId("#status-update-form");
	else 
		ludi_display.hideHTMLId("#status-update-form");

	ludi_routing.createMenu(ludi_language.lanList, ludi_language.lanList[ludi_language.lanIndex].code);
	
	ludi_routing.showDefaultInfo();
	
	// 	automatic activation of visibility of messages and activity
	ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.MessagesHidden] = "1";
	ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.ActivityHidden] = "1";
	ludi_root.visibleMessages = true;
	
	ludi_routing.executeButton('GeneralSettings');
}

ludi_routing.actionButton['Logout'] = function  () {
	// here!
	// the game is still loaded, but player come back to anonymous and plays locally
	ludi_routing.userState.id = 'anonymous';
	ludi_routing.userState.data.idPlayer = 'anonymous';
	
	// to-do: extract from ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu
	
	ludi_renderer.recalculeButtonVisibility();		
	
	if (ludi_routing.userState.data.idPlayer != "anonymous") 
		ludi_display.showHTMLId("#status-update-form");
	else 
		ludi_display.hideHTMLId("#status-update-form");
	
	ludi_display.showHTMLId('#cmbKLan');
	ludi_display.hideHTMLId('#cmbGLan');
	
	ludi_routing.createMenu(ludi_language.lanList, ludi_language.lanList[ludi_language.lanIndex].code);
	
	ludi_routing.showDefaultInfo();
	
	// 	automatic deactivation of visibility of messages and activity
	ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.MessagesHidden] = "0";
	ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.ActivityHidden] = "0";
	ludi_root.visibleMessages = false;
	
	
	ludi_routing.executeButton('GeneralSettings');
}

ludi_routing.actionButton['MyLanguages'] = function  () {
	ludi_routing.tempUserLanguages = ludi_routing.userState.data.profile.userLanguages.slice(0);
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, ludi_renderer.showLanguagePreferences(ludi_routing.tempUserLanguages,ludi_language.lanList), true); 
}

ludi_routing.actionButton['GamesView'] = function  () {
	ludi_routing.interactionPanel_SetVisible (false);		
	ludi_renderer.mainPanel = 0;
	ludi_routing.showPanelView(ludi_root.panel1ViewEnum.Games.value, true);
}

ludi_routing.actionButton['Game'] = function  () {
	var txt = "<h2>" + ludi_renderer.showKernelMSG("Game") + "</h2>";

	txt += "<p>" + ludi_renderer.showKernelMSG("Game") + ": " + ludi_routing.userState.data.gamename + "</p>";

	// Score and turns
	txt += "<p>" + ludi_renderer.showKernelMSG("Score") + "<span class='score' class ='selection'>" + ": " + ludi_routing.userState.profile.score + "</span> ";
	txt += ludi_renderer.showKernelMSG("Turns") + "<span class='turns' class ='selection'>" +  ": " + ludi_routing.userState.profile.turnCounter + " </span> ";

	// show how many items exits
	txt += ludi_renderer.showKernelMSG("Number of Items") + ": " +  ludi_runner.world.items.length;
	var knownItems = 0;
	if (typeof ludi_runner.world.items[ludi_routing.userState.profile.indexPC].state.itemsMemory != "undefined") {
		for (var i=0;i<ludi_runner.world.items[ludi_routing.userState.profile.indexPC].state.itemsMemory.length;i++) {
			if (typeof ludi_runner.world.items[ludi_routing.userState.profile.indexPC].state.itemsMemory[i] != "undefined") {
				knownItems ++;
			}
		}
	}
	// current PC
	txt += " " + ludi_renderer.showKernelMSG("Current playing character is o1", [ludi_runner.world.items[ludi_routing.userState.profile.indexPC].id]);
	
	// known items
	if (knownItems > 0) {
		txt += " " + ludi_renderer.showKernelMSG("Number of known items") + ": " +  knownItems;
	}

	// show game-defined parameters
	if (typeof ludi_game.statusArray == 'function') {
		var gameParams = ludi_game.statusArray ();
		for (var i in gameParams) {
			txt += ludi_renderer.showMSG(gameParams[i].id) + "<span class ='selection'>" +  ": " + gameParams[i].value + " </span> ";
		
		}
	}
	
	txt += "</p>";

	if (ludi_routing.userState.data.idPlayer != "anonymous") {
		txt += ludi_renderer.htmlOfButton ("ChatGame", "horiz");
	}

	// to-do: improve following
	//txt += ludi_renderer.htmlOfButton ("History", "horiz");
	txt += ludi_renderer.htmlOfButton ("ShowAbout", "horiz");
	txt += ludi_renderer.htmlOfButton ("QuitGame", "horiz");
	txt += ludi_renderer.htmlOfButton ("SaveGame", "horiz");
	txt += ludi_renderer.htmlOfButton ("LoadGame", "horiz");
	txt += ludi_renderer.htmlOfButton ("LoadGameFromStart", "horiz");
	txt += ludi_renderer.htmlOfButton ("LoadSavedGame", "horiz");
	
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);
	ludi_routing.interactionPanel_SetVisible (false);
}

ludi_routing.actionButton['Here'] = function  () {
	ludi_routing.interactionPanel_SetVisible (false);		
	var txt = ludi_renderer.htmlAvailableUserActions();	
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);
}

ludi_routing.actionButton['Panels'] = function  () {
	ludi_routing.switchPanels();
}

ludi_routing.actionButton['Redescribe'] = function  () {
	ludi_routing.addACTION (ludi_root.actEnum.LOOK.value, ludi_routing.userState.profile.currentLoc, -1, -1);
}

// social subuttons
ludi_routing.actionButton['MsgView'] = function  () {
	ludi_routing.interactionPanel_SetVisible (false);		
	ludi_renderer.mainPanel = 0;
	ludi_routing.showPanelView(ludi_root.panel1ViewEnum.Messages.value, true);
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, "", true, true);
}

ludi_routing.actionButton['BoardView'] = function  () {
	ludi_routing.interactionPanel_SetVisible (false);		
	ludi_routing.showPanelView(ludi_root.panel1ViewEnum.Boards.value, true);
}

ludi_routing.actionButton['ActivityView'] = function  () {
	ludi_renderer.mainPanel = 0;
	ludi_routing.showPanelView(ludi_root.panel1ViewEnum.Activity.value, true);
	ludi_routing.interactionPanel_SetVisible (false);		
}

ludi_routing.actionButton_ChatVariants = function (id) {
	if (ludi_routing.userState.data.idPlayer == "anonymous") return;
	
	ludi_display.chatParams.scope = id;
	
	if (ludi_display.getHTMLId("#spanMsgTo").length==0) {
		var txt = ludi_renderer.messageInput_html ();
		ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);
		ludi_display.messageInput_after_html ();
	}

	ludi_display.showChat (ludi_renderer.showKernelMSG(ludi_display.chatParams.scope));
}

ludi_routing.actionButton['ChatGlobal'] = function  () {
	ludi_routing.actionButton['ChatView']();
	ludi_routing.actionButton_ChatVariants("global");
}

ludi_routing.actionButton['ChatGame'] = function  () {
	ludi_routing.actionButton['ChatView']();
	ludi_routing.actionButton_ChatVariants("game");
}

ludi_routing.actionButton['ChatLocation'] = function  () {
	ludi_routing.actionButton['ChatView']();
	ludi_routing.actionButton_ChatVariants("loc");
}

ludi_routing.actionButton['ChatPrivate'] = function  () {
	ludi_routing.actionButton['ChatView']();
	ludi_routing.actionButton_ChatVariants("private");
}

ludi_routing.actionButton['Restart'] = function  () {
	ludi_renderer.showKernelMSG_html = false;
	var msg = ludi_renderer.showKernelMSG ("Are you sure");
	ludi_renderer.showKernelMSG_html = true;
	if (!confirm(msg)) return;
	
	location.reload(true); // hard reload
}

ludi_routing.actionButton['SwitchView'] = function  () {
	ludi_renderer.interactionPanel_Switch();
}

ludi_routing.actionButton['Undo'] = function  () {
}

ludi_routing.actionButton['ClearHistory'] = function  () {
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.AllActions,  "<H3>" + ludi_renderer.showKernelMSG("History") + "</H3>", true);
}

ludi_routing.actionButton['SwitchOrientation'] = function  () {
	ludi_routing.switchOrientation();
}

ludi_routing.actionButton['SetLanguagePreferences'] = function  () {
	ludi_routing.setLanguagePreferences(ludi_routing.tempUserLanguages);
}

ludi_routing.actionButton['RemoveLanguage'] = function  (parameter0) {
	if (ludi_routing.tempUserLanguages.length == 1 ) {
		alert ("At least one language, please!");
		return; 
	}
	ludi_routing.tempUserLanguages.pop (parameter0) ;
	ludi_routing.setLanguagePreferences(ludi_routing.tempUserLanguages);
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, ludi_renderer.showLanguagePreferences(ludi_routing.tempUserLanguages,ludi_language.lanList), true); 
}

ludi_routing.actionButton['AddLanguage'] = function  (parameter0) {
	ludi_routing.tempUserLanguages.push (parameter0) ;
	ludi_routing.setLanguagePreferences(ludi_routing.tempUserLanguages);
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, ludi_renderer.showLanguagePreferences(ludi_routing.tempUserLanguages,ludi_language.lanList), true); 
}

ludi_routing.actionButton['UpLanguage'] = function  (parameter0) {
	for (var i=0;i<ludi_routing.tempUserLanguages.length;i++) {
		if (ludi_routing.tempUserLanguages[i] == parameter0) {
			if (i > 0) {
				var temp = ludi_routing.tempUserLanguages[i];
				ludi_routing.tempUserLanguages[i] = ludi_routing.tempUserLanguages[i-1];
				ludi_routing.tempUserLanguages[i-1] = temp;
			}
		}
	}
	ludi_routing.setLanguagePreferences(ludi_routing.tempUserLanguages);
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, ludi_renderer.showLanguagePreferences(ludi_routing.tempUserLanguages,ludi_language.lanList), true); 
}

ludi_routing.actionButton['DownLanguage'] = function  (parameter0) {
	for (var i=0;i<ludi_routing.tempUserLanguages.length;i++) {
		if (ludi_routing.tempUserLanguages[i] == parameter0) {
			if (i < ludi_routing.tempUserLanguages.length -1 ) {
				var temp = ludi_routing.tempUserLanguages[i];
				ludi_routing.tempUserLanguages[i] = ludi_routing.tempUserLanguages[i+1];
				ludi_routing.tempUserLanguages[i+1] = temp;
			}
		}
	}
	ludi_routing.setLanguagePreferences(ludi_routing.tempUserLanguages);
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, ludi_renderer.showLanguagePreferences(ludi_routing.tempUserLanguages,ludi_language.lanList), true); 
}

ludi_routing.actionButton['Save'] = function  () {
	
	// to-do:
	
	
	//txt +="<p>Game Saved!</p>";
}

ludi_routing.actionButton['Load'] = function  () {
	// to-do: data from cookie to memory
}

ludi_routing.actionButton['Mark'] = function  () {
	
	ludi_routing.userState.profile.markedItem = +ludi_renderer.panelOptions[ludi_renderer.subPanel].menu[ludi_renderer.itemInPanel].data.item;

	// to-do: neccessary?
	ludi_renderer.userState.profile.markedItem =  ludi_routing.userState.profile.markedItem;
	
	if (ludi_routing.userState.profile.markedItem >=0) {
		var txt = "<p class=\"echo\">&gt; " + 
				  ludi_renderer.showKernelMSG ("mark") + " | " + 
				  ludi_routing.getItemText (ludi_routing.userState.profile.markedItem ) +
				  "</p>";

		txt += ludi_renderer.showKernelMSG ("You mark o1 for 2-object actions", [ludi_routing.getIdFromTypeAndIndex ("items", ludi_routing.userState.profile.markedItem) ]);
	
		ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.AllActions,  txt , true, true);
	}

	// from data to cS
	ludi_runner.userState = ludi_routing.userState;
	
	ludi_routing.getMenuCache();
	// error:importedPanelOptions ??
	/*
	for (var i = 0; i<importedPanelOptions.length; i++) {
		ludi_renderer.panelOptions[i] = importedPanelOptions[i];
	}
	*/
	ludi_routing.showDefaultInfo();

	ludi_routing.executeButton ("PlayTab");

}

ludi_routing.actionButton['Unmark'] = function  () {
	var txt = "<p class=\"echo\">&gt; " + ludi_renderer.showKernelMSG ("unmark") + " | " + ludi_routing.getItemText (ludi_routing.userState.profile.markedItem ) + "</p>";

	txt += ludi_renderer.showKernelMSG ("You unmark o1", [ludi_routing.getIdFromTypeAndIndex ("items", ludi_routing.userState.profile.markedItem) ]);
	
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.AllActions,  txt , true, true);

	ludi_routing.userState.profile.markedItem = -1;
	// to-do: neccessary?
	ludi_renderer.userState.profile.markedItem =  ludi_routing.userState.profile.markedItem;
	

	// from data to cS
	ludi_runner.userState = ludi_routing.userState;
	
	ludi_routing.getMenuCache(); 
	// error: ludi_renderer.panelOptions?
	/*
	for (var i = 0; i < importedPanelOptions.length; i++) {
		ludi_renderer.panelOptions[i] = importedPanelOptions[i];
	}
	*/
	ludi_routing.showDefaultInfo();

	ludi_routing.executeButton ("PlayTab");
}

ludi_routing.actionButton['PressKey'] = function  () {
	ludi_routing.keyPressed();
}

ludi_routing.actionButton['Input'] = function  () {
	ludi_renderer.mainPanel=0;
	ludi_routing.interactionPanel_SetVisible (false);
	ludi_routing.showPanelView(ludi_root.panel1ViewEnum.Playing.value);
}
		
ludi_routing.actionButton['ChangeProfileMail'] = function  () {
	var newEmail=prompt("Type your email", ludi_routing.userState.data.profile.email);
	if (newEmail!=null) {
		ludi_routing.userState.data.profile.email = newEmail;
		if (typeof ludi_comm !== 'undefined') ludi_comm.updateProfile();
		ludi_routing.executeButton ('GeneralSettings');
	}
}
ludi_routing.actionButton['ChangeProfileStatus'] = function  () {
	var newStatus=prompt("Type your status", ludi_routing.userState.data.profile.status);
	if (newStatus!=null) {
		ludi_routing.userState.data.profile.status = newStatus;
		if (typeof ludi_comm !== 'undefined') ludi_comm.updateProfile();
		ludi_routing.executeButton ('GeneralSettings');
	}		
}

ludi_routing.actionButton['ChangeChatTo'] = function  () {
	ludi_display.chatParams.to = prompt("MessageTo", ludi_display.getHTMLId('#lblMsgTo'));
	if (ludi_display.chatParams.to!=null) {
		ludi_display.setHTMLId('#lblMsgTo', ludi_display.chatParams.to);
	}		
}

ludi_routing.actionButton['ChangeChatText'] = function  () {
	ludi_display.chatParams.text = prompt("MessageText", ludi_display.getHTMLId('#lblMsgText'));
	if (ludi_display.chatParams.text!=null) {
		ludi_display.setHTMLId('#lblMsgText', ludi_display.chatParams.text);
	}		
}

ludi_routing.actionButton['SetFilter'] = function  (parameter0, parameter1) {
	ludi_routing.userState.data.profile.filters[parameter0] = parameter1;
	if (typeof ludi_comm !== 'undefined') ludi_comm.updateProfile();
	
	if ((parameter0 == ludi_root.filterEnum.MessagesHidden) || (parameter0 == ludi_root.filterEnum.ActivityHidden)) { 
		ludi_root.visibleMessages = (ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.MessagesHidden] == "1") || 
									(ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.ActivityHidden] == "1");
		ludi_display.resize();	
	} 
	
	/* to-adapt
	// filters 
	if ( (idCombo === "cmbLanFilter") || (idCombo === "cmbBrdFromFilter") || (idCombo === "cmbActFromFilter") ||  (idCombo === "cmbActToFilter") ) {

		if (idCombo === "cmbLanFilter")
			ludi_routing.userState.profile.filters.language = selectBox.selectedIndex;
		else if (idCombo === "cmbBrdFromFilter") 
			ludi_routing.userState.profile.filters.brdFrom = selectBox.selectedIndex;
		else if (idCombo === "cmbActFromFilter") 
			ludi_routing.userState.profile.filters.actFrom = selectBox.selectedIndex;
		else
			ludi_routing.userState.profile.filters.actTo = selectBox.selectedIndex;
			
		// selection to server
		if (user.name)	{
			socket.emit('mlif-filters', {
				'user': user,
				'filters': ludi_routing.userState.profile.filters,
				'gameName': ludi_routing.userState.data.gamename,
				'loc': ludi_routing.userState.profile.currentLoc,
				'email': ludi_routing.userState.data.profile.email,
				'status': ludi_routing.userState.data.profile.status,
				'userLanguages': ludi_routing.userState.data.profile.userLanguages
			});
		}
		return; 
	}
	
	*/

	
	ludi_routing.executeButton ('GeneralSettings');
}

ludi_routing.quitGame = function (isInteractive) {
	if (isInteractive) {
		ludi_renderer.showKernelMSG_html = false;
		var msg = ludi_renderer.showKernelMSG ("Are you sure");
		ludi_renderer.showKernelMSG_html = true;
		if (!confirm(msg)) return;
	}
	
	if (typeof ludi_comm !== 'undefined') ludi_comm.leaveGame ({gameName:ludi_routing.userState.data.gamename});
	ludi_routing.userState.data.gamename = "";
	ludi_renderer.generalContext = "loadingGame";
	ludi_routing.executeButton ('PlayTab');
}

ludi_routing.actionButton['QuitGame'] = function  () {
	ludi_routing.quitGame (true);
}

ludi_routing.actionButton['ShowAbout'] = function  () {
	var txt = ludi_routing.getAboutToShow (ludi_language.lanIndex, ludi_renderer.about);	
	// to-do: if online, show button to show who are playing now
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);			
}

ludi_routing.actionButton['DoThis'] = function  (action, item1, item2, direction) {
	// rendering echo
	var par_c = {
			pc: ludi_routing.userState.profile.indexPC,
			loc: ludi_routing.userState.profile.currentLoc,
			action:action, 
			item1:item1, 
			item2:item2, 
			direction:direction, 
			option:-1,
			freeText:''};
			
	ludi_routing.expandParC (par_c);
	var echo = ludi_renderer.getEcho (par_c,  false);
	alert ("DoThis: [" + echo + "]. Pending to implement.");
}

ludi_routing.actionButton['AboutUser'] = function  (parameter0) {

	var txt = "<P>" + ludi_renderer.showKernelMSG("User profile") + "</P>";
	
	for (var index=0; index<ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu.length;index++) {
		if (ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu[index].id == parameter0) break;
	}
	
	if (index == ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu.length) {
		alert ("parameter0: Missing player");
		return; 
	}
	
	txt += "<P>" + ludi_renderer.showKernelMSG("nick") + ": " + ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu[index].data.idPlayer + "</P>";
	txt += "<P>" + ludi_renderer.showKernelMSG("mail") + ": " + ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu[index].data.email + "</P>";
	txt += "<P>" + ludi_renderer.showKernelMSG("status") + ": " + ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu[index].data.status + "</P>";
	txt += "<P>" + ludi_renderer.showKernelMSG("game") + ": " + ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu[index].data.game + "</P>";
	
	// to-do: show only if playing the same game
	txt += "<P>" + ludi_renderer.showKernelMSG("location") + ": " + ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu[index].data.loc + "</P>";
	
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);		
	
}

ludi_routing.actionButton['MessageToUser'] = function  (parameter0) {
	var txt = ludi_renderer.messageInput_html ();
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);
	ludi_display.messageInput_after_html ();

	ludi_display.chatParams.to = parameter0;
	ludi_display.chatParams.scope = "private";
	ludi_display.chatParams.text = "";
	ludi_display.showChat (ludi_renderer.showKernelMSG(ludi_display.chatParams.scope));
}

ludi_routing.actionButton['AboutGame'] = function  (parameter0) {
	var fileNames = ["games/"+parameter0+"/about.json"];
	ludi_routing.userState.data.gamename = parameter0;
	ludi_io.multiLoadJSON (fileNames, "multiLoadJSON_AboutGame_OK", "multiLoadJSON_AboutGame_Error");
}

ludi_routing.actionButton['LoadGame'] = function  (parameter0) {
	// to-do: if game state on localstorage, get it there instead of from files
	/*
		if (game state on localstorage) {
			ludi_runner.userState = ludi_routing.userState;
			ludi_routing.launchEnvironment();
			return;
		}
	*/
	var fileNames = ["games/"+parameter0+"/about.json"];
	ludi_routing.userState.data.gamename = parameter0;
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, "<p>Loading game from file...</p>", true, true);

	ludi_io.multiLoadJSON (fileNames, "multiLoadJSON_AboutAndLoadGame_OK", "multiLoadJSON_AboutAndLoadGame_Error");
}

ludi_routing.actionButton['LoadGameFromStart'] = function  (parameter0) {
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, "<p>Loading game from local storage...</p>", true, true);

	ludi_routing.userState.data.gamename = parameter0;
	
	// load game world data
	ludi_runner.world = JSON.parse(localStorage.initial_world || null);
	// load messages
	ludi_language.lanList = JSON.parse(localStorage.initial_lanList || null);
	// initial game state
	ludi_routing.userState = JSON.parse(localStorage.initialUserState || null);

	// what about this?: // ludi_language.lastLoadedLanguages = JSON.parse (localStorage.initial.loadedLanguages || null ); 

	// game logic and environment
	ludi_routing.initialLoad = false; // already from localstorage, so do not load from file
	ludi_routing.loadUserGameCode(); 

}

ludi_routing.actionButton['LoadSavedGame'] = function  (parameter0) {
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, "<p>Loading saved game from local storage...</p>", true, true);

	ludi_routing.userState.data.gamename = parameter0;
	
	// load game world data
	ludi_runner.world = JSON.parse(localStorage.saved_world || null);
	// load messages
	ludi_language.lanList = JSON.parse(localStorage.initial_lanList || null);
	// saved game state
	ludi_routing.userState = JSON.parse(localStorage.saved_state || null);
	
	// what about this?: // ludi_language.lastLoadedLanguages = JSON.parse (localStorage.initial.loadedLanguages || null ); 

	// game logic and environment
	ludi_routing.initialLoad = false; // already from localstorage, so do not load from file
	ludi_routing.loadUserGameCode(); 
	
	
	// echo
	var echo = "<p class=\"echo\">"; // to-do: class= "system"
	echo += "#> ";
	echo += ludi_renderer.showKernelMSG("Game state loaded"); 
	echo += "." + "</p>";
	
	// reset stuff
	ludi_routing.runningDialogMenu = false;
	ludi_routing.pendingAnswer = {};
	ludi_routing.caList = [];
	ludi_routing.pendingCA = 0;
	ludi_routing.linkTable = [];	
				
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.AllActions, echo, true, false);
	
	
	// here!
	
	
	
	// to-do: update ludi_runner.userState from ludi_routing.userState
	// from data to cS
	ludi_runner.userState = ludi_routing.userState;
	
	ludi_routing.getMenuCache();
	// error:importedPanelOptions ??
	/*
	for (var i = 0; i<importedPanelOptions.length; i++) {
		ludi_renderer.panelOptions[i] = importedPanelOptions[i];
	}
	*/
	ludi_routing.showDefaultInfo();

	ludi_routing.showPanelView(ludi_root.panel1ViewEnum.Playing.value);
	ludi_routing.executeButton ("PlayTab");


	// to-do: execute game.onReload()
	ludi_routing.actionButton['Redescribe']();
	
	ludi_routing.showDefaultInfo();

}

ludi_routing.actionButton['SaveGame'] = function  () {
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, "<p>Saving game state to local storage...</p>", true, true);

	localStorage.saved_world = JSON.stringify(ludi_runner.world);
	localStorage.saved_state = JSON.stringify(ludi_routing.userState);
	
	ludi_routing.executeButton ("PlayTab");
	
	// echo
	var echo = "<p class=\"echo\">"; // to-do: class= "system"
	echo += "#> ";
	echo += ludi_renderer.showKernelMSG("Game saved"); 
	echo += "." + "</p>";
				
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.AllActions, echo, true, true);
	
	
}

//**********************************************************************************************
//         End of actions on buttons 
//**********************************************************************************************


ludi_routing.afterCodeLoaded = function  () {
	
	var isFromIO;
	
	ludi_renderer.userGameCodeLoaded = 1;	
	
	if (ludi_routing.initialLoad) {
		isFromIO = true;
		ludi_routing.initialLoad = false;
		// save initial state on localStorage
		localStorage.initialUserState = JSON.stringify(ludi_routing.userState);
	} else {
		isFromIO = false;
	}
	
	// if second language was loaded, do nothing
	if (ludi_renderer.generalContext == "playing") {
		return;
	}
		
	ludi_routing.interactionPanel_SetVisible(true);
	
	// new context (loadingGame -> playing)
	ludi_renderer.generalContext = "playing";

	// game language combo with just loaded language
	var currentLan = ludi_language.lanList [ludi_language.lanIndex]; 
	ludi_root.setComboValue ("cmbGLan", currentLan);
	ludi_display.hideHTMLId('#cmbKLan');
	ludi_display.showHTMLId('#cmbGLan');

	if (isFromIO) {
		// copy data from io memory and free memory
		ludi_runner.world = ludi_io.exportWorld();
		ludi_io.freeMem();
		
		ludi_runner.defaultItemState ();
	}

	// internal dynamic indexes
	if (!ludi_runner.compileIndexes()) { // fatal error, page must be reloaded
		ludi_renderer.setButtonVisible ("Restart", true);
		return;
	}
			
	// after code is in memory, environment is launched
	ludi_runner.userState = ludi_routing.userState;
	
	ludi_routing.launchEnvironment();	

}


ludi_routing.afterLibLoaded = function  () {

	ludi_language.lanList[ludi_language.lanIndex].libLoaded = true;
	ludi_language.lanList[ludi_language.lanIndex].gameLibLoaded = true;
	
	// if game already loaded it is not necessary
	if (ludi_renderer.generalContext == "loadingGame") {
		ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, "<p>Data game loaded. Now game code is loading.</p>", true, true);

		ludi_routing.loadUserGameCode();
		
		setTimeout(function () {
			if (ludi_renderer.userGameCodeLoaded != 1) {
				alert ("Game code not loaded");
				return;
			} 
			
		}, 2000);
	} else {
		ludi_routing.afterCodeLoaded ();
	}
}

// load game data (2): code (js)
ludi_routing.loadUserGameCode = function() {
	
	if (ludi_renderer.userGameCodeLoaded == 1) return; // already loaded

	// start asynchronous loading of game code
	// execution continues in given function
	ludi_io.loadjscssfile("./client/data/games/"+ludi_routing.userState.data.gamename+"/game_reactions.js", ludi_routing.afterCodeLoaded); 
}		

ludi_routing.getItemText = function   (indexItem) {
	return ludi_routing.getMessage ("items", indexItem, "txt");
}

ludi_routing.getActionDesc = function   (actionItem) {
	return ludi_routing.getMessage ("actions", actionItem, "txt");
}

ludi_routing.getMessage  = function (type, index, attribute) {
	var id = ludi_routing.getIdFromTypeAndIndex (type, index);
	if (typeof id != 'undefined') return ludi_language.getMessage_LongId (type + "." + id + "." + attribute);
	// else text for error tracking
	return type + "." + "missing_id" + "." + attribute;
}

ludi_routing.getIdFromTypeAndIndex = function (type, index) {
	var id;

	if (index<0) {
		console.log ("Index < 0 in ludi_routing.getIdFromTypeAndIndex");
		return "undefined";
	} else if (isNaN (+index)) {
		console.log ("Index is not a number in ludi_routing.getIdFromTypeAndIndex but a string (" + index + ")");
		return "undefined";
	}
	
	if (type == "items") {
		id = ludi_runner.world.items[index].id;
	} else if (type == "actions") {
		id = ludi_runner.world.actions[index].id;
	} else if (type == "directions") {
		id = ludi_runner.world.directions[index].id; 
	}  else if (type == "attributes") {
		id = ludi_runner.world.attributes[index].id;
	} else console.log ("error in getIdFromTypeAndIndex. missing type: " +  type);
	
	return id;
}


ludi_routing.changeFunc = function(idCombo) {
    var selectBox = document.getElementById(idCombo);
	if (selectBox.selectedIndex==-1) {
		console.log("warning: idCombo without selectedIndex");
		return;
	}
    var selectedValue = selectBox.options[selectBox.selectedIndex].value;
	
	if (idCombo === "cmbKLan") { 
		ludi_routing.newKernelLanguage(selectedValue);
		return;
	}
	
	if (idCombo === "cmbGLan") { // in playing mode
		if (ludi_renderer.generalContext != "playing") return;
		ludi_routing.newGameLanguage  (selectedValue);
		return;
	}
	
	if (idCombo === "cmbMsgLan") {
		ludi_display.chatParams.lan = selectedValue;
		return;
	}
	
    alert(selectedValue + " from " + idCombo);
}


ludi_routing.afterLoadKernelLanguages["loading"] = function () {

	if (ludi_language.kernel_lanIndex>=0) return;
	
	ludi_routing.userState.profile = {};
	ludi_routing.userState.profile.indexPC = 0; // initial PC by default
	ludi_routing.userState.profile.currentLoc = -1;
	ludi_routing.userState.profile.markedItem = -1;
	ludi_routing.userState.profile.turnCounter = 0;
	ludi_routing.userState.profile.score = 0;
	ludi_routing.userState.profile.panelOptions = [];
	ludi_routing.userState.profile.filters = {language:0, brdFrom:0, actFrom:0};
	
	ludi_language.lanIndex=0;
	ludi_language.kernel_lanIndex = 0;

	ludi_routing.interactionPanel_SetVisible(false);
	
	ludi_routing.afterLoadClient();
	
	ludi_renderer.recalculeButtonVisibility();
	ludi_routing.createMenu(ludi_language.lanList, ludi_language.lanList[ludi_language.lanIndex].code);
	
	localStorage.lastLanguage = (localStorage.lastLanguage || ludi_routing.userState.data.profile.userLanguages[0]);
	ludi_root.setComboValue ("cmbKLan", localStorage.lastLanguage);
	ludi_routing.changeFunc ("cmbKLan");
	
	// to-do: check if cmbLan have a valid value

	ludi_display.showMappedPanel (ludi_root.enumPanels.Panel1, "");
	
	// to-do: set aboutView
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, ludi_renderer.welcomeMsg(ludi_language.lanList), true);
	ludi_display.goTopInMainPanel();
	
	//ludi_routing.interactionPanel_SetVisible (true);
	ludi_display.showHTMLId("#Profile");
	
	//ludi_renderer.recalculeButtonVisibility();
	
	if (ludi_routing.userState.data.idPlayer != "anonymous")
		ludi_display.showHTMLId("#status-update-form"); 
	else 
		ludi_display.hideHTMLId("#status-update-form");
	
	ludi_routing.screenResizeHandler();
	
}

ludi_routing.afterLoadClient = function () {

	// before, here was $(window).resize(function()
		
	ludi_routing.screenChange(ludi_root.screenOrientation.Horiz);
	ludi_display.resize();
	ludi_routing.screenResizeHandler();
}


ludi_routing.afterLoadKernelLanguages["newLanguage"] = function () {
		
	if (ludi_renderer.userGameCodeLoaded == 0) {
		ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, ludi_language.generalInstructionsMsg(), true);
		ludi_display.goTopInMainPanel();

		localStorage.lastLanguage = ludi_language.lanList [ludi_language.lanIndex].code;
		
		ludi_routing.showDefaultInfo ();
	} 			
 
 	ludi_routing.screenResizeHandler();

}


ludi_routing.loadGame = function (data) {

	for (var ilan =0; ilan < ludi_language.lanList.length;ilan++) {
		for (var ilan2=0;ilan2<ludi_renderer.about.translation.length;ilan2++) {
			if (ludi_renderer.about.translation[ilan2].language == ludi_language.lanList[ilan].code) {
				ludi_language.lanList[ilan].gameTranslated = true;
			}
		}
	}
	
	if (!ludi_language.lanList[ludi_language.kernel_lanIndex].gameTranslated) {
		var txt = "Current language (" + ludi_language.lanList[ludi_language.kernel_lanIndex].code + ") is not in the language  list (";
		var txt2=""
		for (var ilan=0;ilan<ludi_language.lanList.length;ilan++) {
			if (ludi_language.lanList[ilan].gameTranslated) {
				if (txt2!="") txt2 += ", ";
				txt2 += ludi_language.lanList[ilan].code;
			}
		}
		txt += txt2 + ") of the game. Please select a correct language before trying to load the game.";
		
		alert (txt);
		return;
	}
	
	ludi_io.flags = [{loaded:false},{loaded:false},{loaded:false},{loaded:false}];

	// if game already loaded it is not necessary
	if (ludi_renderer.generalContext == "loadingGame") {
		// multi json loading
		var fileNames = [];
		
		// world definition (language independent)
		fileNames.push ('lib/lib_world.json'); // lib level
		fileNames.push ('games/' + ludi_routing.userState.data.gamename + '/game_world.json'); // game level
		
		// if multiLoadJSON_Game_OK -> load language-dependent data
		ludi_io.multiLoadJSON (fileNames, "multiLoadJSON_Game_OK", "multiLoadJSON_Game_Error");
	} else { // go directly to language-dependent data
		// load language-dependent data
		ludi_routing.importLibMessages(ludi_language.lanIndex);
	}
	
};

ludi_routing.importLibMessages = function(ilan) {

	// multi json loading
	var fileNames = [];
	
	if (typeof ludi_language.lanList[ilan] == "undefined") ludi_language.lanList[ilan] = [];

	if (typeof ludi_language.lanList[ilan].libMes == "undefined") {
		fileNames[0] = 'lib/libMessages'+ludi_language.lanList[ilan].code+'.json'; // libMes<LAN>.json
	} else {
		fileNames[0] = 'skip';
	}

	if (typeof ludi_language.lanList[ilan].libMesByLan == "undefined") {
		fileNames[1] = 'lib/libMessagesByLan'+ludi_language.lanList[ilan].code+'.json'; // libMesByLan<LAN>.json
	} else {
		fileNames[1] = 'skip';
	}

	if (typeof ludi_language.lanList[ilan].gameMes == "undefined") {
		fileNames[2] = 'games/'+ludi_routing.userState.data.gamename+'/gameMessages'+ludi_language.lanList[ilan].code+'.json'; // gameMes<LAN>.json
	} else {
		fileNames[2] = 'skip';
	}

	if (typeof ludi_language.lanList[ilan].gameMesByLan == "undefined") {
		fileNames[3] = 'games/'+ludi_routing.userState.data.gamename+'/gameMessagesByLan'+ludi_language.lanList[ilan].code+'.json'; // gameMesByLan<LAN>.json
	} else {
		fileNames[3] = 'skip';
	}
	
	ludi_io.multiLoadJSON (fileNames, "multiLoadJSON_libMes_OK", "multiLoadJSON_libMes_Error");
	
}


/* IO handlers */

ludi_routing.multiLoadJSON_Kernel_OK = function (fileNames) {
	
	for (var iFN=0;iFN<fileNames.length;iFN++) {
		for (var ilan=0;ilan<ludi_language.lanList.length;ilan++) {
			if (fileNames[iFN] == "kernel/kernel"+ludi_io.language[ilan].code+".json") {
				// get data from IO to memory
				ludi_language.lanList[ilan].kernelMessages = ludi_io.flags[iFN].data;
				ludi_language.lanList[ilan].kernelLoaded = true;
			}
		}
	}
		
	ludi_routing.afterLoadKernelLanguages["loading"]();
}

ludi_routing.multiLoadJSON_Kernel_Error = function (fileNames) {
	ludi_display.setHTMLId("#complete", ludi_display.getHTMLId("#complete") + "<br/>Kernel messages loading timeout. Maybe compatibility issue.");
	
	//ludi_routing.afterLoadKernelLanguages["loading"]();
	
}

// if succesfully loaded language-independent data
ludi_routing.multiLoadJSON_Game_OK = function (fileNames) {
		
	// lib level
	ludi_io.world = ludi_io.flags[0].data;
	
	// game level: game level appended/mixed to/with lib level
	ludi_io.mixingItems (ludi_io.flags[1].data.items);
	ludi_io.mixingActions (ludi_io.flags[1].data.actions);
	ludi_io.mixingDirections (ludi_io.flags[1].data.directions);
	ludi_io.mixingAttributes (ludi_io.flags[1].data.attributes);
	ludi_io.mixingAttExceptions (ludi_io.flags[1].data.attExceptions);
	
	// save game world on localstorage
	localStorage.initial_world = JSON.stringify(ludi_io.world);
	
	// load language-dependent data
	ludi_routing.importLibMessages(ludi_language.lanIndex);

}

ludi_routing.multiLoadJSON_Game_Error = function (fileNames) {
	
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, "<p>ludi_language.lanList: " + JSON.stringify(ludi_language.lanList) + "</p>",true, true);
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, "<p>You must restart LUDI</p>",true, true);
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, "<p>ludi_io.world.actions: " + JSON.stringify(ludi_io.world.actions) + "</p>",true, true);
	ludi_renderer.setButtonVisible ("Restart", true);
	
}

ludi_routing.multiLoadJSON_AboutGame_OK = function (fileNames) {
	ludi_renderer.about = ludi_io.flags[0].data;
	var txt= ludi_routing.getAboutToShow (ludi_language.lanIndex, ludi_renderer.about);		
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);
	
}

ludi_routing.multiLoadJSON_AboutGame_Error = function (fileNames) {
	var txt = "Error loading about file";
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);

}

ludi_routing.multiLoadJSON_AboutAndLoadGame_OK = function (fileNames) {
	ludi_renderer.about = ludi_io.flags[0].data;
	
	ludi_routing.loadGame(ludi_renderer.about);	
}

ludi_routing.multiLoadJSON_AboutAndLoadGame_Error = function (fileNames) {
	var txt = "Error loading game file";
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);
}

ludi_routing.multiLoadJSON_libMes_OK = function (fileNames) {
	
	if (fileNames[0] != 'skip')	ludi_language.lanList[ludi_language.lanIndex].libMes = ludi_io.flags[0].data;
	if (fileNames[1] != 'skip') ludi_language.lanList[ludi_language.lanIndex].libMesByLan = ludi_io.flags[1].data;
	if (fileNames[2] != 'skip')	ludi_language.lanList[ludi_language.lanIndex].gameMes = ludi_io.flags[2].data;
	if (fileNames[3] != 'skip') ludi_language.lanList[ludi_language.lanIndex].gameMesByLan = ludi_io.flags[3].data;
	
	// save messages on localStorage (in fact, maybe same languages were already saved, but...)
	localStorage.initial_lanList = JSON.stringify(ludi_language.lanList);
	
	console.log("LOADED: " + fileNames);
	
	// game goes on
	ludi_routing.afterLibLoaded();
	
}

ludi_routing.multiLoadJSON_libMes_Error = function (fileNames) {
	var txt = "Error loading lib message file.";
	
	for (var i=0;i<ludi_io.flags.length;i++) {
		if (fileNames[i] != 'skip' && !ludi_io.flags[i].loaded)
			txt += " \nError loading " + fileNames[i];
	}
	
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);
}

/* End of IO handlers */


ludi_routing.createMenu = function  (lanList, lanCode) {

	var txt = ludi_renderer.htmlMenuEnvironment();
	if (ludi_renderer.mainTab == 0 &&  (ludi_renderer.generalContext == "playing")) {
		txt += "<hr/>";
		txt += ludi_renderer.htmlAvailableUserActions(1);
	}
	
	ludi_display.showMappedPanel (ludi_root.enumPanels.Environment, txt);

	for (var saIndex in ludi_renderer.menu.button) {
		sysActionId = ludi_renderer.menu.button[saIndex].id;
		if (ludi_renderer.menu.button[saIndex].visible == false) ludi_display.hideHTMLId('#' + sysActionId);
	}
	
	if (ludi_renderer.generalContext == "loadingGame") {
		ludi_display.showHTMLId('#cmbKLan');
		ludi_display.hideHTMLId('#cmbGLan');
	} else {
		ludi_display.hideHTMLId('#cmbKLan');
		ludi_display.showHTMLId('#cmbGLan');
	}
	
	// feed LanguageCombos
	var cmbId;
	if (ludi_renderer.generalContext == "loadingGame") {
		cmbId = "cmbKLan";
		for (var ilan=0;ilan<ludi_routing.userState.data.profile.userLanguages.length;ilan++) {
			// ludi_routing.userState.data.profile.userLanguages instead of lanList[].isUserPreference, in order to keep the _sort_ of languages
			ludi_root.addComboValue (cmbId, ludi_routing.userState.data.profile.userLanguages[ilan]);
		}
	} else {
		cmbId = "cmbGLan";
		
		// combo with the allowed languages
		// ludi_root.addComboValue ("cmbGLan", "EN");
		// ludi_root.addComboValue ("cmbGLan", "ES");
		// ludi_root.addComboValue ("cmbGLan", "EO");
		
		for (var ilan=0;ilan<lanList.length;ilan++) {
			// if (lanList[ilan].kernelLoaded && lanList[ilan].libLoaded &&
			// if ( lanList[ilan].gameLibLoaded)
			if ( lanList[ilan].gameTranslated) 
				ludi_root.addComboValue (cmbId, lanList[ilan].code);
		}
	}	

	ludi_root.setComboValue (cmbId, lanCode);

}


ludi_routing.newKernelLanguage = function  (newKLan) {

	var newLanIndex = arrayObjectIndexOf(ludi_language.lanList, "code", newKLan);
	if (newLanIndex == ludi_language.kernel_lanIndex) return;

	var languages = [];
	languages.push (newKLan);
	if (ludi_renderer.generalContext != "loadingGame") return;
	
	ludi_language.lastLoadedLanguages = [];
	for (var ilan=0;ilan<ludi_language.lanList.length;ilan++) {
		if (ludi_language.lanList[ilan].kernelLoaded)
			ludi_language.lastLoadedLanguages.push (ludi_language.lanList[ilan].code);
	}
	
	// save it as cookie
	localStorage.lastLoadedLanguages = JSON.stringify (ludi_language.lastLoadedLanguages);
	localStorage.lastLanguage = newKLan;
	ludi_display.chatParams.lan = newKLan;

	ludi_language.kernel_lanIndex = arrayObjectIndexOf(ludi_language.lanList, "code", newKLan);
	ludi_language.lanIndex = ludi_language.kernel_lanIndex; // by now, they are the same

	ludi_routing.loadKernelLanguages (languages, "newLanguage"); 

}

ludi_routing.newGameLanguage = function  (newGLan) {
	
	localStorage.lastLanguage = newGLan;
	ludi_display.chatParams.lan = newGLan;
	
	ludi_language.kernel_lanIndex = arrayObjectIndexOf(ludi_language.lanList, "code", newGLan);
	ludi_language.lanIndex = ludi_language.kernel_lanIndex; // by now, they are the same
	
	// echo
	var echo = "<p class=\"echo\">";
	echo += ludi_renderer.showKernelMSG("Language changed to %s1", [ludi_language.lanList [ludi_language.lanIndex].code]);
	echo += "." + "</p>";
				
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.AllActions, echo, true, true);		
		
	ludi_routing.showDefaultInfo ();

	// loading messages
	// to-do: in fact, it must be loading and then echo message
	var fileNames = ["games/"+ludi_routing.userState.data.gamename+"/about.json"];
	ludi_io.multiLoadJSON (fileNames, "multiLoadJSON_AboutAndLoadGame_OK", "multiLoadJSON_AboutAndLoadGame_Error");	

}

ludi_routing.initializeLanguages = function () {
	//localStorage.lastLoadedLanguages = (localStorage.lastLoadedLanguages || JSON.stringify(ludi_language.defaultLanguage));
	if (localStorage.getItem("lastLoadedLanguages") === null ) {
		localStorage.lastLoadedLanguages = JSON.stringify(ludi_language.defaultLanguage);
	}
			
	for (var i=0;i<ludi_language.allLanguages.length;i++) {
		ludi_language.lanList[i] = {
			code: ludi_language.allLanguages[i],
			toLoad_Kernel: false,
			kernelLoaded: false,
			libLoaded: false,
			//gameLibLoaded: false, // must be undefined by now
			gameTranslated: false
		}
	}
	
	// pointers to ludi_io.js
	ludi_io.language = ludi_language.lanList; 
	ludi_io.allLanguages = ludi_language.allLanguages;
	
	ludi_routing.userState.data.profile.userLanguages = JSON.parse (localStorage.userLanguages || null); 
	if (ludi_routing.userState.data.profile.userLanguages == undefined) ludi_routing.userState.data.profile.userLanguages = ["EN","ES"];
	ludi_routing.tempUserLanguages = ludi_routing.userState.data.profile.userLanguages.slice(0);

	// from ludi_routing.userState.data.profile.userLanguages to ludi_language.lanList[].isUserPreference
	for (var i=0;i<ludi_language.lanList.length;i++) {
		ludi_language.lanList[i].isUserPreference = false;
		for (var j=0;j<ludi_routing.userState.data.profile.userLanguages.length;j++) {
			if ( ludi_language.lanList[i].code == ludi_routing.userState.data.profile.userLanguages[j]) {
				ludi_language.lanList[i].isUserPreference = true;
			}
		}
	}

}

ludi_routing.loadKernelLanguages = function  (languagesToLoad, nextFuction) {

	for (var ilan=0;ilan < ludi_language.lanList.length;ilan++) {
		for (var ilan2=0;ilan2 < languagesToLoad.length;ilan2++) {
			if (ludi_language.lanList[ilan].code == languagesToLoad[ilan2])
				ludi_language.lanList[ilan].toLoad_Kernel = true;
		}
	}	

	ludi_io.loadKernelData();
	
	// get data from IO to memory
	for (var i=0;i<ludi_io.kernelMessages.length;i++)
		ludi_language.lanList[i].kernelMessages = ludi_io.kernelMessages[i];
	
	// refresh menu after loading kernel and lib data
    var myTimeout = setTimeout(function () {
		if (ludi_language.pendingKernelMessages()) {
			alert ("Kernel messages loading timeout (" + ludi_io.kernelCounter + " /" + ludi_language.lastLoadedLanguages.length + ")");
			ludi_display.setHTMLId("#complete", ludi_display.getHTMLId("#complete") + "<br/>Kernel messages loading timeout. Maybe compatibility issue.");
		}
		
		ludi_routing.afterLoadKernelLanguages[nextFuction]();
	
	}, 10000);

	var myInterval = setInterval(
		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;
				}
			}
			if (!ludi_language.pendingKernelMessages()) {
				clearInterval(myInterval);
				clearTimeout(myTimeout);
				ludi_routing.afterLoadKernelLanguages[nextFuction]();}
			}
	, 100);
	
}

ludi_routing.setLanguagePreferences = function (tempUserLanguages) {

	ludi_routing.userState.data.profile.userLanguages = tempUserLanguages.slice(0);
	localStorage.userLanguages = JSON.stringify (ludi_routing.userState.data.profile.userLanguages); 
	
	// from tempUserLanguages to ludi_language.lanList[].isUserPreference
	for (var i=0;i<ludi_language.lanList.length;i++) {
		ludi_language.lanList[i].isUserPreference = false;
		for (var j=0;j<ludi_routing.userState.data.profile.userLanguages.length;j++) {
			if ( ludi_language.lanList[i].code == ludi_routing.userState.data.profile.userLanguages[j]) {
				ludi_language.lanList[i].isUserPreference = true;
			}
		}
	}
	
	/* old version
	// from tempUserLanguages to ludi_language.lanList[].isUserPreference
	for (var i=0;i<ludi_language.lanList.length;i++) {
		ludi_language.lanList[i].isUserPreference = false;
		for (var j=0;j<tempUserLanguages.length;j++) {
			if ( ludi_language.lanList[i].code == tempUserLanguages[j]) {
				ludi_language.lanList[i].isUserPreference = true;
			}
		}
	}
	*/
	
}

ludi_routing.getAboutToShow = function   (ilan, about) {

	var lanCode = ludi_language.lanList [ludi_language.lanIndex].code;
	
	var txt = "<P>" + ludi_renderer.showKernelMSG("about game") + " | " + ludi_routing.userState.data.gamename + "</P>";
	var numTranslations =0;
	
	txt +=  "<P>" + ludi_renderer.showKernelMSG("game") +  "</P>";
	txt += "<UL>";
	
	// check how translations available
	for (var ilan2=0;ilan2<about.translation.length;ilan2++) {
		if (about.translation[ilan2].language == ludi_language.lanList[ilan].code) {
			ludi_language.lanList[ilan].gameTranslated = true;
			numTranslations ++;
		}
	}
	
	// language not available, show original language
	if (numTranslations == 0) {
		txt +=  "<LI>" + ludi_renderer.showKernelMSG("Language not available for playing") + "</LI>";	
		ilan = 0; 
	} else {
		for (var ilan2=0;ilan2<about.translation.length;ilan2++) {
			if (about.translation[ilan2].language == ludi_language.lanList[ilan].code) {
				ilan = ilan2;
				break;
			}
		}
	}
	
	txt +=  "<LI>" + ludi_renderer.showKernelMSG("title") + ": " + about.translation[ilan].title + "</LI>";	
	if (ilan != 0) {
		txt +=  "<LI>" + ludi_renderer.showKernelMSG("original title") + ": " + about.translation[0].title + "</LI>";	
	}
	txt +=  "<LI>" + ludi_renderer.showKernelMSG("desc") + ": " + about.translation[ilan].desc + "</LI>";
	txt +=  "<LI>" + ludi_renderer.showKernelMSG("author");
	txt += "<UL>";
		txt +=  "<LI>" + ludi_renderer.showKernelMSG("name") + ": " + about.translation[0].author.name + "</LI>";
		txt +=  "<LI>" + ludi_renderer.showKernelMSG("ludi account") + ": " + about.translation[0].author.ludi_account + "</LI>";
		txt +=  "<LI>" + ludi_renderer.showKernelMSG("email") + ": " + about.translation[0].author.email + "</LI>";
	txt += "</UL></LI>";
	if (ilan != 0) {
		txt +=  "<LI>" + ludi_renderer.showKernelMSG("translator");
		txt += "<UL>";
			txt +=  "<LI>" + ludi_renderer.showKernelMSG("name") + ": " + about.translation[ilan].author.name + "</LI>";
			txt +=  "<LI>" + ludi_renderer.showKernelMSG("ludi account") + ": " + about.translation[ilan].author.ludi_account + "</LI>";
			txt +=  "<LI>" + ludi_renderer.showKernelMSG("email") + ": " + about.translation[ilan].author.email + "</LI>";
		txt += "</UL></LI>";
	}
	txt +=  "<LI>" + ludi_renderer.showKernelMSG("original language") + ": " + about.translation[0].language + "</LI>";
	
	if (about.translation.length>1) {
		txt +=  "<LI>" + ludi_renderer.showKernelMSG("translations") + ":</LI>";
		
		txt += "<UL>";
		for (ilan2=1;ilan2<about.translation.length;ilan2++) {
			txt +=  "<LI>" +  about.translation[ilan2].language + "</LI>";
		}
		txt += "</UL>";
	} else {
		txt +=  "<LI>" + ludi_renderer.showKernelMSG("translations") + ": 0 </LI>";
	}
	
	txt += "</UL>";

	return txt;
}

ludi_routing.launchEnvironment = function  () {

	ludi_routing.getMenuCache();
	
	// first description: to-do: execute FirstVisited
	var txt = 	"<h3>" + ludi_renderer.showKernelMSG("History") + "</h3>";
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.AllActions,  txt, true);
	
	// game welcome stuff
	ludi_routing.addACTION (ludi_root.actEnum.LOOK.value, ludi_routing.userState.profile.currentLoc, -1, -1);
		
	// from ludi_runner.clientAction to ludi_routing.caList
	for (var i in ludi_runner.clientAction) {
		ludi_routing.caList.push (ludi_runner.clientAction[i]);
	}
	ludi_runner.clientAction = [];

	ludi_routing.executePendingRequests();
	ludi_routing.processClientActionList ();
	
	ludi_renderer.mainPanel = 1; // exits
	ludi_routing.showPanelView(ludi_root.panel1ViewEnum.Playing.value);

	// ludi_renderer.setButtonVisible ("Restart", true);
	// ludi_renderer.setButtonVisible ("ClearHistory", true);
	ludi_display.showHTMLId("#File");

	ludi_renderer.setButtonVisible ("Panels", true);
	ludi_renderer.setButtonVisible ("GamesView", false);
	
	ludi_renderer.recalculeButtonVisibility();
	
	if (ludi_renderer.userState.data.idPlayer != "anonymous")
		ludi_display.showHTMLId("#status-update-form"); 
	else  
		ludi_display.hideHTMLId("#status-update-form");
	
	ludi_routing.createMenu(ludi_language.lanList, ludi_language.lanList[ludi_language.lanIndex].code);
		
	
	// send message to server to update that info
	if (typeof ludi_comm !== 'undefined') {
		if (ludi_renderer.userState.data.idPlayer != "anonymous") {
			ludi_comm.joinGame ({gameName:ludi_renderer.userState.data.gamename});
		}
	}

	// a little bit tricky
	ludi_routing.screenResizeHandler();

	
}

ludi_routing.keyPressed = function  () {

	ludi_renderer.presskeyActive = false;
	var elem = document.getElementById('presskey');
	elem.parentNode.removeChild(elem);
	
	// update buffer with current html
	ludi_display.putTextInMainPanel_AppendLast (
		ludi_root.bufferEnum.AllActions,
		ludi_display.getHTMLId('#' + ludi_display.showMappedPanel (ludi_root.enumPanels.Main)),
		true);
	
	ludi_routing.pendingCA++;
	ludi_routing.processClientActionList();	

}


ludi_routing.processClientActionList = function  () {

	var wrapper = "<p id = \"result\">" , txt="";
	
	for (; ludi_routing.pendingCA < ludi_routing.caList.length; ludi_routing.pendingCA ++) {
		txt += ludi_routing.executeClientAction(ludi_routing.caList[ludi_routing.pendingCA]);
		
		if (ludi_routing.caList[ludi_routing.pendingCA].type == ludi_root.caEnum.PRESS_KEY.value) { 
			// actions pending to be executed, after a key is pressed
			break;
		}
	}
	
	// speech ludi_routing.pendingToSpeech 
	ludi_routing.speechIt();

	// caList already processed
	if (ludi_routing.pendingCA == ludi_routing.caList.length) {
		ludi_routing.pendingCA = 0;
		ludi_routing.caList = [];
	}

	wrapper += txt +"</p>"

	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.AllActions,  ludi_display.buffers [ludi_root.bufferEnum.AllActions] + wrapper , true);
		
	// to-do: resend reaction to server?
	
	// to-do: npc turns here (world turn)
	// for (npc) action_of_npc (npc);
		
	ludi_routing.showDefaultInfo();

}

ludi_routing.addToSpeech = function  (type, txt) {
	
	if (ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.SpeechOn] != "0") return;
	if (typeof ludi_routing.speech == 'undefined' ) return;
		
	if ( (type == ludi_root.caEnum.SHOW_ECHO.value) ||
		 (type == ludi_root.caEnum.PLAY_AUDIO.value) ||
		 (type == ludi_root.caEnum.GRAPH.value) ) return;
	
	// to-do:by now: hard coded
	var lang = 'es-ES';
	if (ludi_language.lanList[ludi_language.lanIndex].code == "EN") lang = 'en-US';
	// else if (ludi_language.lanList[ludi_language.lanIndex].code == "EO") lang = 'eo';
		 
	ludi_routing.pendingToSpeech.push ({lang:lang, text:$("<div>"+txt+"</div>").text()}) ;

}

ludi_routing.speechIt = function  () {
		
	if (typeof ludi_routing.speech == 'undefined' ) return;
	
	ludi_routing.speech.onend = function(e) {
	  if (ludi_routing.pendingToSpeech.length >0) {
		  ludi_routing.speechNext(); 
	  }
	};

	ludi_routing.speechNext();
	
	
}

ludi_routing.speechNext = function  () {
	if ( (ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.SpeechOn] != "0") || (typeof ludi_routing.speech == 'undefined' ) ) {
		ludi_routing.speech.text = "";
		ludi_routing.pendingToSpeech = [];
		return;
	}

	if (ludi_routing.pendingToSpeech.length ==0) return;
	
	speechSynthesis.cancel();
	var line2Speech = ludi_routing.pendingToSpeech.shift();
	ludi_routing.speech.lang = line2Speech.lang;
	ludi_routing.speech.text = line2Speech.text;
	speechSynthesis.speak(ludi_routing.speech);
	
}


// messages are expanded here in order to get language-independent messages in all connected users
// to-do: ca.panel = game_zone or popup
ludi_routing.executeClientAction = function  (ca, isPopUp, backToHistorial) {

	var txt = "";
	isPopUp = isPopUp || false;
	backToHistorial = backToHistorial || true;

	if (ca.type == ludi_root.caEnum.ASIS.value) { 
		txt = ludi_renderer.expandText(ca.txt); 
	} else if (ca.type == ludi_root.caEnum.ATT.value) {
		// to-do: show attribute? by now, only if it has description
		var attId = ludi_routing.getIdFromTypeAndIndex ("attributes", ca.o1);
		if (ludi_language.message_LongId_Exists ("attributes" + "." + attId + "." + "txt")) {
			txt = ludi_language.getMessage_LongId ("attributes." + attId + ".txt");
			txt = ludi_renderer.showMSG (txt, [ca.o2]);
		}
	} else if (ca.type == ludi_root.caEnum.DIR.value) { 
		txt = ludi_routing.getMessage ("directions", ca.dir, "txt");
	} else if (ca.type == ludi_root.caEnum.ITEM.value) { 
		var id = ludi_routing.getIdFromTypeAndIndex("items", ca.o1);
		txt = ludi_language.showItemIdByLan (id);
	} else if (ca.type == ludi_root.caEnum.MSG.value) { 
		txt = ludi_renderer.expandText(ludi_renderer.showMSG (ca.txt, ca.param)); 
	} else if (ca.type == ludi_root.caEnum.DESC.value) { 
		txt = ludi_routing.getMessage ("items", ca.o1, "desc");
	} 
	else if (ca.type == ludi_root.caEnum.REFRESH.value) { 
		ludi_renderer.mainPanel = 1; // exits?
		ludi_renderer.subPanel = 0;
		ludi_routing.showDefaultInfo();
		
		ludi_routing.showPanelView(ludi_root.panel1ViewEnum.Playing.value);
	} else if (ca.type == ludi_root.caEnum.URL.value) { 
		txt = "<a href = \"" + ca.url + "\" target=\"_blank\" ";
		// txt += " class=\"CA\""; // to-do: css
		txt += ">" + ludi_renderer.showMSG (ca.txt, ca.param) + "</a>";
	} else if (ca.type == ludi_root.caEnum.GRAPH.value) { 
		var url;

		if (ca.isLocal) { // relative
			url = "./client/data/games/" + ludi_routing.userState.data.gamename + "\/images\/" + ca.url;
		} else { // absolute
			url = ca.url; 
		}
		url = "\"" + url + "\""; 
		
		if (ca.isLink) { 
			var linkText;
			
			if (typeof ca.txt == "undefined") linkText = ludi_renderer.showKernelMSG("Link to see");
			else linkText = ludi_renderer.showMSG (ca.txt, ca.param);

			// link points to ludi_routing.linkTable[id]
			txt = "<div id=\"linkCounter" + ludi_routing.linkTable.length + "\">";
			txt += "<A HREF=" + "javascript:" + ludi_renderer.handlerToOnClick_showImage + "(" + ludi_routing.linkTable.length + ")" + ">" + linkText + "</a><br/>";
			txt += "</div>";

			ludi_routing.linkTable.push({url:url})
			
		} else {
			// image shown directly
			txt = "<img src = " + url + ">";
		}
		txt += "<br/>";
	} else if (ca.type == ludi_root.caEnum.GRAPH_POPUP.value) { // to-do: to abandone
		txt = ludi_renderer.htmlURLBasic (ca.txt, ca.o1, "", "");
	} else if (ca.type == ludi_root.caEnum.MSG_POPUP.value) { 
	} else if (ca.type == ludi_root.caEnum.PRESS_KEY.value) { 
		// stop any activity till event reactivate it
		ludi_renderer.presskeyActive = true;
		txt ="<div id = 'presskey'>";
		txt += ludi_renderer.htmlOfButtonAs("PressKey", ludi_renderer.showMSG (ca.txt));
		txt += "</div>\n";
	} else if (ca.type == ludi_root.caEnum.SHOW_MENU.value) { 
		txt ="<div id = 'dialogMenu'>";
		//var alfa = "abcdefg";
		for (var di in ca.o1) {
			//var line = alfa.substring (+di,+di+1) + ") " + ludi_renderer.showMSG (ca.o1[di]);
			var line = ludi_renderer.showMSG (ca.o1[di]);
			txt += "\n<li>" + ludi_renderer.htmlURLMenu (line, +di, 'menu'+di, 'menu') + "</li>";
		}
		txt += ludi_renderer.showKernelMSG ("Select what you choose");
		txt += "</div>\n";
		ludi_routing.runningDialogMenu = true;
	} else if (ca.type == ludi_root.caEnum.ACTION.value) { 
		// var id = ludi_routing.getIdFromTypeAndIndex("items", ca.o1);
		// return ludi_language.showItemIdByLan (id);
	} else if (ca.type == ludi_root.caEnum.END_GAME.value) { 
		// to-do: block interface
	} else if (ca.type == ludi_root.caEnum.RESTART_GAME.value) { 
		ludi_routing.quitGame(false);
	}  else if (ca.type == ludi_root.caEnum.SHOW_ECHO.value) { 
		txt = "<p class=\"echo\">";
		txt += ludi_renderer.getEcho (ca.par_c, true);
		txt += "</p>";
	} else if (ca.type == ludi_root.caEnum.PLAY_AUDIO.value) { 
	
		// define sound
		var audioElem = document.getElementById('audio');
		audioElem.src = "./client/data/games/" + ludi_routing.userState.data.gamename + "/audio/" + ca.fileName;
		
		// link to pause/restart
		txt ="<div id = 'audioStart'>";
		txt += ludi_renderer.expandText(ludi_renderer.showMSG (ca.txt, ca.param));
		txt	+= "<button id=\"playIt1\" onclick=\"" + "ludi_routing.playAudio()" + "\">" + "Play/Pause" + "</button>";
		txt += "</div>\n";

		if (ca.autoStart) 
			ludi_routing.playAudio();
	} else if (ca.type == ludi_root.caEnum.QUOTE_BEGIN.value) { 
		// to-do: language-dependent! (use preferences)
		txt = "<b>" + "—" + ludi_language.getMessage_LongId  ("items." + ca.item + ".txt") + "</b>: «";
		txt += ludi_renderer.expandText(ludi_renderer.showMSG (ca.txt, ca.param)); 
		if (ca.last) txt+= "».<br/>"; 
		else txt+= " "; // to-do: provisional tricky
	
	} else if (ca.type == ludi_root.caEnum.QUOTE_CONTINUES.value) { 
		// to-do: language-dependent! (use preferences)
		txt = ludi_renderer.expandText(ludi_renderer.showMSG (ca.txt, ca.param)); 
		if (ca.last) txt+= "».<br/>"; 
		else txt+= " "; //  to-do: provisional tricky
	}

	ludi_routing.addToSpeech (ca.type, txt);

	return txt;

}


ludi_routing.playAudio = function () {
	
	var audioElem = document.getElementById('audio');
	if (audioElem.paused) 
		audioElem.play();
	else 
		audioElem.pause();

}

ludi_routing.showImage = function (counter) {
	
	var txt = "<img src = " + ludi_routing.linkTable[counter].url + ">";
	
	// div id= "linkCounterN">  will be destroyed (similar to ludi_routing.keyPressed)
	var elem = document.getElementById('linkCounter' +  counter);
	
	if (elem == null) return;
	
	elem.parentNode.removeChild(elem);
	
	// update buffer with current html
	ludi_display.putTextInMainPanel_AppendLast (
		ludi_root.bufferEnum.AllActions,
		ludi_display.getHTMLId('#' + ludi_display.showMappedPanel (ludi_root.enumPanels.Main)),
		true);
		
	
	ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.AllActions,  ludi_display.buffers [ludi_root.bufferEnum.AllActions] + txt , true);
	
}

ludi_routing.switchOrientation = function () {

	if (ludi_root.screenType == ludi_root.screenOrientation.Horiz)
		ludi_routing.screenChange (ludi_root.screenOrientation.Vert);
	else if (ludi_root.screenType == ludi_root.screenOrientation.Vert)
		ludi_routing.screenChange (ludi_root.screenOrientation.Horiz);
	else
		ludi_routing.screenChange (ludi_root.screenOrientation.Horiz);
}

ludi_routing.screenResizeHandler = function () {
	// dynamic font size
	// $('#complete,button').css('font-size',($(window).width()*0.02)+'px');
	
	if (((ludi_root.screenType == ludi_root.screenOrientation.Vert) || (ludi_root.screenType == -1)) && ($(window).width() > $(window).height())) {
		ludi_routing.screenChange(ludi_root.screenOrientation.Horiz);
	}
	
	if (((ludi_root.screenType == ludi_root.screenOrientation.Horiz) || (ludi_root.screenType == -1)) && ($(window).width() < $(window).height())) {
		ludi_routing.screenChange(ludi_root.screenOrientation.Vert);
	}

	// space for messages on botton
	//if (ludi_routing.userState.data.profile.externalMessagesHidden)  {
	if (ludi_root.visibleMessages) {
		$('#messages_panel').show();
	} else {
		$('#messages_panel').hide();
	}
	
	// middle zone / subpanel
	if (ludi_root.visiblePanels) {
		if (ludi_root.screenType == ludi_root.screenOrientation.Horiz) {
			$('#subpanel_horiz').show();
			$('#subpanel_vert').hide();
		} else {
			$('#subpanel_horiz').hide();		
			$('#subpanel_vert').show();
		}
	}
	
	// button: place for messages_panel (100% / 8 = 12.5%)
	if (ludi_root.visibleMessages) {
		$('#messages_panel').css('height', $('#complete').height() / 8);
	} else {
		$('#messages_panel').css('height', 0);	
	}

	// middle zone / main
	if (ludi_root.screenType == ludi_root.screenOrientation.Horiz) {
		
		// vertical size
		$('#main_horiz').css('height', $('#complete').height() - $('#environment').height() - $('#messages_panel').height());
		
		// horizontal size
		if (ludi_root.visiblePanels) {
			$('#subpanel_horiz').css('height', $('#main_horiz').height());
		}
	} else {
		// vertical dimension (subpanel_vert uses space)
		$('#main_vert').css('height', $('#complete').height() - $('#subpanel_vert').height() - $('#environment').height() - $('#messages_panel').height());

		// horizontal size
		
	}
	
}

ludi_routing.interactionPanel_SetVisible = function  (visible) {

	ludi_root.visiblePanels = visible;
	ludi_display.resize();
	
}

ludi_routing.screenChange = function ( sc) {

	// to-do: by now...
	var lanList = ludi_language.lanList;
	var lanCode = ludi_language.lanList[ludi_language.lanIndex].code;
	
	var isChanged = (sc != ludi_root.screenType);
	
	if ((sc >=0) && (sc <=2)) ludi_root.screenType = sc;
	else ludi_root.screenType = 0;
	
	var txt = "";

	// environment zone, always on top
	txt = '<div id="environment"></div> ';

	// core
	txt += '<div id="main_vert"></div> ';
	txt += '<div id="main_horiz"></div> ';

	// subpanel, on button or left
	txt += '<div id="subpanel_vert"></div>';
	txt += '<div id="subpanel_horiz"></div> ';

	// messages panel, on bottom
	txt += '<div id="messages_panel"></div> '; 
	
	// just skeleton
	ludi_display.setHTMLId('#complete', txt);
	
	// fill into divs
	ludi_display.setHTMLId('#environment', ludi_renderer.htmlMenuEnvironment());

	txt = "";
	if (ludi_renderer.generalContext == "loadingGame") {
		txt2 = ludi_renderer.htmlPanelView (ludi_root.panel1ViewEnum.Games.value);
	} else { 
		txt2 = ludi_renderer.htmlPanelView (ludi_root.panel1ViewEnum.Playing.value);
	}

	if (ludi_root.screenType == ludi_root.screenOrientation.Vert) { 
		ludi_display.setHTMLId('#subpanel_vert', txt);
	} else {
		ludi_display.setHTMLId('#subpanel_horiz', txt);
	}
	
	// ludi_display.setHTMLId('#messages_panel', "<H1>MESSAGES</H1>"); // here!!! get message buffer

	ludi_display.resize();
	
	if (isChanged) {
		
		// refresh ViewButtons panel
		ludi_routing.createMenu(lanList, lanCode);
		
		ludi_routing.showDefaultInfo();
		
		// refresh main panel
		if (ludi_renderer.generalContext == "loadingGame") {
			ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, "", true, true);
		} else {
			ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.AllActions, "", true, true);
		}

		// refresh messages panel
		ludi_display.putTextInMainPanel_AppendFirst (ludi_root.bufferEnum.allMessages, "", true, true);
		
	}

}

// to-do: redraw relating with current active screen dimensions

ludi_routing.showDefaultInfo = function  () {

	var txt = "";
	if (ludi_renderer.mainTab == 0) { // game tab
		if (ludi_renderer.generalContext == "loadingGame") {
			txt = ludi_renderer.welcomeMsg(ludi_language.lanList);
			ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);
		} else { // playing
			ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.AllActions,  "", true, true);
		}
	} else if (ludi_renderer.mainTab == 1) { // social tab 
		var txt = "<p>";
		txt += ludi_renderer.showKernelMSG("Player") + ": " +  ludi_renderer.userState.data.idPlayer;
		txt += "</p>" ;
		if (ludi_renderer.userState.data.idPlayer != "anonymous") {
			txt += ludi_renderer.htmlPanelView (ludi_root.panel1ViewEnum.Players.value);
		}
		ludi_display.putTextInMainPanel_AppendLast_before (ludi_root.bufferEnum.Config,  txt, true);

	} else if (ludi_renderer.mainTab == 2) { // help tab 
		ludi_routing.executeButton ('About');
	} else if (ludi_renderer.mainTab == 3) { // chat tab 
	
		var txt = ludi_renderer.messageInput_html ();
		ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);
		ludi_display.messageInput_after_html ();
				
		if (ludi_renderer.generalContext == "playing")
			ludi_display.chatParams.scope = "loc";
		else
			ludi_display.chatParams.scope = "global";
		ludi_display.chatParams.to = "";
		ludi_display.chatParams.text = "";
		ludi_display.showChat (ludi_renderer.showKernelMSG(ludi_display.chatParams.scope));
	} else if (ludi_renderer.mainTab == 4) { // profile tab 
	
		// patch	
		ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu[0].id = ludi_renderer.userState.data.idPlayer;
	
		var index = arrayObjectIndexOf(ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu, "id", ludi_renderer.userState.data.idPlayer);
		
		var txt = "";
		
		// error here!!
		txt += ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu[index].getOptionsHTML();
		
		ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);
		ludi_routing.interactionPanel_SetVisible (false);

	}

}

ludi_routing.switchPanels = function () {

	var idPanel1 = "#"+ ludi_root.panelMapping[ludi_root.enumPanels.Panel1][ludi_root.screenType];
	if (idPanel1 == "#") return;
	
	ludi_routing.interactionPanel_SetVisible (!ludi_root.visiblePanels);
	
	ludi_routing.showDefaultInfo();
	
	
}

ludi_routing.sendMessage = function () {

	var data = {
			'user': user, // == from
			'lan': ludi_display.chatParams.lan,
			'to': ludi_display.chatParams.to, 
			'scope': ludi_display.chatParams.scope, 
			'message': ludi_display.chatParams.text,
			'game': ludi_renderer.userState.data.game,
			'filters': ludi_renderer.userState.data.profile.filters,
			// loc
			
			
	};
	
	data.game = ludi_renderer.userState.data.gamename; 
	
	if (data.scope == "loc") data.to = ludi_renderer.userState.data.loc;
	
	ludi_comm.messageSend (data);

	// debug: show sent message echo
	var txt = "out msg: " + data.scope; 
	if (data.to != "") 	txt += "." + data.to; 
	txt += "(" + data.lan + ")";
	txt += ": " + data.message;
	console.log (txt);
	
	ludi_display.setHTMLId('#lblMsgText', "");
}

ludi_routing.expandParC = function (par_c) {
	
	par_c.item1Id =  ludi_routing.getIdFromTypeAndIndex("items", par_c.item1);
	par_c.item2Id =  ludi_routing.getIdFromTypeAndIndex("items", par_c.item2);
	par_c.locId =  ludi_routing.getIdFromTypeAndIndex("items", par_c.loc);
	par_c.pcId =  ludi_routing.getIdFromTypeAndIndex("items", par_c.pc);
	par_c.directionId =  ludi_routing.getIdFromTypeAndIndex("directions", par_c.direction);
	par_c.actionId =  ludi_routing.getIdFromTypeAndIndex("actions", par_c.action);

	return par_c;
}

ludi_routing.updateUserList = function (data) { // online players

	ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu = [];
	
	ludi_renderer.addLogedUserInUserList();
	
	for (var index=0; index<data.users.length; index++) {
	
		var it = new ludi_renderer.menu.MI_Player(
			data.users[index].name,
			{
				idPlayer: data.users[index].name,
				game: data.users[index].game,
				filters: data.users[index].filters,
				loc: data.users[index].loc,
				email: data.users[index].email,
				userLanguages: data.users[index].userLanguages,
				status: data.users[index].status
			} );
	
		it.type = ludi_root.p1Def.OnlinePlayers.value;
		it.viewType = ludi_root.panel1ViewEnum.Players.value;
		ludi_renderer.panelOptions[ludi_root.p1Def.OnlinePlayers.value].menu.push (it);
	}
	
	ludi_renderer.reassignPlayers();

}


ludi_routing.messageReception = function (serverData) {

	// mapping from transmitted data to internal data representation
	var dataFromMessage = {
		txt: serverData.message,
		from: serverData.user.name,
		to: serverData.target,
		lan: serverData.lan,
		game: serverData.game,
		scope: serverData.scope,
	};
	
	// for server messages: expand message, if necessary
	if (serverData.type == 'info' || serverData.type == 'error') {
	
		dataFromMessage.scope = "system";
		
		if (serverData.messageId != undefined) { // system messages mapping
			var kernelMsgId = ludi_comm.serverMessages[serverData.messageId].kernelMsgId;
			if (kernelMsgId<0) {
				alert ("error in messageReception #1");
				return;
			}
			var kernelMsg = ludi_renderer.showKernelMSG (kernelMsgId);
			var hndlbrs = Handlebars.compile(kernelMsg);
			var trick = {id: serverData.message};
			dataFromMessage.txt = hndlbrs (trick); // {id} from ludi_routing.userState

		} // literal message from server, insted of kernel message
	}

	// missing type
	if ( (serverData.type != 'info') && (serverData.type != 'error') && (serverData.type != 'echo') && (serverData.type != 'chat')) {
		alert ("Missing type in messageReception. Received ype: " + serverData.type);
		return;
	}
	
	ludi_renderer.storeMessage (dataFromMessage);
	
	// show in messages panel, if messages are integrated in zone game
	var showMessage = false;
	
	if  ( (serverData.type != 'echo') && 
		  (ludi_root.visibleMessages) &&  // messages_panel on
		  (ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.MessagesHidden] == "1") ) {
			
		showMessage = true;
		
		// check filter by language (to-do: not implmented yet)
		if (ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.IncomingLanguages] == "0") { // : all languages
		
		} else if (ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.IncomingLanguages] == "1") { // check the current language
		
		} else { // == "2": check favorite languages
		
		} 
		
		// check filter by source
		if (ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.BroadcastFrom] == "0") { // from anywhere (allow all messages)

		} else if (ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.BroadcastFrom] == "1") { // from the same game (filter global spam)
			
			if (serverData.scope == "global") showMessage = false;
	
		} else {	//  == "2":  from the same game location (filter global spam and game messages from another game locations)

			if ((serverData.scope == "global") || (serverData.scope == "game")) showMessage = false; //(serverData.scope != "loc") 
		
		}
	}
	
	if (showMessage) {
		var txt = ludi_renderer.getMessage_HTML (dataFromMessage);
		ludi_display.putTextInMainPanel_AppendFirst (ludi_root.bufferEnum.allMessages, txt, true, true);
	}
	
}

ludi_routing.activityReception = function (serverData) {

	var par_c  = serverData.message.par_c;
	
	// show in messages panel, if activity are integrated in zone game
	var showMessage = false;
	
	if ( (ludi_root.visibleMessages) &&  // messages_panel on
		 (ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.ActivityHidden] == "1") ) {
			
		showMessage = true;
		
		// check filter by source
		if (ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.ActivityFrom] == "0") { // all activity (same game)

		} else if (ludi_routing.userState.data.profile.filters[ludi_root.filterEnum.ActivityFrom] == "1") { // activity from the same game location
		
			if (par_c.locId != ludi_routing.userState.profile.currentLocId) showMessage = false;

		
		} else {	//  == "2": no activity shown
			showMessage = false;
		}
		
	}
	
	if (showMessage) { 
	
		var echo = "<p class=\"activity\">" + serverData.user.name + " ";
		echo += ludi_renderer.getEcho (par_c,  false);
		echo += "</p>";
	
		// to-do: using filters to decide which activity to show
		// considering ludi_routing.userState.data.profile.filters[x] , where x= ludi_root.filterEnum.ActivityHidden, ludi_root.filterEnum.ActivityFrom
		
		ludi_display.putTextInMainPanel_AppendFirst (ludi_root.bufferEnum.allMessages, echo, true, true);
		
	}	
	ludi_routing.expandParC(par_c);
		
	// save GameActivity
	var it = new ludi_renderer.menu.MI_Activity(
		"" + ludi_renderer.panelOptions[ludi_root.p1Def.GameActivity.value].menu.length,
		{
			idPlayer:serverData.user.name, 
			par_c: par_c
		}
	);
		 
	it.type = ludi_root.p1Def.GameActivity.value;
	it.viewType = ludi_root.panel1ViewEnum.Activity.value;
	ludi_renderer.panelOptions[ludi_root.p1Def.GameActivity.value].menu.unshift (it);
	
	// to-do: if necessary, save LocationActivity
	
}


// update loc in network
ludi_routing.userChatReallocation = function  () {
	
	if (typeof ludi_comm !== 'undefined') {
		ludi_comm.leaveLoc ({gameName:ludi_renderer.userState.data.gamename, loc:ludi_renderer.userState.data.loc});
		ludi_renderer.userState.data.loc = ludi_renderer.userState.profile.currentLoc;
		ludi_comm.joinLoc ({gameName:ludi_renderer.userState.data.gamename, loc:ludi_renderer.userState.data.loc});
	}
	
}

ludi_routing.savePrivateActivity = function  (par_c) {
	
	ludi_routing.expandParC(par_c);
		
	// save to private activity (history)
	var it = new ludi_renderer.menu.MI_Activity(
		"" + ludi_renderer.panelOptions[ludi_root.p1Def.PrivateActivity.value].menu.length,
		{	
			idPlayer:ludi_renderer.userState.data.idPlayer, 	
			par_c: par_c
		} 
	);
	it.type = ludi_root.p1Def.PrivateActivity.value;
	it.viewType = ludi_root.panel1ViewEnum.Activity.value;
	ludi_renderer.panelOptions[ludi_root.p1Def.PrivateActivity.value].menu.unshift (it);

	
}

// indirect input: ludi_renderer.mainPanel 
ludi_routing.showPanelView = function  (idPanelView, showOnSystemPanelInput) {

	var showOnSystemPanel = showOnSystemPanelInput || false;
	
	var txt = ludi_renderer.htmlPanelView (idPanelView);
	
	if (showOnSystemPanel) {
		if (ludi_renderer.mainPanel == 0)
			ludi_display.putTextInMainPanel_AppendLast (ludi_root.bufferEnum.Config, txt, true);
		else
			ludi_display.showMappedPanel (ludi_root.enumPanels.Panel1, txt);
	} else {
		if (ludi_renderer.mainPanel == 0)
			ludi_display.showMappedPanel (ludi_root.enumPanels.Panel1, txt);
		else {
			ludi_display.showMappedPanel (ludi_root.enumPanels.Panel1, txt);
		}
	}

}


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

BOOT!

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

// very first function
function loadClient () {

	ludi_display.setHTMLId("#complete", "Loading some data, please wait for a while");

	ludi_display.hideHTMLId("#status-update-form");
	
	ludi_renderer.panel1Initialization ();

	ludi_routing.initializeLanguages();
	ludi_renderer.reassignPlayers();
	ludi_io.initialization();
	
	if ('speechSynthesis' in window) {
	    console.log('Synthesis support. Make your web apps talk!');

		ludi_routing.speech = new SpeechSynthesisUtterance();
		var voices = window.speechSynthesis.getVoices();
		ludi_routing.speech.voice = voices[10]; // Note: some voices don't support altering params
		//msg.voiceURI = 'native';
		ludi_routing.speech.volume = 1; // 0 to 1
		ludi_routing.speech.rate = 1; // 0.1 to 10
		ludi_routing.speech.pitch = 1; //0 to 2
	}
	
	ludi_renderer.initialization(ludi_routing.userState);
	
	var lastLoadedLanguages = JSON.parse (localStorage.lastLoadedLanguages);

	ludi_routing.loadKernelLanguages (lastLoadedLanguages, "loading");
	
	

}


