/**
 *	UI Lib
 *
 *	Available modules:
 *	- TimeGap -> display the time gap between the players
 *	- SmallScoresTable -> display the player ranking at the end of the round
 */
#Const	Version		"2014-03-26"
#Const	ScriptName	"UI.Script.txt"

// ---------------------------------- //
// Constants
// ---------------------------------- //
#Const C_LibUI_TimeGapPos <40., -90., 5.>
#Const C_LibUI_SmallScoresTablePos <104., 14., 5.>

// ---------------------------------- //
// Globales
// ---------------------------------- //
declare Text[] G_LibUI_ModulesLoaded;
declare Ident[Text] G_LibUI_LayersIds;

// ---------------------------------- //
// Functions
// ---------------------------------- //

// ---------------------------------- //
// Private
// ---------------------------------- //
// ---------------------------------- //
/** Create a layer for a module
 *
 *	@param	_ModuleId	The name of the module
 */
CUILayer Private_CreateModuleLayer(Text _ModuleId) {
	declare Layer = UIManager.UILayerCreate();
	G_LibUI_LayersIds[_ModuleId] = Layer.Id;
	UIManager.UIAll.UILayers.add(Layer);
	
	return Layer;
}

// ---------------------------------- //
/** Destroy th elayer associated to a module
 *
 *	@param	_ModuleId	The name of the module
 */
Void Private_DestroyModuleLayer(Text _ModuleId) {
	declare LayedId = G_LibUI_LayersIds[_ModuleId];
	declare LayerRemoved = G_LibUI_LayersIds.removekey(_ModuleId);
	if (UIManager.UILayers.existskey(LayedId)) {
		declare Layer <=> UIManager.UILayers[LayedId];
		LayerRemoved = UIManager.UIAll.UILayers.remove(Layer);
		UIManager.UILayerDestroy(Layer);
	}
}

// ---------------------------------- //
/** Create the manialink for the time gap module
 *
 *	@return		The manialink
 */
