/**
 *	Utilility functions for ShootMania
 */

#Const Version		"2017-10-17"
#Const ScriptName	"Libs/Nadeo/ShootMania/SM2.Script.txt"

// ---------------------------------- //
// Libraries
// ---------------------------------- //
#Include "Libs/Nadeo/Ladder.Script.txt" as Ladder
#Include "Libs/Nadeo/Log.Script.txt" as Log

// ---------------------------------- //
// Constants
// ---------------------------------- //
#Const C_Weapons [
	1 => CSmMode::EWeapon::Laser,
	2 => CSmMode::EWeapon::Rocket,
	3 => CSmMode::EWeapon::Nucleus,
	5 => CSmMode::EWeapon::Arrow,
	6 => CSmMode::EWeapon::Missile//,
	//7 => CSmMode::EWeapon::Hunter,
	//8 => CSmMode::EWeapon::Scout,
	//9 => CSmMode::EWeapon::GoldenLaser
]

// ---------------------------------- //
// Globales
// ---------------------------------- //
declare CSmMode::EWeapon[Integer] G_WeaponNumToWeapon;

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

// ---------------------------------- //
/** Spawn a player
 *
 *	@param	_Player				The player to spawn
 *	@param	_ClanNum			The clan in which the player will be spawned
 *	@param	_Landmark			The landmark where the player will be spawned
 */
Void Spawn(CSmPlayer _Player, Integer _ClanNum, CMapSpawn _Spawn) {
	This.SpawnPlayer(_Player, _ClanNum, -1, _Spawn, -1);
	if(_Player.Score != Null) Ladder::AddPlayer(_Player.Score);
}

// ---------------------------------- //
/** Spawn a player
 *
 *	@param	_Player				The player to spawn
 *	@param	_ClanNum			The clan in which the player will be spawned
 *	@param	_Landmark			The landmark where the player will be spawned
 *	@param	_ActivationDate		When the player will be spawned
 */
Void Spawn(CSmPlayer _Player, Integer _ClanNum, CMapSpawn _Spawn, Integer _ActivationDate) {
	This.SpawnPlayer(_Player, _ClanNum, -1, _Spawn, _ActivationDate);
	if(_Player.Score != Null) Ladder::AddPlayer(_Player.Score);
}

// ---------------------------------- //
/** Spawn a player
 *
 *	@param	_Player				The player to spawn
 *	@param	_ClanNum			The clan in which the player will be spawned
 *	@param	_Armor				The numnber of armor at spawn for the player
 *	@param	_Landmark			The landmark where the player will be spawned
 *	@param	_ActivationDate		When the player will be spawned
 */
Void Spawn(CSmPlayer _Player, Integer _ClanNum, Integer _Armor, CMapSpawn _Spawn, Integer _ActivationDate) {
	This.SpawnPlayer(_Player, _ClanNum, _Armor, _Spawn, _ActivationDate);
	if(_Player.Score != Null) Ladder::AddPlayer(_Player.Score);
}

// ---------------------------------- //
/** Spawn a player
 *
 *	@param	_Player				The player to spawn
 *	@param	_ClanNum			The clan in which the player will be spawned
 *	@param	_Landmark			The landmark where the player will be spawned
 */
Void SpawnNoLadder(CSmPlayer _Player, Integer _ClanNum, CMapSpawn _Spawn) {
	This.SpawnPlayer(_Player, _ClanNum, -1, _Spawn, -1);
}

// ---------------------------------- //
/** Spawn a player
 *
 *	@param	_Player				The player to spawn
 *	@param	_ClanNum			The clan in which the player will be spawned
 *	@param	_Landmark			The landmark where the player will be spawned
 *	@param	_ActivationDate		When the player will be spawned
 */
Void SpawnNoLadder(CSmPlayer _Player, Integer _ClanNum, CMapSpawn _Spawn, Integer _ActivationDate) {
	This.SpawnPlayer(_Player, _ClanNum, -1, _Spawn, _ActivationDate);
}

// ---------------------------------- //
/** Spawn a player
 *
 *	@param	_Player				The player to spawn
 *	@param	_ClanNum			The clan in which the player will be spawned
 *	@param	_Armor				The numnber of armor at spawn for the player
 *	@param	_Landmark			The landmark where the player will be spawned
 *	@param	_ActivationDate		When the player will be spawned
 */
Void SpawnNoLadder(CSmPlayer _Player, Integer _ClanNum, Integer _Armor, CMapSpawn _Spawn, Integer _ActivationDate) {
	This.SpawnPlayer(_Player, _ClanNum, _Armor, _Spawn, _ActivationDate);
}

// ---------------------------------- //
/** Unspawn the given player
 *
 *	@param	_Player										The player to unspawn
 */
Void Unspawn(CSmPlayer _Player) {
	This.UnspawnPlayer(_Player);
}

// ---------------------------------- //
/// Unspawn all the players
Void UnspawnAllPlayers() {
	foreach(Player in AllPlayers) {
		UnspawnPlayer(Player);
	}
}

// ---------------------------------- //
/// Unspawn the players requesting a clan change
Void UnspawnPlayersChangingClan() {
	foreach (Player in Players)
	{
		if (UseClans && !UseForcedClans && !Player.IsFakePlayer && Player.SpawnStatus == CSmPlayer::ESpawnStatus::Spawned){
			// if the player wants to change team, then remove him from the current team
			// it will be added to the correct team at next respawn.
			if (Player.CurrentClan != 0 && Player.RequestedClan != Player.CurrentClan) {
				UnspawnPlayer(Player);
			}
		}
	}
}

