/* BdfServer_HtmlProducers - Copyright (c) 2011-2025 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package fr.exemole.bdfserver.htmlproducers.mailing;

import fr.exemole.bdfserver.api.exportation.table.TableExportParameters;
import fr.exemole.bdfserver.api.instruction.BdfParameters;
import fr.exemole.bdfserver.api.interaction.Domains;
import fr.exemole.bdfserver.api.interaction.InteractionConstants;
import fr.exemole.bdfserver.api.interaction.domains.MailingDomain;
import fr.exemole.bdfserver.commands.mailing.SendCommand;
import fr.exemole.bdfserver.email.EmailBuffer;
import fr.exemole.bdfserver.email.FicheAttachmentParameters;
import fr.exemole.bdfserver.email.TableExportEmail;
import fr.exemole.bdfserver.email.ValidAddress;
import fr.exemole.bdfserver.email.WrongAddress;
import fr.exemole.bdfserver.html.BdfHtmlUtils;
import fr.exemole.bdfserver.html.BdfServerHtmlProducer;
import fr.exemole.bdfserver.html.ParameterMap;
import fr.exemole.bdfserver.html.consumers.Button;
import fr.exemole.bdfserver.html.consumers.JunctionSelection;
import fr.exemole.bdfserver.html.consumers.Grid;
import fr.exemole.bdfserver.html.consumers.PageUnit;
import fr.exemole.bdfserver.html.consumers.SubsetTitle;
import fr.exemole.bdfserver.html.consumers.Tree;
import fr.exemole.bdfserver.html.consumers.attributes.Appelant;
import fr.exemole.bdfserver.html.consumers.attributes.Deploy;
import fr.exemole.bdfserver.html.forms.TableExportFormHtml;
import fr.exemole.bdfserver.html.jslib.BdfJsLibs;
import fr.exemole.bdfserver.tools.exportation.table.BdfTableExportUtils;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import net.fichotheque.addenda.Addenda;
import net.fichotheque.addenda.Document;
import net.fichotheque.addenda.Version;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.corpus.Fiches;
import net.fichotheque.exportation.table.TableExportDescription;
import net.fichotheque.exportation.transformation.TemplateDescription;
import net.fichotheque.exportation.transformation.TemplateKey;
import net.fichotheque.exportation.transformation.TransformationDescription;
import net.fichotheque.exportation.transformation.TransformationKey;
import net.fichotheque.tools.exportation.transformation.TransformationCheck;
import net.fichotheque.utils.AddendaUtils;
import net.fichotheque.utils.CorpusMetadataUtils;
import net.fichotheque.utils.CorpusUtils;
import net.mapeadores.util.exceptions.SwitchException;
import net.mapeadores.util.html.HA;
import net.mapeadores.util.html.HtmlAttributes;
import net.mapeadores.util.html.HtmlPrinter;
import net.mapeadores.util.html.HtmlWrapper;
import net.fichotheque.junction.Junctions;


/**
 *
 * @author Vincent Calame
 */
public class SendFormHtmlProducer extends BdfServerHtmlProducer {

    private final static HtmlWrapper VERSION_BRANCH = Tree.branch("mailing-VersionBranch");
    private final String sendType;
    private final EmailBuffer emailBuffer;
    private FicheMeta uniqueFicheMeta;
    private Set<FicheMeta> ficheMetaSet;

    public SendFormHtmlProducer(BdfParameters bdfParameters, EmailBuffer emailBuffer) {
        super(bdfParameters);
        this.sendType = emailBuffer.getSendType();
        this.emailBuffer = emailBuffer;
        switch (sendType) {
            case MailingDomain.FICHE_SENDTYPE:
                uniqueFicheMeta = (FicheMeta) emailBuffer.getSendObject();
                break;
            case MailingDomain.SELECTION_SENDTYPE:
                ficheMetaSet = (Set<FicheMeta>) emailBuffer.getSendObject();
                break;
            case MailingDomain.TABLEEXPORT_SENDTYPE:
            default:
                break;
        }
        addJsLib(BdfJsLibs.COMMANDTEST);
        addJsLib(BdfJsLibs.DEPLOY);
        addJsLib(BdfJsLibs.APPELANT);
        addThemeCss("mailing.css");
    }