Text Private_CreateMLTimeGap() {
	return """
<framemodel id="Framemodel_Player">
	<label posn="13 0" sizen="12 4" halign="right" valign="bottom" id="Label_Time" />
	<label posn="14.1 0.1" sizen="3.9 4" scale="0.9" valign="bottom" id="Label_LocalRank" />
	<label posn="18.5 0" sizen="35 4" valign="bottom" id="Label_Name" />
</framemodel>
<frame posn="{{{C_LibUI_TimeGapPos.X}}} {{{C_LibUI_TimeGapPos.Y}}} {{{C_LibUI_TimeGapPos.Z}}}" id="Frame_TimeGap" hidden="1">
	<quad posn="0 20" sizen="54 3.8 0" valign="bottom" bgcolor="7783" />
	<quad posn="0 16" sizen="54 3.8 0" valign="bottom" bgcolor="7783" />
	<quad posn="0 12" sizen="54 3.8 0" valign="bottom" bgcolor="7783" />
	<quad posn="0 8" sizen="54 3.8 0" valign="bottom" bgcolor="7783" />
	<quad posn="0 4" sizen="54 3.8 0" valign="bottom" bgcolor="7783" />
	<quad posn="0 0" sizen="54 3.8 0" valign="bottom" bgcolor="7783" />
	<quad posn="14 0 1" sizen="4 24 1" valign="bottom" bgcolor="0009" />
	<frame posn="0 0 2" id="Frame_PlayersList">
		<format textemboss="1" textsize="1.5" />
		<frameinstance posn="0 20" modelid="Framemodel_Player" />
		<frameinstance posn="0 16" modelid="Framemodel_Player" />
		<frameinstance posn="0 12" modelid="Framemodel_Player" />
		<frameinstance posn="0 8" modelid="Framemodel_Player" />
		<frameinstance posn="0 4" modelid="Framemodel_Player" />
		<frameinstance posn="0 0" modelid="Framemodel_Player" />
	</frame>
</frame>
<script><!--
#Include "TextLib" as TL

#Const C_LibUI_TimeGapPos <{{{C_LibUI_TimeGapPos.X}}}, {{{C_LibUI_TimeGapPos.Y}}}, {{{C_LibUI_TimeGapPos.Z}}}>

declare CMlFrame[] Frames_Player;

Text TimeToText(Integer _Time) {
	declare Time = TL::TimeToText(_Time, True);
	declare Milliseconds = _Time % 10;
	if (Milliseconds >= 0) Time ^= TL::ToText(Milliseconds);
	return Time;
}

Void UpdateSlot(Integer _SlotNb, CTmMlPlayer _Player) {
	if (!Frames_Player.existskey(_SlotNb)) return;
	declare Frame_Player	<=> Frames_Player[_SlotNb];
	declare Label_Time		<=> (Frame_Player.GetFirstChild("Label_Time")		as CMlLabel);
	declare Label_LocalRank	<=> (Frame_Player.GetFirstChild("Label_LocalRank")	as CMlLabel);
	declare Label_Name		<=> (Frame_Player.GetFirstChild("Label_Name")		as CMlLabel);
	
	if (_Player != Null && Scores.count > 0) {
		if (!Frame_Player.Visible) Frame_Player.Visible = True;
		
		declare Format = "";
		if (_Player.Id == InputPlayer.Id) Format = "$0f0";
			
		declare netread Text[Text] Net_LibUI_Settings for Teams[0];
		declare CheckpointTime = 0;
		
		if (Net_LibUI_Settings.existskey("TimeGap_Mode") && Net_LibUI_Settings["TimeGap_Mode"] == "CurRace") {
			if (_Player.CurRace.Checkpoints.count > 0) {
				CheckpointTime = _Player.CurRace.Checkpoints[InputPlayer.CurRace.Checkpoints.count - 1];
			} else {
				Frame_Player.Visible = False;
				return;
			}
		} else {
			if (InputPlayer.CurLap.Checkpoints.count <= 0) {
				if (_Player.Id == InputPlayer.Id) CheckpointTime = _Player.Score.PrevRace.Time;
				else CheckpointTime = _Player.Score.BestRace.Time;
			} else {
				if (_Player.Id == InputPlayer.Id) CheckpointTime = _Player.CurLap.Checkpoints[InputPlayer.CurLap.Checkpoints.count - 1];
				else CheckpointTime = _Player.Score.BestRace.Checkpoints[InputPlayer.CurLap.Checkpoints.count - 1];
			}
		}
		
		declare LibUI_TimeGap_CheckpointLeadTime for InputPlayer = 0;
		if (_SlotNb == 0 && CheckpointTime == LibUI_TimeGap_CheckpointLeadTime) {
			Label_Time.Value = Format^TimeToText(CheckpointTime);
		} else {
			declare LibUI_TimeGap_CheckpointLeadTime for InputPlayer = 0;
			declare Gap = CheckpointTime - LibUI_TimeGap_CheckpointLeadTime;
			Label_Time.Value = Format^"+"^TimeToText(Gap);
		}
		
		declare LibUI_TimeGap_Rank for _Player = 1;
		Label_LocalRank.Value = Format^(LibUI_TimeGap_Rank)^".";
		Label_Name.Value = _Player.Score.User.Name;
	} else {
		if (Frame_Player.Visible) Frame_Player.Visible = False;
	}
}

Void UpdateTimeGap() {
	if (InputPlayer.CurRace.Checkpoints.count <= 0) return;
	
	declare netread Text[Text] Net_LibUI_Settings for Teams[0];
	
	declare CheckpointsSort = Integer[CTmMlPlayer];
	if (Net_LibUI_Settings.existskey("TimeGap_Mode") && Net_LibUI_Settings["TimeGap_Mode"] == "CurRace") {
		foreach (Player in Players) {
			if (Player.CurRace.Checkpoints.count < InputPlayer.CurRace.Checkpoints.count) continue;
			CheckpointsSort[Player] = Player.CurRace.Checkpoints[InputPlayer.CurRace.Checkpoints.count-1];
		}
	} else {
		if (InputPlayer.CurLap.Checkpoints.count <= 0 && InputPlayer.Score.PrevRace.Checkpoints.count <= 0) return;
	
		declare CheckpointsCount = 0;
		if (InputPlayer.CurLap.Checkpoints.count <= 0) {
			CheckpointsSort[InputPlayer] = InputPlayer.Score.PrevRace.Time;
			CheckpointsCount = InputPlayer.Score.PrevRace.Checkpoints.count;
		} else {
			CheckpointsSort[InputPlayer] = InputPlayer.CurLap.Checkpoints[InputPlayer.CurLap.Checkpoints.count-1];
			CheckpointsCount = InputPlayer.CurLap.Checkpoints.count;
		}
		
		foreach (Player in Players) {
			if (Player.Score == Null) continue;
			if (Player.Score.BestRace.Checkpoints.count < CheckpointsCount || Player.Id == InputPlayer.Id) continue;
			CheckpointsSort[Player] = Player.Score.BestRace.Checkpoints[CheckpointsCount-1];
		}
	}
	
	CheckpointsSort = CheckpointsSort.sort();
	
	declare Start = 0;
	declare End = 0;
	foreach (Player => CheckpointTime in CheckpointsSort) {
		if (Player.Id == InputPlayer.Id) break;
		End +=1;
	}
	Start = End - Frames_Player.count + 1;
	if (Start < 0) Start = 0;
	if (End < Frames_Player.count - 1) End = Frames_Player.count - 1;
	
	declare LibUI_TimeGap_CheckpointLeadTime for InputPlayer = 0;
	declare SlotNb = 0;
	declare I = 0;
	foreach (Player => CheckpointTime in CheckpointsSort) {
		if (I == 0) LibUI_TimeGap_CheckpointLeadTime = CheckpointTime;
		if (I >= Start && I <= End) {
			declare LibUI_TimeGap_Rank for Player = 1;
			LibUI_TimeGap_Rank = I + 1;
			UpdateSlot(SlotNb, Player);
			SlotNb += 1;
		}
		I += 1;
	}
	for (J, SlotNb, Frames_Player.count) {
		UpdateSlot(J, Null);
	}
}

main() {
	declare Frame_TimeGap		<=> (Page.GetFirstChild("Frame_TimeGap")		as CMlFrame);
	declare Frame_PlayersList	<=> (Page.GetFirstChild("Frame_PlayersList")	as CMlFrame);
	foreach (Control in Frame_PlayersList.Controls) {
		Frames_Player.add((Control as CMlFrame));
	}
	
	declare netread Text[Text] Net_LibUI_Settings for Teams[0];
	
	while (True) {
		sleep(250);
		if (InputPlayer == Null) continue;
		if (InputPlayer.Score == Null) continue;
		if (!PageIsVisible) continue;
			
		if (InputPlayer.CurRace.Checkpoints.count <= 0 && Frame_TimeGap.Visible) {
			Frame_TimeGap.Visible = False;
		} else if (InputPlayer.CurRace.Checkpoints.count > 0 && !Frame_TimeGap.Visible) {
			Frame_TimeGap.Visible = True;
		}
		
		declare NeedUpdate = False;
		if (Net_LibUI_Settings.existskey("TimeGap_Mode") && Net_LibUI_Settings["TimeGap_Mode"] == "CurRace") {
			foreach (Player in Players) {
				declare LibUI_TimeGap_PrevCheckpointsCount for Player = -1;
				if (LibUI_TimeGap_PrevCheckpointsCount != Player.CurRace.Checkpoints.count) {
					LibUI_TimeGap_PrevCheckpointsCount = Player.CurRace.Checkpoints.count;
					if (Player.CurRace.Checkpoints.count == InputPlayer.CurRace.Checkpoints.count) {
						NeedUpdate = True;
					}
				}
			}
		} else {
			declare LibUI_TimeGap_PrevCheckpointsCount for InputPlayer = -1;
			declare LibUI_TimeGap_PrevRaceTime for InputPlayer = -1;
			if (
				LibUI_TimeGap_PrevCheckpointsCount != InputPlayer.CurRace.Checkpoints.count 
				|| LibUI_TimeGap_PrevRaceTime != InputPlayer.Score.PrevRace.Time
			) {
				LibUI_TimeGap_PrevCheckpointsCount = InputPlayer.CurRace.Checkpoints.count;
				LibUI_TimeGap_PrevRaceTime = InputPlayer.Score.PrevRace.Time;
				NeedUpdate = True;
			}
			foreach (Score in Scores) {
				declare LibUI_TimeGap_PrevBestRaceTime for Score = -1;
				if (LibUI_TimeGap_PrevBestRaceTime != Score.BestRace.Time) {
					LibUI_TimeGap_PrevBestRaceTime = Score.BestRace.Time;
					NeedUpdate = True;
				}
			}
		}
		
		if (NeedUpdate) UpdateTimeGap();
	}
}
--></script>""";
}

