/**
 *	Clans library
 *
 *	Manage any number of clans
 */
#Const	Version			"2016-09-19"
#Const	ScriptName	"Libs/Nadeo/Clans.Script.txt"

// ---------------------------------- //
// Constants
// ---------------------------------- //
#Const C_DefaultColor <0., 0., 0.>

// ---------------------------------- //
// Globales
// ---------------------------------- //
declare Vec3[Integer] G_ClansColors;

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

// ---------------------------------- //
/** Get the default color
 *
 *	@return														The default color
 */
Vec3 DefaultColor() {
	return C_DefaultColor;
}

// ---------------------------------- //
/** Set the clan of a player
 *
 *	@param	_Score										The score of the player to update
 *	@param	_Clan											The new clan
 */
Void Set(CScore _Score, Integer _Clan) {
	if (_Score == Null) return;
	
	declare LibClans_Clan for _Score = 0;
	LibClans_Clan = _Clan;
	
	// Apply the clan color to the player
	if (This is CSmMode) {
		declare CSmPlayer SelectedPlayer;
		foreach (Player in AllPlayers) {
			if (Player.Score.Id == _Score.Id) {
				SelectedPlayer <=> Player;
				break;
			}
		}
		if (SelectedPlayer != Null) {
			if (_Clan <= 0) {
				SelectedPlayer.ForceColor = C_DefaultColor;
			} else if (G_ClansColors.existskey(_Clan)) {
				SelectedPlayer.ForceColor = G_ClansColors[_Clan];
			} else {
				G_ClansColors[_Clan] = SelectedPlayer.User.Color;
			}
		}
	}
}

// ---------------------------------- //
/** Get the clan of a player
 *
 *	@param	_Score										The score of the player to check
 */
Integer Get(CScore _Score) {
	if (_Score == Null) return 0;
	
	declare LibClans_Clan for _Score = 0;
	return LibClans_Clan;
}

// ---------------------------------- //
/// Reset the clan of all players
Void Reset() {
	foreach (Score in Scores) {
		Set(Score, 0);
	}
}

// ---------------------------------- //
/** List all clans with at least one player
 *
 *	@return														A list of all clans with at least one player
 */
Integer[] List() {
	declare List = Integer[];
	foreach (Player in AllPlayers) {
		declare Clan = Get(Player.Score);
		if (Clan != 0 && !List.exists(Clan)) List.add(Clan);
	}
	return List;
}

// ---------------------------------- //
/** Get the number of clans with at least one player
 *
 *	@return														The number of clans with at least one player
 */
Integer Count() {
	return List().count;
}

// ---------------------------------- //
/** Check if a clan has players
 *
 *	@param	_Clan											The clan to check
 *
 *	@return														True if there are players in the given clan
 *																		False otherwise
 */
Boolean HasPlayers(Integer _Clan) {
	foreach (Player in AllPlayers) {
		if (Get(Player.Score) == _Clan) return True;
	}
	return False;
}

// ---------------------------------- //
/** Get the players of the given clan
 *
 *	@param	_Clan											The clan to get
 *
 *	@return														The players of the given clan
 */
CPlayer[] GetPlayers(Integer _Clan) {
	declare ClanPlayers = CPlayer[];
	foreach (Player in AllPlayers) {
		if (Get(Player.Score) == _Clan) ClanPlayers.add(Player);
	}
	return ClanPlayers;
}

// ---------------------------------- //
/** Get the number of players in the given clan
 *
 *	@param	_Clan											The clan to check
 *
 *	@return														The number of players in the clan
 */
Integer PlayersNb(Integer _Clan) {
	declare Count = 0;
	foreach (Player in AllPlayers) {
		if (Get(Player.Score) == _Clan) Count += 1;
	}
	return Count;
}

// ---------------------------------- //
/** Set the color of a clan
 *
 *	@param	_Clan											The clan to update
 *	@param	_Color										The new color
 */
Void SetColor(Integer _Clan, Vec3 _Color) {
	G_ClansColors[_Clan] = _Color;
	foreach (Player in AllPlayers) {
		if (Get(Player.Score) == _Clan) Player.ForceColor = _Color;
	}
}

// ---------------------------------- //
/** Get the color of a clan
 *
 *	@param	_Clan											The clan to check
 *
 *	@return														The color of the clan if it exists
 *																		The default color otherwise
 */
Vec3 GetColor(Integer _Clan) {
	if (G_ClansColors.existskey(_Clan)) return G_ClansColors[_Clan];
	return C_DefaultColor;
}

// ---------------------------------- //
/** Get the colors of all clans
 *
 *	@return														All clans' colors
 */
Vec3[Integer] GetColors() {
	return G_ClansColors;
}

// ---------------------------------- //
/// Clear the clan colors
Void ClearColors() {
	G_ClansColors = Vec3[Integer];
	foreach (Player in AllPlayers) {
		Player.ForceColor = C_DefaultColor;
	}
}

// ---------------------------------- //
/// Unload the library
Void Unload() {
	G_ClansColors = Vec3[Integer];
	Reset();
}

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