    @Override
    public void printHtml() {
        start();
        this
                .__(PageUnit.start("action-Send", getTitleMessageKey(sendType)))
                .FORM_post(HA.action(Domains.MAILING).attr("data-submit-process", "test"))
                .INPUT_hidden(initParametersMap())
                .__(printSendReport())
                .__(printToInput())
                .__(printCcInput())
                .__(printBccInput())
                .__(printSubjectInput())
                .__(printMessageInput())
                .__(printAttachments())
                .__(Button.COMMAND,
                        Button.submit("action-Send", getSubmitMessageKey(sendType)))
                ._FORM()
                .__(PageUnit.END);
        end();
    }

    private ParameterMap initParametersMap() {
        ParameterMap parametersMap = ParameterMap.init()
                .command(SendCommand.COMMANDNAME)
                .page(MailingDomain.SEND_REPORT_PAGE)
                .errorPage(MailingDomain.SEND_FORM_PAGE)
                .param(SendCommand.TYPE_PARAMNAME, sendType);
        if (sendType.equals(MailingDomain.FICHE_SENDTYPE)) {
            parametersMap
                    .subset(uniqueFicheMeta.getCorpus())
                    .subsetItem(uniqueFicheMeta);
        } else if (sendType.equals(MailingDomain.TABLEEXPORT_SENDTYPE)) {
            TableExportEmail tableExportEmail = (TableExportEmail) emailBuffer.getSendObject();
            parametersMap
                    .subset(tableExportEmail.getCorpus());
        }
        return parametersMap;
    }

    private boolean printToInput() {
        HtmlAttributes toInput = name(SendCommand.TO_PARAMNAME).cols(60).rows(4).populate(Appelant.user().sphere(bdfUser));
        this
                .P("mailing-InputParagraph")
                .LABEL_for(toInput.id())
                .__localize("_ label.mailing.to")
                .__colon()
                ._LABEL()
                .TEXTAREA(toInput)
                .__(printValidAddresses(EmailBuffer.TO_FIELD))
                ._TEXTAREA()
                ._P();
        return true;
    }

    private boolean printCcInput() {
        HtmlAttributes ccInput = name(SendCommand.CC_PARAMNAME).cols(60).rows(3).populate(Appelant.user().sphere(bdfUser));
        this
                .P("mailing-InputParagraph")
                .LABEL_for(ccInput.id())
                .__localize("_ label.mailing.cc")
                .__colon()
                ._LABEL()
                .TEXTAREA(ccInput)
                .__(printValidAddresses(EmailBuffer.CC_FIELD))
                ._TEXTAREA()
                ._P();
        return true;
    }

    private boolean printBccInput() {
        HtmlAttributes bccInput = name(SendCommand.BCC_PARAMNAME).cols(60).rows(3).populate(Appelant.user().sphere(bdfUser));
        HtmlAttributes selfBccCheck = name(SendCommand.SELFBCC_PARAMNAME).value("1").checked(emailBuffer.isWithRedacteurBcc());
        this
                .P("mailing-InputParagraph")
                .LABEL_for(bccInput.id())
                .__localize("_ label.mailing.bcc")
                .__colon()
                ._LABEL()
                .TEXTAREA(bccInput)
                .__(printValidAddresses(EmailBuffer.BCC_FIELD))
                ._TEXTAREA()
                .BR()
                .SPAN("command-FlexInput mailing-SelfBcc")
                .INPUT_checkbox(selfBccCheck)
                .LABEL_for(selfBccCheck.id())
                .__localize("_ label.mailing.selfbcc")
                ._LABEL()
                ._P();
        return true;
    }