// ---------------------------------- //
/** Create the manialink for the small scores table module
 *
 *	@return		The manialink
 */
Text Private_CreateMLSmallScoresTable() {
	return """
<framemodel id="Framemodel_Player">
	<quad posn="0 0" sizen="4 6" valign="center" image="file://Media/Manialinks/Common/Colorize.dds" colorize="000" id="Quad_TeamColor" />
	<quad posn="4 0" sizen="46 6" valign="center" bgcolor="111a" />
	<frame posn="5 0 1">
		<label posn="12 0" sizen="12 6" halign="right" valign="center2" id="Label_Time" />
		<label posn="17 0" sizen="4 6" halign="right" valign="center2" id="Label_RoundPoints" />
		<quad posn="20.5 0" sizen="5 5" halign="center" valign="center" id="Quad_Avatar" />
		<label posn="24 0" sizen="20 6" valign="center2" id="Label_Name" />
	</frame>
</framemodel>
<frame posn="{{{C_LibUI_SmallScoresTablePos.X}}} {{{C_LibUI_SmallScoresTablePos.Y}}} {{{C_LibUI_SmallScoresTablePos.Z}}}" id="Frame_SmallScoresTable" hidden="1">
	<quad sizen="54 51" style="Bgs1InRace" substyle="BgList" />
	<frame posn="2 -4.5 1" id="Frame_PlayersList">
		<format textemboss="1" textsize="1.5" />
		<frameinstance posn="0 0" hidden="1" modelid="Framemodel_Player" />
		<frameinstance posn="0 -6" hidden="1" modelid="Framemodel_Player" />
		<frameinstance posn="0 -12" hidden="1" modelid="Framemodel_Player" />
		<frameinstance posn="0 -18" hidden="1" modelid="Framemodel_Player" />
		<frameinstance posn="0 -24" hidden="1" modelid="Framemodel_Player" />
		<frameinstance posn="0 -30" hidden="1" modelid="Framemodel_Player" />
		<frameinstance posn="0 -36" hidden="1" modelid="Framemodel_Player" />
		<frameinstance posn="0 -42" hidden="1" modelid="Framemodel_Player" />
	</frame>
</frame>
<script><!--
#Include "TextLib" as TL

#Const C_LibUI_SmallScoresTablePos <{{{C_LibUI_SmallScoresTablePos.X}}}, {{{C_LibUI_SmallScoresTablePos.Y}}}, {{{C_LibUI_SmallScoresTablePos.Z}}}>

declare CMlFrame[] Frames_Player;

Text TimeToText(Integer _Time) {
	declare Time = TL::TimeToText(_Time, True);
	declare Milliseconds = _Time % 10;
	if (Milliseconds >= 0) Time ^= TL::ToText(Milliseconds);
	return Time;
}

Void UpdateSlot(Integer _SlotNb, CTmScore _Score) {
	if (!Frames_Player.existskey(_SlotNb)) return;
	declare Frame_Player		<=> Frames_Player[_SlotNb];
	declare Quad_TeamColor		<=> (Frame_Player.GetFirstChild("Quad_TeamColor")		as CMlQuad);
	declare Label_Time			<=> (Frame_Player.GetFirstChild("Label_Time")			as CMlLabel);
	declare Label_RoundPoints	<=> (Frame_Player.GetFirstChild("Label_RoundPoints")	as CMlLabel);
	declare Quad_Avatar			<=> (Frame_Player.GetFirstChild("Quad_Avatar")			as CMlQuad);
	declare Label_Name			<=> (Frame_Player.GetFirstChild("Label_Name")			as CMlLabel);
	
	if (_Score != Null) {
		if (!Frame_Player.Visible) Frame_Player.Visible = True;
		
		declare TextColor = "$070";
		if (UseClans && (_Score.TeamNum == 1 || _Score.TeamNum == 2)) {
			Quad_TeamColor.Colorize = Teams[_Score.TeamNum - 1].ColorPrimary;
			TextColor = Teams[_Score.TeamNum - 1].ColorText;
		}
		
		Label_Time.Value = TimeToText(_Score.PrevRace.Time);
		if (_Score.PrevRaceDeltaPoints > 0) Label_RoundPoints.Value = TextColor^"+"^_Score.PrevRaceDeltaPoints;
		else if (_Score.PrevRaceDeltaPoints == 0) Label_RoundPoints.Value = "";
		else Label_RoundPoints.Value = TextColor^_Score.PrevRaceDeltaPoints;
		Quad_Avatar.ImageUrl = "file://Avatars/"^_Score.User.Login^"/Default";
		Label_Name.Value = _Score.User.Name;
	} else {
		if (Frame_Player.Visible) Frame_Player.Visible = False;
	}
}

Void UpdateSmallScoresTable() {
	declare FinishSort = Integer[CTmScore];
	foreach (Score in Scores) {
		if (Score.PrevRace.Time >= 0) FinishSort[Score] = Score.PrevRace.Time;
	}
	FinishSort = FinishSort.sort();
	
	declare I = 0;
	foreach (Score => Time in FinishSort) {
		UpdateSlot(I, Score);
		I += 1;
		if (I > Frames_Player.count - 1) break;
	}
	for (J, I, Frames_Player.count - 1) {
		UpdateSlot(J, Null);
	}
}

main() {
	declare Frame_SmallScoresTable	<=> (Page.GetFirstChild("Frame_SmallScoresTable")	as CMlFrame);
	declare Frame_PlayersList		<=> (Page.GetFirstChild("Frame_PlayersList")		as CMlFrame);
	foreach (Control in Frame_PlayersList.Controls) {
		Frames_Player.add((Control as CMlFrame));
	}
	
	declare netread Text[Text] Net_LibUI_Settings for Teams[0];
	
	declare PrevUseClans = False;
	declare PrevRaceState = CTmMlPlayer::ERaceState::BeforeStart;
	
	while (True) {
		sleep(250);
		if (InputPlayer == Null) continue;
		if (!PageIsVisible) continue;
		
		if (PrevUseClans != UseClans) {
			PrevUseClans = UseClans;
			if (!UseClans) {
				foreach (Frame_Player in Frames_Player) {
					declare Quad_TeamColor <=> (Frame_Player.GetFirstChild("Quad_TeamColor") as CMlQuad);
					Quad_TeamColor.Colorize = <0., 0., 0.>;
				}
			}
		}
		
		declare NeedUpdate = False;
		declare OneFinish = False;
		foreach (Player in Players) {
			if (Player.Score == Null) continue;
			declare LibUI_SmallScoresTable_PrevRaceTime for Player = -1;
			declare LibUI_SmallScoresTable_PrevRaceDeltaPoints for Player = -1;
			declare LibUI_SmallScoresTable_PrevTeamNum for Player = -1;
			if (
				LibUI_SmallScoresTable_PrevRaceTime != Player.Score.PrevRace.Time
				|| LibUI_SmallScoresTable_PrevRaceDeltaPoints != Player.Score.PrevRaceDeltaPoints
				|| LibUI_SmallScoresTable_PrevTeamNum != Player.Score.TeamNum
			) {
				LibUI_SmallScoresTable_PrevRaceTime = Player.Score.PrevRace.Time;
				LibUI_SmallScoresTable_PrevRaceDeltaPoints = Player.Score.PrevRaceDeltaPoints;
				LibUI_SmallScoresTable_PrevTeamNum = Player.Score.TeamNum;
				if (Player.Score.PrevRace.Time >= 0) NeedUpdate = True; 
			}
			if (Player.Score.PrevRace.Time >= 0) OneFinish = True;
		}
		
		if (NeedUpdate) UpdateSmallScoresTable();
		
		if (Net_LibUI_Settings.existskey("SmallScoresTable_VisibilityMode") && Net_LibUI_Settings["SmallScoresTable_VisibilityMode"] == "AtFinish") {
			if (GUIPlayer != Null && PrevRaceState != GUIPlayer.RaceState) {
				PrevRaceState = GUIPlayer.RaceState;
				if (GUIPlayer.RaceState == CTmMlPlayer::ERaceState::Finished || GUIPlayer.RaceState == CTmMlPlayer::ERaceState::Eliminated) {
					Frame_SmallScoresTable.Visible = True;
				} else {
					Frame_SmallScoresTable.Visible = False;
				}
			}
		} else {
			if (OneFinish && !Frame_SmallScoresTable.Visible) Frame_SmallScoresTable.Visible = True;
			else if (!OneFinish && Frame_SmallScoresTable.Visible) Frame_SmallScoresTable.Visible = False;
		}
	}
}
--></script>""";
}