// ---------------------------------- //
/// Set the default visibility for labels
Void SetupDefaultVisibility() {
	UIManager.UIAll.AlliesLabelsMaxCount = 2;
	UIManager.UIAll.AlliesLabelsVisibility = CUIConfig::ELabelsVisibility::Always;
	UIManager.UIAll.AlliesLabelsShowGauges = CUIConfig::EVisibility::ForcedVisible;
	UIManager.UIAll.AlliesLabelsShowNames = CUIConfig::EVisibility::Normal;
	
	UIManager.UIAll.TeamLabelsVisibility = CUIConfig::ELabelsVisibility::WhenVisible;
	UIManager.UIAll.TeamLabelsShowGauges = CUIConfig::EVisibility::ForcedVisible;
	UIManager.UIAll.TeamLabelsShowNames = CUIConfig::EVisibility::Normal;
	
	UIManager.UIAll.OpposingTeamLabelsVisibility = CUIConfig::ELabelsVisibility::WhenInMiddleOfScreen;
	UIManager.UIAll.OpposingTeamLabelsShowGauges = CUIConfig::EVisibility::ForcedHidden;
	UIManager.UIAll.OpposingTeamLabelsShowNames = CUIConfig::EVisibility::ForcedVisible;
}

// ---------------------------------- //
/**	Set the reload speed and auto switch of the rocket for a player
 *
 *	@param	_Player				The player who will get the weapon
 *	@param	_AmmoGainCoeff		The ammo gain speed
 *	@param	_AutoSwitchWeapon	Allow the siwtch of weapon
 */
Void SetWeapon(CSmPlayer _Player, Real _AmmoGainCoeff, Boolean _AutoSwitchWeapon) {
	SetPlayerWeapon(_Player, CSmMode::EWeapon::Rocket, _AutoSwitchWeapon);
	_Player.AmmoGain = _AmmoGainCoeff;
}

// ---------------------------------- //
/** Get a player from its UI
 *
 *	@param	_UI												The UI owned by the player
 *
 *	@return														The player owning the UI
 */
CSmPlayer GetPlayer(CUIConfig _UI) {
	if (_UI == Null) return Null;
	
	foreach (Player in AllPlayers) {
		if (_UI == UIManager.GetUI(Player)) {
			return Player;
		} 
	}
	
	return Null;
}

// ---------------------------------- //
/**	Get a player from its login
 *
 *	@param	_Login		Login of the player to get
 *	
 *	@return				The player if found, Null otherwise
 */
CSmPlayer GetPlayer(Text _Login) {
	if (_Login == "") return Null;
	
	foreach (Player in AllPlayers) {
		if (Player.User.Login == _Login) return Player;
	}
	
	return Null;
}

// ---------------------------------- //
/** Get a player from its User
 *
 *	@param	_User											The source User
 *
 *	@return														The player if found
 *																		Null otherwise
 */
CSmPlayer GetPlayer(CUser _User) {
	if (_User == Null) return Null;
	
	declare LibSM3_PlayerId for _User = NullId;
	if (LibSM3_PlayerId != NullId && AllPlayers.existskey(LibSM3_PlayerId)) {
		return AllPlayers[LibSM3_PlayerId];
	}
	
	foreach (Player in AllPlayers) {
		if (Player.User == _User) {
			LibSM3_PlayerId = Player.Id;
			return Player;
		}
	}
	
	return Null;
}

// ---------------------------------- //
/**	Get a user from its login
 *
 *	@param	_Login		Login of the user to get
 *	
 *	@return				The user if found, Null otherwise
 */
CUser GetUser(Text _Login) {
	if (_Login == "") return Null;
	
	foreach (User in Users) {
		if (User.Login == _Login) return User;
	}
	
	return Null;
}

// ---------------------------------- //
/**	Get a score from its login
 *
 *	@param	_Login		Login of the score to get
 *	
 *	@return				The score if found, Null otherwise
 */
CSmScore GetScore(Text _Login) {
	if (_Login == "") return Null;
	
	foreach (Score in Scores) {
		if (Score.User != Null && Score.User.Login == _Login) return Score;
	}
	
	return Null;
}

// ---------------------------------- //
/** Get the weapon associated to a given
 *	WeaponNum
 *
 *	@param	_WeaponNum								The WeaponNum
 *
 *	@return														The associated weapon if found
 *																		CSmMode::EWeapon::Rocket otherwise
 */
CSmMode::EWeapon GetWeapon(Integer _WeaponNum) {
	if (G_WeaponNumToWeapon.existskey(_WeaponNum)) {
		return G_WeaponNumToWeapon[_WeaponNum];
	} else if (C_Weapons.existskey(_WeaponNum)) {
		return C_Weapons[_WeaponNum]; //< Back up in case the library was not loaded
	} else {
		Log::Error("""[SM3] GetWeapon() > Unknown WeaponNum : {{{_WeaponNum}}}""");
	}
	
	return CSmMode::EWeapon::Rocket;
}

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

// ---------------------------------- //
/// Load the library
Void Load() {
	Unload();
	
	foreach (Weapon in C_Weapons) {
		G_WeaponNumToWeapon[GetWeaponNum(Weapon)] = Weapon;
	}
}