/* BdfServer_HtmlProducers - Copyright (c) 2010-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.sphere;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.BdfServerConstants;
import fr.exemole.bdfserver.api.exportation.table.TableExportParameters;
import fr.exemole.bdfserver.api.managers.PermissionManager;
import fr.exemole.bdfserver.api.managers.TransformationManager;
import fr.exemole.bdfserver.api.namespaces.BdfUserSpace;
import fr.exemole.bdfserver.api.roles.Role;
import fr.exemole.bdfserver.api.users.BdfUser;
import fr.exemole.bdfserver.commands.sphere.LoginChangeCommand;
import fr.exemole.bdfserver.commands.sphere.RedacteurAttributeChangeCommand;
import fr.exemole.bdfserver.commands.sphere.RedacteurChangeCommand;
import fr.exemole.bdfserver.commands.sphere.RedacteurCreationCommand;
import fr.exemole.bdfserver.commands.sphere.RedacteurCustomizeUICommand;
import fr.exemole.bdfserver.commands.sphere.RedacteurDefaultTableExportParametersCommand;
import fr.exemole.bdfserver.commands.sphere.RedacteurLangCommand;
import fr.exemole.bdfserver.commands.sphere.RedacteurPasswordCommand;
import fr.exemole.bdfserver.commands.sphere.RedacteurRemoveCommand;
import fr.exemole.bdfserver.commands.sphere.RedacteurReplaceCommand;
import fr.exemole.bdfserver.commands.sphere.RedacteurRoleCommand;
import fr.exemole.bdfserver.commands.sphere.RedacteurStatusCommand;
import fr.exemole.bdfserver.commands.sphere.RedacteurTemplatesCommand;
import fr.exemole.bdfserver.commands.sphere.SphereAttributeChangeCommand;
import fr.exemole.bdfserver.commands.sphere.SphereCreationCommand;
import fr.exemole.bdfserver.commands.sphere.SpherePhrasesCommand;
import fr.exemole.bdfserver.commands.sphere.SphereRemoveCommand;
import fr.exemole.bdfserver.html.consumers.AttributesText;
import fr.exemole.bdfserver.html.consumers.Choices;
import fr.exemole.bdfserver.html.consumers.Common;
import fr.exemole.bdfserver.html.consumers.Grid;
import fr.exemole.bdfserver.html.consumers.MetadataPhrases;
import fr.exemole.bdfserver.html.consumers.PageUnit;
import fr.exemole.bdfserver.html.consumers.attributes.Appelant;
import fr.exemole.bdfserver.html.consumers.attributes.Deploy;
import fr.exemole.bdfserver.html.consumers.attributes.InputPattern;
import fr.exemole.bdfserver.html.consumers.commandbox.Flag;
import fr.exemole.bdfserver.html.forms.TableExportFormHtml;
import static fr.exemole.bdfserver.htmlproducers.CommandBoxUtils.insert;
import fr.exemole.bdfserver.tools.roles.RoleUtils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.function.Consumer;
import net.fichotheque.Fichotheque;
import net.fichotheque.FichothequeConstants;
import net.fichotheque.corpus.Corpus;
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.sphere.Redacteur;
import net.fichotheque.sphere.Sphere;
import net.fichotheque.sphere.metadata.SphereMetadata;
import net.fichotheque.tools.exportation.transformation.TransformationCheck;
import net.fichotheque.utils.FichothequeUtils;
import net.mapeadores.util.exceptions.SwitchException;
import net.mapeadores.util.html.CommandBox;
import net.mapeadores.util.html.HA;
import net.mapeadores.util.html.HtmlAttributes;
import net.mapeadores.util.html.HtmlPrinter;
import net.mapeadores.util.localisation.Lang;
import net.mapeadores.util.localisation.LangPreference;
import net.mapeadores.util.localisation.Langs;
import net.mapeadores.util.localisation.Litteral;
import net.mapeadores.util.localisation.LocalisationUtils;
import net.mapeadores.util.models.EmailCore;
import net.mapeadores.util.models.PersonCore;


/**
 *
 * @author Vincent Calame
 */
public final class SphereCommandBoxUtils {

    private SphereCommandBoxUtils() {
    }

    public static boolean printNotAllowed(HtmlPrinter hp, CommandBox commandBox, String commandKey) {
        return printNotAvailableCommand(hp, commandBox, commandKey, "_ warning.sphere.multiadmin");
    }