    private boolean printValidAddresses(String fieldName) {
        List<ValidAddress> validAddressList = emailBuffer.getValidAddressList(fieldName);
        if (validAddressList.isEmpty()) {
            return false;
        }
        for (ValidAddress validAddress : validAddressList) {
            this
                    .__escape(validAddress.getOrginalString(), true)
                    .__newLine();
        }
        return true;
    }

    private boolean printSubjectInput() {
        String inputId = generateId();
        this
                .P("mailing-InputParagraph")
                .LABEL_for(inputId)
                .__localize("_ label.mailing.subject")
                .__colon()
                ._LABEL()
                .INPUT_text(HA.name(SendCommand.SUBJECT_PARAMNAME).id(inputId).value(emailBuffer.getSubject()).size("60"))
                ._P();
        return true;
    }

    private boolean printMessageInput() {
        String inputId = generateId();
        String message = emailBuffer.getMessage();
        if (message == null) {
            message = "";
        }
        this
                .P("mailing-InputParagraph")
                .LABEL_for(inputId)
                .__localize("_ label.mailing.message")
                .__colon()
                ._LABEL()
                .TEXTAREA(HA.name(SendCommand.MESSAGE_PARAMNAME).id(inputId).cols(72).rows(10))
                .__escape(message, true)
                ._TEXTAREA()
                ._P();
        return true;
    }

    private boolean printAttachments() {
        switch (sendType) {
            case MailingDomain.COMPILATION_SENDTYPE:
                printSendCompilation();
                break;
            case MailingDomain.FICHE_SENDTYPE:
                printSendFiche();
                break;
            case MailingDomain.SELECTION_SENDTYPE:
                printSendSelection();
                break;
            case MailingDomain.TABLEEXPORT_SENDTYPE:
                printSendTableExport();
                break;
        }
        return true;
    }

    private boolean printSendReport() {
        printCommandMessage();
        if (emailBuffer.hasWrongAddresses()) {
            this
                    .__(Grid.START)
                    .__(printWrongAddresses(EmailBuffer.TO_FIELD, SendCommand.TO_PARAMNAME))
                    .__(printWrongAddresses(EmailBuffer.CC_FIELD, SendCommand.CC_PARAMNAME))
                    .__(printWrongAddresses(EmailBuffer.BCC_FIELD, SendCommand.BCC_PARAMNAME))
                    .__(Grid.END);
        }
        return true;
    }

    private boolean printWrongAddresses(String fieldName, String inputName) {
        for (WrongAddress wrongAddress : emailBuffer.getWrongAddressList(fieldName)) {
            HtmlAttributes input = name(inputName).value(wrongAddress.getErrorValue()).size("60");
            this
                    .P("grid-Row mailing-WrongAddress")
                    .__(Grid.labelCells(wrongAddress.getErrorMessage(), input.id()))
                    .__(Grid.START_INPUTCELL)
                    .INPUT_text(input)
                    .__(Grid.END_INPUTCELL)
                    ._P();
        }
        return true;
    }

    private void printSendCompilation() {
        FicheAttachmentParameters ficheAttachmentParameters = emailBuffer.getFicheAttachmentParameters();
        this
                .H2()
                .__localize("_ title.mailing.compilationversion")
                ._H2()
                .UL("mailing-AttachmentList")
                .__(new TemplateSelection(TransformationKey.COMPILATION_INSTANCE, ficheAttachmentParameters))
                ._UL()
                .H2()
                .__localize("_ title.mailing.fiches_compilation")
                ._H2()
                .__(printFiches(bdfUser.getSelectedFiches(), false));
    }

    private void printSendSelection() {
        FicheAttachmentParameters ficheAttachmentParameters = emailBuffer.getFicheAttachmentParameters();
        TransformationKey transformationKey;
        Fiches fiches = bdfUser.getSelectedFiches();
        if (fiches.getEntryList().size() == 1) {
            transformationKey = new TransformationKey(fiches.getEntryList().get(0).getCorpus().getSubsetKey());
        } else {
            transformationKey = null;
        }
        this
                .H2()
                .__localize("_ title.mailing.selectionversion")
                ._H2()
                .UL("mailing-AttachmentList")
                .__(new TemplateSelection(transformationKey, ficheAttachmentParameters))
                ._UL()
                .H2()
                .__localize("_ title.mailing.fiches_selection")
                ._H2()
                .__(printFiches(bdfUser.getSelectedFiches(), true));
    }