// ---------------------------------- //
/** Create the manialink for the checkpoint time module
 *
 *	@return		The manialink
 */
Text Private_CreateMLCheckpointTime() {
	return """
<frame posn="-8 31.8 -10" hidden="0" id="Frame_CheckpointTime">
	<format textemboss="1" />
	<frame>
		<label posn="0 0" sizen="50 10" scale="0.95" halign="right" valign="center2" textsize="4" text="1er)" id="Label_CheckpointRank" />
		<label posn="0.3 -0.8" sizen="50 10" scale="0.98" style="TextRaceChrono" valign="center2" textsize="4" text="0:02.48" id="Label_CheckpointTime" />
	</frame>
</frame>
<script><!--
main() {
	while (True) {
		yield;
		if (InputPlayer == Null) continue;
		if (!PageIsVisible) continue;
		
		
	}
}
--></script>""";
}

// ---------------------------------- //
// Public
// ---------------------------------- //
// ---------------------------------- //
/** Return the version number of the script
 *
 *	@return		The version number of the script
 */
Text GetScriptVersion() {
	return Version;
}

// ---------------------------------- //
/** Return the name of the script
 *
 *	@return		The name of the script
 */
Text GetScriptName() {
	return ScriptName;
}

// ---------------------------------- //
/** Load a module
 *
 *	@param	_ModuleId		The name of the module to load
 */