    public static boolean printNotAvailableCommand(HtmlPrinter hp, CommandBox commandBox, String commandKey, String infoLocKey) {
        commandBox = commandBox.derive(null, commandKey);
        hp
                .__start(commandBox)
                .P("sphere-NotAvailableInfo")
                .__localize(infoLocKey)
                ._P()
                .__end(commandBox.lockey(null));
        return true;
    }

    public static boolean printSphereCreationBox(HtmlPrinter hp, CommandBox commandBox) {
        commandBox = commandBox.derive(SphereCreationCommand.COMMANDNAME, SphereCreationCommand.COMMANDKEY)
                .actionCssClass("action-New")
                .__(Flag.UPDATE_COLLECTIONS)
                .submitLocKey("_ submit.sphere.spherecreation");
        hp
                .__start(commandBox)
                .__(Grid.START)
                .__(Grid.textInputRow("_ label.sphere.newspherename", hp.name(SphereCreationCommand.NEWSPHERE_PARAMNAME).size("30").populate(InputPattern.TECHNICAL_STRICT).required(true)))
                .__(Grid.END)
                .__end(commandBox);
        return true;
    }

    public static boolean printSpherePhrasesBox(HtmlPrinter hp, CommandBox commandBox, Sphere sphere, BdfServer bdfServer) {
        SphereMetadata sphereMetadata = sphere.getSphereMetadata();
        commandBox = commandBox.derive(SpherePhrasesCommand.COMMANDNAME, SpherePhrasesCommand.COMMANDKEY)
                .__(insert(sphere))
                .actionCssClass("action-Labels")
                .submitLocKey("_ submit.sphere.spherephrases");
        hp
                .__start(commandBox)
                .__(MetadataPhrases.init(sphereMetadata, bdfServer.getLangConfiguration().getWorkingLangs(), "_ label.sphere.title").populateFromAttributes(sphere).addExtensionPhraseDefList(bdfServer))
                .__end(commandBox);
        return true;
    }

    public static boolean printSphereAttributeChangeBox(HtmlPrinter hp, CommandBox commandBox, Sphere sphere) {
        commandBox = commandBox.derive(SphereAttributeChangeCommand.COMMANDNAME, SphereAttributeChangeCommand.COMMANDKEY)
                .__(insert(sphere))
                .actionCssClass("action-Attributes")
                .submitLocKey("_ submit.global.attributechange");
        hp
                .__start(commandBox)
                .__(Grid.START)
                .__(Grid.textAreaBlockRow("_ label.global.attributes", HA.name(SphereAttributeChangeCommand.ATTRIBUTES_PARAMNAME).rows(8).cols(75).attr("data-codemirror-mode", "attributes"),
                        new AttributesText(sphere.getSphereMetadata().getAttributes())))
                .__(Grid.END)
                .__end(commandBox);
        return true;
    }

    public static boolean printSphereRemoveBox(HtmlPrinter hp, CommandBox commandBox, Sphere sphere) {
        commandBox = commandBox.derive(SphereRemoveCommand.COMMANDNAME, SphereRemoveCommand.COMMANDKEY)
                .__(insert(sphere))
                .actionCssClass("action-Delete")
                .__(Flag.UPDATE_COLLECTIONS)
                .submitLocKey("_ submit.sphere.sphereremove");
        hp
                .__start(commandBox)
                .__(Common.REMOVE_CONFIRM_CHECK)
                .__end(commandBox);
        return true;
    }

    public static boolean printRedacteurCreationBox(HtmlPrinter hp, CommandBox commandBox, Sphere sphere) {
        commandBox = commandBox.derive(RedacteurCreationCommand.COMMANDNAME, RedacteurCreationCommand.COMMANDKEY)
                .__(insert(sphere))
                .actionCssClass("action-New")
                .submitLocKey("_ submit.sphere.redacteurcreation");
        hp
                .__start(commandBox)
                .__(Grid.START)
                .__(Grid.textInputRow("_ label.sphere.login", hp.name(RedacteurCreationCommand.NEWLOGIN_PARAMNAME).size("15").populate(InputPattern.LOGIN).required(true)))
                .__(Grid.END)
                .__end(commandBox);
        return true;
    }