    private void printSendTableExport() {
        TableExportEmail tableExportEmail = (TableExportEmail) emailBuffer.getSendObject();
        TableExportParameters tableExportParameters = tableExportEmail.getTableExportParameters();
        String tableExportName = tableExportParameters.getTableExportName();
        TableExportDescription tableExportDescription;
        if (tableExportName != null) {
            tableExportDescription = BdfTableExportUtils.getValidTableExportDescription(bdfServer.getTableExportManager(), tableExportName);
        } else {
            tableExportDescription = null;
        }
        String charsetPanelId = this.generateId();
        boolean charsetHidden = ((isWithJavascript()) && (!tableExportEmail.getExtension().equals("csv")));
        if (tableExportDescription != null) {
            this
                    .H2()
                    .__localize("_ label.tableexport.tableexport_name")
                    .__space()
                    .STRONG()
                    .__escape(tableExportDescription.getTitle(workingLang))
                    ._STRONG()
                    ._H2()
                    .INPUT_hidden(InteractionConstants.TABLEEXPORT_PARAMNAME, tableExportName);
        } else {
            this
                    .H2()
                    .__localize("_ label.tableexport.tableexport_default")
                    ._H2()
                    .__(TableExportFormHtml.printWithParameters(this, tableExportParameters.getDefaulFicheTableParameters()))
                    .__(TableExportFormHtml.printPatternModeRadios(this, tableExportParameters.getDefaulFicheTableParameters().getPatternMode()));
        }
        this
                .__(TableExportFormHtml.HEADERTYPE_TITLE)
                .__(TableExportFormHtml.printHeaderTypeRadios(this, tableExportParameters.getHeaderType()))
                .H2()
                .__localize("_ title.tableexport.extension")
                ._H2()
                .UL("mailing-AttachmentList")
                .LI()
                .__(printExtensionRadio(tableExportEmail, "csv", charsetPanelId, "action-Csv"))
                .DIV(Grid.detailPanelTable().id(charsetPanelId).addClass(charsetHidden, "hidden"))
                .__(Grid.selectRow("_ label.global.charset", name(InteractionConstants.CHARSET_PARAMNAME).classes("global-CharsetSelect"), new CharsetOptions(tableExportEmail.getCharset())))
                ._DIV()
                ._LI()
                .LI()
                .__(printExtensionRadio(tableExportEmail, "ods", null, "action-Ods"))
                ._LI()
                ._UL()
                .H2()
                .__localize("_ title.mailing.fiches_tableexport")
                ._H2()
                .__(printFiches(CorpusUtils.reduce(bdfUser.getSelectedFiches(), tableExportEmail.getCorpus()), false));
    }


    private boolean printSendFiche() {
        FicheAttachmentParameters ficheAttachmentParameters = emailBuffer.getFicheAttachmentParameters();
        DocumentBranch documentBranch = new DocumentBranch(getFormatLocale(), ficheAttachmentParameters);
        this
                .H2()
                .__localize("_ title.mailing.sendreport_attachments")
                ._H2()
                .H3()
                .__escape(CorpusMetadataUtils.getFicheTitle(uniqueFicheMeta, workingLang, formatLocale))
                ._H3()
                .UL("mailing-AttachmentList")
                .__(new TemplateSelection(uniqueFicheMeta.getCorpus(), ficheAttachmentParameters))
                ._UL();
        boolean first = true;
        for (Addenda addenda : fichotheque.getAddendaList()) {
            Junctions documentJunctions = fichotheque.getJunctions(uniqueFicheMeta, addenda);
            if (!documentJunctions.isEmpty()) {
                if (first) {
                    this
                            .H3()
                            .__localize("_ title.mailing.documentlist")
                            ._H3()
                            .UL("global-JunctionList");
                    first = false;
                }
                this
                        .LI()
                        .P()
                        .__(SubsetTitle.init(addenda, workingLang).subsetIcon(true))
                        ._P()
                        .__(JunctionSelection.TREE, () -> {
                            for (Junctions.Entry entry : documentJunctions.getEntryList()) {
                                this
                                        .__(documentBranch, entry.getSubsetItem());
                            }
                        })
                        ._LI();
            }
        }
        if (!first) {
            this
                    ._UL();
        }
        return true;
    }

