//
// Scripts JS pour éditer les topos, toutes pratiques. Ne concerne que l'édition
// du topo proprement dit, pas les 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,
    nb_modifs: 0
};

function surlignerPendantSurvol()
{
    $(this).addClass('surlignage_eip');
}

function desurlignerPendantSurvol()
{
    $(this).removeClass('surlignage_eip');
}

function annulerFormulaireEip(id_elt_edite, id_formulaire, type_topo, 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, type_topo);
    
    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('annulerFormulaireEip() - données saisies = ', donnees_saisies);
            if ((donnees_saisies.nom_site != contexte_formulaire.donnees_initiales.nom_site)
               || (type_topo == 'riviere' && donnees_saisies.article_nom_site != contexte_formulaire.donnees_initiales.article_nom_site))
                perte_donnees_possible = true;
            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;
        case 'alternatives_navigation':
            if (donnees_saisies.alternatives_navigation.alternatives_be != contexte_formulaire.donnees_initiales.alternatives_navigation.alternatives_be
             || donnees_saisies.alternatives_navigation.alternatives_me != contexte_formulaire.donnees_initiales.alternatives_navigation.alternatives_me
             || donnees_saisies.alternatives_navigation.alternatives_he != contexte_formulaire.donnees_initiales.alternatives_navigation.alternatives_he)
                perte_donnees_possible = true;
            break;
        case 'cotation':
            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 'longueur':
            console.debug('annulerFormulaireEip() - donnees_saisies.longueur = <', donnees_saisies.longueur, '>');
            console.debug('annulerFormulaireEip() - contexte_formulaire.longueur = <', contexte_formulaire.donnees_initiales.longueur, '>');
            if (donnees_saisies.longueur.valeur != contexte_formulaire.donnees_initiales.longueur.valeur
             || donnees_saisies.longueur.commentaire != contexte_formulaire.donnees_initiales.longueur.commentaire)
                perte_donnees_possible = true;
            break;
        default:
            throw('Type de donnée à éditer non supporté (' + type_donnee + ') pour l\'annulation.');
    }

    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, type_topo)
{
    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;
            if (type_topo == 'riviere') {
                var article_saisi = $('#champ_article_eip').val();
                donnees_saisies.article_nom_site = article_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;
        case 'alternatives_navigation':
            var alternatives_he = $.trim($('#champ_alternatives_he_eip').val());
            var alternatives_me = $.trim($('#champ_alternatives_me_eip').val());
            var alternatives_be = $.trim($('#champ_alternatives_be_eip').val());
            donnees_saisies.alternatives_navigation = {alternatives_he: alternatives_he,
                                                       alternatives_me: alternatives_me,
                                                       alternatives_be: alternatives_be};
            break;
        case 'cotation':
            var cotation_saisie = $.trim($('#champ_texte_eip').val());
            donnees_saisies.texte = cotation_saisie;
            break;
        case 'longueur':
            var longueur_saisie = $.trim($('#champ_longueur_eip').val());
            var commentaire_longueur_saisi = $.trim($('#champ_commentaire_longueur_eip').val());
            donnees_saisies.longueur = {valeur: longueur_saisie, commentaire: commentaire_longueur_saisi};
            break;
        default:
            throw('Type de donnée à éditer non supporté (' + type_donnee + ') pour les données saisies.');
    }
    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, type_topo);
    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) {
            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;
                eip.nb_modifs++;

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

    var arguments = {id_topo: id_topo, type_topo: type_topo};
    var url = null;
    switch (nom_rubrique) {
        case 'localisation_geo':
            url = 'renduLocalisationGeo';
            break;
        case 'nom_site':
            url = 'attributTopo';
            arguments.nom_attribut = nom_rubrique;
            break;
        case 'longueur':
            url = 'renduLongueur';
            break;
        default:
            url = 'renduContenuRubrique';
            arguments.nom_rubrique = nom_rubrique;
    }
    /*///
    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:
                        console.debug($('#' + id_elt_edite));
                        $('#' + 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) {
                    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'
            );
    }
    */
    $.post(
        url,
        arguments,
        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:
                var html = data;
                if (nom_rubrique == 'nom_site' && html.length == 0)
                    html = '&nbsp;';
                $('#' + id_elt_edite).html(html);
                //$('#' + 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()
{
    // Vérifie qu'on n'est pas déjà en train d'éditer une rubrique:
    if (eip.formulaire_en_cours.id != undefined) { 
        alert('Une rubrique est en cours d\'édition, fermez de le formulaire correspondant pour pouvoir en éditer une autre.');
        return;
    }

    // Vérifie si l'utilisateur est autorisé à éditer:
    if (eip.ids_topo_editables.indexOf(affichage_topo.id_topo_actif) == -1) {
        alert("Désolé, vous n'êtes pas l'auteur de cette partie du topo et n'avez pas le droit de l'éditer. Voyez avec l'auteur ou un administrateur si nécessaire.");
        return;
    }

    console.info('Edition sur place ...');
    var id_elt_edite = $(this).attr('id');
    var info_topo = idElementVersInfoTopo(id_elt_edite);
    console.debug('Info topo (via l\'ID DOM) = ', info_topo);
    var id_topo = info_topo.id_topo;
    //var id_topo = idTopoPourEip(this);
    var type_topo = info_topo.type_topo;
    //var type_topo = affichage_topo.type_topo_actif;
    var type_donnee = typeDonneePourEip(this);
    console.debug('Type topo = ' + type_topo + ', type donnée = ' + type_donnee);
    if (type_donnee == undefined) {
        alert('Type de donnée à éditer non défini.');
        return;
    }

    // Filtre la rubrique commentaires du descriptif rivière, elle est obsolète
    // (mais présente parce que sont contenu n'a pas été migré):
    //console.debug('ID rubrique = ', id_elt_edite);
    if (id_elt_edite.indexOf('commentaires-', 0) != -1) {
        alert('Cette rubrique est obsolète. Pour ajouter un commentaire, quittez le mode édition et cliquez sur le lien "Contribuez !".');
        return;
    }

    // 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));
    faitPatienter(true, 'Patientez SVP ...');

    // 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 l'élément édité par le formulaire d'édition:
    var id_formulaire = 'eip_' + new Date().getTime();
    var html_formulaire = htmlPourEip(id_topo, type_topo, id_formulaire, idElementVersRubrique(id_elt_edite), type_donnee, contexte_formulaire, dimension_initiale);
    $(this).hide(); // Masque le contenu de rubrique qui est éditée.
    //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_topo, type_donnee, contexte_formulaire);});
    $('#modifier_eip').click(function() {soumettreFormulaireEip(id_elt_edite, id_formulaire, id_topo, type_topo, type_donnee, contexte_formulaire);});
    faitPatienter(false);
}

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 = 0; p < eip.donnees_pour_edition.zones_geo.length; p++) {
                        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 = 0; r < pays.regions.length; r++) {
                                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 = 0; p < eip.donnees_pour_edition.zones_geo.length; p++) {
                        var pays = eip.donnees_pour_edition.zones_geo[p];
                        //if (pays.regions == undefined)
                        //    continue;
                        for (var r = 0; r < pays.regions.length; r++) {
                            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 = 0; d < region.departements.length; d++) {
                                    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 = 0; i < contexte_formulaire.donnees_initiales.localisations_geo.length; i++) {
                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 = 0; j < contexte_formulaire.donnees_initiales.localisations_geo.length; j++) {
                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 = 0; k < contexte_formulaire.donnees_initiales.localisations_geo.length; k++) {
                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':
            var donnees_pour_nom_site = recupererDonneesPourEdition(id_topo, type_topo, 'nom_site');
            contexte.donnees_initiales = donnees_pour_nom_site;
            break;
            ///contexte.donnees_initiales = {nom_site: contexte.rendu_initial};
            break;
        /*///
        case 'nom_riviere':
            var donnees_pour_nom_riviere = recupererDonneesPourEdition(id_topo, 'riviere', 'nom_riviere');
            contexte.donnees_initiales = donnees_pour_nom_riviere;
            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 'alternatives_navigation':
            var donnees_pour_alternatives = recupererDonneesPourEdition(id_topo, type_topo, 'alternatives_navigation');
            contexte.donnees_initiales = {alternatives_navigation: donnees_pour_alternatives};
            break;
        case 'cotation' :
            contexte.donnees_initiales = {texte: contexte.rendu_initial};
            break;
        case 'longueur' :
            var donnees_pour_longueur = recupererDonneesPourEdition(id_topo, type_topo, 'longueur');
            contexte.donnees_initiales = {longueur: donnees_pour_longueur};
            break;
        default:
            throw('Type de donnée à éditer non supporté (' + type_donnee + ') pour le contexte formulaire.');
    }

    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.debug(dimension_initiale);
    
    var aligner_avec_boutons = false;
    var html_champs;
    var texte_aide_basique;
    var complement_style = '';
    switch (type_donnee)
    {
        case 'texte':
            html_champs = htmlPourEipTexte(id_topo, contexte_formulaire, dimension_initiale);
            aligner_avec_boutons = true;
            complement_style = 'float:left';
            break;
        case 'texte_multiligne':
            html_champs = htmlPourEipTexteMultiligne(id_topo, contexte_formulaire, dimension_initiale);
            complement_style = 'float:left';
            break;
        case 'nom_site':
        ///case 'nom_riviere':
            var avec_article = (type_topo == 'riviere');
            ///var avec_article = (type_donnee == 'nom_riviere');
            html_champs = htmlPourEipNomSite(id_topo, contexte_formulaire, dimension_initiale, avec_article);
            aligner_avec_boutons = true;
            complement_style = 'float:left';
            break;
        case 'localisation_geo':
            html_champs = htmlPourEipLocalisationGeo(id_topo, contexte_formulaire, dimension_initiale);
            texte_aide_basique = 'Les listes sont à choix multiple.';
            complement_style = 'float:left';
            break;
        case 'alternatives_navigation':
            html_champs = htmlPourEipAlternativesNavigation(contexte_formulaire, dimension_initiale);
            complement_style = 'float:left';
            break;
        case 'cotation':
            html_champs = htmlPourEipTexte(id_topo, contexte_formulaire, dimension_initiale);
            texte_aide_basique = 'Difficulté et engagement, pas de blabla.';
            aligner_avec_boutons = true;
            complement_style = 'float:left';
            break;
        case 'longueur':
            html_champs = htmlPourEipLongueur(contexte_formulaire, dimension_initiale);
            complement_style = 'float:left';
            break;
        default:
            console.error('Type de champ non attendu (' + type_donnee + ').');
            return '';
    }

    var margin = 7; // Pixels.
    var largeur = Math.max((type_donnee == 'localisation_geo' ? 500 : 360), dimension_initiale.largeur);
    var style = 'width:' + largeur + 'px;' + complement_style;
    var html = '<div class="formulaire_eip" id="' + id_formulaire + '" style="'+ style + '">\n';
    html += '<div style="margin:' + margin + 'px">\n';

    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 htmlPourEipAlternativesNavigation(contexte_formulaire, dimension_initiale)
{
    var html = '<div>\n';

    var blocs_alternative = [
        {intitule: 'Alternatives de navigation basse',
         id: 'champ_alternatives_be_eip',
         valeur: contexte_formulaire.donnees_initiales.alternatives_navigation.alternatives_be},
        {intitule: 'Alternatives de navigation moyenne',
         id: 'champ_alternatives_me_eip',
         valeur: contexte_formulaire.donnees_initiales.alternatives_navigation.alternatives_me},
        {intitule: 'Alternatives de navigation haute',
         id: 'champ_alternatives_he_eip',
         valeur: contexte_formulaire.donnees_initiales.alternatives_navigation.alternatives_he}
    ];

    var hauteur_champ = "4em";
    var largeur_champ =  Math.round(0.9*(dimension_initiale.largeur)) + "px";
    for (var i = 0; i < blocs_alternative.length; i++) {
        html += '<div style="margin-bottom: 0.75em">\n';
        html += '<span style="display: block">' + blocs_alternative[i].intitule + ':</span>\n';
        html += '<textarea id="' + blocs_alternative[i].id + '"'
              + '" style="width:' + largeur_champ + '; height:' + hauteur_champ + '">'
              + blocs_alternative[i].valeur
              + '</textarea>\n';
        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 = 0; p < zones.length; p++)
        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 htmlPourEipLongueur(contexte_formulaire, dimension_initiale)
{
    console.debug('eip = ', eip);
    console.debug('contexte_formulaire = ', contexte_formulaire);
    console.debug('dimension_initiale = ', dimension_initiale);

    var html = '';
    html += '<strong>Distance :</strong><br/>\n';
    html += '<input id="champ_longueur_eip" maxlength="6" style="width:5em" value="' + contexte_formulaire.donnees_initiales.longueur.valeur + '" /> km\n';
    html += '<br/><br/>\n';
    html += '<strong>Commentaire (aucun si possible) :</strong><br/>\n';
    html += '<input id="champ_commentaire_longueur_eip" style="width:23em"'
          + ' value="' + contexte_formulaire.donnees_initiales.longueur.commentaire + '" />\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 = 0; i < eip.donnees_pour_edition.articles.length; i++) {
            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';
}

/*
 * Trouve l'ID et le type du topo à partir de l'ID DOM de l'élement.
 * L'ID DOM doit être de la forme "<nom de rubrique>-<type de topo>_<id>".
 * C'est le dernier tiret qui est considéré comme le séparateur entre nom de
 * rubrique et type de topo/ID. Le type de topo ne doit pas contenir d'underscore.
 * Par ex: "nom_site-riviere:371" => topo de rivière d'ID 371.
 *         "cotation-parcours:23" => topo de spot d'ID 23.
 */
function idElementVersInfoTopo(id_elt)
{
    var items = id_elt.split('-');
    if (items.length < 2)
        throw('Impossible de trouver l\'ID du topo dans l\'ID DOM "' + id_elt + '".');
    
    var identification = items[items.length - 1]; // Par ex. "riviere:275" ou "spot:31".
    var items_identification = identification.split('_');
    if (items_identification.length < 2)
        throw('Impossible de trouver l\'ID du topo dans l\'ID DOM "' + id_elt + '".');

    var type_topo = items_identification[0]; // TODO: filtrer les formats invalides.
    var id_topo = items_identification[1]; // TODO: filtrer les formats invalides.
    var rubrique = idElementVersRubrique(id_elt);

    return {id_topo: id_topo, type_topo: type_topo, rubrique: rubrique};
}

/*///
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) {
            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)
{
    var resultat = {};
    $.ajax({
        async: false,
        type: "POST",
        url: 'publierTopo',
        data: {id_topo: id_topo, type_topo: type_topo},
        dataType: 'json',
        success: function(data, textStatus) {
            console.debug('-> publierTopo() - textStatus = ' + textStatus);
            console.debug('-> publierTopo() - data = ' + data);

            if (textStatus == 'success')
                resultat = data;
            else { // Erreur AJAX :
                resultat.statut = 'erreur';
                resultat.message = data;
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            resultat.statut = 'erreur';
            resultat.message = errorThrown + '\n\n' + textStatus;
        }
    });
    return resultat;
}

function supprimerTopo(id_topo, type_topo)
{
    var resultat = {};
    $.ajax({
        async: false,
        type: 'post',
        url: 'supprimerTopo',
        data: {id_topo: id_topo, type_topo: type_topo},
        dataType: 'json',
        success: function(data, textStatus) {
            console.debug('-> supprimerTopo() - textStatus = ' + textStatus);
            console.debug('-> supprimerTopo() - data = ' + data);

            if (textStatus == 'success')
                resultat = data;
            else { // Erreur AJAX :
                resultat.statut = 'erreur';
                resultat.message = data;
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            resultat.statut = 'erreur';
            resultat.message = errorThrown + '\n\n' + textStatus;
        }
    });
    return resultat;
}

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 ?')) {
                var rc = publierTopo(affichage_topo.id_topo_actif, affichage_topo.type_topo_actif);
                if (rc.statut == 'ok')
                    alert(rc.message);
                else
                    alert('Erreur: ' + rc.message + (rc.details == undefined ? '' : ('\n\n' + rc.details)));
            }
        }
        
        // Recharge la page, sans l'éventuel argument d'édition (si on 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 { // Pas en édition.
        // 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:
    {
        eip.ids_topo_editables = ids_topo_editables;
        eip.nb_modifs = 0;
        $('#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.
        montrerBrouillons(true); // Parties non publiées (présente dans le document mais non visibles).
        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);
        montrerBrouillons(false);
        creerBandeauEip(false);
        if (affichage_topo.type_topo_actif != null)
            $('.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 montrerBrouillons(montrer)
{
    if (montrer)
        $('.brouillon').show();
    else
        $('.brouillon').hide();
}

function montrerRubriquesVides(montrer)
{
    if (montrer) {
        //$('.attribut_parcours').show(); // Fait apparaître les attributs non renseignés (par ex. le nom du parcours).
        $('.rubrique, .attribut_parcours').show(); // Fait apparaître les rubriques vides.
    }
    else {
        $('.contenu_rubrique, .info_parcours').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();
            }
        );
    }
}

var contributions = {
    publierTopo : function(id_topo, type_topo, id_lien_publier, id_lien_supprimer, id_ligne)
    {
        if (!confirm('Etes-vous sûr de vouloir publier ce topo ?'))
            return;

        var rc = publierTopo(id_topo, type_topo);
        if (rc.statut == 'ok') {
            alert(rc.message + (rc.details == undefined ? '' : ('\n\n' + rc.details)));
            $('#' + id_ligne).children('.etat-topo').html('publié');
            $('#' + id_lien_publier).html('&nbsp;');
            $('#' + id_lien_supprimer).html('&nbsp;');
        }
        else {
            alert('Erreur: ' + rc.message + (rc.details == undefined ? '' : ('\n\n' + rc.details)));
        }
    },
    supprimerTopo : function(id_topo, type_topo, id_elt_topo)
    {
        if (!confirm('Etes-vous sûr de vouloir supprimer ce topo ?'))
            return;

        var rc = supprimerTopo(id_topo, type_topo);
        if (rc.statut == 'ok') {
            alert(rc.message + (rc.details == undefined ? '' : ('\n\n' + rc.details)));
            console.debug('Suppression DOM ID ' + id_elt_topo + ' à suivre.')
            $('#' + id_elt_topo).remove();
        }
        else {
            alert('Erreur: ' + rc.message + (rc.details == undefined ? '' : ('\n\n' + rc.details)));
        }
    }
};


