# -*- mode: python -*-
# -*- coding: utf-8 -*-

##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2024 Emmanuel Viennet.  All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#   Emmanuel Viennet      emmanuel.viennet@viennet.net
#
##############################################################################

"""ScoDoc fiche_etud

   Fiche description d'un étudiant et de son parcours

"""
from flask import url_for, g, render_template, request
from flask_login import current_user
import sqlalchemy as sa

from app import log
from app.auth.models import User
from app.but import cursus_but, validations_view
from app.models import Adresse, EtudAnnotation, FormSemestre, Identite, ScoDocSiteConfig
from app.scodoc import (
    codes_cursus,
    html_sco_header,
    htmlutils,
    sco_archives_etud,
    sco_bac,
    sco_cursus,
    sco_etud,
    sco_groups,
    sco_permissions_check,
    sco_report,
)
from app.scodoc.html_sidebar import retreive_formsemestre_from_request
from app.scodoc.sco_bulletins import etud_descr_situation_semestre
from app.scodoc.sco_exceptions import ScoValueError
from app.scodoc.sco_formsemestre_validation import formsemestre_recap_parcours_table
from app.scodoc.sco_permissions import Permission
import app.scodoc.sco_utils as scu


def _menu_scolarite(
    authuser, formsemestre: FormSemestre, etudid: int, etat_inscription: str
):
    """HTML pour menu "scolarite" pour un etudiant dans un semestre.
    Le contenu du menu depend des droits de l'utilisateur et de l'état de l'étudiant.
    """
    locked = not formsemestre.etat
    if locked:
        lockicon = scu.icontag("lock32_img", title="verrouillé", border="0")
        return lockicon  # no menu
    if not authuser.has_permission(
        Permission.EtudInscrit
    ) and not authuser.has_permission(Permission.EtudChangeGroups):
        return ""  # no menu

    args = {"etudid": etudid, "formsemestre_id": formsemestre.id}

    if etat_inscription != scu.DEMISSION:
        dem_title = "Démission"
        dem_url = "scolar.form_dem"
    else:
        dem_title = "Annuler la démission"
        dem_url = "scolar.do_cancel_dem"

    # Note: seul un etudiant inscrit (I) peut devenir défaillant.
    if etat_inscription != codes_cursus.DEF:
        def_title = "Déclarer défaillance"
        def_url = "scolar.form_def"
    elif etat_inscription == codes_cursus.DEF:
        def_title = "Annuler la défaillance"
        def_url = "scolar.do_cancel_def"
    def_enabled = (
        (etat_inscription != scu.DEMISSION)
        and authuser.has_permission(Permission.EtudInscrit)
        and not locked
    )
    items = [
        {
            "title": dem_title,
            "endpoint": dem_url,
            "args": args,
            "enabled": authuser.has_permission(Permission.EtudInscrit) and not locked,
        },
        {
            "title": "Validation du semestre (jury)",
            "endpoint": "notes.formsemestre_validation_etud_form",
            "args": args,
            "enabled": authuser.has_permission(Permission.EtudInscrit) and not locked,
        },
        {
            "title": def_title,
            "endpoint": def_url,
            "args": args,
            "enabled": def_enabled,
        },
        {
            "title": "Inscrire à un module optionnel (ou au sport)",
            "endpoint": "notes.formsemestre_inscription_option",
            "args": args,
            "enabled": authuser.has_permission(Permission.EtudInscrit) and not locked,
        },
        {
            "title": "Désinscrire (en cas d'erreur)",
            "endpoint": "notes.formsemestre_desinscription",
            "args": args,
            "enabled": authuser.has_permission(Permission.EtudInscrit) and not locked,
        },
        {
            "title": "Gérer les validations d'UEs antérieures",
            "endpoint": "notes.formsemestre_validate_previous_ue",
            "args": args,
            "enabled": formsemestre.can_edit_jury(),
        },
        {
            "title": "Inscrire à un autre semestre",
            "endpoint": "notes.formsemestre_inscription_with_modules_form",
            "args": {"etudid": etudid},
            "enabled": authuser.has_permission(Permission.EtudInscrit),
        },
        {
            "title": "Enregistrer un semestre effectué ailleurs",
            "endpoint": "notes.formsemestre_ext_create_form",
            "args": args,
            "enabled": authuser.has_permission(Permission.EditFormSemestre),
        },
        {
            "title": "Affecter les notes manquantes",
            "endpoint": "notes.formsemestre_note_etuds_sans_notes",
            "args": args,
            "enabled": authuser.has_permission(Permission.EditAllNotes),
        },
    ]

    return htmlutils.make_menu(
        "Scolarité", items, css_class="direction_etud", alone=True
    )