    private boolean printFiches(Fiches fiches, boolean withCheckbox) {
        this
                .UL("global-JunctionList");
        for (Fiches.Entry entry : fiches.getEntryList()) {
            Corpus corpus = entry.getCorpus();
            this
                    .LI()
                    .P()
                    .__(SubsetTitle.init(corpus, workingLang).subsetIcon(true))
                    ._P()
                    .__(JunctionSelection.TREE, () -> {
                        for (FicheMeta ficheMeta : entry.getFicheMetaList()) {
                            if (withCheckbox) {
                                boolean checked = ((ficheMetaSet != null) && (ficheMetaSet.contains(ficheMeta)));
                                HtmlAttributes inputAttributes = name("selection_" + corpus.getSubsetName()).value(String.valueOf(ficheMeta.getId())).checked(checked);
                                this
                                        .__(Tree.checkboxLeaf(inputAttributes, () -> {
                                            this
                                                    .__escape(CorpusMetadataUtils.getFicheTitle(ficheMeta, workingLang, formatLocale));
                                        }));

                            } else {
                                this
                                        .__(Tree.LEAF, () -> {
                                            this
                                                    .SPAN("mailing-Fiche")
                                                    .__escape(CorpusMetadataUtils.getFicheTitle(ficheMeta, workingLang, formatLocale))
                                                    ._SPAN();
                                        });
                            }
                        }
                    })
                    ._LI();
        }
        this
                ._UL();
        return true;
    }

    private boolean printExtensionRadio(TableExportEmail tableExportEmail, String extension, String targetId, String actionName) {
        HtmlAttributes radio = name(SendCommand.EXTENSION_PARAMNAME).value(extension).checked(tableExportEmail.getExtension());
        if (targetId != null) {
            radio.populate(Deploy.radio(targetId));
        }
        this
                .P("command-FlexInput " + actionName)
                .INPUT_radio(radio)
                .__(Button.ICON)
                .LABEL_for(radio.id())
                .__escape(extension)
                ._LABEL()
                ._P();
        return true;
    }

    private static String getSubmitMessageKey(String sendType) {
        switch (sendType) {
            case MailingDomain.FICHE_SENDTYPE:
                return "_ submit.mailing.send_fiche";
            case MailingDomain.COMPILATION_SENDTYPE:
                return "_ submit.mailing.send_compilation";
            case MailingDomain.SELECTION_SENDTYPE:
                return "_ submit.mailing.send_selection";
            case MailingDomain.TABLEEXPORT_SENDTYPE:
                return "_ submit.mailing.send_tableexport";
            default:
                throw new SwitchException("Unknown sendType: " + sendType);
        }
    }

    private static String getTitleMessageKey(String sendType) {
        switch (sendType) {
            case MailingDomain.FICHE_SENDTYPE:
                return "_ title.mailing.send_fiche";
            case MailingDomain.COMPILATION_SENDTYPE:
                return "_ title.mailing.send_compilation";
            case MailingDomain.SELECTION_SENDTYPE:
                return "_ title.mailing.send_selection";
            case MailingDomain.TABLEEXPORT_SENDTYPE:
                return "_ title.mailing.send_tableexport";
            default:
                throw new SwitchException("Unknown sendType: " + sendType);
        }
    }


