/**
 * Used for gameselection details.
 */
const g_VictoryConditions = g_Settings && g_Settings.VictoryConditions;

/**
 * Used for the gamelist-filtering.
 */
const g_MapSizes = prepareForDropdown(g_Settings && g_Settings.MapSizes);

/**
 * Used for the gamelist-filtering.
 */
const g_MapTypes = prepareForDropdown(g_Settings && g_Settings.MapTypes);

/**
 * Used for civ settings display of the selected game.
 */
const g_CivData = loadCivData(false, false);

/**
 * Current nickname.
 */
var g_Nickname = Engine.LobbyGetNick();

/**
 * This class organizes all components of this GUI page.
 */
var g_LobbyHandler;

/**
 * Called after the XmppConnection succeeded and when returning from a game.
 */
function init(attribs)
{
	if (g_Settings)
		g_LobbyHandler = new LobbyHandler(attribs && attribs.dialog);
	else
		error("Could not load settings");
}


/**
 * List of more buttons bar below the chat input.
 */
 var g_MoreButtonsBarFuncs = {
	"Replays": () => Engine.PushGuiPage("page_replaymenu.xml", { "ingame": g_InGame, "dialog": true, "callback": "startReplay" }),
	"Last Summary": { "func": showLastGameSummary, "tooltip": "Show complete last " + setStringTags("summary", { "color": "yellow" }) + " (if not disconnected during game)." },
	"Civilizations": { "func": openCivInfo, "tooltip": colorizeHotkey("Press %(hotkey)s to open structure tree.", "structree") },
	"Options": { "func": openGameOptions, "tooltip": colorizeHotkey("Press %(hotkey)s to open options.", "options") }
};

function openCivInfo()
{
	Engine.PushGuiPage(g_CivInfo.page, { "civ": g_CivInfo.code, "callback": "storeCivInfoPage" });
}

function openGameOptions()
{
	Engine.PushGuiPage("page_options.xml", {
		"selectedCategory": g_OptionsPage || "Lobby",
		"callback": "initUserConfigurables"
	})
}


var g_WindowFocus = true;

var g_Presence = {
	"timer": 0,
	"setNew": "",
	"timeoutMilliSeconds": 500
};

/**
 * Configuration auto away.
 */
 var g_AutoAway = {
	"timeMinutes": +Engine.ConfigDB_GetValue("user", "lobby.autoawaytime"),
	"time": false,
	"background": false,
	"timeInBackground": false,
	"timerHandler": 0,
	"applied": false
};


/**
 * Different states for presence and auto-away feature.
 * Called as function due to configurable g_AutoAway.timeMinutes.
 */
 var g_AutoAwayStates = [
	{
		"name": "available",
		"desc": () => translate("Available"),
		"func": () => setPlayerPresence("available", false, false, false)
	},
	{
		"name": "away",
		"desc": () => translate("Away"),
		"func": () => setPlayerPresence("away", false, false, false)
	},
	{
		"name": "available_awaytime",
		"desc": () => sprintf(translate("Away after %(minutes)s %(minute)s"),
		{
			"minutes": g_AutoAway.timeMinutes,
			"minute": translatePlural("minute", "minutes", g_AutoAway.timeMinutes)
		}),
		"func": () => setPlayerPresence("available", true, false, false)
	}
];


/**
 * Apply lobby presence for player.
 * 500ms timeouts between multiple presence changes. After timeout applies latest presence change.
 * 
 * @param {string} presence - Presence string for user. ("available", "away", "busy")
 * @param {bool} awayTime - Optional auto away when time g_AutoAway.timeMinutes inactive.
 * @param {bool} awayBackground - Optional auto away when window looses focus.
 * @param {bool} awayTimeInBackground - Optional auto away when time inactive while window is unfocused.
 */
 function setPlayerPresence(presence, awayTime, awayBackground, awayTimeInBackground)
 {
	 g_AutoAway.time = awayTime;
	 g_AutoAway.background = awayBackground;
	 g_AutoAway.timeInBackground = awayTimeInBackground;
	 resetAutoAway();
 
	 // When timeout, store presence.
	 if (g_Presence.timer)
		 g_Presence.setNew = presence;
	 else
	 {
		 applyPlayerPresence(presence);
		 g_Presence.setNew = "";
		 // Start timeout for next presence apply.
		 g_Presence.timer = setTimeout(() => {
			 if (g_Presence.setNew)
				 applyPlayerPresence(g_Presence.setNew);
			 g_Presence.timer = 0;
			 }, g_Presence.timeoutMilliSeconds);
	 }
 }
 
 function handleInputAfterGui(ev)
 {
	 // Wait for window focus to reset auto away.
	 if (g_WindowFocus) // ev.type != "mousemotion" && 
		 resetAutoAway();
 
	 return false;
 }
 
 function setAutoAway()
 {
	 Engine.LobbySetPlayerPresence("away");
	 g_AutoAway.applied = true;
 }
 
 function resetAutoAway()
 {
	 if (g_AutoAway.applied)
	 {
		 Engine.LobbySetPlayerPresence("available");
		 g_AutoAway.applied = false;
	 }
 
	 if (g_AutoAway.timerHandler)
		 clearTimeout(g_AutoAway.timerHandler);
 
	 if (g_AutoAway.time && (!g_AutoAway.timeInBackground || !g_WindowFocus))
		 g_AutoAway.timerHandler = setTimeout(setAutoAway, 1000 * 60 * g_AutoAway.timeMinutes);
 
	 if (g_AutoAway.background && !g_AutoAway.timeInBackground && !g_WindowFocus)
		 setAutoAway();
 }
 

 
function showLastGameSummary()
{
	let replays = Engine.GetReplays(false).filter(replay =>
		replay.attribs.settings.PlayerData.filter(player => player && !player.AI).length > 1 ).sort((a, b) =>
			b.attribs.timestamp - a.attribs.timestamp
		);

	let simData = {};
	if (replays)
		for (let i in replays)
		{
			simData = Engine.GetReplayMetadata(replays[i].directory);
			if (simData)
				break;
		}

	if (!replays || !simData)
	{
		messageBox(500, 200, translate("No summary data available."), translate("Error"));
		return;
	}

	Engine.PushGuiPage("page_summary.xml", {
		"sim": simData,
		"gui": {
			"replayDirectory": replays[0].directory,
			"isInLobby": true,
			"ingame": g_InGame,
			"dialog": true },
		"callback": "startReplay"
	});
}


function storeCivInfoPage(data)
{
	g_CivInfo.code = data.civ;
	g_CivInfo.page = data.page;
}