def fiche_etud(etudid=None):
    "fiche d'informations sur un etudiant"
    restrict_etud_data = not current_user.has_permission(Permission.ViewEtudData)
    try:
        etud = Identite.get_etud(etudid)
    except Exception as exc:
        log(f"fiche_etud: etudid={etudid!r} request.args={request.args!r}")
        raise ScoValueError("Étudiant inexistant !") from exc
    # la sidebar est differente s'il y a ou pas un etudid
    # voir html_sidebar.sidebar()
    g.etudid = etudid
    info = etud.to_dict_scodoc7(restrict=restrict_etud_data)
    if etud.prenom_etat_civil:
        info["etat_civil"] = (
            "<h3>Etat-civil: "
            + etud.civilite_etat_civil_str
            + " "
            + etud.prenom_etat_civil
            + " "
            + etud.nom
            + "</h3>"
        )
    else:
        info["etat_civil"] = ""
    info["ScoURL"] = scu.ScoURL()
    info["authuser"] = current_user
    if restrict_etud_data:
        info["info_naissance"] = ""
        adresse = None
    else:
        info["info_naissance"] = info["date_naissance"]
        if info["lieu_naissance"]:
            info["info_naissance"] += " à " + info["lieu_naissance"]
        if info["dept_naissance"]:
            info["info_naissance"] += f" ({info['dept_naissance']})"
        adresse = etud.adresses.first()
    info.update(_format_adresse(adresse))

    info.update(etud.inscription_descr())
    info["etudfoto"] = etud.photo_html()

    # Champ dépendant des permissions:
    if current_user.has_permission(
        Permission.EtudChangeAdr
    ) and current_user.has_permission(Permission.ViewEtudData):
        info[
            "modifadresse"
        ] = f"""<a class="stdlink" href="{
                url_for("scolar.form_change_coordonnees",
                    scodoc_dept=g.scodoc_dept, etudid=etudid)
            }">modifier adresse</a>"""
    else:
        info["modifadresse"] = ""

    # Groupes:
    inscription_courante = etud.inscription_courante()
    sco_groups.etud_add_group_infos(
        info,
        inscription_courante.formsemestre.id if inscription_courante else None,
        only_to_show=True,
    )
    # Parcours de l'étudiant
    last_formsemestre = None
    inscriptions = etud.inscriptions()
    info["last_formsemestre_id"] = (
        inscriptions[0].formsemestre.id if inscriptions else ""
    )

    sem_info = {}
    for inscription in inscriptions:
        formsemestre = inscription.formsemestre
        if inscription.etat != scu.INSCRIT:
            descr, _ = etud_descr_situation_semestre(
                etudid,
                formsemestre,
                etud.e,
                show_date_inscr=False,
            )
            grlink = f"""<span class="fontred">{descr["situation"]}</span>"""
        else:
            e = {"etudid": etudid}
            sco_groups.etud_add_group_infos(e, formsemestre.id, only_to_show=True)

            grlinks = []
            for partition in e["partitions"].values():
                if partition["partition_name"]:
                    gr_name = partition["group_name"]
                else:
                    gr_name = "tous"

                grlinks.append(
                    f"""<a class="discretelink" href="{
                    url_for('scolar.groups_view',
                    scodoc_dept=g.scodoc_dept, group_ids=partition['group_id'])
                }" title="Liste du groupe {gr_name}">{gr_name}</a>
                """
                )
            grlink = ", ".join(grlinks)
        # infos ajoutées au semestre dans le parcours (groupe, menu)
        menu = _menu_scolarite(current_user, formsemestre, etudid, inscription.etat)
        if menu:
            sem_info[formsemestre.id] = (
                "<table><tr><td>" + grlink + "</td><td>" + menu + "</td></tr></table>"
            )
        else:
            sem_info[formsemestre.id] = grlink

    if inscriptions:
        Se = sco_cursus.get_situation_etud_cursus(info, info["last_formsemestre_id"])
        info["liste_inscriptions"] = formsemestre_recap_parcours_table(
            Se,
            etudid,
            with_links=False,
            sem_info=sem_info,
            with_all_columns=False,
            a_url="Notes/",
        )
        info["link_bul_pdf"] = (
            """<span class="link_bul_pdf fontred">PDF interdits par l'admin.</span>"""
            if ScoDocSiteConfig.is_bul_pdf_disabled()
            else f"""
            <span class="link_bul_pdf">
            <a class="stdlink" href="{
                url_for("notes.etud_bulletins_pdf", scodoc_dept=g.scodoc_dept, etudid=etudid)
                }">Tous les bulletins</a>
            </span>
            """
        )
        last_formsemestre: FormSemestre = inscriptions[0].formsemestre
        if last_formsemestre.formation.is_apc() and last_formsemestre.semestre_id > 2:
            info[
                "link_bul_pdf"
            ] += f"""
            <span class="link_bul_pdf">
            <a class="stdlink" href="{
                url_for("notes.validation_rcues",
                    scodoc_dept=g.scodoc_dept, etudid=etudid, formsemestre_id=last_formsemestre.id)
                }">Visualiser les compétences BUT</a>
            </span>
            """
        if current_user.has_permission(Permission.EtudInscrit):
            info[
                "link_inscrire_ailleurs"
            ] = f"""<span class="link_bul_pdf"><a class="stdlink" href="{
                url_for("notes.formsemestre_inscription_with_modules_form",
                scodoc_dept=g.scodoc_dept, etudid=etudid)
                }">Inscrire à un autre semestre</a></span>
                <span class="link_bul_pdf"><a class="stdlink" href="{
                url_for("notes.jury_delete_manual",
                scodoc_dept=g.scodoc_dept, etudid=etudid)
                }">Éditer toutes décisions de jury</a></span>
                """

        else:
            info["link_inscrire_ailleurs"] = ""
    else:
        # non inscrit
        l = [f"""<p><b>Étudiant{etud.e} non inscrit{etud.e}"""]
        if current_user.has_permission(Permission.EtudInscrit):
            l.append(
                f"""<a href="{
                    url_for("notes.formsemestre_inscription_with_modules_form",
                    scodoc_dept=g.scodoc_dept, etudid=etudid)
                }">inscrire</a></li>"""
            )
        l.append("</b></b>")
        info["liste_inscriptions"] = "\n".join(l)
        info["link_bul_pdf"] = ""
        info["link_inscrire_ailleurs"] = ""

    # Liste des annotations
    html_annotations_list = "\n".join(
        [] if restrict_etud_data else get_html_annotations_list(etud)
    )

    # fiche admission
    if etud.admission:
        infos_admission = _infos_admission(etud, restrict_etud_data)
        has_adm_notes = any(
            infos_admission[k] for k in ("math", "physique", "anglais", "francais")
        )
        has_bac_info = any(
            infos_admission[k]
            for k in (
                "bac_specialite",
                "annee_bac",
                "rapporteur",
                "commentaire",
                "classement",
                "type_admission",
                "rap",
            )
        )
        if has_bac_info or has_adm_notes:
            adm_tmpl = """<!-- Donnees admission -->
    <div class="fichetitre">Informations admission</div>
    """
            if has_adm_notes:
                adm_tmpl += """
<table>
<tr><th>Bac</th><th>Année</th><th>Rg</th>
<th>Math</th><th>Physique</th><th>Anglais</th><th>Français</th></tr>
<tr>
<td>%(bac_specialite)s</td>
<td>%(annee_bac)s </td>
<td>%(classement)s</td>
<td>%(math)s</td><td>%(physique)s</td><td>%(anglais)s</td><td>%(francais)s</td>
</tr>
</table>
    """
            adm_tmpl += """
    <div>Bac %(bac_specialite)s obtenu en %(annee_bac)s </div>
    <div class="info_lycee">%(info_lycee)s</div>"""
            if infos_admission["type_admission"] or infos_admission["classement"]:
                adm_tmpl += """<div class="vadmission">"""
            if infos_admission["type_admission"]:
                adm_tmpl += """<span>Voie d'admission: <span class="etud_type_admission">%(type_admission)s</span></span> """
            if infos_admission["classement"]:
                adm_tmpl += """<span>Rang admission: <span class="etud_type_admission">%(classement)s</span></span>"""
            if infos_admission["type_admission"] or infos_admission["classement"]:
                adm_tmpl += "</div>"
            if infos_admission["rap"]:
                adm_tmpl += """<div class="note_rapporteur">%(rap)s</div>"""
            adm_tmpl += """</div>"""
        else:
            adm_tmpl = ""  # pas de boite "info admission"
        info["adm_data"] = adm_tmpl % infos_admission
    else:
        info["adm_data"] = ""

    # Fichiers archivés:
    info["fichiers_archive_htm"] = (
        ""
        if restrict_etud_data
        else (
            '<div class="fichetitre">Fichiers associés</div>'
            + sco_archives_etud.etud_list_archives_html(etud)
        )
    )

    # Devenir de l'étudiant:
    has_debouche = True
    if sco_permissions_check.can_edit_suivi():
        suivi_readonly = "0"
        link_add_suivi = """<li class="adddebouche">
            <a id="adddebouchelink" class="stdlink" href="#">ajouter une ligne</a>
            </li>"""
    else:
        suivi_readonly = "1"
        link_add_suivi = ""
    if has_debouche:
        info[
            "debouche_html"
        ] = f"""<div id="fichedebouche"
            data-readonly="{suivi_readonly}"
            data-etudid="{info['etudid']}">
        <span class="debouche_tit">Devenir:</span>
        <div><form>
        <ul class="listdebouches">
        {link_add_suivi}
        </ul>
        </form></div>
        </div>"""
    else:
        info["debouche_html"] = ""  # pas de boite "devenir"

    # Inscriptions
    info[
        "inscriptions_mkup"
    ] = f"""<div class="ficheinscriptions" id="ficheinscriptions">
        <div class="fichetitre">Cursus</div>{info["liste_inscriptions"]}
            {info["link_bul_pdf"]} {info["link_inscrire_ailleurs"]}
        </div>"""

    #
    if info["groupes"].strip():
        info[
            "groupes_row"
        ] = f"""<tr>
        <td class="fichetitre2">Groupes :</td><td>{info['groupes']}</td>
        </tr>"""
    else:
        info["groupes_row"] = ""
    info["menus_etud"] = menus_etud(etudid)
    if info["boursier"] and not restrict_etud_data:
        info["bourse_span"] = """<span class="boursier">boursier</span>"""
    else:
        info["bourse_span"] = ""

    # Liens vers compétences BUT
    if last_formsemestre and last_formsemestre.formation.is_apc():
        but_cursus = cursus_but.EtudCursusBUT(etud, last_formsemestre.formation)
        refcomp = last_formsemestre.formation.referentiel_competence
        if refcomp:
            ue_validation_by_niveau = validations_view.get_ue_validation_by_niveau(
                refcomp, etud
            )
            ects_total = sum((v.ects() for v in ue_validation_by_niveau.values()))
        else:
            ects_total = ""
        info[
            "but_cursus_mkup"
        ] = f"""
            <div class="section_but">
                {render_template(
                    "but/cursus_etud.j2",
                    cursus=but_cursus,
                    scu=scu,
                )}
                <div class="fiche_but_col2">
                    <div class="link_validation_rcues">
                        <a class="stdlink" href="{url_for("notes.validation_rcues",
                                            scodoc_dept=g.scodoc_dept, etudid=etudid,
                                            formsemestre_id=last_formsemestre.id)}"
                            title="Visualiser les compétences BUT"
                            >
                            <img src="/ScoDoc/static/icons/parcours-but.png" alt="validation_rcues" height="100px"/>
                            <div style="text-align: center;">Compétences BUT</div>
                        </a>
                    </div>
                    <div class="fiche_total_etcs">
                        Total ECTS BUT: {ects_total:g}
                    </div>
                </div>
            </div>
        """
    else:
        info["but_cursus_mkup"] = ""

    adresse_template = (
        ""
        if restrict_etud_data
        else """
    <!-- Adresse -->
    <div class="ficheadresse" id="ficheadresse">
        <table>
        <tr>
            <td class="fichetitre2">Adresse :</td>
            <td> %(domicile)s %(codepostaldomicile)s %(villedomicile)s %(paysdomicile)s
            %(modifadresse)s
            %(telephones)s
            </td>
        </tr>
        </table>
    </div>
    """
    )

    info_naissance = (
        f"""<tr><td class="fichetitre2">Né{etud.e} le :</td>
                <td>{info["info_naissance"]}</td></tr>
        """
        if info["info_naissance"]
        else ""
    )
    situation_template = (
        f"""
    <div class="fichesituation">
        <div class="fichetablesitu">
            <table>
            <tr><td class="fichetitre2">Situation :</td><td>%(situation)s %(bourse_span)s</td></tr>
            %(groupes_row)s
            {info_naissance}
            </table>
    """
        + adresse_template
        + """
        </div>
    </div>
    """
    )

    info["annotations_mkup"] = (
        f"""
<div class="ficheannotations">
    <div class="fichetitre">Annotations</div>
    <table id="etudannotations">{html_annotations_list}</table>

        <form action="doAddAnnotation" method="GET" class="noprint">
            <input type="hidden" name="etudid" value="{etudid}">
            <b>Ajouter une annotation sur {etud.nomprenom}: </b>
            <div>
                <textarea name="comment" rows="4" cols="50" value=""></textarea>
                <div style="font-size: small; font-style: italic;">
                    <div>Ces annotations sont lisibles par tous les utilisateurs ayant la permission
                    <tt>ViewEtudData</tt> dans ce département (souvent les enseignants et le
                    secrétariat).
                    </div>
                    <div>L'annotation commençant par "PE:" est un avis de poursuite d'études.</div>
                </div>
            </div>

            <input type="hidden" name="author" width=12 value="{current_user}">
            <input type="submit" value="Ajouter annotation">
        </form>
</div>
    """
        if not restrict_etud_data
        else ""
    )

    tmpl = (
        """<div class="menus_etud">%(menus_etud)s</div>
<div class="fiche_etud" id="fiche_etud"><table>
<tr><td>
<h2>%(nomprenom)s (%(inscription)s)</h2>
%(etat_civil)s
<span>%(email_link)s</span>
</td><td class="photocell">
<a href="etud_photo_orig_page?etudid=%(etudid)s">%(etudfoto)s</a>
</td></tr></table>
"""
        + situation_template
        + """

%(inscriptions_mkup)s

%(but_cursus_mkup)s

<div class="ficheadmission">
%(adm_data)s

%(fichiers_archive_htm)s
</div>

%(debouche_html)s

%(annotations_mkup)s

<div class="code_nip">code NIP: %(code_nip)s</div>

</div>
        """
    )
    header = html_sco_header.sco_header(
        page_title=f"Fiche étudiant {etud.nomprenom}",
        cssstyles=[
            "libjs/jQuery-tagEditor/jquery.tag-editor.css",
            "css/jury_but.css",
            "css/cursus_but.css",
        ],
        javascripts=[
            "libjs/jinplace-1.2.1.min.js",
            "js/ue_list.js",
            "libjs/jQuery-tagEditor/jquery.tag-editor.min.js",
            "libjs/jQuery-tagEditor/jquery.caret.min.js",
            "js/recap_parcours.js",
            "js/etud_debouche.js",
        ],
    )
    return header + tmpl % info + html_sco_header.sco_footer()