Void LoadModule(Text _ModuleId) {
	if (G_LibUI_ModulesLoaded.exists(_ModuleId)) return;
	
	declare ModuleLoaded = False;
	switch (_ModuleId) {
		case "TimeGap": {
			Private_CreateModuleLayer(_ModuleId).ManialinkPage = Private_CreateMLTimeGap();
			declare netwrite Net_LibUI_Settings for Teams[0] = Text[Text];
			Net_LibUI_Settings["TimeGap_Mode"] = "CurRace";
			UIManager.UIAll.OverlayHideCheckPointList = True;
			ModuleLoaded = True;
		}
		case "SmallScoresTable": {
			Private_CreateModuleLayer(_ModuleId).ManialinkPage = Private_CreateMLSmallScoresTable();
			UIManager.UIAll.SmallScoreTableVisibility = CUIConfig::EVisibility::ForcedHidden;
			ModuleLoaded = True;
		}
		case "CheckpointTime": {
			Private_CreateModuleLayer(_ModuleId).ManialinkPage = Private_CreateMLCheckpointTime();
			ModuleLoaded = True;
		}
	}
	
	if (ModuleLoaded) {
		G_LibUI_ModulesLoaded.add(_ModuleId);
	}
}
// ---------------------------------- //
/** Load several modules
 *
 *	@param	_ModulesIds		A list of modules to load with the library
 */