    private class TemplateSelection implements Consumer<HtmlPrinter> {

        private final Map<String, TemplateCheckboxes> checkboxesMap = new HashMap<String, TemplateCheckboxes>();
        private final TransformationCheck transformationCheck;
        private final FicheAttachmentParameters ficheAttachmentParameters;

        private TemplateSelection(TransformationKey transformationKey, FicheAttachmentParameters ficheAttachmentParameters) {
            if (transformationKey != null) {
                TransformationDescription transformationDescription = bdfServer.getTransformationManager().getTransformationDescription(transformationKey);
                this.transformationCheck = TransformationCheck.check(transformationDescription, true);
            } else {
                this.transformationCheck = null;
            }
            this.ficheAttachmentParameters = ficheAttachmentParameters;
            addHtml();
            addOdt();
        }

        private TemplateSelection(Corpus corpus, FicheAttachmentParameters ficheAttachmentParameters) {
            this(new TransformationKey(corpus.getSubsetKey()), ficheAttachmentParameters);
        }

        private void addHtml() {
            String name = "html";
            TemplateCheckboxes templateCheckboxes = new TemplateCheckboxes(name, SendCommand.HTML_FICHEVERSION_PARAMVALUE, "_ label.mailing.format_html", SendCommand.HTMLTEMPLATE_PARAMNAME, ficheAttachmentParameters.isWithHtml(), ficheAttachmentParameters.getHtmlTemplateName(), "action-Html");
            checkboxesMap.put(name, templateCheckboxes);
        }

        private void addOdt() {
            String name = "odt";
            TemplateCheckboxes templateCheckboxes = new TemplateCheckboxes(name, SendCommand.ODT_FICHEVERSION_PARAMVALUE, "_ label.mailing.format_odt", SendCommand.ODTTEMPLATE_PARAMNAME, ficheAttachmentParameters.isWithOdt(), ficheAttachmentParameters.getOdtTemplateName(), "action-Odt");
            checkboxesMap.put(name, templateCheckboxes);
        }

        @Override
        public void accept(HtmlPrinter hp) {
            accept("html", hp);
            accept("odt", hp);
        }

        private void accept(String name, HtmlPrinter hp) {
            TemplateCheckboxes templateCheckboxes = checkboxesMap.get(name);
            if (templateCheckboxes != null) {
                templateCheckboxes.accept(hp);
            }
        }


        private class TemplateCheckboxes implements Consumer<HtmlPrinter> {

            private final String name;
            private final String value;
            private final String locKey;
            private final boolean checked;
            private final String templateSelectName;
            private final String selectedTemplateName;
            private final String actionName;

            private TemplateCheckboxes(String name, String value, String locKey, String templateSelectName, boolean checked, String selectedTemplateName, String actionName) {
                this.name = name;
                this.value = value;
                this.locKey = locKey;
                this.templateSelectName = templateSelectName;
                this.checked = checked;
                this.actionName = actionName;
                if (selectedTemplateName == null) {
                    this.selectedTemplateName = TemplateKey.DEFAULT_NAME;
                } else {
                    this.selectedTemplateName = selectedTemplateName;
                }
            }

            @Override
            public void accept(HtmlPrinter hp) {
                TemplateDescription[] templateDescriptionArray = getTemplateDescriptionArray();
                String detailId = null;
                HtmlAttributes checkbox = hp.name(SendCommand.FICHEVERSION_PARAMNAME).value(value).checked(checked);
                if (templateDescriptionArray != null) {
                    detailId = hp.generateId();
                    checkbox.populate(Deploy.checkbox(detailId));
                }
                hp
                        .LI()
                        .P("command-FlexInput " + actionName)
                        .INPUT_checkbox(checkbox)
                        .__(Button.ICON)
                        .LABEL_for(checkbox.id())
                        .__localize(locKey)
                        ._LABEL()
                        ._P();
                if (templateDescriptionArray != null) {
                    hp
                            .DIV(Grid.detailPanelTable().id(detailId).addClass(!checked, "hidden"))
                            .__(Grid.selectRow("_ label.transformation.template", name(templateSelectName), new TemplateOptions(templateDescriptionArray)))
                            ._DIV();
                }
                hp
                        ._LI();
            }