def _format_adresse(adresse: Adresse | None) -> dict:
    """{ "telephonestr" : ..., "telephonemobilestr" : ... } (formats html)"""
    d = {
        "telephonestr": (
            ("<b>Tél.:</b> " + scu.format_telephone(adresse.telephone))
            if (adresse and adresse.telephone)
            else ""
        ),
        "telephonemobilestr": (
            ("<b>Mobile:</b> " + scu.format_telephone(adresse.telephonemobile))
            if (adresse and adresse.telephonemobile)
            else ""
        ),
        # e-mail:
        "email_link": (
            ", ".join(
                [
                    f"""<a class="stdlink" href="mailto:{m}">{m}</a>"""
                    for m in [adresse.email, adresse.emailperso]
                    if m
                ]
            )
            if adresse and (adresse.email or adresse.emailperso)
            else ""
        ),
        "domicile": (
            (adresse.domicile or "")
            if adresse
            and (
                adresse.domicile or adresse.codepostaldomicile or adresse.villedomicile
            )
            else "<em>inconnue</em>"
        ),
        "paysdomicile": (
            f"{sco_etud.format_pays(adresse.paysdomicile)}"
            if adresse and adresse.paysdomicile
            else ""
        ),
    }
    d["telephones"] = (
        f"<br>{d['telephonestr']} &nbsp;&nbsp; {d['telephonemobilestr']}"
        if adresse and (adresse.telephone or adresse.telephonemobile)
        else ""
    )
    return d


