package client;

import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;

import client.control.menu.ThemeManager;
import client.model.LienProblemeMethodeResultat;
import client.model.LienUserGroupRole;
import client.model.benchmark.Benchmarks;
import client.model.group.Groupe;
import client.model.problem.Probleme;
import client.model.problem.Resultat;
import client.model.user.Role;
import client.model.user.Utilisateur;
import client.view.connexion.Fenetre;

/**
 * <u><b>Explication générale de la classe :</b></u>
 * <P>
 * Cette classe permet de créer des outils permettant de simplifier l'accès aux
 * données dans l'application
 * <P>
 * Nous avons centralisé toutes les variables utiles dans toute l'application
 * ici afin de simplifier le travail
 * 
 * @author Dream Team - ING2
 */
public class Application implements ApplicationProperties {

	// Application launch parameters
	private final Properties applicationProperties = new Properties(System
			.getProperties());

	// On déclare et initialise l'ensemble des array utilisés dans l'application
	private Map<Integer, Utilisateur> arrayUser = new HashMap<Integer, Utilisateur>();
	private Map<Integer, Utilisateur> arrayUserPending = new HashMap<Integer, Utilisateur>();
	private Map<Integer, Groupe> arrayGroup = new HashMap<Integer, Groupe>();
	private Map<Integer, Probleme> arrayProbleme = new HashMap<Integer, Probleme>();
	private Map<Integer, Resultat> arrayResultat = new HashMap<Integer, Resultat>();
	private Map<Integer, Role> arrayRole = new HashMap<Integer, Role>();
	private Map<Integer, Benchmarks> arrayBenchmark = new HashMap<Integer, Benchmarks>();
	private ArrayList<LienUserGroupRole> arrayLinkOfUserGroupRole = new ArrayList<LienUserGroupRole>();
	private ArrayList<LienProblemeMethodeResultat> arrayLinkOfProblemeMethodeResultat = new ArrayList<LienProblemeMethodeResultat>();
	private static final Application f = new Application();
	public static int idSelect;

	// On crée un singleton d'application
	public static Application getInstance() {
		return f;
	}

	private Application() {}

