package reseau;

import client.Application;
import client.model.LienUserGroupRole;
import client.model.benchmark.Benchmarks;
import client.model.group.Groupe;
import client.model.problem.Parameters;
import client.model.problem.Probleme;
import client.model.problem.Resultat;
import client.model.user.Utilisateur;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.BufferedWriter;
import java.io.File;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class XMLBuilder {

    private static final Logger logger = Logger.getLogger(XMLBuilder.class
            .getCanonicalName());

    private static Transformer DEFAULT_TRANSFORMER;
    private static DocumentBuilder DEFAULT_DOCUMENT_BUILDER;
    private static final Pattern DIGIT_PATTERN = Pattern.compile("\\d");

    static {
        try {
            DEFAULT_DOCUMENT_BUILDER = DocumentBuilderFactory.newInstance()
                    .newDocumentBuilder();
            DEFAULT_TRANSFORMER = TransformerFactory.newInstance()
                    .newTransformer();
        } catch (TransformerConfigurationException e) {
            // ERROR Very bad if it doesnt work...
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            // ERROR Very bad if it doesnt work...
            e.printStackTrace();
        }
    }

    public static String BuildProblemaMessage(Probleme p) {

        try {

            logger.log(Level.FINE, "Problem Builder : {0}", p);

            // Create blank DOM Document
            Document document = DEFAULT_DOCUMENT_BUILDER.newDocument();

            Element probleme = document.createElement("probleme");
            probleme.setAttribute("xmlns:xsi",
                    "http://www.w3.org/2001/XMLSchema-instance");
            probleme.setAttribute("xsi:noNamespaceSchemaLocation",
                    "resources/XSD/problem.xsd");
            probleme.setAttribute("id", "" + p.getIdProbleme());
            document.appendChild(probleme);

            Element nomProbleme = document.createElement("nom_probleme");
            nomProbleme.setTextContent(p.getNomProbleme());
            probleme.appendChild(nomProbleme);

            Element fonction = document.createElement("fonction");
            probleme.appendChild(fonction);

            Element dimension = document.createElement("dimension");
            dimension.setTextContent("" + p.getDimensionFonction());
            fonction.appendChild(dimension);

            Element repreText = document
                    .createElement("representation-textuelle");
            repreText.setTextContent(p.getLibelleFonction());
            fonction.appendChild(repreText);

            if (p.getNomFonction().length() > 0) {
                Element appelFonction = document.createElement("appel-fonction");
                appelFonction.setTextContent(p.getNomFonction());
                fonction.appendChild(appelFonction);
            }

            if (p.getAppelFonction().length() > 0) {
                Element chemin = document.createElement("chemin");
                chemin.setTextContent(p.getAppelFonction());
                fonction.appendChild(chemin);
            }

            // Copy of PointDeDepart
            String copyOfSolutionExacte = p.getSolutionExacte();
            boolean firstTime = true;
            String pointText = null;
            Element point = null;

            if (copyOfSolutionExacte.length() > 0) {
                Element solution = document.createElement("solution");
                probleme.appendChild(solution);

                while (copyOfSolutionExacte.length() > 1) {
                    int virgule = copyOfSolutionExacte.indexOf(",");
                    if (virgule != -1) {
                        point = document.createElement("point");

                        if (firstTime) {
                            pointText = copyOfSolutionExacte.substring(1, virgule);
                            copyOfSolutionExacte = copyOfSolutionExacte.substring(
                                    virgule + 2, copyOfSolutionExacte.length());
                            firstTime = false;
                        } else {
                            pointText = copyOfSolutionExacte.substring(0, virgule);
                            copyOfSolutionExacte = copyOfSolutionExacte.substring(
                                    virgule + 2, copyOfSolutionExacte.length());
                        }

                        // Le dernier point
                    } else {
                        point = document.createElement("point");

                        pointText = copyOfSolutionExacte.substring(0,
                                copyOfSolutionExacte.length() - 1);
                        copyOfSolutionExacte = copyOfSolutionExacte
                                .substring(copyOfSolutionExacte.length());
                    }

                    point.setTextContent(pointText);
                    solution.appendChild(point);
                }
            }

            Element contraintes = document.createElement("contraintes");
            probleme.appendChild(contraintes);

            for (int i = 0; i < p.getVectContraintes().size(); i++) {
                if (p.getVectContraintes().get(i).getParameters(0).getContent()
                        .contains(">")
                        || p.getVectContraintes().get(i).getParameters(0)
                        .getContent().contains("<")) {

                    Element contraintesInegalite = document
                            .createElement("contrainte-inegalite");
                    contraintes.appendChild(contraintesInegalite);

                    Element repreTextCI = document
                            .createElement("representation-textuelle");
                    repreTextCI.setTextContent(p.getVectContraintes().get(i)
                            .getParameters(0).getContent());
                    contraintesInegalite.appendChild(repreTextCI);

                    if (p.getVectContraintes().get(i).getParameters(1).getContent().length() > 0) {
                        Element appelFonctionCI = document
                                .createElement("appel-fonction");
                        appelFonctionCI.setTextContent(p.getVectContraintes()
                                .get(i).getParameters(1).getContent());
                        contraintesInegalite.appendChild(appelFonctionCI);
                    }

                    if (p.getVectContraintes().get(i).getParameters(2).getContent().length() > 0) {
                        Element cheminCI = document.createElement("chemin");
                        cheminCI.setTextContent(p.getVectContraintes().get(i)
                                .getParameters(2).getContent());
                        contraintesInegalite.appendChild(cheminCI);
                    }

                } else if (p.getVectContraintes().get(i).getParameters(0)
                        .getContent().contains("=")) {
                    Element contraintesEgalite = document
                            .createElement("contrainte-egalite");
                    contraintes.appendChild(contraintesEgalite);

                    Element repreTextCE = document
                            .createElement("representation-textuelle");
                    repreTextCE.setTextContent(p.getVectContraintes().get(i)
                            .getParameters(0).getContent());
                    contraintesEgalite.appendChild(repreTextCE);

                    if (p.getVectContraintes().get(i).getParameters(1).getContent().length() > 0) {
                        Element appelFonctionCE = document
                                .createElement("appel-fonction");
                        appelFonctionCE.setTextContent(p.getVectContraintes()
                                .get(i).getParameters(1).getContent());
                        contraintesEgalite.appendChild(appelFonctionCE);
                    }

                    if (p.getVectContraintes().get(i).getParameters(2).getContent().length() > 0) {
                        Element cheminCE = document.createElement("chemin");
                        cheminCE.setTextContent(p.getVectContraintes().get(i)
                                .getParameters(2).getContent());
                        contraintesEgalite.appendChild(cheminCE);
                    }
                } else {
                    System.err.println("Erreur");
                }
            }

            Element derivees = document.createElement("derivees");
            probleme.appendChild(derivees);

            for (int i = 0; i < p.getDeriveeOrdreUn().size(); i++) {
                Element derivee = document.createElement("derivee");
                derivee.setAttribute("ordre", "1");
                derivees.appendChild(derivee);

                Element repreTextCE = document
                        .createElement("representation-textuelle");
                repreTextCE.setTextContent(p.getDerive(i).getParameters(0)
                        .getContent());
                derivee.appendChild(repreTextCE);

                if (p.getDerive(i).getParameters(1).getContent().length() > 0) {
                    Element appelFonctionCE = document
                            .createElement("appel-fonction");
                    appelFonctionCE.setTextContent(p.getDerive(i).getParameters(1)
                            .getContent());
                    derivee.appendChild(appelFonctionCE);
                }

                if (p.getDerive(i).getParameters(2).getContent().length() > 0) {
                    Element cheminCE = document.createElement("chemin");
                    cheminCE.setTextContent(p.getDerive(i).getParameters(2)
                            .getContent());
                    derivee.appendChild(cheminCE);
                }
            }

            return extractDOMOutput(document);

        } catch (TransformerException e) {
            logger.log(Level.SEVERE, "Unable to transform DOM to String", e);
        }
        return null;
    }

    public static String BuildResultMessage(Resultat r) {

        int idProblem = r.getIdProblem();
        int idMethod = r.getIdMethod();
        int idResult = r.getIdResultat();

        try {

            // Create blank DOM Document
            Document document = DEFAULT_DOCUMENT_BUILDER.newDocument();

            Element resultats = document.createElement("resultats");
            resultats.setAttribute("xmlns:xsi",
                    "http://www.w3.org/2001/XMLSchema-instance");
            resultats.setAttribute("xsi:noNamespaceSchemaLocation",
                    "resources/XSD/result.xsd");
            document.appendChild(resultats);

            Element resultatSimple = document.createElement("resultat-simple");
            resultatSimple.setAttribute("id", "" + idResult);
            resultats.appendChild(resultatSimple);

            Element nomResultat = document.createElement("nom_resultat");
            nomResultat.setTextContent(r.getNomResultat());
            resultatSimple.appendChild(nomResultat);

            Element nomProbleme = document.createElement("probleme");
            nomProbleme.setTextContent(r.getNomProbleme());
            nomProbleme.setAttribute("id", "" + idProblem);
            resultatSimple.appendChild(nomProbleme);

            Element nomMethode = document.createElement("methode");
            nomMethode.setTextContent(r.getNomMethode());
            nomMethode.setAttribute("id", "" + idMethod);
            resultatSimple.appendChild(nomMethode);

            Element runDate = document.createElement("run_date");
            runDate.setTextContent(r.getDate());
            resultatSimple.appendChild(runDate);

            Element valeur = document.createElement("point_depart");

            // Copy of PointDeDepart
            String copyOfPointDepart = r.getPointDeDepart();
            boolean firstTime = true;
            String pointText = null;
            Element point = null;

            while (copyOfPointDepart.length() > 1) {
                int virgule = copyOfPointDepart.indexOf(",");
                if (virgule != -1) {
                    point = document.createElement("point");

                    if (firstTime) {
                        pointText = copyOfPointDepart.substring(1, virgule);
                        copyOfPointDepart = copyOfPointDepart.substring(
                                virgule + 2, copyOfPointDepart.length());
                        firstTime = false;
                    } else {
                        pointText = copyOfPointDepart.substring(0, virgule);
                        copyOfPointDepart = copyOfPointDepart.substring(
                                virgule + 2, copyOfPointDepart.length());
                    }

                    // Le dernier point
                } else {
                    point = document.createElement("point");

                    pointText = copyOfPointDepart.substring(0,
                            copyOfPointDepart.length() - 1);
                    copyOfPointDepart = copyOfPointDepart
                            .substring(copyOfPointDepart.length());
                }

                point.setTextContent(pointText);
                valeur.appendChild(point);
            }

            resultatSimple.appendChild(valeur);

            Element parametres = document.createElement("parametres");
            resultatSimple.appendChild(parametres);

            Element epsilon = document.createElement("epsilon");
            epsilon.setTextContent("" + r.getEpsilon());
            parametres.appendChild(epsilon);

            Element pas = document.createElement("pas");
            pas.setTextContent("" + r.getPas());
            parametres.appendChild(pas);

            Element pointValeurOptimisation = document
                    .createElement("point_valeur_optimisation");
            resultatSimple.appendChild(pointValeurOptimisation);

            Element patience = document.createElement("patience");
            patience.setTextContent("" + r.getMaxIteration());
            pointValeurOptimisation.appendChild(patience);

            // Copy of PointValOptim
            String copyOfPointDepart2 = r.getPointValOptim();
            boolean firstTime2 = true;
            String pointText2 = null;
            Element point2 = null;

            while (copyOfPointDepart2.length() > 1) {
                int virgule = copyOfPointDepart2.indexOf(",");

                if (virgule != -1) {
                    point2 = document.createElement("point");

                    if (firstTime2) {
                        pointText2 = copyOfPointDepart2.substring(1, virgule);
                        copyOfPointDepart2 = copyOfPointDepart2.substring(
                                virgule + 2, copyOfPointDepart2.length());
                        firstTime2 = false;
                    } else {
                        pointText2 = copyOfPointDepart2.substring(0, virgule);
                        copyOfPointDepart2 = copyOfPointDepart2.substring(
                                virgule + 2, copyOfPointDepart2.length());
                    }

                    // Le dernier point
                } else {
                    point2 = document.createElement("point");

                    pointText2 = copyOfPointDepart2.substring(0,
                            copyOfPointDepart2.length() - 1);
                    copyOfPointDepart2 = copyOfPointDepart2
                            .substring(copyOfPointDepart2.length());
                }

                point2.setTextContent(pointText2);
                pointValeurOptimisation.appendChild(point2);
            }

            Element valeurOptim = document.createElement("valeur");
            valeurOptim.setTextContent("" + r.getValeurResultat());
            resultatSimple.appendChild(valeurOptim);

            Element complexiteIteration = document
                    .createElement("complexite_iteration");
            complexiteIteration.setTextContent("" + r.getComplexite());
            resultatSimple.appendChild(complexiteIteration);

            Element erreurAbsolue = document.createElement("erreur_absolue");
            erreurAbsolue.setTextContent("" + r.getErrAbsolue());
            resultatSimple.appendChild(erreurAbsolue);

            return extractDOMOutput(document);

        } catch (TransformerException e) {
            logger.log(Level.SEVERE, "Unable to transform DOM to String", e);
        }
        return null;
    }

    public static String BuildBenchmarkMessage(Benchmarks b) {

        try {
            // Create blank DOM Document
            Document document = DEFAULT_DOCUMENT_BUILDER.newDocument();

            Element resultats = document.createElement("resultats");

            document.appendChild(resultats);

            Element resultatBenchmark = document
                    .createElement("resultat-benchmark");
            resultats.setAttribute("xmlns:xsi",
                    "http://www.w3.org/2001/XMLSchema-instance");
            resultats.setAttribute("xsi:noNamespaceSchemaLocation",
                    "resources/XSD/result.xsd");
            resultatBenchmark.setAttribute("id", "" + b.getIdBenchmark());
            resultats.appendChild(resultatBenchmark);

            Element solutions = document.createElement("solutions");
            resultatBenchmark.appendChild(solutions);

            Element pointOptimisation = document
                    .createElement("point-optimisation");
            solutions.appendChild(pointOptimisation);

            // Copy of PointValOptim
            String copyOfPointDepart3 = b.getSolution().getPoint();
            boolean firstTime3 = true;
            String pointText3 = null;
            Element point3 = null;

            while (copyOfPointDepart3.length() > 1) {
                int virgule = copyOfPointDepart3.indexOf(",");

                if (virgule != -1) {
                    point3 = document.createElement("point");

                    if (firstTime3) {
                        pointText3 = copyOfPointDepart3.substring(1, virgule);
                        copyOfPointDepart3 = copyOfPointDepart3.substring(
                                virgule + 2, copyOfPointDepart3.length());
                        firstTime3 = false;
                    } else {
                        pointText3 = copyOfPointDepart3.substring(0, virgule);
                        copyOfPointDepart3 = copyOfPointDepart3.substring(
                                virgule + 2, copyOfPointDepart3.length());
                    }

                    // Le dernier point
                } else {
                    point3 = document.createElement("point");

                    pointText3 = copyOfPointDepart3.substring(0,
                            copyOfPointDepart3.length() - 1);
                    copyOfPointDepart3 = copyOfPointDepart3
                            .substring(copyOfPointDepart3.length());
                }

                point3.setTextContent(pointText3);
                pointOptimisation.appendChild(point3);
            }

            Element valeurOptimisation = document
                    .createElement("valeur-optimisation");
            valeurOptimisation.setTextContent(""
                    + b.getSolution().getValOptim());
            solutions.appendChild(valeurOptimisation);

            for (Resultat r : b.getResults()) {

                int idResult = r.getIdResultat();
                int idProblem = r.getIdProblem();
                int idMethod = r.getIdMethod();

                Element resultat = document.createElement("resultat");
                resultat.setAttribute("id", "" + idResult);
                resultatBenchmark.appendChild(resultat);

                Element nomResultat = document.createElement("nom_resultat");
                nomResultat.setTextContent(r.getNomResultat());
                resultat.appendChild(nomResultat);

                Element nomProbleme = document.createElement("probleme");
                nomProbleme.setTextContent(r.getNomProbleme());
                nomProbleme.setAttribute("id", "" + idProblem);
                resultat.appendChild(nomProbleme);

                Element nomMethode = document.createElement("methode");
                nomMethode.setTextContent(r.getNomMethode());
                nomMethode.setAttribute("id", "" + idMethod);
                resultat.appendChild(nomMethode);

                Element runDate = document.createElement("run_date");
                runDate.setTextContent(r.getDate());
                resultat.appendChild(runDate);

                Element valeur = document.createElement("point_depart");

                // Copy of PointDeDepart
                String copyOfPointDepart = r.getPointDeDepart();
                boolean firstTime = true;
                String pointText = null;
                Element point = null;

                while (copyOfPointDepart.length() > 1) {
                    int virgule = copyOfPointDepart.indexOf(",");
                    if (virgule != -1) {
                        point = document.createElement("point");

                        if (firstTime) {
                            pointText = copyOfPointDepart.substring(1, virgule);
                            copyOfPointDepart = copyOfPointDepart.substring(
                                    virgule + 2, copyOfPointDepart.length());
                            firstTime = false;
                        } else {
                            pointText = copyOfPointDepart.substring(0, virgule);
                            copyOfPointDepart = copyOfPointDepart.substring(
                                    virgule + 2, copyOfPointDepart.length());
                        }

                        // Le dernier point
                    } else {
                        point = document.createElement("point");

                        pointText = copyOfPointDepart.substring(0,
                                copyOfPointDepart.length() - 1);
                        copyOfPointDepart = copyOfPointDepart
                                .substring(copyOfPointDepart.length());
                    }

                    point.setTextContent(pointText);
                    valeur.appendChild(point);
                }

                resultat.appendChild(valeur);

                Element parametres = document.createElement("parametres");
                resultat.appendChild(parametres);

                Element epsilon = document.createElement("epsilon");
                epsilon.setTextContent("" + r.getEpsilon());
                parametres.appendChild(epsilon);

                Element pas = document.createElement("pas");
                pas.setTextContent("" + r.getPas());
                parametres.appendChild(pas);

                Element pointValeurOptimisation = document
                        .createElement("point_valeur_optimisation");
                resultat.appendChild(pointValeurOptimisation);

                Element patience = document.createElement("patience");
                patience.setTextContent("" + r.getMaxIteration());
                pointValeurOptimisation.appendChild(patience);

                // Copy of PointValOptim
                String copyOfPointDepart2 = r.getPointValOptim();
                boolean firstTime2 = true;
                String pointText2 = null;
                Element point2 = null;

                while (copyOfPointDepart2.length() > 1) {
                    int virgule = copyOfPointDepart2.indexOf(",");

                    if (virgule != -1) {
                        point2 = document.createElement("point");

                        if (firstTime2) {
                            pointText2 = copyOfPointDepart2.substring(1,
                                    virgule);
                            copyOfPointDepart2 = copyOfPointDepart2.substring(
                                    virgule + 2, copyOfPointDepart2.length());
                            firstTime2 = false;
                        } else {
                            pointText2 = copyOfPointDepart2.substring(0,
                                    virgule);
                            copyOfPointDepart2 = copyOfPointDepart2.substring(
                                    virgule + 2, copyOfPointDepart2.length());
                        }

                        // Le dernier point
                    } else {
                        point2 = document.createElement("point");

                        pointText2 = copyOfPointDepart2.substring(0,
                                copyOfPointDepart2.length() - 1);
                        copyOfPointDepart2 = copyOfPointDepart2
                                .substring(copyOfPointDepart2.length());
                    }

                    point2.setTextContent(pointText2);
                    pointValeurOptimisation.appendChild(point2);
                }

                Element valeurOptim = document.createElement("valeur");
                valeurOptim.setTextContent("" + r.getValeurResultat());
                resultat.appendChild(valeurOptim);

                Element complexiteIteration = document
                        .createElement("complexite_iteration");
                complexiteIteration.setTextContent("" + r.getComplexite());
                resultat.appendChild(complexiteIteration);

                Element erreurAbsolue = document
                        .createElement("erreur_absolue");
                erreurAbsolue.setTextContent("" + r.getErrAbsolue());
                resultat.appendChild(erreurAbsolue);
            }

            return extractDOMOutput(document);

        } catch (TransformerException e) {
            logger.log(Level.SEVERE, "Unable to transform DOM to String", e);
        }
        return null;
    }

    public static void BuildBenchmarkPrintMessage(Benchmarks b) {

        Document document = DEFAULT_DOCUMENT_BUILDER.newDocument();

        Element resultats = document.createElement("resultats");

        document.appendChild(resultats);

        Element resultatBenchmark = document
                .createElement("resultat-benchmark");
        resultats.setAttribute("xmlns:xsi",
                "http://www.w3.org/2001/XMLSchema-instance");
        resultats.setAttribute("xsi:noNamespaceSchemaLocation",
                "resources/XSD/result.xsd");
        resultatBenchmark.setAttribute("id", "" + b.getIdBenchmark());
        resultats.appendChild(resultatBenchmark);

        Element solutions = document.createElement("solutions");
        resultatBenchmark.appendChild(solutions);

        Element pointOptimisation = document
                .createElement("point-optimisation");
        solutions.appendChild(pointOptimisation);

        // Copy of PointValOptim
        String copyOfPointDepart3 = b.getSolution().getPoint();
        boolean firstTime3 = true;
        String pointText3 = null;
        Element point3 = null;

        while (copyOfPointDepart3.length() > 1) {
            int virgule = copyOfPointDepart3.indexOf(",");

            if (virgule != -1) {
                point3 = document.createElement("point");

                if (firstTime3) {
                    pointText3 = copyOfPointDepart3.substring(1, virgule);
                    copyOfPointDepart3 = copyOfPointDepart3.substring(
                            virgule + 2, copyOfPointDepart3.length());
                    firstTime3 = false;
                } else {
                    pointText3 = copyOfPointDepart3.substring(0, virgule);
                    copyOfPointDepart3 = copyOfPointDepart3.substring(
                            virgule + 2, copyOfPointDepart3.length());
                }

                // Le dernier point
            } else {
                point3 = document.createElement("point");

                pointText3 = copyOfPointDepart3.substring(0,
                        copyOfPointDepart3.length() - 1);
                copyOfPointDepart3 = copyOfPointDepart3
                        .substring(copyOfPointDepart3.length());
            }

            point3.setTextContent(pointText3);
            pointOptimisation.appendChild(point3);
        }

        Element valeurOptimisation = document
                .createElement("valeur-optimisation");
        valeurOptimisation.setTextContent("" + b.getSolution().getValOptim());
        solutions.appendChild(valeurOptimisation);

        for (Resultat r : b.getResults()) {

            int idResult = r.getIdResultat();
            int idProblem = r.getIdProblem();
            int idMethod = r.getIdMethod();

            Element resultat = document.createElement("resultat");
            resultat.setAttribute("id", "" + idResult);
            resultatBenchmark.appendChild(resultat);

            Element nomResultat = document.createElement("nom_resultat");
            nomResultat.setTextContent(r.getNomResultat());
            resultat.appendChild(nomResultat);

            Element nomProbleme = document.createElement("probleme");
            nomProbleme.setTextContent(r.getNomProbleme());
            nomProbleme.setAttribute("id", "" + idProblem);
            resultat.appendChild(nomProbleme);

            Element nomMethode = document.createElement("methode");
            nomMethode.setTextContent(r.getNomMethode());
            nomMethode.setAttribute("id", "" + idMethod);
            resultat.appendChild(nomMethode);

            Element runDate = document.createElement("run_date");
            runDate.setTextContent(r.getDate());
            resultat.appendChild(runDate);

            Element valeur = document.createElement("point_depart");

            // Copy of PointDeDepart
            String copyOfPointDepart = r.getPointDeDepart();
            boolean firstTime = true;
            String pointText = null;
            Element point = null;

            while (copyOfPointDepart.length() > 1) {
                int virgule = copyOfPointDepart.indexOf(",");
                if (virgule != -1) {
                    point = document.createElement("point");

                    if (firstTime) {
                        pointText = copyOfPointDepart.substring(1, virgule);
                        copyOfPointDepart = copyOfPointDepart.substring(
                                virgule + 2, copyOfPointDepart.length());
                        firstTime = false;
                    } else {
                        pointText = copyOfPointDepart.substring(0, virgule);
                        copyOfPointDepart = copyOfPointDepart.substring(
                                virgule + 2, copyOfPointDepart.length());
                    }

                    // Le dernier point
                } else {
                    point = document.createElement("point");

                    pointText = copyOfPointDepart.substring(0,
                            copyOfPointDepart.length() - 1);
                    copyOfPointDepart = copyOfPointDepart
                            .substring(copyOfPointDepart.length());
                }

                point.setTextContent(pointText);
                valeur.appendChild(point);
            }

            resultat.appendChild(valeur);

            Element parametres = document.createElement("parametres");
            resultat.appendChild(parametres);

            Element epsilon = document.createElement("epsilon");
            epsilon.setTextContent("" + r.getEpsilon());
            parametres.appendChild(epsilon);

            Element pas = document.createElement("pas");
            pas.setTextContent("" + r.getPas());
            parametres.appendChild(pas);

            Element pointValeurOptimisation = document
                    .createElement("point_valeur_optimisation");
            resultat.appendChild(pointValeurOptimisation);

            Element patience = document.createElement("patience");
            patience.setTextContent("" + r.getMaxIteration());
            pointValeurOptimisation.appendChild(patience);

            // Copy of PointValOptim
            String copyOfPointDepart2 = r.getPointValOptim();
            boolean firstTime2 = true;
            String pointText2 = null;
            Element point2 = null;

            while (copyOfPointDepart2.length() > 1) {
                int virgule = copyOfPointDepart2.indexOf(",");

                if (virgule != -1) {
                    point2 = document.createElement("point");

                    if (firstTime2) {
                        pointText2 = copyOfPointDepart2.substring(1, virgule);
                        copyOfPointDepart2 = copyOfPointDepart2.substring(
                                virgule + 2, copyOfPointDepart2.length());
                        firstTime2 = false;
                    } else {
                        pointText2 = copyOfPointDepart2.substring(0, virgule);
                        copyOfPointDepart2 = copyOfPointDepart2.substring(
                                virgule + 2, copyOfPointDepart2.length());
                    }

                    // Le dernier point
                } else {
                    point2 = document.createElement("point");

                    pointText2 = copyOfPointDepart2.substring(0,
                            copyOfPointDepart2.length() - 1);
                    copyOfPointDepart2 = copyOfPointDepart2
                            .substring(copyOfPointDepart2.length());
                }

                point2.setTextContent(pointText2);
                pointValeurOptimisation.appendChild(point2);
            }

            Element valeurOptim = document.createElement("valeur");
            valeurOptim.setTextContent("" + r.getValeurResultat());
            resultat.appendChild(valeurOptim);

            Element complexiteIteration = document
                    .createElement("complexite_iteration");
            complexiteIteration.setTextContent("" + r.getComplexite());
            resultat.appendChild(complexiteIteration);

            Element erreurAbsolue = document.createElement("erreur_absolue");
            erreurAbsolue.setTextContent("" + r.getErrAbsolue());
            resultat.appendChild(erreurAbsolue);
        }

        exportXML(document, "benchmark-n" + b.getIdBenchmark());
    }

    public static String BuildGroupMessage(Groupe g) {

        try {
            logger.log(Level.FINE, "g : {0}", g.getIdGroupe());
            logger.log(Level.FINE, "name : {0}", g.getNomGroupe());
            logger.log(Level.FINE, "respo : {0}", g.getResponsableGroupe()
                    .getLogin());

            // Create blank DOM Document
            Document document = DEFAULT_DOCUMENT_BUILDER.newDocument();

            Element group = document.createElement("group");
            group.setAttribute("xmlns:xsi",
                    "http://www.w3.org/2001/XMLSchema-instance");
            group.setAttribute("xsi:noNamespaceSchemaLocation",
                    "resources/XSD/group.xsd");
            group.setAttribute("id", "" + g.getIdGroupe());
            group.setAttribute("name", g.getNomGroupe());

            document.appendChild(group);

            Element users = document.createElement("users");
            group.appendChild(users);

            System.out.println("Builder Group : "
                    + Application.getInstance()
                    .toStringArrayLinkUserGroupRole());

            for (int i = 0; i < Application.getInstance()
                    .getArrayLinkOfUserGroupRole().size(); i++) {
                if (Application.getInstance().getArrayLinkOfUserGroupRole()
                        .get(i).getIdGroup() == g.getIdGroupe()) {
                    Element user = document.createElement("user");
                    user.setAttribute("id", ""
                            + Application.getInstance()
                            .getArrayLinkOfUserGroupRole().get(i)
                            .getIdUser());
                    users.appendChild(user);
                }
            }

            logger.info("OK");
            Element problems = document.createElement("problems");
            group.appendChild(problems);

            for (int i = 0; i < g.getVectProbleme().size(); i++) {
                Element problem = document.createElement("problem");
                problem.setAttribute("id", "" + g.getIdProbleme(i));
                problems.appendChild(problem);
            }

            return extractDOMOutput(document);
        } catch (TransformerException e) {
            logger.log(Level.SEVERE, "Unable to transform DOM to String", e);
        }
        return null;
    }

    public static String BuildUserMessage(Utilisateur u) {

        try {
            // Create blank DOM Document
            Document document = DEFAULT_DOCUMENT_BUILDER.newDocument();

            Element user = document.createElement("user");
            user.setAttribute("xmlns:xsi",
                    "http://www.w3.org/2001/XMLSchema-instance");
            user.setAttribute("xsi:noNamespaceSchemaLocation",
                    "resources/XSD/user.xsd");
            user.setAttribute("id", "" + u.getIdPersonne());
            document.appendChild(user);

            Element login = document.createElement("login");
            login.setTextContent(u.getLogin());
            user.appendChild(login);

            Element password = document.createElement("password");
            password.setTextContent(u.getPassword());
            user.appendChild(password);

            Element groups = document.createElement("groups");
            user.appendChild(groups);

            for (LienUserGroupRole l : Application.getInstance()
                    .getArrayLinkOfUserGroupRole()) {
                Element group = document.createElement("group");
                if (l.getIdUser() == u.getIdPersonne()) {
                    group.setAttribute("id", "" + (l.getIdGroup()));
                    group.setAttribute("associated-role-id",
                            "" + (l.getIdRole()));
                    groups.appendChild(group);
                }
            }

            return extractDOMOutput(document);

        } catch (TransformerException e) {
            logger.log(Level.SEVERE, "Unable to transform DOM to String", e);
        }
        return null;
    }

    private final static String extractDOMOutput(Document document)
            throws TransformerException {
        DEFAULT_TRANSFORMER.setOutputProperty(OutputKeys.INDENT, "yes");
        DEFAULT_TRANSFORMER.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        DEFAULT_TRANSFORMER.setOutputProperty(OutputKeys.METHOD, "xml");
        DEFAULT_TRANSFORMER.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
                "yes");

        StringWriter sw = new StringWriter();
        Writer bw = new BufferedWriter(sw);

        DEFAULT_TRANSFORMER.transform(new DOMSource(document),
                new StreamResult(bw));

        return sw.toString();
    }

    private final static void exportXML(Document document, String nameOfFile) {

        try {
            DEFAULT_TRANSFORMER.setOutputProperty(OutputKeys.METHOD, "xml");
            DEFAULT_TRANSFORMER.setOutputProperty(OutputKeys.INDENT, "yes");
            File file = new File(nameOfFile);

            if (file.exists()) {
                file.delete();
            }

            DEFAULT_TRANSFORMER.transform(new DOMSource(document),
                    new StreamResult(file));

        } catch (TransformerException ex) {
            Logger.getLogger(XMLBuilder.class.getName()).log(Level.SEVERE,
                    null, ex);
        }
    }

    public static String buildParametersMessage(Map<Parameters.InitialCondition, String> conditions) {

        try {
            // Create blank DOM Document
            Document document = DEFAULT_DOCUMENT_BUILDER.newDocument();

            Element parameters = document.createElement("parameters");
            parameters.setAttribute("xmlns:xsi",
                    "http://www.w3.org/2001/XMLSchema-instance");
            parameters.setAttribute("xsi:noNamespaceSchemaLocation",
                    "resources/XSD/parameters.xsd");

            for (Parameters.InitialCondition type : conditions.keySet())
                switch (type) {
                    case INITIAL_VECTOR:
                        Element vector = document.createElement(type.toString());
                        parameters.appendChild(vector);
                        Matcher matcher = DIGIT_PATTERN.matcher(conditions.get(type));
                        while (matcher.find()) {
                            Element point = document.createElement("point");
                            point.setTextContent(matcher.group());
                            vector.appendChild(point);
                        }
                        break;
                    default:
                        Element parameter = document.createElement(type.toString());
                        parameter.setTextContent(conditions.get(type));
                        parameters.appendChild(parameter);
                        break;
                }

            document.appendChild(parameters);
            return extractDOMOutput(document);

        } catch (TransformerException e) {
            logger.log(Level.SEVERE, "Unable to transform DOM to String", e);
        }
        return null;
    }
}
