//
// Scripts JS pour éditer les topos, toutes pratiques. Ne concerne que l'édition
// du topo proprement dit, pas des contributions au topo (commentaires, relevés, photos, etc.).
// 
// Dépendances:  'js/evo.js', 'js/topo.js', 'js/json2.js', JQuery.
//

var eip = {
    mode_edition: false,
    formulaire_en_cours: {id: undefined},
    donnees_pour_edition: undefined
};

function surlignerPendantSurvol()
{
    $(this).addClass('surlignage_eip');
}

function desurlignerPendantSurvol()
{
    $(this).removeClass('surlignage_eip');
}

function annulerFormulaireEip(id_elt_edite, id_formulaire, type_donnee, contexte_formulaire)
{
    // Vérifie que l'utilisateur ne perdra rien par erreur:
    var perte_donnees_possible = false;
    var donnees_saisies = donneesSaisies(type_donnee);
    
    switch (type_donnee)
    {
        case 'texte':
            console.debug('annulerFormulaireEip() - contenu_champ = <' + donnees_saisies.texte + '>');
            console.debug('annulerFormulaireEip() - contenu_initial = <' + contexte_formulaire.donnees_initiales.texte + '>');
            if (donnees_saisies.texte != contexte_formulaire.rendu_initial)
                perte_donnees_possible = true;
            break;
        case 'texte_multiligne':
            console.debug('annulerFormulaireEip() - contenu_champ = <' + donnees_saisies.texte + '>');
            console.debug('annulerFormulaireEip() - contenu_initial = <' + contexte_formulaire.donnees_initiales.texte + '>');
            if (donnees_saisies.texte != contexte_formulaire.rendu_initial
                && !(donnees_saisies.texte.length == 0 && contexte_formulaire.rendu_initial == '&nbsp;')) // Un champ initialement vide contient '&nbsp;'.
                perte_donnees_possible = true;
            break;
        case 'nom_site':
            console.debug('TODO: implémenter vérif perte de données avant annulation pour type de donnée "' + type_donnee + '").');
            break;
        case 'nom_riviere':
            console.debug('annulerFormulaireEip() - données saisies = ', donnees_saisies);
            if (donnees_saisies.nom_site != contexte_formulaire.donnees_initiales.nom_site
                || donnees_saisies.article_nom_site != contexte_formulaire.donnees_initiales.article_nom_site)
                perte_donnees_possible = true;
            break;
        case 'localisation_geo':
            console.debug('TODO: implémenter vérif perte de données avant annulation pour type de donnée "' + type_donnee + '").');
            break;
        default:
            throw('Type de donnée à éditer non supporté (' + type_donnee + ').');
    }

    if (perte_donnees_possible)
    {
        if (!confirm('Les modifications effectuées dans ce formulaire seront perdues.\n\nConfirmez-vous l\'annulation ?'))
            return;
    }

    // Annule l'édition en cours:
    $('#' + id_formulaire).remove();
    $('#' + id_elt_edite).show();
    eip.formulaire_en_cours.id = undefined;
}

//
// Retourne les données du formulaire.
//
function donneesSaisies(type_donnee)
{
    var donnees_saisies = {};
    switch (type_donnee)
    {
        case 'texte':
            var ligne_saisie = $.trim($('#champ_texte_eip').val());
            donnees_saisies.texte = ligne_saisie;
            break;
        case 'texte_multiligne':
            var texte_saisi = $.trim($('#champ_texte_eip').val());
            donnees_saisies.texte = texte_saisi;
            break;
        case 'nom_site':
            var nom_site_saisi = $.trim($('#champ_texte_eip').val());
            donnees_saisies.nom_site = nom_site_saisi;
            break;
        case 'nom_riviere':
            var nom_riviere_saisi = $.trim($('#champ_texte_eip').val());
            donnees_saisies.nom_site = nom_riviere_saisi;
            var article_saisi = $('#champ_article_eip').val();
            donnees_saisies.article_nom_site = article_saisi;
            break;
        case 'localisation_geo':
            var i = 0;
            var ids_zones_geo = [];
            $('#selecteur_pays option:selected').each(function () {if ($(this).attr('value') != 0) ids_zones_geo[i++] = $(this).attr('value');});
            if (ids_zones_geo.length == 0)
            {
                alert('Il faut au moins renseigner le pays...');
                return null;
            }
            $('#selecteur_regions option:selected').each(function () {if ($(this).attr('value') != 0) ids_zones_geo[i++] = $(this).attr('value');});
            $('#selecteur_departements option:selected').each(function () {if ($(this).attr('value') != 0) ids_zones_geo[i++] = $(this).attr('value');});
            donnees_saisies.ids_zones_geo = ids_zones_geo;
            break;
        default:
            throw('Type de donnée à éditer non supporté (' + type_donnee + ').');
    }
    return donnees_saisies;
}