    public static boolean printLoginChangeBox(HtmlPrinter hp, CommandBox commandBox, Redacteur redacteur) {
        commandBox = commandBox.derive(LoginChangeCommand.COMMANDNAME, LoginChangeCommand.COMMANDKEY)
                .__(insert(redacteur))
                .submitLocKey("_ submit.sphere.loginchange");
        hp
                .__start(commandBox)
                .__(Grid.START)
                .__(Grid.textInputRow("_ label.sphere.login", hp.name(LoginChangeCommand.NEWLOGIN_PARAMNAME).value(redacteur.getLogin()).size("15").populate(InputPattern.LOGIN).required(true)))
                .__(Grid.END)
                .__end(commandBox);
        return true;
    }

    public static boolean printRedacteurPasswordBox(HtmlPrinter hp, CommandBox commandBox, Redacteur redacteur) {
        commandBox = commandBox.derive(RedacteurPasswordCommand.COMMANDNAME, RedacteurPasswordCommand.COMMANDKEY)
                .__(insert(redacteur))
                .submitLocKey("_ submit.sphere.passwordchange");
        hp
                .__start(commandBox)
                .__(Grid.START)
                .__(Grid.passwordInputRow("_ label.sphere.password_1", hp.name(RedacteurPasswordCommand.PASSWORD1_PARAMNAME).size("20")))
                .__(Grid.passwordInputRow("_ label.sphere.password_2", hp.name(RedacteurPasswordCommand.PASSWORD2_PARAMNAME).size("20")))
                .__(Grid.END)
                .__end(commandBox);
        return true;
    }

    public static boolean printRedacteurChangeBox(HtmlPrinter hp, CommandBox commandBox, Redacteur redacteur, BdfServer bdfServer) {
        EmailCore email = redacteur.getEmailCore();
        PersonCore personCore = redacteur.getPersonCore();
        boolean withNonlatin;
        if ((personCore.getNonlatin().length() > 0) || (bdfServer.getLangConfiguration().isWithNonlatin())) {
            withNonlatin = true;
        } else {
            withNonlatin = false;
        }
        String emailValue = (email != null) ? email.toCompleteString() : "";
        commandBox = commandBox.derive(RedacteurChangeCommand.COMMANDNAME, RedacteurChangeCommand.COMMANDKEY)
                .__(insert(redacteur))
                .submitLocKey("_ submit.sphere.redacteurchange");
        hp
                .__start(commandBox)
                .__(Grid.START)
                .__if((withNonlatin), () -> {
                    hp
                            .__(Grid.textInputRow("_ label.sphere.nonlatin", hp.name(RedacteurChangeCommand.NONLATIN_PARAMNAME).value(personCore.getNonlatin()).size("30")));
                })
                .__(Grid.textInputRow((withNonlatin) ? "_ label.sphere.surname_latin" : "_ label.sphere.surname", hp.name(RedacteurChangeCommand.SURNAME_PARAMNAME).value(personCore.getSurname()).size("30")))
                .__(Grid.textInputRow((withNonlatin) ? "_ label.sphere.forename_latin" : "_ label.sphere.forename", hp.name(RedacteurChangeCommand.FORENAME_PARAMNAME).value(personCore.getForename()).size("30")))
                .__(printSurnameFirstRow(hp, RedacteurChangeCommand.SURNAMEFIRST_PARAMNAME, personCore.isSurnameFirst()))
                .__(Grid.textInputRow("_ label.sphere.email", hp.name(RedacteurChangeCommand.EMAIL_PARAMNAME).value(emailValue).size("30")))
                .__(Grid.END)
                .__end(commandBox);
        return true;
    }

    private static boolean printSurnameFirstRow(HtmlPrinter hp, String inputName, boolean checked) {
        String inputId = hp.generateId();
        hp
                .__(Grid.START_ROW)
                .__(Grid.START_INPUTCELL)
                .SPAN("command-FlexInput command-Smaller")
                .INPUT_checkbox(HA.name(inputName).value("1").id(inputId).checked(checked))
                .LABEL_for(inputId)
                .__localize("_ label.sphere.surnamefirst")
                ._LABEL()
                ._SPAN()
                .__(Grid.END_INPUTCELL)
                .__(Grid.END_ROW);
        return true;
    }

