<?php 
/**
 * Ce script permet de déclarer la classe or_web.
 * 
 * @package openresultat
 * @version SVN : $Id$
 */

/**
 * Inclusion d'une librairie permettant de gérer les problématiques d'encodage.
 * Les fichiers générés depuis la version 1.00 de l'applicatif peuvent avoir 
 * été généré dans divers encodage. Cette librairie permet de palier à cette 
 * problématique en passant les contenus de fichiers générés par cette
 * librairie.
 */
require "encoding.class.php";

/**
 * Class or_web
 */
class or_web {

    /**
     * Tableau contenant les paramètres de l'élections
     * @var array
     */
    protected $params = array();

    /**
     * Liste des élections disponible et info relative à ces élections
     * @var array
     */
    protected $elections = null;

    /**
     * Identifiant de l'élection si une élection est sélectionnée
     * @var integer
     */
    protected $election = null;

    /**
     * Constructeur
     *
     * @param integer $election identifiant de l'élection
     */
    function __construct($election = null) {
        $this->election = $election;
        if (! file_exists("dyn/param.ini")) {
            $message = 'Le portail web n\'est pas actif';
            $this->display_template_page_erreur($message);
            return;
        }

        // Récupère le paramétrage du fichier : dyn/var.inc.php (V1)
        $this->set_params();
        // Récupère le paramétrage du modèle : dyn/param.ini (V2)
        $this->set_param_personnalisation();
        $this->set_infos();
        $this->set_plans();

        $this->display_html_header();
        $this->display_header();
        $this->display();
        //
        $this->display_footer();
        //
        $this->display_html_footer();
    }

    /**
     * Cette méthode permet de récupérer tous les paramètres sur les
     * élections : si il s'agit d'une simulation, la liste des plans,
     * les infos sur la collectivité , ...
     */
    protected function set_params() {
        // Valeurs par défaut des paramètres au cas où il ne sont pas définis
        // dans le fichier dyn/var.inc.php
        $this->params = array(
            //
            "display_simulation" => false,
            //
            "override_election_libelle" => true,
            //
            "plans" => array(),
            //
            "infos_collectivite" => array(
                "title" => "",
                "logo" => "",
                "url" => "",
            ),
            //
            "jscript_stats" => '',
        );
        //
        if (file_exists("dyn/var.inc.php")) {
            include "dyn/var.inc.php";
        }
        //
        if (isset($infos_collectivite)) {
            foreach ($this->params["infos_collectivite"] as $key => $value) {
                if (isset($infos_collectivite[$key])) {
                    $this->params["infos_collectivite"][$key] = $infos_collectivite[$key];
                }
            }
        }
        //
        if (isset($plans)) {
            $this->params["plans"] = $plans;
        }
        //
        if (isset($display_simulation)) {
            $this->params["display_simulation"] = $display_simulation;
        }
        //
        if (isset($override_election_libelle)) {
            $this->params["override_election_libelle"] = $override_election_libelle;
        }
        //
        if (isset($jscript_stats)) {
            $this->params['jscript_stats'] = $jscript_stats;
        }
    }

    /**
     * Getter des paramétres de personnalisation
     *
     * @return array tableau contenant les paramétres de la personnalisation
     */
    protected function get_param_personnalisation() {
        return $this->param_personnalisation;
    }

    /**
     * Récupére les infos issues du fichier de paramétrage si ce fichier existe
     * et stocke ces infos dans un tableau.
     * Récupère le chemin vers les images des unites arrivées et non arrivées et
     * les stocke dans le tableau à l'index de ces images.
     *
     * Stocke le tableau obtenus dans l'attribut param_personnalisation.
     *
     * @return void
     */
    protected function set_param_personnalisation() {
        //par défaut les icônes choisies sont celles disponible dans le repertoire
        // img/bureau avec img_unite_arrivee.gif et img_unite_non_arrivee.gif
        $paramPerso = array();
        //Récupération du paramétrage
        if (file_exists("dyn/param.ini")) {
            $modele = parse_ini_file("dyn/param.ini", true);
            $paramPerso = $modele['parametrage'];
        }
        $this->param_personnalisation = $paramPerso;
    }

    /**
     * Récupère les infos de toutes les unités de l'élection sous la
     * forme d'un tableau
     *
     * @return array tableau contenant les informations
     */
    protected function get_infos_unites() {
        return $this->elections[$this->election]['infos']['unites'];
    }

    /**
     * Récupére les infos de l'unité dont l'id est passé en paramétre
     *
     * @param integer $uniteId identifiant de l'unité
     * @return mixed array contenant les infos de l'unité ou false si
     * l'unité n'existe pas
     */
    protected function get_info_unite($uniteId) {
        $infosUnites = $this->get_infos_unites();
        if (array_key_exists($uniteId, $infosUnites)) {
            return $infosUnites[$uniteId];
        }
        return false;
    }

    /**
     * Le libellé des unités est constitué de cette facon :
     *      n°ordre - nom
     * Cette méthode récupére le nom de l'unité en découpant le libellé
     * et en récupérant uniquement la partie nom
     *
     * @param integer $uniteId identifiant de l'unité
     * @return string nom de l'unité
     */
    protected function get_nom_unite($uniteId) {
        $nom = '';
        $infoUnite = $this->get_info_unite($uniteId);
        if ($infoUnite && array_key_exists('libelle', $infoUnite)) {
            $nom = preg_replace('(\d+ - )', '', $infoUnite['libelle']);
        }
        return $nom;
    }

    /**
     * Tableau contenant tous les paramètres nécessaire à la personnalisation
     * de la page web
     *
     * @var array
     */
    protected $param_personnalisation = array();