	/**
	 * <u><i>Explication générale de la méthode :</i></u>
	 * <P> Cette méthode permet
	 * de récupérer les propriétés que nous avons instauré
	 * 
	 * @return les propriétés initiales
	 * 
	 */
	public Properties getProperties() {
		return applicationProperties;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer la référence de l'array des utilisateurs/groupe/role
	 * 
	 * @return la référence de l'array des utilisateurs/groupe/role
	 * 
	 */
	public ArrayList<LienUserGroupRole> getArrayLinkOfUserGroupRole() {
		return arrayLinkOfUserGroupRole;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer la référence de l'array des problemes/methode/resultats
	 * 
	 * @return la référence de l'array des problemes/methode/resultat
	 * 
	 */
	public ArrayList<LienProblemeMethodeResultat> getArrayLinkOfProblemeMethodeResultats() {
		return arrayLinkOfProblemeMethodeResultat;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un utilisateur à partir de son id
	 * 
	 * @param idUser
	 *            Id de l'utilisateur recherché
	 * 
	 * @return l'utilisateur voulu
	 * 
	 */
	public Utilisateur getUser(int idUser) {
		return arrayUser.get(idUser);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un iterable des utilisateurs
	 * 
	 * @return l'iterable des utilisateurs
	 * 
	 */
	public Iterable<Utilisateur> getUsers() {
		return arrayUser.values();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un utilisateur à partir de son login
	 * 
	 * @param login
	 *            login de l'utilisateur
	 * 
	 * @return l'utilisateur recherché
	 * 
	 */
	public Utilisateur getUser(String login) {
		for (Utilisateur user : arrayUser.values()) {
			if (login.equals(user.getLogin())) {
				return user;
			}
		}
		return null;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérerl'id d'un utilisateur à partir de son login dans le cache
	 * 
	 * @param nomUser
	 *            login de l'utilisateur
	 * 
	 * @return id de l'utilisateur
	 * 
	 */
	public int getIdUser(String nomUser) {
		for (Utilisateur user : arrayUser.values()) {
			if (nomUser.equals(user.getLogin())) {
				return user.getIdPersonne();
			}
		}
		return -1;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un utilisateur en attente à partir de son login
	 * 
	 * @param idUser
	 *            id de l'utilisateur en attente
	 * 
	 * @return l'utilisateur recherché
	 * 
	 */
	public Utilisateur getUserPending(int idUser) {
		return arrayUserPending.get(idUser);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un iterable des utilisateurs en attente
	 * 
	 * @return l'iterable des utilisateurs en attente
	 * 
	 */
	public Iterable<Utilisateur> getUsersPending() {
		return arrayUserPending.values();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un utilisateur en attente à partir de son login
	 * 
	 * @param login
	 *            login de l'utilisateur en attente
	 * 
	 * @return l'utilisateur en attente
	 * 
	 */
	public Utilisateur getUserPending(String login) {
		for (Utilisateur user : arrayUserPending.values()) {
			if (login.equals(user.getLogin())) {
				return user;
			}
		}
		return null;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer l'id de l'utilisateur en attente
	 * 
	 * @param nomUser
	 *            login de l'utilisateur en attente
	 * 
	 * @return l'utilisateur recherché
	 * 
	 */
	public int getIdUserPending(String nomUser) {
		for (Utilisateur user : arrayUserPending.values()) {
			if (nomUser.equals(user.getLogin())) {
				return user.getIdPersonne();
			}
		}
		return -1;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer l'id de l'administrateur
	 * 
	 * @return l'id de l'admin
	 */
	public int getIdAdmin() {
		for (int i = 0; i < arrayUser.size(); i++) {
			if (arrayUser.get(i).getRolePersonne().equals(Role.ADMINISTRATEUR)) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un groupe à partir de son id
	 * 
	 * @param idGroup
	 *            id du groupe recherché
	 * 
	 * @return le groupe recherché
	 */
	public Groupe getGroupe(int idGroup) {
		return arrayGroup.get(idGroup);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un groupe à partir de son nom
	 * 
	 * @param nomGroupe
	 *            nom du groupe recherché
	 * 
	 * @return le groupe recherché
	 */
	public Groupe getGroupe(String nomGroupe) {
		for (Groupe group : arrayGroup.values()) {
			if (nomGroupe.equals(group.getNomGroupe())) {
				return group;
			}
		}
		return null;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un iterable des groupes
	 * 
	 * @return l'iterable des groupes
	 */
	public Iterable<Groupe> getGroupes() {
		return arrayGroup.values();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer l'id d'un groupe à partir de son nom
	 * 
	 * @param nomGroupe
	 *            nom du groupe
	 * 
	 * @return l'id du groupe recherché
	 */
	public int getIdGroupe(String nomGroupe) {
		for (Groupe group : arrayGroup.values()) {
			if (nomGroupe.equals(group.getNomGroupe())) {
				return group.getIdGroupe();
			}
		}
		return -1;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer le rôle à partir de son id
	 * 
	 * @param idRole
	 *            id du rôle recherché
	 * 
	 * @return rôle recherché
	 */
	public Role getRole(int idRole) {
		return arrayRole.get(idRole);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un iterable des rôles
	 * 
	 * @return l'iterable des rôles
	 */
	public Iterable<Role> getRoles() {
		return arrayRole.values();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un rôle à partir de l'id de l'utilisateur
	 * 
	 * @param idUser
	 *            id de l'utilisateur
	 * 
	 * @return le rôle recherché
	 */
	public Role getRoleOfUser(int idUser) {
		return arrayUser.get(idUser).getRolePersonne();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un rôle à partir de l'id de l'utilisateur
	 * 
	 * @param rolePersonne
	 *            role de l'utilisateur
	 * 
	 * @return le rôle recherché
	 */
	public int getIdRole(String rolePersonne) {
		for (Role role : arrayRole.values()) {
			if (rolePersonne.equals(role.getNomRole())) {
				return role.getIdRole();
			}
		}
		return -1;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer l'id de d'un rôle à partir d'un rôle
	 * 
	 * @param rolePersonne
	 *            rôle recherché
	 * 
	 * @return id du rôle recherché
	 */
	public int getIdRole(Role rolePersonne) {
		for (Role role : arrayRole.values()) {
			if (rolePersonne.equals(role)) {
				return role.getIdRole();
			}
		}
		return -1;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un problème à partir d'un id donné
	 * 
	 * @param idProbleme
	 *            id du problème recherché
	 * 
	 * @return le problème recherché
	 */
	public Probleme getProbleme(int idProbleme) {
		return arrayProbleme.get(idProbleme);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer l'id d'un problème à partir de son nom
	 * 
	 * @param nomProbleme
	 *            nom du problème
	 * 
	 * @return l'id du problème recherché
	 */
	public int getIdProbleme(String nomProbleme) {
		for (Probleme p : arrayProbleme.values()) {
			if (p.getNomProbleme().equals(nomProbleme))
				return p.getIdProbleme();
		}
		return -1;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un problème à partir de son nom
	 * 
	 * @param nomProbleme
	 *            nom du problème
	 * 
	 * @return l'id du problème recherché
	 */
	public Probleme getProbleme(String nomProbleme) {
		for (Probleme p : arrayProbleme.values()) {
			if (p.getNomProbleme().equals(nomProbleme))
				return p;
		}
		return null;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un résultat à partir d'un id résultat
	 * 
	 * @param idResultat
	 *            id du résultat recherché
	 * 
	 * @return resultat recherché
	 */
	public Resultat getResultat(int idResultat) {
		return arrayResultat.get(idResultat);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un résultat à partir d'un id résultat
	 * 
	 * @param nomResultat
	 *            id du résultat recherché
	 * 
	 * @return resultat recherché
	 */
	public int getIdResultat(String nomResultat) {
		for (Probleme p : arrayProbleme.values()) {
			if (p.getNomProbleme().equals(nomResultat))
				return p.getIdProbleme();
		}
		return -1;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un benchmark
	 * 
	 * @param idBenchmark
	 *            id du benchmark
	 * 
	 * @return benchmark recherché
	 */
	public Benchmarks getBenchmark(int idBenchmark) {
		return arrayBenchmark.get(idBenchmark);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un iterable sur les problèmes
	 * 
	 * @return iterable des problèmes
	 */
	public Iterable<Probleme> getProblemes() {
		return arrayProbleme.values();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un iterable sur les résultats
	 * 
	 * @return iterable des résultats
	 */
	public Iterable<Resultat> getResultats() {
		return arrayResultat.values();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un iterable sur les benchmarks
	 * 
	 * @return iterable des benchmarks
	 */
	public Iterable<Benchmarks> getBenchmarks() {
		return arrayBenchmark.values();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer le tableau des activités correspondant à un groupe
	 * 
	 * @param nomGroupe
	 *            nom du groupe
	 * 
	 * @return tableau des activités récentes du groupe
	 */
	public String[] getTabActivities(String nomGroupe) {
		return Application.getInstance().getGroupe(nomGroupe)
				.displayActivities();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de modifier un utilisateur dans le cache
	 * 
	 * @param idUser
	 *            id de l'utilisateur à modifié
	 * @param login
	 *            login modifié
	 * @param password
	 *            password modifié
	 * 
	 */
	public void modifyUser(int idUser, String login, String password) {
		arrayUser.get(idUser).setLogin(login);
		arrayUser.get(idUser).setPassword(password);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer un iterable sur les résultats
	 * 
	 * @param idGroup
	 *            id du group
	 * @param nomGroupe
	 *            nom du groupe
	 * 
	 */
	public void modifyGroup(int idGroup, String nomGroupe) {
		arrayGroup.get(idGroup).setNomGroupe(nomGroupe);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * d'ajouter des utilisateurs
	 * 
	 * @param idUser
	 *            id de l'utilisateur
	 * @param user
	 *            utilisateur à ajouter
	 * 
	 */
	public void addUser(int idUser, Utilisateur user) {
		arrayUser.put(idUser, user);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * d'ajouter des utilisateurs en attente
	 * 
	 * @param idUser
	 *            id de l'utilisateur en attente
	 * @param user
	 *            utilisateur à ajouter
	 * 
	 */
	public void addUserPending(int idUser, Utilisateur user) {
		arrayUserPending.put(idUser, user);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * d'ajouter des groupes
	 * 
	 * @param idGroup
	 *            id du groupe
	 * @param group
	 *            groupe que l'on ajoute
	 * 
	 */
	public void addGroup(int idGroup, Groupe group) {
		arrayGroup.put(idGroup, group);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * d'ajouter des rôles
	 * 
	 * @param idRole
	 *            id du rôle
	 * @param role
	 *            rôle à ajouter
	 * 
	 */
	public void addRole(int idRole, Role role) {
		arrayRole.put(idRole, role);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * d'ajouter des problèmes
	 * 
	 * @param idProbleme
	 *            id du problème
	 * @param probleme
	 *            problème à ajouter
	 * 
	 */
	public void addProbleme(int idProbleme, Probleme probleme) {
		arrayProbleme.put(idProbleme, probleme);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * d'ajouter des résultats
	 * 
	 * @param idResultat
	 *            id du résultat
	 * @param resultat
	 *            résultat à ajouter
	 * 
	 */
	public void addResultat(int idResultat, Resultat resultat) {
		arrayResultat.put(idResultat, resultat);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * d'ajouter des benchmarks
	 * 
	 * @param idBenchmark
	 *            id du benchmark
	 * @param benchmark
	 *            benchmark à ajouter
	 * 
	 */
	public void addBenchmark(int idBenchmark, Benchmarks benchmark) {
		arrayBenchmark.put(idBenchmark, benchmark);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de supprimer un utilisateur à partir de son id
	 * 
	 * @param idUser
	 *            id de l'utilisateur à supprimer
	 * 
	 */
	public void removeUser(int idUser) {
		arrayUser.remove(idUser);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de supprimer un utilisateur en attente
	 * 
	 * @param idUser
	 *            id de l'utilisateur en attente à supprimer
	 * 
	 */
	public void removeUserPending(int idUser) {
		arrayUserPending.remove(idUser);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de supprimer un groupe
	 * 
	 * @param idGroup
	 *            id du group à supprimer
	 * 
	 */
	public void removeGroup(int idGroup) {
		arrayGroup.remove(idGroup);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de supprimer un rôle
	 * 
	 * @param idRole
	 *            id du role à supprimer
	 * 
	 */
	public void removeRole(int idRole) {
		arrayRole.remove(idRole);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de supprimer un problème
	 * 
	 * @param idProbleme
	 *            id du problème à supprimer
	 * 
	 */
	public void removeProbleme(int idProbleme) {
		arrayProbleme.remove(idProbleme);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de supprimer un resultat
	 * 
	 * @param idResultat
	 *            id du resultat à supprimer
	 * 
	 */
	public void removeResultat(int idResultat) {
		arrayResultat.remove(idResultat);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de supprimer un benchmark
	 * 
	 * @param idBenchmark
	 *            id du benchmark à supprimer
	 * 
	 */
	public void removeBenchmark(int idBenchmark) {
		arrayBenchmark.remove(idBenchmark);
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de supprimer un resultat
	 * 
	 * @param nomProbleme
	 *            nom du problème
	 * 
	 */
	public void removeResultatOfProblem(String nomProbleme) {
		Map<Integer, Resultat> arrayResult = Application.getInstance()
				.getArrayResultat();

		for (Iterator<Resultat> i = arrayResult.values().iterator(); i
				.hasNext();) {
			if (i.next().getNomProbleme().equals(nomProbleme)) {
				i.remove();
			}
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de remplir l'array des utilisateurs
	 * 
	 * @param tabUsers
	 *            tableau des users à rajouter dans le cache
	 * 
	 */
	public void fillArrayUser(Utilisateur[] tabUsers) {
		for (int i = 0; i < tabUsers.length; i++) {
			arrayUser.put(tabUsers[i].getIdPersonne(), tabUsers[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de mettre à jour l'array des utilisateurs
	 * 
	 * @param tabUsers
	 *            tableau des users à rajouter dans le cache
	 * 
	 */
	public void updateArrayUser(Utilisateur[] tabUsers) {
		arrayUser.clear();
		for (int i = 0; i < tabUsers.length; i++) {
			arrayUser.put(tabUsers[i].getIdPersonne(), tabUsers[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de remplir l'array des utilisateurs en attente
	 * 
	 * @param tabUsersPending
	 *            tableau des users en attente à rajouter dans le cache
	 * 
	 */
	public void filArrayUserPending(Utilisateur[] tabUsersPending) {
		for (int i = 0; i < tabUsersPending.length; i++) {
			arrayUserPending.put(tabUsersPending[i].getIdPersonne(),
					tabUsersPending[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de mettre à jour l'array des utilisateurs
	 * 
	 * @param tabUsersPending
	 *            tableau des users à rajouter dans le cache
	 * 
	 */
	public void updateArrayUserPending(Utilisateur[] tabUsersPending) {
		arrayUserPending.clear();
		for (int i = 0; i < tabUsersPending.length; i++) {
			arrayUserPending.put(tabUsersPending[i].getIdPersonne(),
					tabUsersPending[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de remplir l'array des groupes
	 * 
	 * @param tabGroups
	 *            tableau des groupes à rajouter dans le cache
	 * 
	 */
	public void fillArrayGroup(Groupe[] tabGroups) {
		for (int i = 0; i < tabGroups.length; i++) {
			arrayGroup.put(tabGroups[i].getIdGroupe(), tabGroups[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de mettre à jour l'array des groupes
	 * 
	 * @param tabGroups
	 *            tableau des groupes à rajouter dans le cache
	 * 
	 */
	public void updateArrayGroup(Groupe[] tabGroups) {
		arrayGroup.clear();
		for (int i = 0; i < tabGroups.length; i++) {
			arrayGroup.put(tabGroups[i].getIdGroupe(), tabGroups[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de remplir l'array des rôles
	 * 
	 * @param tabRoles
	 *            tableau des roles à rajouter dans le cache
	 * 
	 */
	public void fillArrayRole(Role[] tabRoles) {
		for (int i = 0; i < tabRoles.length; i++) {
			arrayRole.put(tabRoles[i].getIdRole(), tabRoles[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de mettre à jour l'array des rôles
	 * 
	 * @param tabRoles
	 *            tableau des users à rajouter dans le cache
	 * 
	 */
	public void updateArrayRole(Role[] tabRoles) {
		arrayRole.clear();
		for (int i = 0; i < tabRoles.length; i++) {
			arrayRole.put(tabRoles[i].getIdRole(), tabRoles[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de mettre à jour l'array des problèmes
	 * 
	 * @param tabProblemes
	 *            tableau des problemes à rajouter dans le cache
	 * 
	 */
	public void updateArrayProbleme(Probleme[] tabProblemes) {
		arrayProbleme.clear();
		for (int i = 0; i < tabProblemes.length; i++) {
			arrayProbleme.put(tabProblemes[i].getIdProbleme(), tabProblemes[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de remplir l'array des problèmes
	 * 
	 * @param tabProblemes
	 *            tableau des problèmes à rajouter dans le cache
	 * 
	 */
	public void fillArrayProbleme(Probleme[] tabProblemes) {
		for (int i = 0; i < tabProblemes.length; i++) {
			arrayProbleme.put(tabProblemes[i].getIdProbleme(), tabProblemes[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de mettre à jour l'array des résultats
	 * 
	 * @param tabResultat
	 *            tableau des resultats à rajouter dans le cache
	 * 
	 */
	public void updateArrayResult(Resultat[] tabResultat) {
		arrayResultat.clear();
		for (int i = 0; i < tabResultat.length; i++) {
			arrayResultat.put(tabResultat[i].getIdResultat(), tabResultat[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de remplir l'array des résultats
	 * 
	 * @param tabResultat
	 *            tableau des résultats à rajouter dans le cache
	 * 
	 */
	public void fillArrayResult(Resultat[] tabResultat) {
		for (int i = 0; i < tabResultat.length; i++) {
			arrayResultat.put(tabResultat[i].getIdResultat(), tabResultat[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de mettre à jour l'array des benchmarks
	 * 
	 * @param tabBenchmarks
	 *            tableau des benchmarks à rajouter dans le cache
	 * 
	 */
	public void updateArrayBenchmark(Benchmarks[] tabBenchmarks) {
		arrayBenchmark.clear();
		for (int i = 0; i < tabBenchmarks.length; i++) {
			arrayBenchmark.put(tabBenchmarks[i].getIdBenchmark(),
					tabBenchmarks[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de remplir l'array des utilisateurs
	 * 
	 * @param tabBenchmarks
	 *            tableau des benchmarks à rajouter dans le cache
	 * 
	 */
	public void fillArrayBenchmark(Benchmarks[] tabBenchmarks) {
		for (int i = 0; i < tabBenchmarks.length; i++) {
			arrayBenchmark.put(tabBenchmarks[i].getIdBenchmark(),
					tabBenchmarks[i]);
		}
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de donner la taille de l'array des utilisateurs
	 * 
	 * @return taille de l'array des utilisateurs
	 * 
	 */
	public int sizeOfArrayUser() {
		return arrayUser.size();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de donner la taille de l'array des utilisateurs en attente
	 * 
	 * @return taille de l'array des utilisateurs en attente
	 * 
	 */
	public int sizeOfArrayUserPending() {
		return arrayUserPending.size();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de donner la taille de l'array des groupes
	 * 
	 * @return taille de l'array des groupes
	 * 
	 */
	public int sizeOfArrayGroup() {
		return arrayGroup.size();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de donner la taille de l'array des rôles
	 * 
	 * @return taille de l'array des rôles
	 * 
	 */
	public int sizeOfArrayRole() {
		return arrayRole.size();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de donner la taille de l'array des problèmes
	 * 
	 * @return taille de l'array des problèmes
	 * 
	 */
	public int sizeOfProbleme() {
		return arrayProbleme.size();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de donner la taille de l'array des résultats
	 * 
	 * @return taille de l'array des résultats
	 * 
	 */
	public int sizeOfResultat() {
		return arrayResultat.size();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de donner la taille de l'array des benchmarks
	 * 
	 * @return taille de l'array des benchmarks
	 * 
	 */
	public int sizeOfBenchmark() {
		return arrayBenchmark.size();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer la référence de l'array contenant le triplet d'informations
	 * : problème/methode/resultat
	 * 
	 * @return l'array des problème/méthode/resultat
	 * 
	 */
	public ArrayList<LienProblemeMethodeResultat> getArrayLinkOfProblemeMethodeResultat() {
		return arrayLinkOfProblemeMethodeResultat;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer de mettre à jour la référence de l'array contenant le
	 * triplet d'informations : problème/methode/resultat
	 * 
	 * @param arrayLinkOfProblemeMethodeResultat
	 *            nouvelle référence de l'array
	 * 
	 */
	public void setArrayLinkOfProblemeMethodeResultat(
			ArrayList<LienProblemeMethodeResultat> arrayLinkOfProblemeMethodeResultat) {
		this.arrayLinkOfProblemeMethodeResultat = arrayLinkOfProblemeMethodeResultat;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer de mettre à jour la référence de l'array contenant le
	 * triplet d'informations : utilisateur/groupe/role
	 * 
	 * @param arrayLinkOfUserGroupRole
	 *            nouvelle référence de l'array
	 * 
	 */
	public void setArrayLinkOfUserGroupRole(
			ArrayList<LienUserGroupRole> arrayLinkOfUserGroupRole) {
		this.arrayLinkOfUserGroupRole = arrayLinkOfUserGroupRole;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer l'array des groupes
	 * 
	 * @return l'array des groupes
	 * 
	 */
	public Map<Integer, Groupe> getArrayGroup() {
		return arrayGroup;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer l'array des groupes
	 * 
	 * @return l'array des groupes
	 * 
	 */
	public Map<Integer, Role> getArrayRole() {
		return arrayRole;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer l'array des utilisateurs
	 * 
	 * @return l'array des utilisateurs
	 * 
	 */
	public Map<Integer, Utilisateur> getArrayUser() {
		return arrayUser;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer l'array des utilisateurs en attente
	 * 
	 * @return l'array des utilisateurs en attente
	 * 
	 */
	public Map<Integer, Utilisateur> getArrayUserPending() {
		return arrayUserPending;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer l'array des problèmes
	 * 
	 * @return l'array des problèmes
	 * 
	 */
	public Map<Integer, Probleme> getArrayProbleme() {
		return arrayProbleme;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer l'array des résultats
	 * 
	 * @return l'array des résultats
	 * 
	 */
	public Map<Integer, Resultat> getArrayResultat() {
		return arrayResultat;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de récupérer l'array des utilisateurs
	 * 
	 * @return l'array des utilisateurs
	 * 
	 */
	public Map<Integer, Benchmarks> getArrayBenchmarks() {
		return arrayBenchmark;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de d'afficher l'array du triplet utilisateur/groupe/role
	 * 
	 * @return un string contenant le tableau
	 * 
	 */
	public String toStringArrayLinkUserGroupRole() {
		String s = "\n";

		for (LienUserGroupRole l : arrayLinkOfUserGroupRole) {
			s += l.toString();
		}
		return s;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de d'afficher l'array du triplet probleme/methode/resultat
	 * 
	 * @return un string contenant le tableau
	 * 
	 */
	public String toStringArrayLinkProblemResultMethod() {
		String s = "\n";

		for (LienProblemeMethodeResultat l : arrayLinkOfProblemeMethodeResultat) {
			s += l.toString();
		}
		return s;
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de trier l'array du triplet utilisateur/groupe/role
	 * 
	 */
	public void sortByIdUserArrayLink() {
		for (int i = 1; i < arrayLinkOfUserGroupRole.size(); i++) {
			int j = i;
			while ((j > 0)
					&& (arrayLinkOfUserGroupRole.get(j).getIdUser() < arrayLinkOfUserGroupRole
							.get(j - 1).getIdUser())) {
				int idUserTemp = arrayLinkOfUserGroupRole.get(j).getIdUser();
				int idGroupTemp = arrayLinkOfUserGroupRole.get(j).getIdGroup();
				int idRoleTemp = arrayLinkOfUserGroupRole.get(j).getIdRole();

				arrayLinkOfUserGroupRole.get(j).setIdUser(
						arrayLinkOfUserGroupRole.get(j - 1).getIdUser());
				arrayLinkOfUserGroupRole.get(j).setIdGroup(
						arrayLinkOfUserGroupRole.get(j - 1).getIdGroup());
				arrayLinkOfUserGroupRole.get(j).setIdRole(
						arrayLinkOfUserGroupRole.get(j - 1).getIdRole());
				arrayLinkOfUserGroupRole.get(j - 1).setIdUser(idUserTemp);
				arrayLinkOfUserGroupRole.get(j - 1).setIdGroup(idGroupTemp);
				arrayLinkOfUserGroupRole.get(j - 1).setIdRole(idRoleTemp);
				j--;
			}
		}
	}
	
	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de vider toutes les maps
	 */
	public void clearAllMap() {
		arrayUser.clear();
		arrayUserPending.clear();
		arrayGroup.clear();
		arrayProbleme.clear();
		arrayResultat.clear(); 
		arrayRole.clear();
		arrayBenchmark.clear();
		arrayLinkOfUserGroupRole.clear();
		arrayLinkOfProblemeMethodeResultat.clear();
	}

	/**
	 * <u><i>Explication générale de la méthode :</i></u> <P> Cette méthode permet
	 * de lancer l'application
	 * 
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String[] args) {

		// Read logger configuration file
		try {
			LogManager.getLogManager().readConfiguration(
					new FileInputStream("resources/logging.properties"));
			Logger.getLogger(Application.class.getCanonicalName()).log(
					Level.INFO,
					"Logging configuration file successfully loaded");
		} catch (Exception e) {
			Logger.getLogger(Application.class.getCanonicalName()).log(
					Level.SEVERE, "Unable to read logging configuration file",
					e);
		}

		// Read application preferences
		try {
			Application.getInstance().getProperties().load(
					new FileInputStream("resources/application.properties"));
			Logger.getLogger(Application.class.getCanonicalName()).log(
					Level.INFO,
					"Application configuration file successfully loaded");
		} catch (Exception e) {
			Logger.getLogger(Application.class.getCanonicalName()).log(
					Level.SEVERE,
					"Unable to read application configuration file", e);
		}

		// Lancement du logiciel
		ThemeManager.getInstance().registerUIComponent(Fenetre.getInstance());
		Fenetre.getInstance();
	}

}