    public static boolean printLangBox(HtmlPrinter hp, CommandBox commandBox, Redacteur redacteur, BdfUser redacBdfUser, BdfServer bdfServer, Locale formatLocale) {
        Langs workingLangs = bdfServer.getLangConfiguration().getWorkingLangs();
        Lang currentLang = redacBdfUser.getWorkingLang();
        Locale customFormatLocale = redacBdfUser.getPrefs().getCustomFormatLocale();
        String customFormatLocaleValue = "";
        if (customFormatLocale != null) {
            customFormatLocaleValue = Lang.toISOString(customFormatLocale);
        }
        StringBuilder langPreferenceBuf = new StringBuilder();
        LangPreference customLangPreference = redacBdfUser.getPrefs().getCustomLangPreference();
        if (customLangPreference != null) {
            for (Lang lang : customLangPreference) {
                if (langPreferenceBuf.length() > 0) {
                    langPreferenceBuf.append(";");
                }
                langPreferenceBuf.append(lang);
            }
        }
        commandBox = commandBox.derive(RedacteurLangCommand.COMMANDNAME, RedacteurLangCommand.COMMANDKEY)
                .__(insert(redacteur))
                .submitLocKey("_ submit.sphere.redacteurlang");
        hp
                .__start(commandBox)
                .__(Grid.START)
                .__(Grid.selectRow("_ label.sphere.workinglang", hp.name(RedacteurLangCommand.WORKINGLANG_PARAMNAME),
                        () -> {
                            for (Lang lang : workingLangs) {
                                String langString = lang.toString();
                                hp
                                        .OPTION(langString, (lang.equals(currentLang)))
                                        .__escape(langString)
                                        .__dash();
                                String voTitle = LocalisationUtils.getVOTitle(lang);
                                if (voTitle != null) {
                                    hp
                                            .__escape(voTitle);
                                } else {
                                    hp
                                            .__localize(langString);
                                }
                                hp
                                        ._OPTION();
                            }
                        }))
                .__(Grid.textInputRow("_ label.sphere.customformatlocale", hp.name(RedacteurLangCommand.CUSTOMFORMATLOCALE_PARAMNAME).value(customFormatLocaleValue).size("10")))
                .__(Grid.textInputRow("_ label.sphere.customlangpreference", hp.name(RedacteurLangCommand.CUSTOMLANGPREFERENCE_PARAMNAME).value(langPreferenceBuf.toString()).size("30")))
                .__(Grid.END)
                .__end(commandBox);
        return true;
    }

    public static boolean printTemplatesBox(HtmlPrinter hp, CommandBox commandBox, BdfServer bdfServer, Lang workingLang, Redacteur redacteur, BdfUser redacBdfUser) {
        TransformationLists lists = new TransformationLists(bdfServer, workingLang, redacBdfUser);
        if (lists.isEmpty()) {
            hp
                    .__(PageUnit.start("_ USR-04"))
                    .P()
                    .__localize("_ info.transformation.onlydefault")
                    ._P()
                    .__(PageUnit.END);
            return true;
        }
        commandBox = commandBox.derive(RedacteurTemplatesCommand.COMMANDNAME, RedacteurTemplatesCommand.COMMANDKEY)
                .__(insert(redacteur))
                .submitLocKey("_ submit.sphere.redacteurtemplates");
        hp
                .__start(commandBox)
                .__(lists.listSpecial())
                .__(lists.listCorpus())
                .__end(commandBox);
        return true;
    }

    public static boolean printDefaultTableExportParametersBox(HtmlPrinter hp, CommandBox commandBox, Redacteur redacteur, BdfUser redacBdfUser) {
        TableExportParameters tableExportParameters = redacBdfUser.getPrefs().getDefaultTableExportParameters();
        boolean checked = redacBdfUser.getPrefs().getBoolean(BdfUserSpace.TABLEEXPORT_STATUSSHEET_KEY);
        commandBox = commandBox.derive(RedacteurDefaultTableExportParametersCommand.COMMANDNAME, RedacteurDefaultTableExportParametersCommand.COMMANDKEY)
                .__(insert(redacteur))
                .submitLocKey("_ submit.sphere.redacteurdefaulttableexportparameters");
        hp
                .__start(commandBox)
                .__(TableExportFormHtml.printWithParameters(hp, tableExportParameters.getDefaulFicheTableParameters()))
                .__(TableExportFormHtml.printPatternModeRadios(hp, tableExportParameters.getDefaulFicheTableParameters().getPatternMode()))
                .__(TableExportFormHtml.HEADERTYPE_TITLE)
                .__(TableExportFormHtml.printHeaderTypeRadios(hp, tableExportParameters.getHeaderType()))
                .__(TableExportFormHtml.ODSSPECIFIC_TITLE)
                .__(Choices.LIST, () -> {
                    hp
                            .__(Choices.checkboxLi(hp.name(RedacteurDefaultTableExportParametersCommand.STATUSSHEET_PARAMNAME).value("1").checked(checked), "_ label.tableexport.statussheet"));
                })
                .__end(commandBox);
        return true;
    }