Void LoadModules(Text[] _ModulesIds) {
	foreach (ModuleId in _ModulesIds) {
		LoadModule(ModuleId);
	}
}

// ---------------------------------- //
/** Unload a module
 *
 *	@param	_ModuleId		The name of the module to unload
 */
Void UnloadModule(Text _ModuleId) {
	declare Removed = G_LibUI_ModulesLoaded.remove(_ModuleId);
	
	if (Removed) {
		// Remove module layer
		Private_DestroyModuleLayer(_ModuleId);
		
		// Unload the module
		switch (_ModuleId) {
			case "TimeGap": {
				UIManager.UIAll.OverlayHideCheckPointList = False;
			}
			case "SmallScoresTable": {
				UIManager.UIAll.SmallScoreTableVisibility = CUIConfig::EVisibility::Normal;
			}
			case "CheckpointTime": {
				
			}
		}
	}
}

// ---------------------------------- //
/// Unload the library
Void Unload() {
	foreach (ModuleId in G_LibUI_ModulesLoaded) {
		UnloadModule(ModuleId);		
	}
	
	declare netwrite Net_LibUI_Settings for Teams[0] = Text[Text];
	Net_LibUI_Settings.clear();
	
	G_LibUI_ModulesLoaded.clear();
	G_LibUI_LayersIds.clear();
}