function soumettreFormulaireEip(id_elt_edite, id_formulaire, id_topo, type_topo, type_donnee, contenu_initial)
{
    /*
    console.log('soumettreFormulaireEip...');
    console.log('id_elt_edite = ' + id_elt_edite);
    console.log('id_formulaire = ' + id_formulaire);
    console.log('type_donnee = ' + type_donnee);
    */
    // Définit les paramètres de la requête de mise-à-jour :
    var donnees_saisies = donneesSaisies(type_donnee);
    if (donnees_saisies == null)
        return;
    var arguments_requete = {id_topo: id_topo,
                              type_topo: type_topo,
                              rubrique: idElementVersRubrique(id_elt_edite),
                              donnees_saisies: JSON.stringify(donnees_saisies)};

    // Envoit la requête de modification des données et actualise l'affichage:
    $.ajax({
        async: false,
        type: 'POST',
        url: 'modifierRubrique',
        data: arguments_requete,
        dataType: 'json',
        success: function(data, textStatus) {
            /*
            console.log('textStatus = ' + textStatus);
            console.log('data = ' + data);
            for (var i in data)
                console.log('data[' + i + '] = ' + data[i]);
            */
            if (textStatus != 'success') // si erreur AJAX ...
                alert('Erreur: ' + data);
            else if (data.hasOwnProperty('erreur')) // ... ou si erreur EVO:
            {
                var message_erreur = 'Erreur: ' + data.erreur;
                if (data.hasOwnProperty('message'))
                    message_erreur += ('\n\nDétails: ' + data.message);
                alert(message_erreur);
            }
            else // Résultat de requête récupéré correctement :
            {
                // Termine l'édition en cours:
                $('#' + id_formulaire).remove();
                $('#' + id_elt_edite).html('<div class="patientez_svp">Patienter SVP ...</div>');
                $('#' + id_elt_edite).show();
                eip.formulaire_en_cours.id = undefined;

                // Actualise le contenu du topo:
                actualiserContenuRubrique(id_elt_edite, id_topo, type_topo, idElementVersRubrique(id_elt_edite));
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(errorThrown);
        }
    });
}

function actualiserContenuRubrique(id_elt_edite, id_topo, type_topo, nom_rubrique)
{
    console.log('ID élt édité = ' + id_elt_edite + ', ID topo = ' + id_topo + ', type topo = ' + type_topo + ', nom rubrique = ' + nom_rubrique);

    // TODO: voir au final si on peut réduire le switch aux arguments.

    switch (nom_rubrique)
    {
        case 'localisation_geo':
            $.post(
                'renduLocalisationGeo',
                {id_topo: id_topo, type_topo: type_topo},
                function(data, textStatus) {
                    if (textStatus != 'success') // si erreur AJAX ...
                        alert('Erreur: ' + data);
                    else // Résultat de requête récupéré correctement :
                    {
                        // Termine l'édition en cours:
                        $('#' + id_elt_edite).html(data);
                        $('#' + id_elt_edite).show();
                    }
                },
                'html'
            );
            break;
        case 'nom_site':
            $.post(
                'attributTopo',
                {id_topo: id_topo, nom_attribut: nom_rubrique, type_topo: type_topo},
                function(data, textStatus) {
                    if (textStatus != 'success') // si erreur AJAX ...
                        alert('Erreur: ' + data);
                    else // Résultat de requête récupéré correctement :
                    {
                        // Termine l'édition en cours:
                        $('#' + id_elt_edite).html(data);
                        $('#' + id_elt_edite).show();
                    }
                },
                'html'
            );
            break;
        default:
            $.post(
                'renduContenuRubrique',
                {id_topo: id_topo, nom_rubrique: nom_rubrique, type_topo: type_topo},
                function(data, textStatus) {
                    /*
                    console.log('textStatus = ' + textStatus);
                    console.log('data = ' + data);
                    */
                    if (textStatus != 'success') // si erreur AJAX ...
                        alert('Erreur: ' + data);
                    else // Résultat de requête récupéré correctement :
                    {
                        // Termine l'édition en cours:
                        $('#' + id_elt_edite).html(data);
                        $('#' + id_elt_edite).show();
                    }
                },
                'html'
            );
    }
}

//
// Détermine le nom de la rubrique à partir de l'ID du bloc contenu rubrique.
// L'ID est construit avec le nom de la rubrique, éventuellement suivi de l'ID du topo.
// Ex: L'ID 'situation_geographique-15' retourne le nom de rubrique 'situation_geographique'.
//
function idElementVersRubrique(id_elt)
{
    var idx = id_elt.lastIndexOf('-');
    if (idx == -1)
        return id_elt;

    var suffixe = id_elt.substring(idx);
    if (!suffixe.search([0-9]))
        return id_elt;

    return id_elt.substring(0, idx);
}

function editerSurPlace()
{
    if (eip.formulaire_en_cours.id != undefined) // Déjà en train d'éditer une rubrique.
    {
        alert('Une rubrique est en cours d\'édition, fermez de le formulaire correspondant pour pouvoir en éditer une autre.');
        return;
    }

    console.info('Edition sur place ...');
    var id_topo = idTopoPourEip(this);
    console.debug('ID topo = ' + id_topo);
    var type_donnee = typeDonneePourEip(this);
    var type_topo = affichage_topo.type_topo_actif;
    console.debug('Type topo = ' + type_topo + ', type donnée = ' + type_donnee);
    if (type_donnee == undefined)
    {
        alert('Erreur interne: type de donnée à éditer non défini.');
        return;
    }

    // Masque le contenu de rubrique qui est éditée:
    $(this).hide();

    // Remplace la rubrique par un message pour patienter (les données à éditer sont parfois
    // récupérées sur le serveur via une requête AJAX => temps de latence) :
    var dimension_initiale = {largeur: $(this).width(), hauteur: $(this).height()};
    var id_message_patienter = 'patienter_' + new Date().getTime();
    $(this).after(htmlPourPatienterEip(id_message_patienter, dimension_initiale));

    // Récupère les données nécessaires à la création/gestion du formulaire:
    var contexte_formulaire = contexteFormulaire(this, type_donnee, id_topo, type_topo);

    // Remplace le message pour patienter (donc le contenu de la rubrique) par le formulaire d'édition:
    var id_formulaire = 'eip_' + new Date().getTime();
    var id_elt_edite = $(this).attr('id');
    var html_formulaire = htmlPourEip(id_topo, type_topo, id_formulaire, idElementVersRubrique(id_elt_edite), type_donnee, contexte_formulaire, dimension_initiale);
    //console.log('HTML formulaire = ' + html_formulaire);
    $('#' + id_message_patienter).remove();
    $(this).after(html_formulaire);
    initialiserFormulaire(type_donnee, contexte_formulaire);

    eip.formulaire_en_cours.id = id_formulaire;

    // Ajoute le traitement du formulaire:
    $('#annuler_eip').click(function() {annulerFormulaireEip(id_elt_edite, id_formulaire, type_donnee, contexte_formulaire);});
    $('#modifier_eip').click(function() {soumettreFormulaireEip(id_elt_edite, id_formulaire, id_topo, type_topo, type_donnee, contexte_formulaire);});
}

function initialiserFormulaire(type_donnee, contexte_formulaire)
{
    //console.debug('initialiserFormulaire(' + type_donnee + ').');
    switch (type_donnee)
    {
        case 'localisation_geo':
            // Ajoute la gestion des événements:
            $('#selecteur_pays').change( function() {

                $("#selecteur_regions option").remove(); 
                $("#selecteur_departements option").remove();

                //console.log('Changement de la sélection des pays.');
                var trace_pays = '';
                $('#selecteur_pays option:selected').each(function () {
                    trace_pays += $(this).text() + ' (ID = ' + $(this).attr('value') + ') ';
                    for (var p in eip.donnees_pour_edition.zones_geo)
                    {
                        var pays = eip.donnees_pour_edition.zones_geo[p];
                        if (pays.id == $(this).attr('value'))
                        {
                            //console.log('Pays dans la liste des zones: ' + pays.nom + ' (regions : ' + (pays.regions == undefined ? 'aucune' : pays.regions.length) + ').');
                            if (pays.regions.length > 0)
                                $('#selecteur_regions').append($('<option></option>').attr('value', '0').text(' ---'));
                            for (var r in pays.regions)
                            {
                                var region = pays.regions[r];
                                $('#selecteur_regions').append($('<option></option>').attr('value', region.id).text(region.nom));
                            }
                        }
                    }
                });
                //console.log(trace_pays);
            });

            $('#selecteur_regions').change( function() {

                //console.log('Changement de la sélection des régions.');
                $("#selecteur_departements option").remove(); 

                var trace_regions = '';
                $('#selecteur_regions option:selected').each(function () {
                    trace_regions += $(this).text() + ' (ID = ' + $(this).attr('value') + ') ';
                    for (var p in eip.donnees_pour_edition.zones_geo)
                    {
                        var pays = eip.donnees_pour_edition.zones_geo[p];
                        //if (pays.regions == undefined)
                        //    continue;
                        for (var r in pays.regions)
                        {
                            var region = pays.regions[r];
                            if (region.id == $(this).attr('value'))
                            {
                                //console.log('Départements dans la liste des zones: ' + region.nom + ' (départements : ' + (region.departements == undefined ? 'aucun' : region.departements.length) + ').');
                                if (region.departements.length > 0)
                                    $('#selecteur_departements').append($('<option></option>').attr('value', '0').text(' ---'));
                                for (var d in region.departements)
                                {
                                    var departement = region.departements[d];
                                    $('#selecteur_departements').append($('<option></option>').attr('value', departement.id).text(departement.nom));
                                }
                            }
                        }
                    }
                });
                //console.log(trace_regions);
            });

            // Sélectionne les zones géo du topo (pays puis région puis département, en 3 boucles
            // distinctes pour ne déclencher qu'une fois à la fin de chaque boucle l'évènement 'change'
            // qui entraîne la remise à zéro et le peuplement de la liste suivante):
            for (var i in contexte_formulaire.donnees_initiales.localisations_geo)
            {
                var pays = contexte_formulaire.donnees_initiales.localisations_geo[i].pays;
                $('#selecteur_pays option[value=' + pays.id + ']').attr('selected', 'selected');
            }
            $('#selecteur_pays').trigger('change');

            for (var j in contexte_formulaire.donnees_initiales.localisations_geo)
            {
                var region = contexte_formulaire.donnees_initiales.localisations_geo[j].region;
                if (region != undefined)
                    $('#selecteur_regions option[value=' + region.id + ']').attr('selected', 'selected');
            }
            $('#selecteur_regions').trigger('change');

            for (var k in contexte_formulaire.donnees_initiales.localisations_geo)
            {
                var dept = contexte_formulaire.donnees_initiales.localisations_geo[k].departement;
                if (dept != undefined)
                    $('#selecteur_departements option[value=' + dept.id + ']').attr('selected', 'selected');
            }
            $('#selecteur_pays').focus();
            break;
        default:
            var champ_texte = $('#champ_texte_eip');
            if (champ_texte != undefined)
                champ_texte.focus();
    }
}

function contexteFormulaire(elt_rubrique_editee, type_donnee, id_topo, type_topo)
{
    var contexte = {};

    contexte.rendu_initial = $.trim($(elt_rubrique_editee).html());

    switch (type_donnee)
    {
        case 'texte' :
        case 'texte_multiligne':
            contexte.donnees_initiales = {texte: contexte.rendu_initial};
            break;
        case 'nom_site': // TODO: récupérer les valeurs du serveur (article + nom du site).
            contexte.donnees_initiales = {nom_site: contexte.rendu_initial};
            break;
        case 'localisation_geo':
            var donnees_pour_loc = recupererDonneesPourEdition(id_topo, type_topo, 'localisation_geo');
            contexte.donnees_initiales = {localisations_geo: donnees_pour_loc.localisations_geo};
            break;
        case 'nom_riviere':
            var donnees_pour_nom_riviere = recupererDonneesPourEdition(id_topo, type_topo, type_donnee);
            contexte.donnees_initiales = donnees_pour_nom_riviere;
            break;
        default:
            throw('Type de donnée à éditer non supporté (' + type_donnee + ').');
    }

    return contexte;
}

function htmlPourPatienterEip(id_formulaire, dimension_initiale)
{
    var html = '<div id="' + id_formulaire + '" style="float: left; width:' + dimension_initiale.largeur + 'px; padding: 0 1em 0 1em; text-align: center; background-color: gold; color: darkred">\n';
    html += 'Chargement en cours ...';
    html += '</div>\n';
    return html;
}

function htmlPourEip(id_topo, type_topo, id_formulaire, rubrique, type_donnee, contexte_formulaire, dimension_initiale)
{
    //console.log(dimension_initiale);
    var margin = 7; // Pixels.
    var largeur = Math.max((type_donnee == 'localisation_geo' ? 500 : 360), dimension_initiale.largeur);
    var html = '<div class="formulaire_eip" id="' + id_formulaire + '" style="float: left; width: ' + largeur + 'px">\n';
    html += '<div style="margin:' + margin + 'px">\n';

    var aligner_avec_boutons = false;
    var html_champs;
    var texte_aide_basique;
    switch (type_donnee)
    {
        case 'texte':
            html_champs = htmlPourEipTexte(id_topo, contexte_formulaire, dimension_initiale);
            aligner_avec_boutons = true;
            break;
        case 'texte_multiligne':
            html_champs = htmlPourEipTexteMultiligne(id_topo, contexte_formulaire, dimension_initiale);
            break;
        case 'nom_site':
        case 'nom_riviere':
            var avec_article = (type_donnee == 'nom_riviere');
            html_champs = htmlPourEipNomSite(id_topo, contexte_formulaire, dimension_initiale, avec_article);
            aligner_avec_boutons = true;
            break;
        case 'localisation_geo':
            html_champs = htmlPourEipLocalisationGeo(id_topo, contexte_formulaire, dimension_initiale);
            texte_aide_basique = 'Les listes sont à choix multiple.';
            break;
        default:
            console.error('Type de champ non attendu (' + type_donnee + ').');
            return '';
    }
    var html_boutons = '<input id="annuler_eip" type="button" value="Annuler" style="margin-left: 3px">\n'
                     + '<input id="modifier_eip" type="button" value="Modifier">\n';

    if (aligner_avec_boutons)
    {
        html += html_champs;
        html += html_boutons;
    }
    else // On met les boutons en haut.
    {
        html += '<div style="padding-bottom: ' + margin + 'px; margin-bottom: 1em; border-bottom: 1px solid #dadaef; text-align: right">\n';
        html += html_boutons;
        html += '</div>\n';
        html += html_champs;
    }

    html += htmlPourAideBasique(type_topo, rubrique, texte_aide_basique);
    html += '</div>\n';
    html += '</div>\n';

    return html;
}

function htmlPourEipLocalisationGeo(id_topo, contexte_formulaire, dimension_initiale)
{
    var html = '<div>\n';

    var zones = eip.donnees_pour_edition.zones_geo;
    var zone_indeterminee = {id: 0, nom: ' ---'};
    
    // Crée la listbox des pays:
    html += '<div style="float:left">\n';
    html += '<strong>Pays:</strong><br/>\n';
    html += '<select id="selecteur_pays" multiple="multiple" size="9" style="width:120px">\n';
    html += '<option value="' + zone_indeterminee.id + '">' + zone_indeterminee.nom + '</option>\n';
    for (var p in zones)
        html += '<option value="' + zones[p].id + '">' + zones[p].nom + '</option>\n';
    html += '</select>\n';
    html += '</div>\n';

    // Crée la listbox des régions, vide:
    html += '<div style="margin-left:8px;float:left">\n';
    html += '<strong>Régions:</strong><br/>\n';
    html += '<select id="selecteur_regions" multiple="multiple" size="9" style="width:150px">\n';
    html += '<option value="' + zone_indeterminee.id + '">' + zone_indeterminee.nom + '</option>\n';
    html += '</select>\n';
    html += '</div>\n';

    // Crée la listbox des départements, vide:
    html += '<div style="margin-left:8px;float:left">\n';
    html += '<strong>Départements:</strong><br/>\n';
    html += '<select id="selecteur_departements" multiple="multiple" size="9" style="width:150px">\n';
    html += '<option value="' + zone_indeterminee.id + '">' + zone_indeterminee.nom + '</option>\n';
    html += '</select>\n';
    html += '</div>\n';

    html += '<div style="clear:both"></div>\n';

    html += '</div>\n';
    return html;
}

function htmlPourEipNomSite(id_topo, contexte_formulaire, dimension_initiale, avec_article)
{
    console.debug('eip = ', eip);
    console.debug('contexte_formulaire = ', contexte_formulaire);
    console.debug('dimension_initiale = ', dimension_initiale);

    var html = '';
    if (avec_article) {
        html = '<select id="champ_article_eip" style="display: inline; width:3.5em">\n';
        for (var i in eip.donnees_pour_edition.articles) {
            html += '<option value="' + eip.donnees_pour_edition.articles[i] + '"';
            if (contexte_formulaire.donnees_initiales.article_nom_site == eip.donnees_pour_edition.articles[i])
                html += ' selected="selected"';
            html += '>' + eip.donnees_pour_edition.articles[i] + '</option>';
        }
        html += '</select>\n';
    }

    var style = (avec_article ? 'style="width:9em"' : '');
    html += '<input id="champ_texte_eip" ' + style + ' value="' + contexte_formulaire.donnees_initiales.nom_site + '" />\n';
    return html;
}

function htmlPourEipTexteMultiligne(id_topo, contexte_formulaire, dimension_initiale)
{
    if (contexte_formulaire.donnees_initiales.texte == '&nbsp;') // Un champ initialement vide contient '&nbsp;' pour avoir une dimension physique et être cliquable.
        contexte_formulaire.donnees_initiales.texte = '';
    var hauteur = (40 + dimension_initiale.hauteur); // Pixels.
    var margin = 7; // Pixels.
    var html = '<textarea id="champ_texte_eip" style="width:' + (dimension_initiale.largeur - 4*margin) + 'px; height:' + hauteur + 'px">' + contexte_formulaire.donnees_initiales.texte + '</textarea>\n';
    return html;
}

function htmlPourEipTexte(id_topo, contexte_formulaire, dimension_initiale)
{
    if (contexte_formulaire.donnees_initiales.texte == '&nbsp;') // Un champ initialement vide contient '&nbsp;' pour avoir une dimension physique et être cliquable.
        contexte_formulaire.donnees_initiales.texte = '';
    return '<input id="champ_texte_eip" value="' + contexte_formulaire.donnees_initiales.texte + '" />\n';
}

function idTopoPourEip(elt)
{
    var id_dom = $(elt).attr('id');
    var items = id_dom.split('-');
    if (items.length < 2)
        throw('Impossible de trouver l\'ID du topo dans l\'ID DOM "' + id_dom + '".');
    var id = items[items.length - 1];
    // TODO: filtrer les formats invalides.
    return id;
}

//
// Détermine le type de donnée à éditer d'après la classe CSS du contenu de la rubrique.
//
function typeDonneePourEip(elt)
{
    var classes = $(elt).attr('class').split(' ');
    for (i in classes)
    {
        var items = classes[i].split('-');
        if (items.length == 2 && items[0] == 'eip')
            return items[1];
    }
    return undefined;
}

//
// Récupère du serveur les données nécessaires à la construction des formulaires:
// données qui ne peuvent pas être retrouvées à partir de HTML de la page courante, et données
// de contexte (options des listes, etc.).
//
// Attention: cette requête AJAX est synchrone, elle bloque le navigateur durant son exécution.
//
function recupererDonneesPourEdition(id_topo, type_topo, rubrique)
{
    var arguments_requete = {id_topo: id_topo, type_topo: type_topo};
    if (rubrique != undefined)
        arguments_requete.rubrique = rubrique;
    var donnees_pour_edition = undefined;
    $.ajax({
        async: false,
        type: "POST",
        url: 'donneesPourEdition',
        data: arguments_requete,
        dataType: 'json',
        success: function(data, textStatus) {
            /*
            console.log('textStatus = ' + textStatus);
            console.log('data = ' + data);
            for (var i in data)
                console.log('data[' + i + '] = ' + data[i]);
            */
            if (textStatus != 'success') // si erreur AJAX ...
                alert('Erreur: ' + data);
            else if (data.hasOwnProperty('erreur')) // ... ou si erreur EVO:
            {
                var message_erreur = 'Erreur: ' + data.erreur;
                if (data.hasOwnProperty('message'))
                    message_erreur += ('\n\nDétails: ' + data.message);
                alert(message_erreur);
            }
            else // Résultat de requête récupéré correctement :
            {
                //console.log('Données pour édition récupérées.');
                donnees_pour_edition = data;
                if (donnees_pour_edition.est_publie != undefined)
                    donnees_pour_edition.est_publie = (donnees_pour_edition.est_publie === 'true' ? true : false);
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(errorThrown);
        }
    });
    return donnees_pour_edition; // Nécessite que la requête soit synchrone.
}

function htmlPourAideBasique(type_topo, rubrique, texte)
{
    var html = '<div id="aide_basique_formulaire">\n';
    if (texte != undefined && texte != null && texte.length > 0)
        html += '<div style="float:left">' + texte + '</div>\n';
    html += '<div style="float:right"><a title="Afficher l\'aide de la rubrique éditée" href="javascript:;" onclick="afficherAideEip(\'' + type_topo + '\',\'' + rubrique + '\')"><span style="font-weight:bold">?</span></a></div>\n';
    html += '<div style="clear:both"></div>\n';
    html += '</div>\n';
    return html;
}

function afficherAideEip(type_topo, rubrique)
{
    // Génère le HTML conteneur de l'aide:
    var html = '<div id="aide_rubrique_formulaire" style="display:none">\n';
    html += '<div id="outils_aide_formulaire">\n';
    html += '<a onclick="$(\'#aide_rubrique_formulaire\').slideUp().remove();$(\'#aide_basique_formulaire\').show();" href="javascript:;" title="Masquer l\'aide de la rubrique éditée"><span style="font-weight:bold">X</span></a>\n';
    html += '</div>\n';
    html += '<div id="contenu_aide_edition_topo" style="color: navy; background-color: #ffffeb; padding: 0.67em; margin-top: 1em">\n';
    html += '<p class="patientez_svp" style="padding: 2em 0 2em 0">Patientez SVP...</span>\n';
    html += '</div>\n';
    html += '</div>\n';

    // Affiche le conteneur de l'aide avec un message d'attente:
    $('#aide_basique_formulaire').after(html);
    $('#aide_basique_formulaire').hide();
    $('#aide_rubrique_formulaire').slideDown();

    // Récupère (en tâche de fond) le HTML du contenu de l'aide et l'insère dans le conteneur:
    $.post(
        'renduAideRubrique',
        {type_topo: type_topo, rubrique: rubrique},
        function(data, textStatus) {
            if (textStatus != 'success') // si erreur AJAX ...
            {
                console.error('Impossible de récupérer l\'aide de la rubrique du topo.');
                console.error(data);
            }
            else // Résultat de requête récupéré correctement :
            {
                //console.debug(data);
                if (data != undefined && data.length > 0)
                    $('#contenu_aide_edition_topo').html(data);
                else
                    $('#contenu_aide_edition_topo').html('<p style="padding: 2em 0 2em 0; text-align: center">Désolé, pas d\'aide disponible pour cette rubrique.</p>');
            }
        },
        'html'
    );
}

function publierTopo(id_topo, type_topo)
{
    $.ajax({
        async: false,
        type: "POST",
        url: 'publierTopo',
        data: {id_topo: id_topo, type_topo: type_topo},
        dataType: 'json',
        success: function(data, textStatus) {
            /*
            console.debug('textStatus = ' + textStatus);
            console.debug('data = ' + data);
            */
            if (textStatus != 'success') // si erreur AJAX ...
                alert('Erreur: ' + data);
            else if (data.hasOwnProperty('erreur')) { // ... ou si erreur EVO:
                var message_erreur = 'Erreur: ' + data.erreur;
                if (data.hasOwnProperty('message'))
                    message_erreur += ('\n\nDétails: ' + data.message);
                alert(message_erreur);
            }
            else {// Résultat de requête récupéré correctement :
                console.info('Topo publié (ID = ', id_topo, ', type = ', type_topo, ').');
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(errorThrown + '\n\n' + textStatus);
        }
    });
}

function basculerEnEdition(ids_topo_editables)
{
    //console.info('Bascule en édition, ID topo = ' + affichage_topo.id_topo_actif + ', type topo = ' + affichage_topo.type_topo_actif);

    if (eip.mode_edition) {
        if (eip.formulaire_en_cours.id != undefined) { // Déjà en train d'éditer une rubrique.
            alert('Une rubrique est en cours d\'édition, fermez de le formulaire correspondant pour pouvoir sortir du mode édition du topo.');
            return;
        }
        else { // Pas de formulaire ouvert:
            if (!confirm('Voulez-vous vraiment quitter le mode édition ?'))
                return;
        }
        //console.debug('eip.donnees_pour_edition.est_publie = ', eip.donnees_pour_edition.est_publie);
        if (!eip.donnees_pour_edition.est_publie) {
            if (confirm('Le topo n\'est pas publié, il ne sera visible que de vous. Voulez-vous le rendre public maintenant ?'))
                publierTopo(affichage_topo.id_topo_actif, affichage_topo.type_topo_actif);
        }
        
        // Recharge la page, sans l'éventuel argument d'édition (si ne recharge
        // pas la page, l'éventuel argument "mode=edition" reste, et si ensuite
        // l'utilisateur ou une autre action recharge la page, on se retrouve à
        // nouveau en mode édition):
        var url_topo = document.URL;
        //console.debug('URL = ', url_topo);
        var fin = url_topo.indexOf('/mode:edition');
        if (fin != -1)
            url_topo = url_topo.substring(0, fin);
        //console.debug('URL nettoyée = ', url_topo);
        window.location = url_topo;
    }
    else { // Vérifie si l'utilisateur est autorisé à éditer.
        if (ids_topo_editables.indexOf(affichage_topo.id_topo_actif) == -1) {
            alert('Seul l\'auteur du topo ou un administrateur a le droit de modifier celui-ci. Si c\'est votre cas, vérifiez que vous êtes connecté et sur la partie que vous avez rédigée.');
            return;
        }
    }


    eip.mode_edition = !eip.mode_edition;
    //console.log('eip.mode_edition = ' + eip.mode_edition);
    //$('#' + id_lien).attr('title', (eip.mode_edition ? 'Sortir du mode édition' : 'Editer cette partie du topo'));
    //$('#' + id_lien).html(eip.mode_edition ? 'Terminer l\'édition' : 'Editer');

    var elts_editables;
    if (eip.mode_edition) // On passe en édition:
    {
        $('#header').slideUp('slow'); // Fait de la place verticalement en masquant le bandeau EVO.
        $('.bascule_edition').hide(); // Masque le bouton pour passer en mode édition puisqu'on y est maintenant.
        creerBandeauEip(true); // Place un bandeau fixe de rappel en haut de page avec le bouton pour quitter le mode édition.
        montrerRubriquesVides(true); // Des fois qu'on souhaite les renseigner.
        empecherChangementDePagePendantEip(true); // Il faudra sortir du mode édition avant.
        inhiberContribution(true);

        eip.donnees_pour_edition = recupererDonneesPourEdition(affichage_topo.id_topo_actif, affichage_topo.type_topo_actif);

        // Rend cliquables toutes les parties éditables:
        elts_editables = $('.eip');
        //console.log(elts_editables);
        elts_editables.bind('mouseover', surlignerPendantSurvol).bind('mouseout', desurlignerPendantSurvol).bind('click', editerSurPlace);

    }
    else // Plus en édition.
    {
        // Annule les manips faites pour passer en mode édition, plus ou moins dans l'ordre inverse:
        elts_editables = $('.eip');
        elts_editables.unbind('mouseover', surlignerPendantSurvol).unbind('mouseout', desurlignerPendantSurvol).unbind('click', editerSurPlace);

        inhiberContribution(false);
        empecherChangementDePagePendantEip(false);
        montrerRubriquesVides(false);
        creerBandeauEip(false);
        $('.bascule_edition').show();
        $('#header').slideDown('slow');

        eip.formulaire_en_cours.id = undefined;
        eip.donnees_pour_edition = undefined;
    }
}

function inhiberContribution(inhiber)
{
    if (inhiber)
        $('.incitation_a_contribuer').hide('slow');
    else
        $('.incitation_a_contribuer').show('slow');
}

function empecherChangementDePagePendantEip(empecher)
{
    var liens = $('a');
    liens.each(function() {
        var href = $(this).attr('href');
        //if (href == undefined) console.log('undefined: HTML = ' + $(this).html() + ', ID = ' + $(this).attr('id') + ', class = ' + $(this).attr('class'));
        if (href != 'javascript:;' && href != '#' && href != undefined)
        {
            var rel = $(this).attr('rel'); // Attribut des liens éventuellement utilisé par Lightbox (diaporama).
            if (rel == undefined || rel.substring(0, 'lightbox'.length) != 'lightbox') // Ce n'est pas un lien d'image utilisé par Lightbox (diaporama).
            {
                if (empecher)
                    $(this).bind('click', ouvrirDansNouvelleFenetre);
                else
                    $(this).unbind('click', ouvrirDansNouvelleFenetre);
            }
        }
    });
}

function ouvrirDansNouvelleFenetre()
{
    window.open(this.href, this.name);
    return false;
}

function creerBandeauEip(creer)
{
    var id_bandeau = 'bandeau_eip';
    if (creer)
    {
        var html = '<div id="' + id_bandeau + '" style="position: fixed; left:0; top:0; width:100%; height:40px; z-index:100; opacity:0.65; background-color:yellow; border-bottom: 1px solid gray; text-align: center; font-weight: bold; font-size: 175%; padding-top:10px">\n';
        html += 'Edition du topo';
        html += '<div style="position: fixed; right: 10px; top: 15px">\n';
        html += '<input type="button" value="Quitter l\'édition" onClick="basculerEnEdition()">\n';
        html += '</div>\n';
        html += '</div>\n';
        $('body').prepend(html);
    }
    else // Supprimer.
        $('#' + id_bandeau).remove();
}

function montrerRubriquesVides(montrer)
{
    if (montrer)
        $('.rubrique').show(); // Fait apparaître les rubriques vides.
    else
    {
        $('.contenu_rubrique').each(function()
            {
                var contenu = $.trim($(this).html());
                //console.log(contenu.substring(0, 20) + (contenu.length > 20 ? '...' : ''));
                if (contenu.length == 0 || contenu == '&nbsp;')
                    $(this).parent().hide();
            }
        );
    }
}