    public static boolean printCustomizeUIBox(HtmlPrinter hp, CommandBox commandBox, Redacteur redacteur, BdfUser redacBdfUser) {
        boolean noTab = redacBdfUser.getPrefs().getBoolean(BdfUserSpace.NOTAB_KEY);
        boolean hideEmpty = redacBdfUser.getPrefs().getBoolean(BdfUserSpace.HIDEEMPTY_KEY);
        boolean syntaxActive = redacBdfUser.getPrefs().getBoolean(BdfUserSpace.SYNTAXACTIVE_KEY);
        String dateInputs = redacBdfUser.getPrefs().getDateInputsType();
        commandBox = commandBox.derive(RedacteurCustomizeUICommand.COMMANDNAME, RedacteurCustomizeUICommand.COMMANDKEY)
                .__(insert(redacteur))
                .submitLocKey("_ submit.sphere.redacteurcustomizeui");
        hp
                .__start(commandBox)
                .__(Grid.START)
                .__(Grid.checkboxRow("_ label.sphere.notab", hp.name(RedacteurCustomizeUICommand.NOTAB_PARAMNAME).value("1").checked(noTab)))
                .__(Grid.checkboxRow("_ label.sphere.hideempty", hp.name(RedacteurCustomizeUICommand.HIDEEMPTY_PARAMNAME).value("1").checked(hideEmpty)))
                .__(Grid.checkboxRow("_ label.sphere.syntaxactive", hp.name(RedacteurCustomizeUICommand.SYNTAXACTIVE_PARAMNAME).value("1").checked(syntaxActive)))
                .__(Grid.choiceSetRow("_ label.sphere.dateinputs",
                        () -> {
                            hp
                                    .__(Grid.radioCell("_ label.sphere.dateinputs_iso", hp.name(RedacteurCustomizeUICommand.DATEINPUTS_PARAMNAME).value(BdfServerConstants.DATEINPUTS_ISO).checked(dateInputs)))
                                    .__(Grid.radioCell("_ label.sphere.dateinputs_inv", hp.name(RedacteurCustomizeUICommand.DATEINPUTS_PARAMNAME).value(BdfServerConstants.DATEINPUTS_INVERSE).checked(dateInputs)))
                                    .__(Grid.radioCell("_ label.sphere.dateinputs_usa", hp.name(RedacteurCustomizeUICommand.DATEINPUTS_PARAMNAME).value(BdfServerConstants.DATEINPUTS_USA).checked(dateInputs)));

                        }))
                .__(Grid.END)
                .__end(commandBox);
        return true;
    }


    public static boolean printRedacteurRoleBox(HtmlPrinter hp, CommandBox commandBox, BdfServer bdfServer, Lang lang, Redacteur redacteur) {
        PermissionManager permissionManager = bdfServer.getPermissionManager();
        boolean isAdmin = permissionManager.isAdmin(redacteur);
        Set<String> redacteurRoleNameSet = new HashSet<String>();
        for (Role redacteurRole : permissionManager.getRoleList(redacteur)) {
            redacteurRoleNameSet.add(redacteurRole.getName());
        }
        String status = redacteur.getStatus();
        commandBox = commandBox.derive(RedacteurRoleCommand.COMMANDNAME, RedacteurRoleCommand.COMMANDKEY)
                .__(insert(redacteur))
                .submitLocKey("_ submit.sphere.redacteurrole");
        hp
                .__start(commandBox);
        if (status.equals(FichothequeConstants.ACTIVE_STATUS)) {
            hp
                    .__(Grid.START)
                    .__(Grid.checkboxRow("_ label.sphere.admin", hp.name(RedacteurRoleCommand.ADMIN_PARAMNAME).value("1").checked(isAdmin)))
                    .__(Grid.END);
        }
        hp
                .H2()
                .__localize("_ title.sphere.rolelist")
                ._H2()
                .__(Choices.SPACED_LIST, () -> {
                    for (Role role : permissionManager.getRoleList()) {
                        String roleName = role.getName();
                        HtmlAttributes checkAttributes = hp.name(RedacteurRoleCommand.ROLE_PARAMNAME).value(roleName).checked(redacteurRoleNameSet.contains(roleName));
                        hp
                                .__(Choices.checkboxLi(checkAttributes,
                                        () -> {
                                            if (RoleUtils.isDefaultRole(role)) {
                                                hp
                                                        .EM()
                                                        .__localize("_ label.global.role_default")
                                                        ._EM();
                                            } else {
                                                hp
                                                        .__escape('[')
                                                        .__escape(role.getName())
                                                        .__escape(']');
                                            }
                                            hp
                                                    .__space()
                                                    .__escape(role.getTitleLabels().seekLabelString(lang, ""));
                                        }));
                    }
                })
                .__end(commandBox);
        return true;
    }