    /**
     * Cette méthode permet de récupérer toutes les informations sur les 
     * élections : la liste des élections disponibles, les résultats,
     * la participation, les résultats par unite, ...
     */
    protected function set_infos() {

        /**
         * Composition de la liste des élections disponibles
         */
        //
        $elections = array();
        //
        if (!file_exists(WEB_RESULTS_PATH)) {
            $this->election = null;
            return false;
        }
        //
        $dossier = opendir(WEB_RESULTS_PATH);
        while ($entree = readdir($dossier)) {
            if (preg_match("@[.]@", $entree) || $entree == 'CVS') {
                continue;
            } else {
                $elections[$entree] = array();
            }
        }
        closedir($dossier);
        // On boucle sur chaque répertoire 
        foreach ($elections as $key => $value) {
            // Initialisation des valeurs par défaut
            $election_libelle = "NC";
            $election_date = "1970-01-01";
            $nbcandidat = "0";
            $unite_arr = "0";
            $unite_tot = "0";
            //
            // Compatibilité avec la v1 qui utilise des variables "bureau" au lieu de "unite"
            // Si les valeurs ne sont pas réinitialisé elles risquent d'être utilisée pour toutes
            // les autres élections.
            $bureau_arr = null;
            $bureau_tot = null;
            if (file_exists(WEB_RESULTS_PATH.$key."/election.inc")) {
                include WEB_RESULTS_PATH.$key."/election.inc";
            }
            //
            if ($this->get_param_override_election_libelle() == true) {
                //
                $election_type = $this->get_election_type_from_id($key);
                if ($election_type != null) {
                    $election_libelle = ucwords($election_type." ".$this->formatdate($election_date, 'Y'));
                }
            }

            // Compatibilité v1 : si des bureaux sont enregistrés au lieu d'unité ce sont les
            // bureaux qui sont utilisé
            $unite_arr = ! empty($bureau_arr) ? $bureau_arr : $unite_arr;
            $unite_tot = ! empty($bureau_tot) ? $bureau_tot : $unite_tot;

            $elections[$key] = array(
                "id" => $key,
                "libelle" => $this->normalize_libelle($election_libelle),
                "date" => $this->formatdate($election_date),
                "datetri" => $election_date,
                "tour" => $this->which_tour($key),
                "nbcandidat" => $nbcandidat,
                "nbunitearrive" => $unite_arr,
                "nbunitetotal" => $unite_tot,
                "centaine" => $this->is_centaine($key),
            );
        }

        /**
         * Comparateur de date
         */
        function cmp($a, $b) {
            if ($a["datetri"] == $b["datetri"]) {
                return 0;
            }
            return ($a["datetri"] > $b["datetri"]) ? -1 : 1;
        }

        //
        uasort($elections, "cmp");
        //
        $this->elections = $elections;

        /**
         * Récupération de toutes les infos sur l'élection sélectionnée
         */
        if ($this->election != null) {
            // Définition des constantes des path d'accès aux répertoires résultats
            define("WEB_ELECTION_RESULTS_PATH", WEB_RESULTS_PATH.$this->election."/");
            define("WEB_ELECTION_RESULTS_URL", WEB_RESULTS_URL.$this->election."/");
            // Si le répertoire résultat de l'élection n'existe pas
            if (!file_exists(WEB_ELECTION_RESULTS_PATH)) {
                // On arrête la récupération
                $this->election = null;
                return false;
            }
            // Si l'élection est un simulation et que l'option ne les autorise pas
            if ($this->is_centaine($this->election) != 0 
                && $this->get_param_display_simulation() == false) {
                // On arrête la récupération
                $this->election = null;
                return false;
            }
            //
            $inscrits = 0;
            $votants = 0;
            $blancs = 0;
            $nuls = 0;
            $exprimes = 0;
            $candidats = array();
            if (file_exists(WEB_ELECTION_RESULTS_PATH."/collectivite.inc")) {
                include WEB_ELECTION_RESULTS_PATH."/collectivite.inc";
            }
            //
            $participations = array();
            if (file_exists(WEB_ELECTION_RESULTS_PATH."/participation.inc")) {
                include WEB_ELECTION_RESULTS_PATH."/participation.inc";
            }
            //
            foreach ($candidats as $key => $candidat) {
                $candidats[$key]["nom"] = $this->normalize_libelle($candidat["nom"]);
                $candidats[$key]["prenom"] = $this->normalize_libelle($candidat["prenom"]);
            }
            // Initialisation des plans réellement configurés pour cette élection
            $plans = array();
            // Récupération des informations sur les unites de vote
            $unite = array();
            if (file_exists(WEB_ELECTION_RESULTS_PATH."/unite.inc")) {
                include WEB_ELECTION_RESULTS_PATH."/unite.inc";
            } elseif (file_exists(WEB_ELECTION_RESULTS_PATH."/bureau.inc")) {
                // Compatibilité avec la v1 :
                // Les infos des unités sont récupérées dans le fichier bureau.inc au lieu
                // de unite.inc. Elles sont ensuite mise en forme comme celle de la v2
                // (code deviens ordre). Les positions en x et y sur les plans sont conservées.
                $bureau = array();
                include WEB_ELECTION_RESULTS_PATH."/bureau.inc";
                $unite = array_map(function ($bureau) {
                    return array(
                        'ordre' => $bureau['code'],
                        'etat' => $bureau['etat'],
                        'obj' => $bureau['obj'],
                        'positionx' => $bureau['positionx'],
                        'positiony' => $bureau['positiony']
                    );
                }, $bureau);
            }
            foreach ($unite as $key => $value) {
                // Si le plan n'est pas vide et n'est pas déjà référencé dans 
                // la liste des plans alors on l'ajoute à la liste des plans
                if ($value["obj"] != "" && !in_array($value["obj"], $plans)) {
                    $plans[] = $value["obj"];
                }
                //
                $unite[$key]["fichier"] = "b".$value["ordre"].".html";
                $unite[$key]["inscrits"] = 0;
                $unite[$key]["votants"] = 0;
                $unite[$key]["blancs"] = 0;
                $unite[$key]["nuls"] = 0;
                $unite[$key]["exprimes"] = 0;
                if (file_exists(WEB_ELECTION_RESULTS_PATH.$unite[$key]["fichier"])) {
                    //
                    $doc = new DOMDocument();
                    // Le @ permet de cacher d'éventuelles erreurs liées à la malformation
                    // html des fichiers parsés
                    @$doc->loadHTMLFile(WEB_ELECTION_RESULTS_PATH.$unite[$key]["fichier"]);
                    //
                    $flag_generation = 0;
                    //
                    $elements = $doc->getElementsByTagName('font');
                    if (!is_null($elements)) {
                        foreach ($elements as $element) {
                            $nodes = $element->childNodes;
                            foreach ($nodes as $node) {
                                if (trim($node->nodeValue) != "") {
                                    $flag_generation = 1;
                                }
                            }
                        }
                    }
                    //
                    if ($flag_generation == 1) {
                        $elements = $doc->getElementsByTagName('html');
                        if (!is_null($elements)) {
                            foreach ($elements as $element) {
                                $nodes = $element->childNodes;
                                foreach ($nodes as $node) {
                                    $subnodes = $node->childNodes;
                                    foreach ($subnodes as $subnode) {
                                        // Compatibilité v1 : Dans la v2 le libellé de l'unité est issu du fichier
                                        // contenant les infos des unités. Or dans la v1 ce n'est pas le cas.
                                        // Le libellé est uniquement accessible dans les fichiers contenant les
                                        // résultats des bureaux. Donc si le libellé n'existe pas dans le tableau
                                        // des infos de l'unité, il est récupéré du fichier des résultats et ajouté.
                                        if (! array_key_exists('libelle', $unite[$key]) &&
                                            $subnode->nodeName == "font") {
                                            $unite[$key]['libelle'] = trim($subnode->nodeValue);
                                        }
                                        if ($subnode->nodeName == "#text") {
                                            if (trim($subnode->nodeValue) != "") {
                                                if (preg_match("/^Inscrits/", trim($subnode->nodeValue))) {
                                                    $nombre = explode(":", $subnode->nodeValue);
                                                    $unite[$key]["inscrits"] = trim($nombre[1]);
                                                } elseif (preg_match("/^Votants/", trim($subnode->nodeValue))) {
                                                    $nombre = explode(":", $subnode->nodeValue);
                                                    $unite[$key]["votants"] = trim($nombre[1]);
                                                } elseif (preg_match("/^Blancs/", trim($subnode->nodeValue))) {
                                                    $nombre = explode(":", $subnode->nodeValue);
                                                    $unite[$key]["blancs"] = trim($nombre[1]);
                                                } elseif (preg_match("/^Nuls/", trim($subnode->nodeValue))) {
                                                    $nombre = explode(":", $subnode->nodeValue);
                                                    $unite[$key]["nuls"] = trim($nombre[1]);
                                                } elseif (preg_match("/^Exprim/", trim($subnode->nodeValue))) {
                                                    $nombre = explode(":", $subnode->nodeValue);
                                                    $unite[$key]["exprimes"] = trim($nombre[1]);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        // Generation n°1
                        $elements = $doc->getElementsByTagName('tr');
                        if (!is_null($elements)) {
                            $ligne = 0;
                            foreach ($elements as $element) {
                                //
                                if ($ligne == 0) {
                                    $ligne++;
                                    continue;
                                }
                                //
                                $nodes = $element->childNodes;
                                $unite[$key]["candidats"][$ligne] = array();
                                $colonne = 0;
                                $nbColonne = $element->childNodes->length;
                                foreach ($nodes as $node) {
                                    if ($colonne == 0) {
                                        $unite[$key]["candidats"][$ligne]["nom"] = $candidats[$ligne]["nom"];
                                        $unite[$key]["candidats"][$ligne]["prenom"] = $candidats[$ligne]["prenom"];
                                    } elseif (($nbColonne == 3 && $colonne == 1) || ($nbColonne == 4 && $colonne == 2)) {
                                        $unite[$key]["candidats"][$ligne]["voix"] = trim($node->nodeValue);
                                    } elseif (($nbColonne == 3 && $colonne == 2) || ($nbColonne == 4 && $colonne == 3)) {
                                        $unite[$key]["candidats"][$ligne]["tx"] = trim($node->nodeValue);
                                    }
                                    $colonne++;
                                }
                                $ligne++;
                            }
                        }
                    } else {
                        // Generation n°2
                        $elements = $doc->getElementsByTagName('p');
                        if (!is_null($elements)) {
                            foreach ($elements as $element) {
                                $nodes = $element->childNodes;
                                foreach ($nodes as $node) {
                                    if (trim($node->nodeValue) != "") {
                                        $unite[$key]["libelle"] = trim($node->nodeValue);
                                    }
                                }
                            }
                        }
                        //
                        $elements = $doc->getElementsByTagName('table');
                        if (!is_null($elements)) {
                            $table = 0;
                            foreach ($elements as $element) {
                                if ($table == 0) {
                                    $nodes = $element->childNodes;
                                    foreach ($nodes as $node) {
                                        $nombre = explode(":", $node->nodeValue);
                                        if ($node->attributes != null) {
                                            $unite[$key][str_replace("ligne_", "", trim($node->attributes->item(0)->value))] = trim($nombre[1]);
                                        }
                                    }
                                }
                                if ($table == 1) {
                                    $ligne = 0;
                                    $nodes = $element->childNodes;
                                    foreach ($nodes as $node) {
                                        //
                                        if ($ligne == 0) {
                                               $ligne++;
                                            continue;
                                        }
                                        $subnodes = $node->childNodes;
                                        $unite[$key]["candidats"][$ligne] = array();
                                        $colonne = 0;
                                        foreach ($subnodes as $subnode) {
                                            if ($colonne == 0) {
                                                $unite[$key]["candidats"][$ligne]["nom"] = $candidats[$ligne]["nom"];;
                                                $unite[$key]["candidats"][$ligne]["prenom"] = $candidats[$ligne]["prenom"];;
                                            } elseif ($colonne == 1) {
                                                $unite[$key]["candidats"][$ligne]["voix"] = trim($subnode->nodeValue);
                                            } elseif ($colonne == 2) {
                                                $unite[$key]["candidats"][$ligne]["tx"] = trim($subnode->nodeValue);
                                            }
                                            $colonne++;
                                        }
                                        //
                                        $ligne++;
                                    }
                                }
                                $table++;
                            }
                        }
                    }
                }
                // Compatibilité v1 : Si aucun libellé n'a pu être récupéré dans le fichier
                // des résultats
                if (! array_key_exists('libelle', $unite[$key])) {
                    $unite[$key]['libelle'] = "unité ".$unite[$key]['ordre'];
                }
            }
            //
            $this->elections[$this->election]["infos"] = array(
                "inscrits" => $inscrits,
                "votants" => $votants,
                "blancs" => $blancs,
                "nuls" => $nuls,
                "exprimes" => $exprimes,
                "candidats" => $candidats,
                "participation" => $participations,
                "unites" => $unite,
                "plans" => $plans,
            );
        }
    }

    /**************************************************************************
     * Accesseurs
     */

    /**
     * Récupère le tableau contenant la liste des élections avec leur
     * information
     * 
     * @return array
     */
    protected function get_elections() {
        //
        return $this->elections;
    }

    /**
     * Récupère l'élection et ses informations
     * 
     * @return array
     */
    protected function get_election() {
        $election = null;
        if (! empty($this->election) &&
            array_key_exists($this->election, $this->elections)
        ) {
            $election = $this->elections[$this->election];
        }
        return $election;
    }

    /**
     * Récupère le nom de la collectivité
     *
     * @return string
     */
    protected function get_collectivite_title() {
        // Récupère par défaut le paramètre issu du fichier var.inc.php.
        // Cependant, si un modèle web est défini le paramétrage récupéré est celui du modèle
        $personnalisation = $this->get_param_personnalisation();
        if (! empty($personnalisation) && array_key_exists('entete', $personnalisation)) {
            return $personnalisation['entete'];
        }
        // Compatibilité avec le paramétrage de la v1
        return $this->params["infos_collectivite"]["title"];
    }

    /**
     * Récupère le logo de la collectivité
     * 
     * @return string
     */
    protected function get_collectivite_logo() {
        // Récupère par défaut le paramètre issu du fichier var.inc.php.
        // Cependant, si un modèle web est défini le paramétrage récupéré est celui du modèle
        $personnalisation = $this->get_param_personnalisation();
        $logo = $this->params["infos_collectivite"]["logo"];
        if (! empty($personnalisation)) {
            $pathLogo = glob('img/logo.*');
            $logo = ! empty($pathLogo[0]) ? $pathLogo[0] : $logo;
        }
        return $logo;
    }

    /**
     * Récupère l'url de la collectivité
     * 
     * @return string
     */
    protected function get_collectivite_url() {
        // Récupère par défaut le paramètre issu du fichier var.inc.php.
        // Cependant, si un modèle web est défini le paramétrage récupéré est celui du modèle
        $personnalisation = $this->get_param_personnalisation();
        if (! empty($personnalisation) && array_key_exists('url_collectivite', $personnalisation)) {
            return $personnalisation['url_collectivite'];
        }
        // Compatibilité avec le paramétrage de la v1
        return $this->params["infos_collectivite"]["url"];
    }

    /**
     * Récupère le paramètre display_simulation.
     * 
     * @return boolean valeur du paramètre
     */
    protected function get_param_display_simulation() {
        // Récupère par défaut le paramètre issu du fichier var.inc.php.
        // Cependant, si un modèle web est défini le paramétrage récupéré est celui du modèle
        $personnalisation = $this->get_param_personnalisation();
        $display = $this->params["display_simulation"] == true;
        if (! empty($personnalisation) && array_key_exists('display_simulation', $personnalisation)) {
            $display = $personnalisation['display_simulation'] == 't' ||
                $personnalisation['display_simulation'] == 'Oui';
        }

        return $display;
    }

    /**
     * Récupère le paramètre override_election_libelle
     * 
     * @return boolean valeur du paramètre
     */
    protected function get_param_override_election_libelle() {
        //
        return $this->params["override_election_libelle"];
    }

    /**
     * Récupère le parammètre jscripts_stats
     * 
     * @return $this->params['jscript_stats']
     */
    protected function get_param_jscript_stats() {
        // Récupère par défaut le paramètre issu du fichier var.inc.php.
        // Cependant, si un modèle web est actif le paramétrage récupéré est celui du modèle
        $personnalisation = $this->get_param_personnalisation();
        $jscript = $this->params["jscript_stats"];
        if (! empty($personnalisation) && array_key_exists('jscript_stats', $personnalisation)) {
            $jscript = $personnalisation['jscript_stats'];
        }
        return $this->params['jscript_stats'];
    }

    /**
     * Récupère les unités de l'élection
     * 
     * @return array liste des unites
     */
    protected function get_election_unites() {
        //
        return $this->elections[$this->election]["infos"]["unites"];
    }

    /**
     * Récupère les plans
     * 
     * @return array liste des plans
     */
    protected function get_plans() {
        //
        return $this->params["plans"];
    }

    /**
     * Récupère les plans de l'élection
     * 
     * @return : liste des plans de l'élection
     */
    protected function get_election_plans() {
        return $this->plans;
    }

    /**
     * Récupére le paramétrage d'un plan donné par son id
     *
     * @param integer identifiant du plan dont on souhaite récupérer le
     * paramétrage
     * @return mixed array : parametrage du plan ou boolean : false car
     * le plan voulu n'a pas été trouvé
     */
    protected function get_parametrage_plan($idPlan) {
        $plans = $this->get_election_plans();
        foreach ($plans as $plan) {
            if ($plan['plan'] === $idPlan) {
                return $plan;
            }
        }
        return false;
    }

    /**
     * Récupére le paramétrage de l'affichage d'une unité sur un plan
     * donné.
     * Si l'unité n'est pas paramétré pour le plan voulu renvoie false
     *
     * @param integer identifiant du plan dont on souhaite récupérer le
     * paramétrage
     * @param integer identifiant de l'unité à chercher
     *
     * @return mixed array : parametrage de l'unité sur le plan ou
     * boolean : false, car le paramétrage de l'unité sur le plan n'a pas été trouvé
     */
    protected function get_plan_unite($idPlan, $uniteId) {
        $plan = $this->get_parametrage_plan($idPlan);
        if (! empty($plan) && array_key_exists('plans_unite', $plan)) {
            foreach ($plan['plans_unite'] as $planUnite) {
                if ($planUnite['unite'] == $uniteId) {
                    return $planUnite;
                }
            }
        }
        return false;
    }

    /**
     * Récupére l'url de l'icone d'affichage de l'unité sur le plan
     *
     * @param array tableau du parametrage de l'affichage de l'unité sur le plan
     * @param array tableau de paramétrage du plan
     * @param boolean indique si l'unité est arrivé ou pas
     *
     * @return mixed array : parametrage de l'unité sur le plan ou
     * boolean : false, car le paramétrage de l'unité sur le plan n'a pas été trouvé
     */
    protected function get_url_icone_unite($planUnite, $plan) {
        $uniteInfo = $this->get_info_unite($planUnite['unite']);
        if ($uniteInfo['etat'] === '1') {
            $url = $plan['img_unite_arrivee']['filepath'];
            if (! empty($planUnite['img_unite_arrivee'])) {
                $url = $planUnite['img_unite_arrivee']['filepath'];
            }
        } else {
            $url = $plan['img_unite_non_arrivee']['filepath'];
            if (! empty($planUnite['img_unite_non_arrivee'])) {
                $url = $planUnite['img_unite_non_arrivee']['filepath'];
            }
        }
        return $url;
    }

    /**
     * Récupère le contenu du fichier plans.json. Converti le json en
     * tableau et ajoute à ce tableau le lien vers l'image.
     * Stocke le tableau résultant dans l'attribut : plans
     */
    protected function set_plans() {
        $plansElection = array();
        if (! empty($this->election) &&
            file_exists(WEB_RESULTS_PATH.$this->election."/plans.json")) {
            $plansJson =  file_get_contents(WEB_ELECTION_RESULTS_PATH."/plans.json");
            $plansElection = json_decode($plansJson, true);
        }
        $this->plans = $plansElection;
    }

    /**
     * Paramétrage des plans de l'élection
     *
     * @var array
     */
    protected $plans = array();


    /**************************************************************************
     * Définition des méthodes d'affichage dépendantes des templates
     */

    /**
     * Méthode d'affichage globale du contenu de la page
     * 
     * @return void
     */
    protected function display() {
        /**
         *
         */
        //
        if ($this->get_election() == NULL) {

            //
            $template_global_elections_liste = '
            <div class="container">
                <div class="col-xs-12 col-sm-9">
                %s
                %s
                </div>
                <div class="col-xs-12 col-sm-3">
                    <div class="text-center">
                    %s
                    %s
                    </div>
                </div>
            </div>';
            //
            printf(
                $template_global_elections_liste,
                $this->display_page_title("Choix de l'élection"),
                $this->display_elections_liste(),
                $this->display_collectivite_logo(),
                $this->display_collectivite_url()
            );

        } else {

            //
            $template_global_election_detail = '
            <!-- ELECTION DETAILS - START -->
            <div class="container">
                <div class="col-xs-12 col-sm-9">
                %s
                %s
                <!-- Container niveau 1 - START -->
                %s
                <!-- Container niveau 1 - END -->
                %s
                </div>
                <div class="col-xs-12 col-sm-3">
                    <div class="text-center">
                        %s
                        %s
                    </div>
                </div>
            </div>
            <!-- ELECTION DETAILS - END -->';

            //
            $election_infos = $this->get_election();
            
            //
            printf(
                //
                $template_global_election_detail,
                //
                $this->display_page_title(
                    $election_infos["libelle"],
                    ($election_infos["tour"] == "" || $this->get_param_override_election_libelle() != true ? "" : ($election_infos["tour"] == 1 ? "1er tour" : "2nd tour")).' ('.$election_infos["date"].')'
                ),
                //
                $this->display_onglets_niveau_1(),
                //
                $this->display_election_container(),
                //
                $this->display_election_resultats_par_unite(),
                //
                $this->display_collectivite_logo(),
                //
                $this->display_collectivite_url()
            );
        }
    }

    /**
     * Affichage onglets de niveau 1
     * 
     * @return string html de l'affichage
     */
    protected function display_onglets_niveau_1() {
        //
        $election_infos = $this->get_election();
        //
        $return = sprintf(
            //
            $this->template_onglets_niveau_1,
            //
            "class='active'",
            //
            ""
        );
        //
        if ($election_infos["nbunitearrive"] > 0) {
            //
            $return = sprintf(
                //
                $this->template_onglets_niveau_1,
                //
                "",
                //
                "class='active'"
            );
        }

        //
        return $return;
    }

    /**
     * Affichage de la liste des unites
     * 
     * @return string html de l'affichage
     */
    protected function display_election_unites_liste() {
        //
        $unites = $this->get_election_unites();
        // Tri des unités par code pour les afficher dans le bon ordre
        usort($unites, function ($a, $b) {
            if ($a['ordre'] === $b['ordre']) {
                return 0;
            }
            return ($a['ordre'] < $b['ordre']) ? -1 : 1;
        });
        $unites_liste_content = "";
        foreach ($unites as $key => $value) {
            if ($value["etat"] == "1") {
                //
                $unites_liste_content .= sprintf(
                    $this->template_election_unites_liste_ligne_arrive,
                    $value["ordre"],
                    $value["libelle"]
                );
            } else {
                //
                $unites_liste_content .= sprintf(
                    $this->template_election_unites_liste_ligne_non_arrive,
                    $value["ordre"],
                    $value["libelle"]
                );
            }
        }
        //
        return sprintf(
            $this->template_election_unites_liste,
            $unites_liste_content
        );
    }

    /**
     * Affichage des résultats par unité
     * 
     * @return string html de l'affichage
     */
    protected function display_election_resultats_par_unite() {
        //
        $election_resultats_par_unite_content = "";
        //
        foreach ($this->get_election_unites() as $election_unite) {
            //
            if (file_exists(WEB_ELECTION_RESULTS_PATH.$election_unite["fichier"])) {
                //
                if (!isset($election_unite["candidats"])) {
                    $resultats_unite = "";
                    include WEB_ELECTION_RESULTS_PATH.$election_unite["fichier"];
                } else {
                    $resultats_unite = $this->display_results(
                        $election_unite["inscrits"],
                        $election_unite["votants"],
                        $election_unite["blancs"],
                        $election_unite["nuls"],
                        $election_unite["exprimes"],
                        $election_unite["candidats"]
                    );
                }
                //
                $election_resultats_par_unite_content .= sprintf(
                    //
                    $this->template_election_resultats_unite_modal,
                    //
                    $election_unite["ordre"],
                    //
                    $election_unite["libelle"],
                    //
                    $resultats_unite
                );
            }
        }
        //
        return $election_resultats_par_unite_content;

    }

    /**
     * Affichage de la barre de progression
     * 
     * @return string html de l'affichage
     */
    protected function display_progress_bar(
        $nb_unites_arrives, 
        $nb_unites_total
    ) {
        //
        if ($this->get_election() == null) {
            return "";
        }
        //
        $css_class = "";
        if ($nb_unites_arrives != $nb_unites_total) {
            $css_class = " progress-striped active";
        }
        //
        if ($nb_unites_total == 0) {
            $pourcentage = 0;
        } else {
            $pourcentage = $nb_unites_arrives * 100 / $nb_unites_total;
        }
        //
        $txt_unite = "unité arrivé";
        if ($nb_unites_arrives > 1) {
            $txt_unite = "unités arrivés";
        }
        //
        return sprintf(
            $this->template_election_progress_bar,
            $nb_unites_arrives,
            $txt_unite,
            $nb_unites_total,
            $css_class,
            $pourcentage,
            $pourcentage
        );

    }

    /**
     * Affichage des résultats
     * 
     * @return string html de l'affichage
     */
    protected function display_results(
        $inscrits,
        $votants,
        $blancs,
        $nuls,
        $exprimes,
        $candidats
    ) {
        //
        if ($this->get_election() == null) {
            return "";
        }
        $inscrits = isset($inscrits) ? $inscrits : 0;
        $votants = isset($votants) ? $votants : 0;
        $blancs = isset($blancs) ? $blancs : 0;
        $nuls = isset($nuls) ? $nuls : 0;
        $exprimes = isset($exprimes) ? $exprimes : 0;
        /**
         *
         */
        // Abstentions
        if ($votants > $inscrits || $votants == 0) {
            $abstentions = 0;
        } else {
            $abstentions = $inscrits - $votants;
        }
        // Abstentions - % Inscrits
        if ($inscrits == 0) {
            $abstentions_pc_inscrits = 0;
        } else {
            $abstentions_pc_inscrits = $abstentions * 100 / $inscrits;
        }
        // Votants
        if ($votants > $inscrits) {
            $votants = 0;
        } else {
            $votants = $votants;
        }
        // Votants - % Inscrits
        if ($inscrits == 0) {
            $votants_pc_inscrits = 0;
        } else {
            $votants_pc_inscrits = $votants * 100 / $inscrits;
        }
        // Blancs - % Inscrits
        if ($inscrits == 0) {
            $blancs_pc_inscrits = 0;
        } else {
            $blancs_pc_inscrits = $blancs * 100 / $inscrits;
        }
        // Blancs - % Votants
        if ($votants == 0) {
            $blancs_pc_votants = 0;
        } else {
            $blancs_pc_votants = $blancs * 100 / $votants;
        }
        // Nuls - % Inscrits
        if ($inscrits == 0) {
            $nuls_pc_inscrits = 0;
        } else {
            $nuls_pc_inscrits = $nuls * 100 / $inscrits;
        }
        // Nuls - % Votants
        if ($votants == 0) {
            $nuls_pc_votants = 0;
        } else {
            $nuls_pc_votants = $nuls * 100 / $votants;
        }
        // Exprimés - % Inscrits
        if ($inscrits == 0) {
            $exprimes_pc_inscrits = 0;
        } else {
            $exprimes_pc_inscrits = $exprimes * 100 / $inscrits;
        }
        // Exprimés - % Votants
        if ($votants == 0) {
            $exprimes_pc_votants = 0;
        } else {
            $exprimes_pc_votants = $exprimes * 100 / $votants;
        }
        //
        $global_results = "
            <table class=\"table table-bordered table-condensed\">
                <thead>
                    <tr>
                        <th></th>
                        <th class=\"text-center\">Nombre</th>
                        <th class=\"text-center\">%% Inscrits</th>
                        <th class=\"text-center\">%% Votants</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>Inscrits</td>
                        <td class=\"text-right\">%s</td>
                        <td></td>
                        <td></td>
                    </tr>
                    <tr>
                        <td>Abstentions</td>
                        <td class=\"text-right\">%s</td>
                        <td class=\"text-right\">%s</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td>Votants</td>
                        <td class=\"text-right\">%s</td>
                        <td class=\"text-right\">%s</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td>Blancs</td>
                        <td class=\"text-right\">%s</td>
                        <td class=\"text-right\">%s</td>
                        <td class=\"text-right\">%s</td>
                    </tr>
                    <tr>
                        <td>Nuls</td>
                        <td class=\"text-right\">%s</td>
                        <td class=\"text-right\">%s</td>
                        <td class=\"text-right\">%s</td>
                    </tr>
                    <tr>
                        <td>Exprimés</td>
                        <td class=\"text-right\">%s</td>
                        <td class=\"text-right\">%s</td>
                        <td class=\"text-right\">%s</td>
                    </tr>
                </tbody>
            </table>
            <table class=\"table table-bordered table-striped table-condensed table-resultats\">
                <thead>
                  <tr>
                    <th>Candidats / Listes</th>
                    <th class=\"text-center\">Voix</th>
                    <th class=\"text-center\">%% Exprimés</th>
                  </tr>
                </thead>
                <tbody>
                    %s
                </tbody>
              </table>";
        //
        $output_vote_results_lines = "";
        foreach ($candidats as $candidat) {
            //
            $vote_results_line = '
            <tr class="ligne-resultat">
                <td class="candidat-liste">%s</td>
                <td class="candidat-liste-voix text-right">%s</td>
                <td class="candidat-liste-taux text-right">%s</td>
            </tr>';
            //
            $output_vote_results_lines .= sprintf(
                $vote_results_line,
                $candidat["nom"]." ".$candidat["prenom"],
                number_format(floatval($candidat["voix"]), 0, ",", " "),
                number_format(floatval(str_replace("%", "", $candidat["tx"])), 2, ",", " ")
                //number_format($candidat["voix"], 0, ",", " "),
                //number_format(str_replace("%", "", $candidat["tx"]), 2, ",", " ")
            );
        }
        //
        return sprintf(
            $global_results,
            number_format($inscrits, 0, '.', ' '),
            number_format($abstentions, 0, '.', ' '),
            number_format($abstentions_pc_inscrits, 2, ',', ' '),
            number_format($votants, 0, '.', ' '),
            number_format($votants_pc_inscrits, 2, ',', ' '),
            number_format($blancs, 0, '.', ' '),
            number_format($blancs_pc_inscrits, 2, ',', ' '),
            number_format($blancs_pc_votants, 2, ',', ' '),
            number_format($nuls, 0, '.', ' '),
            number_format($nuls_pc_inscrits, 2, ',', ' '),
            number_format($nuls_pc_votants, 2, ',', ' '),
            number_format($exprimes, 0, '.', ' '),
            number_format($exprimes_pc_inscrits, 2, ',', ' '),
            number_format($exprimes_pc_votants, 2, ',', ' '),
            $output_vote_results_lines
        );
    }

    /**
     * Affichage de l'élement qui contiens l'élection
     * 
     * @return string html de l'affichage
     */
    protected function display_election_container() {
        //
        $election_infos = $this->get_election();
        //
        $return = sprintf(
            //
            $this->template_election_container,
            //
            'active',
            //
            $this->display_election_participation(),
            //
            '',
            //
            $this->display_election_resultat()
        );
        //
        if ($election_infos["nbunitearrive"] > 0) {
            //
            $return = sprintf(
                //
                $this->template_election_container,
                //
                '',
                //
                $this->display_election_participation(),
                //
                'active',
                //
                $this->display_election_resultat()
            );
        }
        //
        return $return;
    }

    /**
     * Affichage de la participation pour une élection
     * 
     * @return string html de l'affichage
     */
    protected function display_election_participation() {
        //
        if ($this->get_election() == null) {
            return "";
        }
        //
        $participation_table_content = "";
        //
        $election = $this->get_election();
        //
        foreach ($election["infos"]["participation"] as $participation) {
            $participation_table_content .= sprintf(
                $this->template_election_participation_ligne,
                $participation['heure'],
                number_format($participation['votants'], 0, ",", " "),
                number_format(str_replace("%", "", $participation['tx']), 2, ",", " ")
            );
        }
        //
        return sprintf(
            $this->template_election_participation,
            $participation_table_content
        );
    }

    /**
     * Affiche les résultats de l'élection
     * 
     * @return string html de l'affichage
     */
    protected function display_election_resultat() {
        //
        $election_infos = $this->get_election();
        //
        return sprintf(
            //
            $this->template_election_resultat,
            //
            $this->display_progress_bar(
                $election_infos["nbunitearrive"],
                $election_infos["nbunitetotal"]
            ),
            //
            $this->display_election_resultat_onglets(),
            //
            $this->display_election_resultat_container()
        );
    }

    /**
     * Affiche l'onglet des résultats
     *
     * @return string html de l'onglet des résultats
     */
    protected function display_election_resultat_onglets() {

        $plans_onglets_content = "";
        // Récupère la liste des plans et pour chaque plan ajoute
        // un onglet ayant pour nom le libellé du plan
        // Cet onglet aura également un lien (href) vers : #resultats-idPlan
        $plans = $this->get_election_plans();
        if (! empty($plans)) {
            foreach ($plans as $value) {
                    $plans_onglets_content .= sprintf(
                        $this->template_plans_onglets,
                        $value['plan'],
                        $value['plan'],
                        $value['libelle']
                    );
            }
        } elseif (file_exists(WEB_ELECTION_RESULTS_PATH."/bureau.inc")) {
            // Compatibilité v1 : récupère la liste des plans comme sur la v1 si les bureau sont défini comme sur la v1
            $plans = $this->get_plans();
            foreach ($plans as $value) {
                    $plans_onglets_content .= sprintf(
                        $this->template_plans_onglets,
                        $value['id'],
                        $value['id'],
                        $value['libelle']
                    );
            }
        }
        // Ajoute les onglets précédemment crée à la liste des onglets des résultats
        return sprintf(
            $this->template_election_resultat_onglets,
            $plans_onglets_content
        );
    }

    /**
     * Affiche l'élément contenant les résultats
     * 
     * @return string code html de l'affichage des résultats
     */
    protected function display_election_resultat_container() {
        //
        $election_infos = $this->get_election();
        //
        $plans_containers_content = "";
        //
        $plans = $this->get_election_plans();
        if (! empty($plans)) {
            foreach ($plans as $plan) {
                $plans_containers_content .= sprintf(
                    $this->template_plans_containers,
                    $plan['plan'],
                    $this->display_plan($plan)
                );
            }
        } else {
            $plans = $this->get_plans();
            foreach ($this->elections[$this->election]["infos"]["plans"] as $value) {
                //
                if (isset($plans[$value]["id"])) {
                    $plans_containers_content .= sprintf(
                        $this->template_plans_containers,
                        $plans[$value]["id"],
                        $this->display_plan_v1($value)
                    );
                }
            }
        }

        return sprintf(
            //
            $this->template_election_resultat_container,
            //
            $this->display_results(
                $election_infos["infos"]["inscrits"],
                $election_infos["infos"]["votants"],
                $election_infos["infos"]["blancs"],
                $election_infos["infos"]["nuls"],
                $election_infos["infos"]["exprimes"],
                $election_infos["infos"]["candidats"]
            ),
            //
            $this->display_election_unites_liste(),
            //
            $plans_containers_content
        );
    }

    /**
     * Affichage de la liste des élections
     * 
     * @return string le contenu de la liste à afficher
     */
    protected function display_elections_liste() {
        //
        $elections_liste_content = "";
        //
        foreach ($this->get_elections() as $election) {
            //
            if ($election['centaine'] == 0
                || ($election['centaine'] == 1 &&
                    $this->get_param_display_simulation())) {
                //
                $elections_liste_content .= sprintf(
                    $this->template_elections_liste_ligne,
                    $election["id"],
                    substr($election['id'], 0, 3),
                    $election["libelle"],
                    ($election["tour"] == ""  || $this->get_param_override_election_libelle() != true ? "" : ($election["tour"] == 1 ? "1er tour" : "2nd tour")),
                    $election["date"]
                );
            }
        }
        //
        return sprintf(
            $this->template_elections_liste,
            $elections_liste_content
        );
    }

    /**
     * Méthode d'affichage des plans paramétrés comme sur la v1.
     *
     * @param $plan
     */
    protected function display_plan_v1($plan) {
        //
        if ($this->election == null) {
            return "";
        }
        //
        $plan_params = $this->get_plans();
        if (!isset($plan_params[$plan]["img"])) {
            return "";
        }
        //
        $election_plan_content = "";
        $unites = $this->get_infos_unites();
        foreach ($unites as $unite) {
            $image = "b";
            // Si le bureau est bien positionne sur le plan en objet
            if ($unite["obj"] == $plan) {
                if ($unite["etat"] == 1 && file_exists(WEB_ELECTION_RESULTS_PATH."b".$unite["ordre"].".html")) {
                    $etat = 1;
                    // Récupération de l'icone des bureaux arrivées
                    if (file_exists("img/bureau/img_unite_arrivee.gif")) {
                        $image = "img/bureau/img_unite_arrivee.gif";
                    }
                } else {
                    $etat = 0;
                    // Récupération de l'icone des bureaux arrivées
                    if (file_exists("img/bureau/img_unite_non_arrivee.gif")) {
                        $image = "img/bureau/img_unite_non_arrivee.gif";
                    }
                }
                // Taille de l'icone des bureaux de la v1
                $width = 80;
                if ($etat == 1) {
                    //
                    $election_plan_content .= sprintf(
                        $this->template_election_plan_unite_arrive,
                        $unite["positiony"],
                        $unite["positionx"],
                        $width,
                        $unite["positiony"],
                        $unite["positionx"],
                        $unite["ordre"],
                        $image,
                        $unite['ordre'],
                        $unite['ordre']
                    );
                } else {
                    //
                    $election_plan_content .= sprintf(
                        $this->template_election_plan_unite_non_arrive,
                        $unite["positiony"],
                        $unite["positionx"],
                        $width,
                        $unite["positiony"],
                        $unite["positionx"],
                        $image,
                        $unite['ordre'],
                        $unite['ordre']
                    );
                }
            }
        }

        $width = "620";
        if (file_exists($plan_params[$plan]["img"])) {
            $size = getimagesize($plan_params[$plan]["img"]);

            if ($size !== false) {
                $width = $size[0];
            }
        }

        return sprintf(
            $this->template_election_plan,
            $plan,
            $plan_params[$plan]["img"],
            $width,
            $election_plan_content
        );
    }

    /**
     * Affichage des plans
     *
     * @param $plan
     */
    protected function display_plan($plan) {
        if (empty($this->get_election()) || empty($plan['image_plan'])) {
            return "";
        }
        $idPlan = $plan['plan'];

        $election_plan_content = "";
        $unites = $this->get_election_unites();
        foreach ($unites as $idUnite => $unite) {
            // Si les unités associées aux plans sont également associée à l'élection
            // elles sont affichées
            if ($planUnite = $this->get_plan_unite($idPlan, $idUnite)) {
                // Récupération de l'image et de sa largeur
                $urlImage = $this->get_url_icone_unite($planUnite, $plan);
                $width = 80;
                if (! empty($planUnite['largeur_icone'])) {
                    $planUnite['largeur_icone'];
                } elseif (! empty($plan['largeur_icone'])) {
                    $plan['largeur_icone'];
                } elseif (file_exists($urlImage)) {
                    $size = getimagesize($urlImage);
                }

                if ($unite['etat'] == 1) {
                    $election_plan_content .= sprintf(
                        $this->template_election_plan_unite_arrive,
                        $planUnite['position_y'],
                        $planUnite['position_x'],
                        $width,
                        $planUnite['position_y'],
                        $planUnite['position_x'],
                        $unite['ordre'],
                        $urlImage,
                        $unite['libelle'],
                        $unite['libelle']
                    );
                } else {
                    $election_plan_content .= sprintf(
                        $this->template_election_plan_unite_non_arrive,
                        $planUnite['position_y'],
                        $planUnite['position_x'],
                        $width,
                        $planUnite['position_y'],
                        $planUnite['position_x'],
                        $urlImage,
                        $unite['libelle'],
                        $unite['libelle']
                    );
                }
            }
        }

        // Récupération de la largeur du plan
        $width = "620";
        if (file_exists($plan['image_plan']['filepath'])) {
            //
            $size = getimagesize($plan['image_plan']['filepath']);
            //
            if ($size !== false) {
                $width = $size[0];
            }
        }

        return sprintf(
            $this->template_election_plan,
            $idPlan,
            $plan['image_plan']['filepath'],
            $width = $size[0],
            $election_plan_content
        );
    }

    /**
     * Remplissage et affichage du logo
     */
    protected function display_collectivite_logo() {
        // Cas ou il n'y a pas de fichier de paramétrage. Conservé
        // pour garder la compatibilité avec l'affichage de la V1
        if (empty($this->get_collectivite_logo())) {
            return "";
        }
        return sprintf(
            $this->template_collectivite_logo,
            $this->get_collectivite_logo()
        );
    }

    /**
     * Remplissage et affichage de l'url de la collectivité
     */
    protected function display_collectivite_url() {
        // Cas ou il n'y a pas de fichier de paramétrage. Conservé
        // pour garder la compatibilité avec l'affichage de la V1
        if ($this->get_collectivite_url() == "") {
            return "";
        }
        $perso = $this->get_param_personnalisation();
        // Si un libelle a été choisi pour l'url, il est affiché. Sinon c'est le
        // nom de la collectivité défini dans les paramétres qui est utilisé.
        $title = array_key_exists('libelle_url', $perso) && ! empty($perso['libelle_url']) ?
            $perso['libelle_url'] : $this->get_collectivite_title();

        return sprintf(
            $this->template_collectivite_url,
            $this->get_collectivite_url(),
            $title
        );
    }



    /**
     * Remplissage et affichage du header html
     */
    protected function display_html_header() {
        $personnalisation = $this->get_param_personnalisation();
        $style = '';
        if (! empty($personnalisation)) {
            $style = array_key_exists('feuille_style', $personnalisation) ?
                $personnalisation['feuille_style'] : '';
        }
        printf(
            $this->template_html_header,
            $this->get_collectivite_title(),
            $style
        );
    }

    /**
     * Remplissage et affichage du header
     */
    protected function display_header() {
        $personnalisation = $this->get_param_personnalisation();
        $titre = $this->get_collectivite_title();
        if (! empty($personnalisation) && array_key_exists('entete', $personnalisation)) {
            $titre = $personnalisation['entete'];
        }

        printf(
            $this->template_header,
            $titre
        );
    }

    /**
     * Remplissage et affichage du titre de la page
     */
    protected function display_page_title($page_title, $page_subtitle = "") {
        return sprintf(
            $this->template_page_title,
            $page_title,
            $page_subtitle
        );
    }

    /**
     * Remplissage et affichage du footer
     */
    protected function display_footer() {
        printf(
            $this->template_footer
        );
    }

    /**
     * Remplissage et affichage du footer html
     */
    protected function display_html_footer() {
        $personnalisation = $this->get_param_personnalisation();
        $script = $this->get_param_jscript_stats();
        if (! empty($personnalisation) && array_key_exists('jscript_stats', $personnalisation)) {
            $script = $personnalisation['jscript_stats'];
        }

        printf(
            $this->template_html_footer,
            '<script type="text/javascript">'.
                $script.
            '</script>'
        );
    }


    /**************************************************************************
     * Définition des templates d'affichage
     */

    /**
     * Template du header du fichier html
     * 
     * @var string
     */
    protected $template_html_header = '<!DOCTYPE html>
<html lang="fr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>%s</title>
    <link href="themes/t01/css/bootstrap.min.css" rel="stylesheet">
    <link href="themes/t01/css/style.css" rel="stylesheet">
    <style>
        %s
    </style>
  </head>
  <body>';

    /**
     * Template du header de la page
     * 
     * @var string
     */
    protected $template_header = '
    <div id="wrap">
        <!-- HEADER - START -->
        <div class="navbar navbar-default" role="navigation">
            <div class="container">
              <div class="navbar-header">
                <a class="navbar-brand" href="index.php">%s</a>
              </div>
            </div>
        </div>
        <!-- HEADER - END -->';

    /**
     * Template du titre de la page
     * 
     * @var string
     */
    protected $template_page_title = '
        <!-- PAGE TITLE - START -->
        <div class="page-header">
            <h1>
                %s
                <small>%s</small>
            </h1>
        </div>
        <!-- PAGE TITLE - END -->';

    /**
     * Template de l'onglet de niveau 1
     * 
     * @var string
     */
    protected $template_onglets_niveau_1 = '
    <!-- Onglets niveau 1 - START -->
        <ul class="nav nav-tabs">
            <li %s>
                <a href="#participation" data-toggle="tab">
                    <span class="glyphicon glyphicon-dashboard"><!-- --></span> 
                    Participation
                </a>
            </li>
            <li %s>
                <a href="#resultats" data-toggle="tab">
                    <span class="glyphicon glyphicon-stats"><!-- --></span> 
                    Résultats
                </a>
            </li>
        </ul>
    <!-- Onglets niveau 1 - END -->
    ';

    /**
     * Template du footer de la page
     * 
     * @var string
     */
    protected $template_footer = '
    </div>
    <!-- FOOTER - START -->
    <div id="footer">
      <div class="container">
        <p class="text-muted credit">Généré avec <a href="http://www.openmairie.org/">openRésultat</a>.</p>
      </div>
    </div>
    <!-- FOOTER - END -->';

    /**
     * Template du footer html
     * 
     * @var string
     */
    protected $template_html_footer = '
    <!-- JavaScript -->
    <script src="themes/t01/js/jquery.min.js"></script>
    <script src="themes/t01/js/bootstrap.min.js"></script>
    <script src="themes/t01/js/script.js"></script>
    %s
  </body>
</html>';

    /**
     * Template de la modal d'affichage des résultats pour une unité
     * 
     * @var string
     */
    protected $template_election_resultats_unite_modal = '
    <div class="modal" id="myModal%s" tabindex="-1" role="dialog">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                    <h4 class="modal-title">%s</h4>
                </div>
                <div class="modal-body">
                    %s
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Fermer</button>
                </div>
            </div>
        </div>
    </div>';

    /**
     * Template de la barre de progression de l'arrivée des unités
     * 
     * @var string
     */
    protected $template_election_progress_bar = '
    <!-- progress bar - START -->
    <div class="text-center">
        %d %s sur %d
    </div>
    <div class="progress%s">
        <div class="progress-bar" style="width: %d%%;" 
             aria-valuemax="100" aria-valuemin="0" 
             aria-valuenow="%d" role="progressbar">
             &nbsp;
        </div>
    </div>
    <!-- progress bar - END -->';

    /**
     * Template d'une liste
     * 
     * @var string
     */
    protected $template_elections_liste = '
    <div class="list-group">
        %s
    </div>
    ';

    /**
     * Template d'une ligne de la liste
     * 
     * @var string
     */
    protected $template_elections_liste_ligne = '
    <a href="index.php?election=%s" class="list-group-item election-type-%s">
    <h4 class="list-group-item-heading">
        <span class="glyphicon glyphicon-chevron-right"><!-- --></span>
        %s <small>%s (%s)</small>
    </h4>
    </a>';

    /**
     * Template du logo de la collectivité
     * 
     * @var string
     */
    protected $template_collectivite_logo = '
    <img src="%s" id="logo" class="img-responsive" alt="-">';

    /**
     * Template du lien vers l'url de la collectivité
     * 
     * @var string
     */
    protected $template_collectivite_url = '
    <a href="%s">%s</a>';

    /**
     *
     */
    var $template_election_plan = '
    <div id="plan-%s" class="plan">
        <img class="plan img-responsive" src="%s" alt="-" data-originalwidth="%s" />
        %s
    </div>';

    /**
     *
     */
    var $template_election_plan_unite_arrive = '
    <span class="bureau" data-postop="%s" data-posleft="%s" data-originalwidth="%s" style="top:%spx;left:%spx;">
        <a data-toggle="modal" href="#myModal%s">
            <img class="img-responsive" src="%s"
                 alt="Résultats de l\'unité %s" title="Résultats de l\'unité %s" />
        </a>
    </span>';

    /**
     *
     */
    var $template_election_plan_unite_non_arrive = '
    <span class="bureau" data-postop="%s" data-posleft="%s" data-originalwidth="%s" style="top:%spx;left:%spx;">
        <img class="img-responsive" src="%s"
             alt="Unité %s non arrivé" title="Unité %s non arrivé" />
    </span>';

    /**
     * Template des container pour la participation et les résultats de 
     * l'élection
     * 
     * @var string
     */
    protected $template_election_container = '
    <div class="tab-content">
        <!-- Niveau 1 - Onglet 1 - Participation - START -->
        <div class="tab-pane %s" id="participation">
            %s
        </div>
        <!-- Niveau 1 - Onglet 1 - Participation - END -->
        <!-- Niveau 1 - Onglet 2 - Résultats - START -->
        <div class="tab-pane %s" id="resultats">
            %s
        </div>
        <!-- Niveau 1 - Onglet 2 - Résultats - END -->
    </div>
    ';

    /**
     * Template de la participation
     * 
     * @var string
     */
    protected $template_election_participation = '
    <table class="table table-bordered table-condensed">
        <thead>
            <tr>
                <th class="text-center">Heure</th>
                <th class="text-center">Votants</th>
                <th class="text-center">%% Inscrits</th>
            </tr>
        </thead>
        <tbody>
            %s
        </tbody>
    </table>';

    /**
     * Template d'une ligne de la participation
     * 
     * @var string
     */
    protected $template_election_participation_ligne = '
    <tr>
        <td>%s</td>
        <td class="text-right">%s</td>
        <td class="text-right">%s</td>
    </tr>';

    /**
     * Template des résultats
     * 
     * @var string
     */
    protected $template_election_resultat = '
        %s
        <!-- Onglets niveau 2 - START -->
        %s
        <!-- Onglets niveau 2 - END -->
        <!-- Container niveau 2 - START -->
        %s
        <!-- Container niveau 2 - END -->
    ';

    /**
     * Template d'une ligne des résultats
     * 
     * @var string
     */
    protected $template_election_resultat_onglets = '
    <ul class="nav nav-pills">
        <li class="active">
            <a href="#resultats-collectivite" data-toggle="tab">
                <span class="glyphicon glyphicon-home"><!-- --></span>
                Collectivité
            </a>
        </li>
        <li>
            <a href="#resultats-par-unite" data-toggle="tab">
                <span class="glyphicon glyphicon-list"><!-- --></span>
                Par unité
            </a>
        </li>
        %s
    </ul>
    ';

    /**
     * Template du conteneur des résultats
     * 
     * @var string
     */
    protected $template_election_resultat_container = '
    <div class="tab-content">
        <div class="tab-pane active" id="resultats-collectivite">
            %s
        </div>
        <div class="tab-pane" id="resultats-par-unite">
            %s
        </div>
        %s
    </div>
    ';

    /**
     * Template d'un element de liste pour les plans
     * 
     * @var string
     */
    protected $template_plans_onglets = '
    <li>
        <a href="#resultats-%s" data-toggle="tab" id="plan-%s">
            <span class="glyphicon glyphicon-map-marker"><!-- --></span>
            %s
        </a>
    </li>
    ';

    /**
     * Template du conteneur des plans
     */
    protected $template_plans_containers = '
    <div class="tab-pane" id="resultats-%s">
        %s
    </div>
    ';

    /**
     * Template de la liste des unités de l'élection
     * 
     * @var string
     */
    protected $template_election_unites_liste = '
    <div class="list-group">
    %s
    </div>';

    /**
     * Template d'une unité, de la liste, qui est arrivée
     * 
     * @var string
     */
    protected $template_election_unites_liste_ligne_arrive = '
    <a data-toggle="modal" href="#myModal%s" class="list-group-item">
        <span class="label label-success pull-right"><span class="glyphicon glyphicon-ok"><!-- --></span></span>
        %s
    </a>';

    /**
     * Template d'une unité, de la liste, qui n'est pas arrivée
     *
     * @var string
     */
    protected $template_election_unites_liste_ligne_non_arrive = '
    <p class="list-group-item disabled elem-%s">
        <span class="badge"><span class="glyphicon glyphicon-time"><!-- --></span></span>
        %s
    </p>';

    /**************************************************************************
     * Méthodes utilitaires
     */

    /**
     * Récupère le type de l'élection à partir de son id. Utilise le code
     * de l'élection pour récupère le libellé du type.
     * 
     * @param $election = null identifiant de l'élection
     * @return $correspondance[$code] : libellé du type ou null si pas de correspondance
     * avec les code référencés
     */
    protected function get_election_type_from_id($election = null) {
        // codes référencés
        $correspondance = array(
            "PRE" => "Présidentielle",
            "REG" => "Régionales",
            "CAN" => "Cantonales",
            "MUN" => "Municipales",
            "LEG" => "Législatives",
            "EUR" => "Européennes",
            "REF" => "Référendum",
            "DEP" => "Départementales",
        );
        //
        $code = substr($election, 0, 3);
        if (isset($correspondance[$code])) {
            return $correspondance[$code];
        } else {
            return null;
        }
    }

    /**
     * Normalise un libellé
     * 
     * @param $libelle_to_normalize libellé à normaliser
     * @return $libelle_to_normalize libellé normalisé
     */
    protected function normalize_libelle($libelle_to_normalize = "") {
        //
        $libelle_to_normalize = Encoding::toUTF8($libelle_to_normalize);
        //
        $libelle_to_normalize = preg_replace("/&eacute;/", "é", $libelle_to_normalize);
        $libelle_to_normalize = preg_replace("/&egrave;/", "è", $libelle_to_normalize);
        //
        $libelle_to_normalize = preg_replace("/  /", " ", $libelle_to_normalize);
        $libelle_to_normalize = preg_replace("/  /", " ", $libelle_to_normalize);
        $libelle_to_normalize = preg_replace("/  /", " ", $libelle_to_normalize);
        $libelle_to_normalize = preg_replace("/  /", " ", $libelle_to_normalize);
        $libelle_to_normalize = preg_replace("/  /", " ", $libelle_to_normalize);
        //
        return $libelle_to_normalize;
    }

    /**
     * Donne à une date le format "d/m/Y"
     * 
     * @param $date la date à transformer
     * @param $format = "d/m/Y" Le format à donner
     * 
     * @return DateTime date au format souhaité
     */
    protected function formatdate($date, $format = "d/m/Y") {
        $date = new DateTime($date);
        return $date->format($format);
    }

    /**
     * Cette méthode permet de retourner le tour de l'élection en question
     * en fonction de son identifiant d'élection. Si l'identifiant n'est pas 
     * formé correctement alors la méthode renverra 0.
     * 
     * @param integer $election identifiant de l'élection
     * @return integer numero du tour : 1, 2 ou 0 si autre
     */
    protected function which_tour($election) {
        // Si l'élection est un premier tour
        if (preg_match("@([A-Za-z0-9]{3,5})-1([C-D]{0,1})@", $election)) {
            return 1;
        }
        // Si l'élection est un second tour
        if (preg_match("@([A-Za-z0-9]{3,5})-2([C-D]{0,1})@", $election)) {
            return 2;
        }
        // Sinon on retourne 0
        return 0;
    }

    /**
     * Cette méthode permet de retourner le numéro de simulation si l'élection
     * en question en est une en fonction de son identifiant d'élection.
     * 
     * @param integer $election identifiant de l'élection
     * @return integer le numero de simulation, 1 : 1ere simulation, 2 : 2ème
     * et 0 : pas une simulation
     */
    protected function is_centaine($election) {
        // Si l'élection est une seconde simulation 
        if (preg_match("@([A-Za-z0-9]{3,5})-([0-9]{1})D@", $election)) {
            return 2;
        }
        // Si l'élection est une premiere simulation 
        if (preg_match("@([A-Za-z0-9]{3,5})-([0-9]{1})C@", $election)) {
            return 1;
        }
        // Sinon on retourne 0
        return 0;
    }

    protected function display_template_page_erreur($titre, $description = '') {
        // Récupération du thème de la page
        $theme = 't01';
        if (isset($_GET['theme']) && $_GET['theme'] !== null && $_GET['theme'] !== '') {
            $theme = $_GET['theme'];
        }
        printf(
            '%1$s
                <div id="affichage_container">
                    <div id="affichage_text">
                        <h1>%2$s</h1>
                        <p>%3$s</p>
                    </div>
                    <img src="themes/%4$s/fonts/erreur-urne.svg" alt="">
                </div>
            </body>',
            sprintf($this->template_html_header, '', $theme, ''),
            $titre,
            $description,
            $theme
        );
    }
}
