/**
 * Trackmania UI server library
 */
#Const Version    "2017-06-20"
#Const ScriptName "ManiaApps/Nadeo/TrackMania/Common/UI_Server.Script.txt"

// ---------------------------------- //
// Libraries
// ---------------------------------- //
#Include "ManiaApps/Nadeo/TrackMania/UI_Common.Script.txt" as UI_Common

// ---------------------------------- //
// Constants
// ---------------------------------- //
#Const C_ViewersCountUpdateInterval 1000

// ---------------------------------- //
// Globales
// ---------------------------------- //
declare Integer G_NextViewersCountUpdate; //< Time before the next vierwers count update
declare Boolean G_ViewersCountReset; ///< The viewers count need a reset

// ---------------------------------- //
// Functions
// ---------------------------------- //
// ---------------------------------- //
// 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;
}

// ---------------------------------- //
/** Create the given module in the mania app
 *
 *	@param	_ModuleId									The id of the module to create
 */
Void LoadModule(Text _ModuleId) {
	declare netwrite AppTMUI_ModulesUpdate for Teams[0] = -1;
	declare netwrite Text[] AppTMUI_Modules for Teams[0];
	if (!AppTMUI_Modules.exists(_ModuleId)) {
		AppTMUI_Modules.add(_ModuleId);
	}
	AppTMUI_ModulesUpdate = Now;
}

// ---------------------------------- //
/** Destroy the given module in the mania app
 *
 *	@param	_ModuleId									The id of the module to destroy
 */
Void UnloadModule(Text _ModuleId) {
	declare netwrite AppTMUI_ModulesUpdate for Teams[0] = -1;
	declare netwrite Text[] AppTMUI_Modules for Teams[0];
	declare Removed = AppTMUI_Modules.remove(_ModuleId);
	AppTMUI_ModulesUpdate = Now;
}

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

// ---------------------------------- //
/** Send a live event to a player
 *
 *	@param	_Player										The receiver of the live event
 *	@param	_Message									The message
 *	@param	_Image										The path to the image
 */
Void SendLiveEvent(CPlayer _Player, Text _Message, Text _Image) {
	if (_Player == Null) return;
	declare UI <=> UIManager.GetUI(_Player);
	if (UI == Null) return;
	
	declare netwrite Text[Integer][Integer] Net_LibUI_LiveEvent for UI;
	declare netwrite Net_LibUI_LiveEventUpdate for UI = Now;
	declare netread Integer[] Net_LibUI_LiveEventRead for UI;
	
	foreach (Key in Net_LibUI_LiveEventRead) {
		declare Removed = Net_LibUI_LiveEvent.removekey(Key);
	}
	
	declare MessageKey = -1;
	for (Key, 0, 100) {
		if (!Net_LibUI_LiveEvent.existskey(Key) && !Net_LibUI_LiveEventRead.exists(Key)) {
			MessageKey = Key;
			break;
		}
	}
	
	if (MessageKey >= 0) {
		Net_LibUI_LiveEvent[MessageKey] = [
			UI_Common::C_Message_Message => _Message, 
			UI_Common::C_Message_Image => _Image
		];
	}
	
	Net_LibUI_LiveEventUpdate = Now;
}

// ---------------------------------- //
/// Update the viewers count
Void UpdateViewersCount() {
	declare Integer[Text] ViewersCount;
	
	foreach (Player in AllPlayers) {
		declare UI <=> UIManager.GetUI(Player);
		if (UI != Null) {
			declare netread Net_LibUI_SpectatorTarget for UI = "";
			if (Net_LibUI_SpectatorTarget != "" && Player.User.Login != Net_LibUI_SpectatorTarget) {
				if (ViewersCount.existskey(Net_LibUI_SpectatorTarget)) {
					ViewersCount[Net_LibUI_SpectatorTarget] += 1;
				} else {
					ViewersCount[Net_LibUI_SpectatorTarget] = 1;
				}
			}
		}
	}
	
	if (ViewersCount.count > 0) {
		G_ViewersCountReset = True;
		
		foreach (Player in Players) {
			declare UI <=> UIManager.GetUI(Player);
			if (UI != Null) {
				declare netwrite Net_LibUI_ViewersCount for UI = 0;
				
				if (ViewersCount.existskey(Player.User.Login)) {
					Net_LibUI_ViewersCount = ViewersCount[Player.User.Login];
					declare Removed = ViewersCount.removekey(Player.User.Login);
				} else {
					Net_LibUI_ViewersCount = 0;
				}
			}
		}
	} else if (G_ViewersCountReset && ViewersCount.count <= 0) {
		G_ViewersCountReset = False;
		foreach (Player in AllPlayers) {
			declare UI <=> UIManager.GetUI(Player);
			if (UI != Null) {
				declare netwrite Net_LibUI_ViewersCount for UI = 0;
				Net_LibUI_ViewersCount = 0;
			}
		}
	}
}

// ---------------------------------- //
/// Update the library
Void Yield() {
	if (Now >= G_NextViewersCountUpdate) {
		G_NextViewersCountUpdate = Now + C_ViewersCountUpdateInterval;
		UpdateViewersCount();
	}
}

// ---------------------------------- //
/// Unload the library
Void Unload() {
	declare netwrite AppTMUI_ModulesUpdate for Teams[0] = -1;
	declare netwrite Text[] AppTMUI_Modules for Teams[0];
	AppTMUI_Modules.clear();
	AppTMUI_ModulesUpdate = Now;
	
	declare netwrite Net_LibUI_SettingsUpdate for Teams[0] = 0;
	declare netwrite Text[Text] Net_LibUI_Settings for Teams[0];
	Net_LibUI_SettingsUpdate = 0;
	Net_LibUI_Settings.clear();
	
	foreach (Player in AllPlayers) {
		declare UI <=> UIManager.GetUI(Player);
		if (UI != Null) {
			declare netwrite Net_LibUI_ViewersCount for UI = 0;
			Net_LibUI_ViewersCount = 0;
		}
	}
	
	G_ViewersCountReset = False;
}

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