    public static boolean printRedacteurAttributeChangeBox(HtmlPrinter hp, CommandBox commandBox, Redacteur redacteur) {
        commandBox = commandBox.derive(RedacteurAttributeChangeCommand.COMMANDNAME, RedacteurAttributeChangeCommand.COMMANDKEY)
                .__(insert(redacteur))
                .actionCssClass("action-Attributes")
                .submitLocKey("_ submit.global.attributechange");
        hp
                .__start(commandBox)
                .__(Grid.START)
                .__(Grid.textAreaBlockRow("_ label.global.attributes", hp.name(RedacteurAttributeChangeCommand.ATTRIBUTES_PARAMNAME).rows(8).cols(75).attr("data-codemirror-mode", "attributes"),
                        new AttributesText(redacteur.getAttributes())))
                .__(Grid.END)
                .__end(commandBox);
        return true;
    }

    public static boolean printRedacteurStatusBox(HtmlPrinter hp, CommandBox commandBox, Redacteur redacteur) {
        String status = redacteur.getStatus();
        commandBox = commandBox.derive(RedacteurStatusCommand.COMMANDNAME, RedacteurStatusCommand.COMMANDKEY)
                .__(insert(redacteur))
                .submitLocKey("_ submit.sphere.redacteurstatus");
        hp
                .__start(commandBox)
                .__(Grid.START)
                .__(printStatusRow(hp, FichothequeConstants.ACTIVE_STATUS, status))
                .__(printStatusRow(hp, FichothequeConstants.READONLY_STATUS, status))
                .__(printStatusRow(hp, FichothequeConstants.INACTIVE_STATUS, status))
                .__(Grid.END)
                .__end(commandBox);
        return true;
    }


    public static boolean printRedacteurRemoveBox(HtmlPrinter hp, CommandBox commandBox, Redacteur redacteur) {
        commandBox = commandBox.derive(RedacteurRemoveCommand.COMMANDNAME, RedacteurRemoveCommand.COMMANDKEY)
                .__(insert(redacteur))
                .submitLocKey("_ submit.sphere.redacteurremove");
        hp
                .__start(commandBox)
                .__(Common.REMOVE_CONFIRM_CHECK)
                .__end(commandBox);
        return true;
    }

    public static boolean printRedacteurReplaceBox(HtmlPrinter hp, CommandBox commandBox, Redacteur redacteur) {
        String otherId = hp.generateId();
        String litteralId = hp.generateId();
        commandBox = commandBox.derive(RedacteurReplaceCommand.COMMANDNAME, RedacteurReplaceCommand.COMMANDKEY)
                .__(insert(redacteur))
                .submitLocKey("_ submit.sphere.redacteurreplace");
        hp
                .__start(commandBox)
                .__(Grid.START)
                .__(Grid.radioRow("_ label.sphere.otherlogin", hp.name(RedacteurReplaceCommand.REPLACETYPE_PARAMNAME).value(RedacteurReplaceCommand.OTHER_REPLACETYPE_PARAMVALUE).checked(true).populate(Deploy.radio(otherId)),
                        () -> {
                            HtmlAttributes inputAttributes = hp.name(RedacteurReplaceCommand.OTHER_PARAMNAME).size("30").populate(Appelant.user().limit(1));
                            hp
                                    .DIV(Grid.detailPanelTable().id(otherId))
                                    .__(Grid.textInputRow("_ label.global.value", inputAttributes))
                                    ._DIV();
                        }))
                .__(Grid.radioRow("_ label.sphere.litteral", hp.name(RedacteurReplaceCommand.REPLACETYPE_PARAMNAME).value(RedacteurReplaceCommand.LITTERAL_REPLACETYPE_PARAMVALUE).checked(false).populate(Deploy.radio(litteralId)),
                        () -> {
                            hp
                                    .DIV(Grid.detailPanelTable().id(litteralId).addClass("hidden"))
                                    .__(Grid.textInputRow("_ label.global.value", hp.name(RedacteurReplaceCommand.LITTERAL_PARAMNAME).size("30")))
                                    ._DIV();
                        }))
                .__(Grid.END)
                .__(Common.REPLACE_CONFIRM_CHECK)
                .__end(commandBox);
        return true;
    }