def _infos_admission(etud: Identite, restrict_etud_data: bool) -> dict:
    """dict with admission data, restricted or not"""
    # info sur rapporteur et son commentaire
    rap = ""
    if not restrict_etud_data:
        if etud.admission.rapporteur or etud.admission.commentaire:
            rap = "Note du rapporteur"
            if etud.admission.rapporteur:
                rap += f" ({etud.admission.rapporteur})"
            rap += ": "
            if etud.admission.commentaire:
                rap += f"<em>{etud.admission.commentaire}</em>"
    # nom du lycée
    if restrict_etud_data:
        info_lycee = ""
    elif etud.admission.nomlycee:
        info_lycee = "Lycée " + sco_etud.format_lycee(etud.admission.nomlycee)
        if etud.admission.villelycee:
            info_lycee += f" ({etud.admission.villelycee})"
        info_lycee += "<br>"
    elif etud.admission.codelycee:
        info_lycee = sco_etud.format_lycee_from_code(etud.admission.codelycee)
    else:
        info_lycee = ""

    return {
        # infos accessibles à tous:
        "bac_specialite": f"{etud.admission.bac or ''}{(' '+(etud.admission.specialite or '')) if etud.admission.specialite else ''}",
        "annee_bac": etud.admission.annee_bac or "",
        # infos protégées par ViewEtudData:
        "info_lycee": info_lycee,
        "rapporteur": etud.admission.rapporteur if not restrict_etud_data else "",
        "rap": rap,
        "commentaire": (
            (etud.admission.commentaire or "") if not restrict_etud_data else ""
        ),
        "classement": (
            (etud.admission.classement or "") if not restrict_etud_data else ""
        ),
        "type_admission": (
            (etud.admission.type_admission or "") if not restrict_etud_data else ""
        ),
        "math": (etud.admission.math or "") if not restrict_etud_data else "",
        "physique": (etud.admission.physique or "") if not restrict_etud_data else "",
        "anglais": (etud.admission.anglais or "") if not restrict_etud_data else "",
        "francais": (etud.admission.francais or "") if not restrict_etud_data else "",
    }