// ---------------------------------- //
/// Load the library
Void Load() {
	Unload();
}

// ---------------------------------- //
/** (Overload) Load the library with some modules
 *
 *	@param	_AutoLoadModules		A list of modules to load with the library
 */
Void Load(Text[] _AutoLoadModules) {
	Unload();
	
	LoadModules(_AutoLoadModules);
}

// ---------------------------------- //
/** Update the settings for a module
 *
 *	@param	_Name		The name of the setting
 *	@param	_Value		The value of the setting
 */
Void SetModuleSetting(Text _Name, Text _Value) {
	declare netwrite Net_LibUI_Settings for Teams[0] = Text[Text];
	Net_LibUI_Settings[_Name] = _Value;
}

// ---------------------------------- //
/** Set the time gap mode for the TM time gap module
 *
 *	@param	_Mode		The mode to use between "BestRace" and "CurRace"
 *						- BestRace: compare the best time of the players
 *						- CurRace: compare the times of the current race of the players
 */
Void SetTimeGapMode(Text _Mode) {
	if (_Mode != "BestRace" && _Mode != "CurRace") return;
	SetModuleSetting("TimeGap_Mode", _Mode);
}

// ---------------------------------- //
/** Set the visibility mode of the small scores table
 *
 *	@param	_Mode		The mode to use between "OneFinish" and "CurRace"
 *						- FirstFinish: displayed to all players as soon as one player finish the map and until the turn ends
 *						- AtFinish: displayed only to the player who finished and until he restart the map
 */
Void SetSmallScoresTableVisibilityMode(Text _Mode) {
	if (_Mode != "FirstFinish" && _Mode != "AtFinish") return;
	SetModuleSetting("SmallScoresTable_VisibilityMode", _Mode);
}