    private static class TransformationLists implements Consumer<HtmlPrinter> {

        private final BdfServer bdfServer;
        private final BdfUser redacBdfUser;
        private final Lang workingLang;
        private final List<TransformationCheck> specialList = new ArrayList<TransformationCheck>();
        private final List<TransformationCheck> byCorpusList = new ArrayList<TransformationCheck>();
        private final List<Corpus> corpusList = new ArrayList<Corpus>();
        private final TransformationManager transformationManager;
        private boolean specialLists = false;

        private TransformationLists(BdfServer bdfServer, Lang workingLang, BdfUser redacBdfUser) {
            this.bdfServer = bdfServer;
            this.workingLang = workingLang;
            this.redacBdfUser = redacBdfUser;
            this.transformationManager = bdfServer.getTransformationManager();
            addSpecialTransformation(TransformationKey.COMPILATION_INSTANCE);
            addSpecialTransformation(TransformationKey.STATTHESAURUS_INSTANCE);
            Fichotheque fichotheque = bdfServer.getFichotheque();
            for (Corpus corpus : fichotheque.getCorpusList()) {
                TransformationDescription transformationDescription = transformationManager.getTransformationDescription(new TransformationKey(corpus.getSubsetKey()));
                TransformationCheck transformationCheck = TransformationCheck.check(transformationDescription, true);
                if (transformationCheck.withTemplate()) {
                    byCorpusList.add(transformationCheck);
                    corpusList.add(corpus);
                }
            }
        }

        private void addSpecialTransformation(TransformationKey transformationKey) {
            TransformationDescription transformationDescription = transformationManager.getTransformationDescription(transformationKey);
            TransformationCheck transformationCheck = TransformationCheck.check(transformationDescription, true);
            if (transformationCheck.withTemplate()) {
                specialList.add(transformationCheck);
            }
        }

        public boolean isEmpty() {
            return (specialList.isEmpty()) && (byCorpusList.isEmpty());
        }

        public TransformationLists listSpecial() {
            this.specialLists = true;
            return this;
        }

        public TransformationLists listCorpus() {
            this.specialLists = false;
            return this;
        }

        @Override
        public void accept(HtmlPrinter hp) {
            if (specialLists) {
                if (!specialList.isEmpty()) {
                    hp
                            .H2()
                            .__localize("_ title.transformation.specialkeys")
                            ._H2()
                            .__(Grid.START);
                    for (TransformationCheck transformationCheck : specialList) {
                        String title = hp.getLocalization(getTransformationMessageKey(transformationCheck.getTransformationDescription().getTransformationKey()));
                        printTransformationCheck(hp, transformationCheck, title);
                    }
                    hp
                            .__(Grid.END);
                }
            } else {
                if (!byCorpusList.isEmpty()) {
                    hp
                            .H2()
                            .__localize("_ title.transformation.corpuskeys")
                            ._H2()
                            .__(Grid.START);
                    int size = byCorpusList.size();
                    for (int i = 0; i < size; i++) {
                        TransformationCheck transformationCheck = byCorpusList.get(i);
                        Corpus corpus = corpusList.get(i);
                        String title = FichothequeUtils.getTitle(corpus, workingLang);
                        printTransformationCheck(hp, transformationCheck, title);
                    }
                    hp
                            .__(Grid.END);
                }
            }
        }

        private boolean printTransformationCheck(HtmlPrinter hp, TransformationCheck transformationCheck, String title) {
            if (transformationCheck.withSimpleTemplate()) {
                String templateName = redacBdfUser.getPrefs().getSimpleTemplateName(transformationCheck.getTransformationKey());
                if (templateName == null) {
                    templateName = TemplateKey.DEFAULT_NAME;
                }
                String currentName = templateName;
                hp
                        .__(Grid.selectRow(new Litteral(title), hp.name(transformationCheck.getTransformationKey().getKeyString()),
                                () -> {
                                    hp
                                            .__(printDefaultOption(hp, true, currentName))
                                            .__(printOptionArray(hp, transformationCheck.getSimpleTemplateDescriptionArray(), currentName));
                                }));
            } else {
                hp
                        .__(Grid.START_ROW)
                        .__(Grid.labelCells(new Litteral(title)))
                        .__(Grid.END_ROW);
            }
            if (transformationCheck.withStreamTemplate()) {
                for (String extension : transformationCheck.getExtensionArray()) {
                    printStreamTemplateSelect(hp, transformationCheck, extension);
                }
            }
            return true;
        }