def get_html_annotations_list(etud: Identite) -> list[str]:
    """Liste de chaînes html décrivant les annotations."""
    html_annotations_list = []
    annotations = EtudAnnotation.query.filter_by(etudid=etud.id).order_by(
        sa.desc(EtudAnnotation.date)
    )
    for annot in annotations:
        del_link = (
            f"""<td class="annodel"><a href="{
                url_for("scolar.doSuppressAnnotation",
                    scodoc_dept=g.scodoc_dept, etudid=etud.id, annotation_id=annot.id)}">{
                        scu.icontag(
                        "delete_img",
                        border="0",
                        alt="suppress",
                        title="Supprimer cette annotation",
                )
                }</a></td>"""
            if sco_permissions_check.can_suppress_annotation(annot.id)
            else ""
        )

        author = User.query.filter_by(user_name=annot.author).first()
        html_annotations_list.append(
            f"""<tr><td><span class="annodate">Le {
                annot.date.strftime("%d/%m/%Y") if annot.date else "?"}
            par {author.get_prenomnom() if author else "?"} :
            </span><span class="annoc">{annot.comment or ""}</span></td>{del_link}</tr>
            """
        )
    return html_annotations_list


def menus_etud(etudid):
    """Menu etudiant (operations sur l'etudiant)"""
    authuser = current_user

    etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]

    menuEtud = [
        {
            "title": etud["nomprenom"],
            "endpoint": "scolar.fiche_etud",
            "args": {"etudid": etud["etudid"]},
            "enabled": True,
            "helpmsg": "Fiche étudiant",
        },
        {
            "title": "Changer la photo",
            "endpoint": "scolar.form_change_photo",
            "args": {"etudid": etud["etudid"]},
            "enabled": authuser.has_permission(Permission.EtudChangeAdr),
        },
        {
            "title": "Changer les données identité/admission",
            "endpoint": "scolar.etudident_edit_form",
            "args": {"etudid": etud["etudid"]},
            "enabled": authuser.has_permission(Permission.EtudInscrit)
            and authuser.has_permission(Permission.ViewEtudData),
        },
        {
            "title": "Copier dans un autre département...",
            "endpoint": "scolar.etud_copy_in_other_dept",
            "args": {"etudid": etud["etudid"]},
            "enabled": authuser.has_permission(Permission.EtudInscrit),
        },
        {
            "title": "Supprimer cet étudiant...",
            "endpoint": "scolar.etudident_delete",
            "args": {"etudid": etud["etudid"]},
            "enabled": authuser.has_permission(Permission.EtudInscrit),
        },
        {
            "title": "Voir le journal...",
            "endpoint": "scolar.showEtudLog",
            "args": {"etudid": etud["etudid"]},
            "enabled": True,
        },
    ]

    return htmlutils.make_menu(
        "Étudiant", menuEtud, alone=True, css_class="menu-etudiant"
    )