            private TemplateDescription[] getTemplateDescriptionArray() {
                if (transformationCheck == null) {
                    return null;
                }
                if (name.equals("html")) {
                    return transformationCheck.getSimpleTemplateDescriptionArray();
                } else {
                    return transformationCheck.getStreamTemplateDescriptionArray(name);
                }
            }


            class TemplateOptions implements Consumer<HtmlPrinter> {

                private final TemplateDescription[] templateDescriptionArray;

                private TemplateOptions(TemplateDescription[] templateDescriptionArray) {
                    this.templateDescriptionArray = templateDescriptionArray;
                }

                @Override
                public void accept(HtmlPrinter hp) {
                    hp
                            .OPTION(TemplateKey.DEFAULT_NAME, selectedTemplateName.equals(TemplateKey.DEFAULT_NAME))
                            .__localize("_ label.transformation.defaulttemplate")
                            ._OPTION();
                    for (TemplateDescription templateDescription : templateDescriptionArray) {
                        String name = templateDescription.getTemplateKey().getName();
                        hp
                                .OPTION(name, name.equals(selectedTemplateName))
                                .__escape(templateDescription.getTitle(workingLang))
                                ._OPTION();
                    }
                }

            }

        }

    }


    private static class CharsetOptions implements Consumer<HtmlPrinter> {

        private final String currentCharset;

        private CharsetOptions(String currentCharset) {
            this.currentCharset = currentCharset;
        }

        @Override
        public void accept(HtmlPrinter hp) {
            SortedMap<String, Charset> charsetMap = Charset.availableCharsets();
            for (Map.Entry<String, Charset> entry : charsetMap.entrySet()) {
                String canonicalName = entry.getKey();
                Charset charset = entry.getValue();
                boolean selected = (canonicalName.equals(currentCharset));
                hp
                        .OPTION(canonicalName, selected)
                        .__escape(canonicalName);
                Set<String> aliases = charset.aliases();
                for (String alias : aliases) {
                    hp
                            .__escape(" ; ")
                            .__escape(alias);
                }
                hp
                        ._OPTION();
            }
        }

    }


    private static class DocumentBranch implements BiConsumer<HtmlPrinter, Object> {

        private final Locale formatLocale;
        private final FicheAttachmentParameters ficheAttachmentParameters;

        private DocumentBranch(Locale formatLocale, FicheAttachmentParameters ficheAttachmentParameters) {
            this.formatLocale = formatLocale;
            this.ficheAttachmentParameters = ficheAttachmentParameters;
        }

        @Override
        public void accept(HtmlPrinter hp, Object object) {
            Document document = (Document) object;
            hp.__(JunctionSelection.OPEN_NODE, () -> {
                hp
                        .DIV("mailing-Document")
                        .__escape(document.getGlobalId())
                        .__dash()
                        .__escape(document.getBasename())
                        ._DIV()
                        .__(VERSION_BRANCH, () -> {
                            for (Version version : document.getVersionList()) {
                                String versionKey = AddendaUtils.toVersionKey(version);
                                HtmlAttributes inputAttributes = hp.name(SendCommand.DOCUMENTVERSION_PARAMNAME).value(versionKey).checked(ficheAttachmentParameters.containsVersion(versionKey));
                                hp.__(Tree.checkboxLeaf(inputAttributes, () -> {
                                    hp
                                            .SPAN("mailing-Version")
                                            .__escape(version.getFileName())
                                            ._SPAN()
                                            .SPAN("mailing-Size")
                                            .__space()
                                            .__escape('(')
                                            .__(BdfHtmlUtils.printDocumentVersionSize(hp, version, formatLocale))
                                            .__escape(')')
                                            ._SPAN();
                                }));
                            }
                        });
            });
        }

    }


}
