/**
 *	SM library
 *
 *	Utilility functions for ShootMania
 */

#Const Version		"2014-04-10"
#Const ScriptName	"SM.Script.txt"

#Include "MathLib" as MathLib
#Include "TextLib" as TextLib

// ---------------------------------- //
// Deprecated
// ---------------------------------- //

// ---------------------------------- //
/** Spawn a player
 *
 *	@param	_Player				The player to spawn
 *	@param	_ClanNum			The clan in which the player will be spawned
 *	@param	_BlockSpawn			The block where the player will be spawned
 */
Void SpawnPlayer(CSmPlayer _Player, Integer _ClanNum, CSmBlockSpawn _BlockSpawn) {
	This.SpawnPlayer(_Player, _ClanNum, -1, _BlockSpawn, -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	_BlockSpawn			The block where the player will be spawned
 *	@param	_ActivationDate		When the player will be spawned
 */
Void SpawnPlayer(CSmPlayer _Player, Integer _ClanNum, CSmBlockSpawn _BlockSpawn, Integer _ActivationDate) {
	This.SpawnPlayer(_Player, _ClanNum, -1, _BlockSpawn, _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	_BlockSpawn			The block where the player will be spawned
 *	@param	_ActivationDate		When the player will be spawned
 */
Void SpawnPlayer(CSmPlayer _Player, Integer _ClanNum, Integer _Armor, CSmBlockSpawn _BlockSpawn, Integer _ActivationDate) {
	This.SpawnPlayer(_Player, _ClanNum, _Armor, _BlockSpawn, _ActivationDate);	// beware of infinite recursion!
	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	_BlockSpawn			The block where the player will be spawned
 */
Void SpawnPlayerNoLadder(CSmPlayer _Player, Integer _ClanNum, CSmBlockSpawn _BlockSpawn) {
	This.SpawnPlayer(_Player, _ClanNum, -1, _BlockSpawn, -1);
}

// ---------------------------------- //
/** Spawn a player
 *
 *	@param	_Player				The player to spawn
 *	@param	_ClanNum			The clan in which the player will be spawned
 *	@param	_BlockSpawn			The block where the player will be spawned
 *	@param	_ActivationDate		When the player will be spawned
 */
Void SpawnPlayerNoLadder(CSmPlayer _Player, Integer _ClanNum, CSmBlockSpawn _BlockSpawn, Integer _ActivationDate) {
	This.SpawnPlayer(_Player, _ClanNum, -1, _BlockSpawn, _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	_BlockSpawn			The block where the player will be spawned
 *	@param	_ActivationDate		When the player will be spawned
 */
Void SpawnPlayerNoLadder(CSmPlayer _Player, Integer _ClanNum, Integer _Armor, CSmBlockSpawn _BlockSpawn, Integer _ActivationDate) {
	This.SpawnPlayer(_Player, _ClanNum, _Armor, _BlockSpawn, _ActivationDate);	// beware of infinite recursion!
}

// ---------------------------------- //
/**	Get a block spawn from its tag and order
 *
 *	@param	_Tag		The tag of the spawn
 *	@param	_Index		The order of the spawn
 *
 *	@return		The spawn if found, Null otherwise
 */
CSmBlockSpawn GetSpawn(Text _Tag, Integer _Index) {
	foreach(Spawn in BlockSpawns) {
		if(Spawn.Tag == _Tag && Spawn.Order == _Index)
			return Spawn;
	}
	return Null;
}

// ---------------------------------- //
/**	Get a block pole from its tag and order
 *
 *	@param	_Tag		The tag of the pole
 *	@param	_Index		The order of the pole
 *
 *	@return		The pole if found, Null otherwise
 */
CSmBlockPole GetPole(Text _Tag, Integer _Index) {
	foreach(Pole in BlockPoles) {
		if(Pole.Tag == _Tag && Pole.Order == _Index)
			return Pole;
	}	
	return Null;
}

// ---------------------------------- //
// 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 SpawnPlayer(CSmPlayer _Player, Integer _ClanNum, CSmMapPlayerSpawn _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 SpawnPlayer(CSmPlayer _Player, Integer _ClanNum, CSmMapPlayerSpawn _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 SpawnPlayer(CSmPlayer _Player, Integer _ClanNum, Integer _Armor, CSmMapPlayerSpawn _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 SpawnPlayerNoLadder(CSmPlayer _Player, Integer _ClanNum, CSmMapPlayerSpawn _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 SpawnPlayerNoLadder(CSmPlayer _Player, Integer _ClanNum, CSmMapPlayerSpawn _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 SpawnPlayerNoLadder(CSmPlayer _Player, Integer _ClanNum, Integer _Armor, CSmMapPlayerSpawn _Spawn, Integer _ActivationDate) {
	This.SpawnPlayer(_Player, _ClanNum, _Armor, _Spawn, _ActivationDate);
}

// ---------------------------------- //
/// 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 SetPlayerWeapon(CSmPlayer _Player, Real _AmmoGainCoeff, Boolean _AutoSwitchWeapon) {
	SetPlayerWeapon(_Player, CSmMode::EWeapon::Rocket, _AutoSwitchWeapon);
	_Player.AmmoGain = _AmmoGainCoeff;
}

// ---------------------------------- //
/**	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.Login == _Login) 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;
}