        private boolean printStreamTemplateSelect(HtmlPrinter hp, TransformationCheck transformationCheck, String extension) {
            TransformationKey transformationKey = transformationCheck.getTransformationKey();
            boolean isDefaultStreamTemplateAvailable = bdfServer.getTransformationManager().isDefaultStreamTemplateAvailable(transformationKey, extension);
            TemplateDescription[] templateDescriptionArray = transformationCheck.getStreamTemplateDescriptionArray(extension);
            String currentName = redacBdfUser.getPrefs().getStreamTemplateName(transformationKey, extension);
            if (currentName == null) {
                currentName = TemplateKey.DEFAULT_NAME;
            }
            if ((!isDefaultStreamTemplateAvailable) && (currentName.equals(TemplateKey.DEFAULT_NAME))) {
                currentName = templateDescriptionArray[0].getTemplateKey().getName();
            }
            HtmlAttributes selectAttributes = hp.name(transformationKey + "/" + extension);
            hp
                    .__(Grid.START_ROW)
                    .__(Grid.START_INPUTCELL)
                    .SPAN()
                    .LABEL_for(selectAttributes.id())
                    .__escape('.')
                    .__escape(extension)
                    .__colon()
                    ._LABEL()
                    .__space()
                    .SELECT(selectAttributes)
                    .__(printDefaultOption(hp, isDefaultStreamTemplateAvailable, currentName))
                    .__(printOptionArray(hp, templateDescriptionArray, currentName))
                    ._SELECT()
                    ._SPAN()
                    .__(Grid.END_INPUTCELL)
                    .__(Grid.END_ROW);
            return true;
        }

        private boolean printDefaultOption(HtmlPrinter hp, boolean defaultAvailable, String currentName) {
            if (!defaultAvailable) {
                return false;
            }
            hp
                    .OPTION(TemplateKey.DEFAULT_NAME, (currentName.equals(TemplateKey.DEFAULT_NAME)))
                    .__localize("_ label.transformation.defaulttemplate")
                    ._OPTION();
            return true;
        }

        private boolean printOptionArray(HtmlPrinter hp, TemplateDescription[] templateDescriptionArray, String currentName) {
            for (TemplateDescription templateDescription : templateDescriptionArray) {
                hp
                        .__(printOption(hp, templateDescription, currentName));
            }
            return true;
        }

        private boolean printOption(HtmlPrinter hp, TemplateDescription templateDescription, String currentName) {
            String templateName = templateDescription.getTemplateKey().getName();
            hp
                    .OPTION(templateName, templateName.equals(currentName))
                    .__escape(templateDescription.getTitle(workingLang))
                    ._OPTION();
            return true;
        }

    }

    private static String getTransformationMessageKey(TransformationKey transformationKey) {
        switch (transformationKey.getKeyString()) {
            case TransformationKey.COMPILATION:
                return "_ label.transformation.templates_compilation";
            case TransformationKey.STATTHESAURUS:
                return "_ label.transformation.templates_statthesaurus";
            case TransformationKey.INVERSETHESAURUS:
                return "_ label.transformation.templates_inversethesaurus";
            case TransformationKey.SECTION:
                return "_ label.transformation.templates_section";
            case TransformationKey.FORMAT:
                return "_ label.transformation.templates_format";
            case TransformationKey.MEMENTO:
                return "_ label.transformation.templates_memento";
            default:
                throw new SwitchException("Unknown transformationKey: " + transformationKey);
        }
    }

    private static boolean printStatusRow(HtmlPrinter hp, String status, String currentStatus) {
        hp
                .__(Grid.radioRow(getStatusMessageKey(status), hp.name(RedacteurStatusCommand.STATUS_PARAMNAME).value(status).checked(currentStatus)));
        return true;
    }

    private static String getStatusMessageKey(String status) {
        switch (status) {
            case FichothequeConstants.ACTIVE_STATUS:
                return "_ label.sphere.status_active";
            case FichothequeConstants.READONLY_STATUS:
                return "_ label.sphere.status_readonly";
            case FichothequeConstants.INACTIVE_STATUS:
                return "_ label.sphere.status_inactive";
            default:
                throw new SwitchException("Unknown status: " + status);
        }
    }

}