def etud_info_html(etudid, with_photo="1", debug=False):
    """An HTML div with basic information and links about this etud.
    Used for popups information windows.
    """
    formsemestre_id = retreive_formsemestre_from_request()
    with_photo = int(with_photo)
    etud = Identite.get_etud(etudid)

    photo_html = etud.photo_html(title="fiche de " + etud.nomprenom)
    code_cursus, _ = sco_report.get_code_cursus_etud(
        etud, formsemestres=etud.get_formsemestres(), prefix="S", separator=", "
    )
    if etud.admission:
        bac = sco_bac.Baccalaureat(etud.admission.bac, etud.admission.specialite)
        bac_abbrev = bac.abbrev()
    else:
        bac_abbrev = "-"
    H = f"""<div class="etud_info_div">
    <div class="eid_left">
     <div class="eid_nom"><div><a class="stdlink" target="_blank" href="{
         url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
     }">{etud.nomprenom}</a></div></div>
     <div class="eid_info eid_bac">Bac: <span class="eid_bac">{bac_abbrev}</span></div>
     <div class="eid_info eid_parcours">{code_cursus}</div>
    """

    # Informations sur l'etudiant dans le semestre courant:
    if formsemestre_id:  # un semestre est spécifié par la page
        formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
    else:
        # le semestre "en cours" pour l'étudiant
        inscription_courante = etud.inscription_courante()
        formsemestre = (
            inscription_courante.formsemestre if inscription_courante else None
        )

    if formsemestre:
        groups = sco_groups.get_etud_groups(etudid, formsemestre.id)
        grc = sco_groups.listgroups_abbrev(groups)
        H += f"""<div class="eid_info">En <b>S{formsemestre.semestre_id}</b>: {grc}</div>"""
    H += "</div>"  # fin partie gauche (eid_left)
    if with_photo:
        H += '<span class="eid_right">' + photo_html + "</span>"

    H += "</div>"
    if debug:
        return (
            html_sco_header.standard_html_header()
            + H
            + html_sco_header.standard_html_footer()
        )
    else:
        return H
