/* BdfServer_Html - Copyright (c) 2010-2024 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.html.forms;

import fr.exemole.bdfserver.api.ficheform.AmountInfoSubfieldsElement;
import fr.exemole.bdfserver.api.ficheform.AmountPropSubfieldsElement;
import fr.exemole.bdfserver.api.ficheform.FormElement;
import fr.exemole.bdfserver.api.ficheform.GeopointPropSubfieldsElement;
import fr.exemole.bdfserver.api.ficheform.HiddenFieldElement;
import fr.exemole.bdfserver.api.ficheform.ImagePropSubfieldsElement;
import fr.exemole.bdfserver.api.ficheform.ItemFieldElement;
import fr.exemole.bdfserver.api.ficheform.LangFieldElement;
import fr.exemole.bdfserver.api.ficheform.PersonnePropSubfieldsElement;
import fr.exemole.bdfserver.api.ficheform.TextFieldElement;
import fr.exemole.bdfserver.api.namespaces.BdfUserSpace;
import fr.exemole.bdfserver.api.namespaces.FicheFormSpace;
import fr.exemole.bdfserver.html.consumers.FicheForm;
import java.util.List;
import java.util.Map;
import net.fichotheque.SubsetKey;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.metadata.AmountSubfieldKey;
import net.fichotheque.corpus.metadata.CorpusField;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.corpus.metadata.SubfieldKey;
import net.mapeadores.util.attr.Attribute;
import net.mapeadores.util.attr.AttributeKey;
import net.mapeadores.util.attr.Attributes;
import net.mapeadores.util.exceptions.ImplementationException;
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.models.PersonCore;
import net.mapeadores.util.money.Currencies;
import net.mapeadores.util.money.ExtendedCurrency;
import net.mapeadores.util.text.MultiStringable;
import net.mapeadores.util.text.StringUtils;


/**
 * Série de méthodes statiques traduisant en code HTML des instances de
 * FieldElement.
 *
 * @author Vincent Calame
 */
public final class CorpusFieldFormHtml {

    private CorpusFieldFormHtml() {

    }

    public static boolean print(HtmlPrinter hp, FormElement.Field formElement, FormHandler formHandler) {
        if (formElement instanceof TextFieldElement) {
            printTextField(hp, (TextFieldElement) formElement, formHandler);
        } else if (formElement instanceof LangFieldElement) {
            printLangField(hp, (LangFieldElement) formElement, formHandler);
        } else if (formElement instanceof PersonnePropSubfieldsElement) {
            printPersonPropSubfields(hp, (PersonnePropSubfieldsElement) formElement, formHandler);
        } else if (formElement instanceof GeopointPropSubfieldsElement) {
            printGeopointPropSubfields(hp, (GeopointPropSubfieldsElement) formElement, formHandler);
        } else if (formElement instanceof AmountPropSubfieldsElement) {
            printAmountPropSubfields(hp, (AmountPropSubfieldsElement) formElement, formHandler);
        } else if (formElement instanceof AmountInfoSubfieldsElement) {
            printAmountInfoSubfields(hp, (AmountInfoSubfieldsElement) formElement, formHandler);
        } else if (formElement instanceof ItemFieldElement) {
            printItemField(hp, (ItemFieldElement) formElement, formHandler);
        } else if (formElement instanceof HiddenFieldElement) {
            printHiddenField(hp, (HiddenFieldElement) formElement, formHandler);
        } else if (formElement instanceof ImagePropSubfieldsElement) {
            printImagePropSubfields(hp, (ImagePropSubfieldsElement) formElement, formHandler);
        } else {
            return false;
        }
        return true;
    }

    public static boolean printImagePropSubfields(HtmlPrinter hp, ImagePropSubfieldsElement formElement, FormHandler formHandler) {
        CorpusField corpusField = formElement.getCorpusField();
        FieldKey fieldKey = corpusField.getFieldKey();
        String src = formElement.getSrc();
        String srcName = formHandler.getPrefixedName(fieldKey, SubfieldKey.SRC_SUBTYPE);
        String altString = formElement.getAlt();
        String altName = formHandler.getPrefixedName(fieldKey, SubfieldKey.ALT_SUBTYPE);
        String titleString = formElement.getTitle();
        String titleName = formHandler.getPrefixedName(fieldKey, SubfieldKey.TITLE_SUBTYPE);
        String genId = hp.generateId();
        String srcId = genId + "_src";
        String altId = genId + "_alt";
        String titleId = genId + "_title";
        hp
                .SECTION(formHandler.getEntryAttributes(formElement))
                .__(CommonFormHtml.printStandardLabel(hp, formElement, formHandler.getWorkingLang(), srcId))
                .__(FicheForm.STANDARD_CELL, () -> {
                    hp
                            .TABLE("ficheform-SubfieldsTable")
                            .__(startSubFieldRow(hp, "_ label.edition.src", srcId))
                            .INPUT_text(HA.name(srcName).id(srcId).value(src).size("45"))
                            .__(endSubfieldRow(hp))
                            .__(startSubFieldRow(hp, "_ label.edition.alt", altId))
                            .INPUT_text(HA.name(altName).id(altId).value(altString).size("45"))
                            .__(endSubfieldRow(hp))
                            .__(startSubFieldRow(hp, "_ label.edition.title", titleId))
                            .INPUT_text(HA.name(titleName).id(titleId).value(titleString).size("45"))
                            .__(endSubfieldRow(hp))
                            ._TABLE();
                })
                ._SECTION();
        return true;
    }

    public static boolean printLangField(HtmlPrinter hp, LangFieldElement formElement, FormHandler formHandler) {
        if (formElement.getAvailableLangArray() != null) {
            printSelectLangField(hp, formElement, formHandler);
            return false;
        }
        String name = formHandler.getPrefixedName(formElement);
        String langId = hp.generateId();
        Lang currentLang = formElement.getLang();
        String langString;
        if (currentLang == null) {
            langString = "";
        } else {
            langString = currentLang.toString();
        }
        hp
                .SECTION(formHandler.getEntryAttributes(formElement, "language-code").attr("data-ficheform-limit", "1"))
                .__(CommonFormHtml.printStandardLabel(hp, formElement, formHandler.getWorkingLang(), langId))
                .__(FicheForm.STANDARD_CELL, () -> {
                    hp
                            .INPUT_text(HA.name(name).id(langId).size("4").value(langString).classes("ficheform-XSmall").attr("data-ficheform-role", "textinput"));
                })
                ._SECTION();
        return true;
    }

    private static boolean printSelectLangField(HtmlPrinter hp, LangFieldElement formElement, FormHandler formHandler) {
        String name = formHandler.getPrefixedName(formElement);
        Lang currentLang = formElement.getLang();
        Lang[] array = formElement.getAvailableLangArray();
        int length = array.length;
        if (length == 0) {
            throw new ImplementationException("formElement.getAvailableLangArray().length == 0");
        } else if ((length == 1) && ((currentLang == null) || (currentLang.equals(array[0])))) {
            hp
                    .INPUT_hidden(name, array[0].toString());
            return false;
        }
        String langId = hp.generateId();
        hp
                .SECTION(formHandler.getEntryAttributes(formElement))
                .__(CommonFormHtml.printStandardLabel(hp, formElement, formHandler.getWorkingLang(), langId))
                .__(FicheForm.STANDARD_CELL, () -> {
                    hp
                            .SELECT(HA.name(name).id(langId));
                    boolean here = false;
                    for (int i = 0; i < length; i++) {
                        Lang availableLang = array[i];
                        String currLangString = availableLang.toString();
                        boolean selected = false;
                        if (currentLang != null) {
                            selected = availableLang.equals(currentLang);
                        } else if (i == 0) {
                            selected = true;
                        }
                        if (selected) {
                            here = true;
                        }
                        hp
                                .OPTION(currLangString, selected)
                                .__escape(currLangString)
                                .__dash()
                                .__localize(currLangString)
                                ._OPTION();
                    }
                    if (!here) {
                        String otherLangString = currentLang.toString();
                        hp
                                .OPTION(otherLangString, true)
                                .__escape(otherLangString)
                                .__dash()
                                .__localize(otherLangString)
                                ._OPTION();
                    }
                    hp
                            ._SELECT();
                })
                ._SECTION();
        return true;
    }

    public static boolean printHiddenField(HtmlPrinter hp, HiddenFieldElement formElement, FormHandler formHandler) {
        String name = formHandler.getPrefixedName(formElement);
        hp
                .DIV()
                .INPUT_hidden(name, formElement.getValue())
                ._DIV();
        return true;
    }

    public static boolean printItemField(HtmlPrinter hp, ItemFieldElement formElement, FormHandler formHandler) {
        CorpusField corpusField = formElement.getCorpusField();
        String name = formHandler.getPrefixedName(formElement);
        String entryType = getEntryType(formElement);
        String widthType = formElement.getWidthType();
        int defaultSize = CommonFormHtml.getDefaultSize(widthType);
        String defaultSphereParam = null;
        SubsetKey sphereKey = formElement.getSphereKey();
        if (sphereKey != null) {
            defaultSphereParam = sphereKey.getKeyString();
        }
        int rows = formElement.getRows();
        String spellcheckValue = getSpellcheckValue(corpusField, formElement.getAttributes());
        String specificLang = null;
        if (spellcheckValue != null) {
            specificLang = getSpecificLang(formElement, formHandler);
        }
        HtmlAttributes inputAttr = hp.name(name).classes(CommonFormHtml.getCssClass(widthType)).attr("data-ficheform-role", "textinput").attr("spellcheck", spellcheckValue).attr("lang", specificLang);
        CommonFormHtml.addTextInputAttributes(inputAttr, formElement.getAttributes(), formHandler.getWorkingLang());
        hp
                .SECTION(formHandler.getEntryAttributes(formElement, entryType)
                        .attr((entryType != null), "data-ficheform-limit", getPiocheLimit(corpusField))
                        .attr("data-ficheform-defaultsphere", defaultSphereParam))
                .__(CommonFormHtml.printStandardLabel(hp, formElement, formHandler.getWorkingLang(), inputAttr.id()))
                .__(FicheForm.getMatchingCellHtmlWrapper(rows), () -> {
                    if (rows == 1) {
                        hp
                                .INPUT_text(inputAttr.value(formElement.getValue()).size(String.valueOf(defaultSize)));
                    } else {
                        hp
                                .TEXTAREA(inputAttr.cols(defaultSize).rows(rows))
                                .__escape(formElement.getValue(), true)
                                ._TEXTAREA();
                    }
                })
                ._SECTION();
        return true;
    }

    public static boolean printAmountPropSubfields(HtmlPrinter hp, AmountPropSubfieldsElement formElement, FormHandler formHandler) {
        CorpusField corpusField = formElement.getCorpusField();
        String currentCur = formElement.getCur();
        FieldKey fieldKey = corpusField.getFieldKey();
        String genId = hp.generateId();
        hp
                .SECTION(formHandler.getEntryAttributes(formElement))
                .__(CommonFormHtml.printStandardLabel(hp, formElement, formHandler.getWorkingLang(), genId))
                .__(FicheForm.STANDARD_CELL, () -> {
                    if (formElement.isUnique()) {
                        hp
                                .EM()
                                .__escape(currentCur)
                                ._EM()
                                .INPUT_hidden(formHandler.getPrefixedName(fieldKey, SubfieldKey.CURRENCY_SUBTYPE), currentCur);
                    } else {
                        boolean inSelection = false;
                        Currencies currencies = formElement.getCurrencies();
                        hp.
                                SELECT(formHandler.getPrefixedName(fieldKey, SubfieldKey.CURRENCY_SUBTYPE));
                        for (ExtendedCurrency currency : currencies) {
                            String curString = currency.getCurrencyCode();
                            boolean selected = curString.equals(formElement.getCur());
                            if (selected) {
                                inSelection = true;
                            }
                            hp
                                    .OPTION(curString, selected)
                                    .__escape(curString)
                                    ._OPTION();
                        }
                        if (!inSelection) {
                            hp
                                    .OPTION(formElement.getCur(), true)
                                    .__escape('?')
                                    .__escape(formElement.getCur())
                                    .__escape('?')
                                    ._OPTION();
                        }
                        hp
                                ._SELECT();
                    }
                    hp
                            .__space()
                            .INPUT_text(HA.name(formHandler.getPrefixedName(fieldKey, SubfieldKey.VALUE_SUBTYPE)).id(genId).value(formElement.getNum()).size("30"));
                })
                ._SECTION();
        return true;
    }

    public static boolean printAmountInfoSubfields(HtmlPrinter hp, AmountInfoSubfieldsElement formElement, FormHandler formHandler) {
        CorpusField corpusField = formElement.getCorpusField();
        FieldKey fieldKey = corpusField.getFieldKey();
        String genId = hp.generateId();
        List<AmountInfoSubfieldsElement.Entry> entryList = formElement.getEntryList();
        String firstId;
        if (entryList.size() > 0) {
            firstId = genId + "_" + entryList.get(0).getCurrency().getCurrencyCode();
        } else {
            firstId = genId + "_others";
        }
        hp
                .SECTION(formHandler.getEntryAttributes(formElement))
                .__(CommonFormHtml.printStandardLabel(hp, formElement, formHandler.getWorkingLang(), firstId))
                .__(FicheForm.STANDARD_CELL, () -> {
                    hp
                            .TABLE("ficheform-SubfieldsTable");
                    for (AmountInfoSubfieldsElement.Entry entry : entryList) {
                        ExtendedCurrency currency = entry.getCurrency();
                        AmountSubfieldKey subfieldKey = new AmountSubfieldKey(fieldKey, currency);
                        String subname = formHandler.getPrefixedName(subfieldKey.getKeyString());
                        String currencyId = genId + "_" + currency.getCurrencyCode();
                        hp
                                .__(startCurrencySubFieldRow(hp, currency, currencyId))
                                .INPUT_text(HA.name(subname).id(currencyId).value(entry.getAmountValue()).size("30"))
                                .__(endSubfieldRow(hp));
                    }
                    String wrong = formElement.getOthersValue();
                    if (wrong.length() > 0) {
                        String wrongName = formHandler.getPrefixedName(fieldKey, SubfieldKey.OTHERS_SUBTYPE);
                        String othersId = genId + "_others";
                        hp
                                .__(startSubFieldRow(hp, "_ label.edition.others", othersId))
                                .TEXTAREA(HA.name(wrongName).id(othersId).rows(4).cols(45))
                                .__escape(wrong, true)
                                ._TEXTAREA()
                                .__(endSubfieldRow(hp));
                    }
                    hp
                            ._TABLE();
                })
                ._SECTION();
        return true;
    }

    public static boolean printGeopointPropSubfields(HtmlPrinter hp, GeopointPropSubfieldsElement formElement, FormHandler formHandler) {
        CorpusField corpusField = formElement.getCorpusField();
        Attributes formAttributes = formElement.getAttributes();
        String name = formHandler.getPrefixedName(formElement);
        FieldKey fieldKey = corpusField.getFieldKey();
        MultiStringable fieldNames = formElement.getAddressFieldNames();
        String latName = formHandler.getPrefixedName(fieldKey, SubfieldKey.LATITUDE_SUBTYPE);
        String lonName = formHandler.getPrefixedName(fieldKey, SubfieldKey.LONGITUDE_SUBTYPE);
        String genId = hp.generateId();
        String latId = genId + "_lat";
        String lonId = genId + "_lon";
        String addressFields = null;
        if (fieldNames != null) {
            StringBuilder buf = new StringBuilder();
            boolean next = false;
            for (String fieldName : fieldNames.toStringArray()) {
                if (next) {
                    buf.append(",");
                } else {
                    next = true;
                }
                buf.append(formHandler.getPrefixedName(fieldName));
            }
            addressFields = buf.toString();
        }
        hp
                .SECTION(formHandler.getEntryAttributes(formElement, "geocodage")
                        .attr("data-ficheform-addressfields", addressFields)
                        .attr("data-ficheform-geostart-lat", formAttributes.getFirstValue(FicheFormSpace.GEOSTART_LAT_KEY))
                        .attr("data-ficheform-geostart-lon", formAttributes.getFirstValue(FicheFormSpace.GEOSTART_LON_KEY))
                        .attr("data-ficheform-geostart-zoom", formAttributes.getFirstValue(FicheFormSpace.GEOSTART_ZOOM_KEY))
                )
                .__(CommonFormHtml.printStandardLabel(hp, formElement, formHandler.getWorkingLang(), latId))
                .__(FicheForm.STANDARD_CELL, () -> {
                    hp
                            .TABLE("ficheform-SubfieldsTable")
                            .__(startSubFieldRow(hp, "_ label.edition.latitude", latId))
                            .INPUT_text(HA.name(latName).id(latId).value(formElement.getLatitude()).size("15").attr("data-ficheform-role", "latitude"))
                            .__(endSubfieldRow(hp))
                            .__(startSubFieldRow(hp, "_ label.edition.longitude", lonId))
                            .INPUT_text(HA.name(lonName).id(lonId).value(formElement.getLongitude()).size("15").attr("data-ficheform-role", "longitude"))
                            .__(endSubfieldRow(hp))
                            ._TABLE();
                })
                ._SECTION();
        return true;
    }

    public static boolean printPersonPropSubfields(HtmlPrinter hp, PersonnePropSubfieldsElement formElement, FormHandler formHandler) {
        CorpusField corpusField = formElement.getCorpusField();
        FieldKey fieldKey = corpusField.getFieldKey();
        PersonCore personCore = formElement.getPersonCore();
        boolean withNonlatin = formElement.isWithNonlatin();
        if (personCore.getNonlatin().length() > 0) {
            withNonlatin = true;
        }
        HtmlAttributes inputAttr = HA.classes("ficheform-Medium").size("30");
        String surnameParamName = formHandler.getPrefixedName(fieldKey, SubfieldKey.SURNAME_SUBTYPE);
        String forenameParamName = formHandler.getPrefixedName(fieldKey, SubfieldKey.FORENAME_SUBTYPE);
        String genId = hp.generateId();
        String surnameId = genId + "_surname";
        String forenameId = genId + "_forename";
        hp
                .SECTION(formHandler.getEntryAttributes(formElement))
                .__(printStandardLabel(hp, hp.getLocalization((withNonlatin) ? "_ label.sphere.surname_latin" : "_ label.sphere.surname"), surnameId))
                .__(FicheForm.STANDARD_CELL, () -> {
                    hp
                            .INPUT_text(inputAttr.name(surnameParamName).id(surnameId).value(personCore.getSurname()));
                })
                ._SECTION();
        hp
                .SECTION(formHandler.getEntryAttributes(forenameParamName, formElement))
                .__(printStandardLabel(hp, hp.getLocalization((withNonlatin) ? "_ label.sphere.forename_latin" : "_ label.sphere.forename"), forenameId))
                .__(FicheForm.STANDARD_CELL, () -> {
                    hp
                            .INPUT_text(inputAttr.name(forenameParamName).id(forenameId).value(personCore.getForename()));
                });
        if ((!formElement.isWithoutSurnameFirst()) || (personCore.isSurnameFirst())) {
            hp
                    .__(FicheForm.STANDARD_CELL, () -> {
                        String surnameFirstParamName = formHandler.getPrefixedName(fieldKey, SubfieldKey.SURNAMEFIRST_SUBTYPE);
                        String surnameFirstId = genId + "_surnamefirst";
                        hp
                                .DIV("ficheform-Choice")
                                .INPUT_checkbox(HA.name(surnameFirstParamName).id(surnameFirstId).value("1").checked(personCore.isSurnameFirst()))
                                .LABEL_for(surnameFirstId)
                                .__localize("_ label.sphere.surnamefirst")
                                ._LABEL()
                                ._DIV();
                    });
        }
        hp
                ._SECTION();
        if (withNonlatin) {
            String nonlatinParamName = formHandler.getPrefixedName(fieldKey, SubfieldKey.NONLATIN_SUBTYPE);
            String nonlatinId = genId + "_nonlatin";
            hp
                    .SECTION(formHandler.getEntryAttributes(nonlatinParamName, formElement))
                    .__(printStandardLabel(hp, hp.getLocalization("_ label.sphere.nonlatin"), nonlatinId))
                    .__(FicheForm.STANDARD_CELL, () -> {
                        hp
                                .INPUT_text(inputAttr.name(nonlatinParamName).id(nonlatinId).value(personCore.getNonlatin()));
                    })
                    ._SECTION();
        }
        return true;
    }

    public static boolean printTextField(HtmlPrinter hp, TextFieldElement formElement, FormHandler formHandler) {
        String textId = hp.generateId();
        CorpusField corpusField = formElement.getCorpusField();
        Corpus corpus = corpusField.getCorpusMetadata().getCorpus();
        String fieldString = corpusField.getFieldString();
        String name = formHandler.getPrefixedName(formElement);
        String specificLang = getSpecificLang(formElement, formHandler);
        boolean noSpellCheck = isNoSpellCheck(formElement);
        HtmlAttributes textAreaAttributes = HA.name(name)
                .id(textId)
                .cols(77)
                .rows(formElement.getRows())
                .attr("data-ficheform-role", "sectiontext")
                .attr("lang", specificLang)
                .attr(noSpellCheck, "spellcheck", "false")
                .attr("data-user-key", fieldString)
                .attr("data-user-spellcheck", getActiveValue(corpus, formHandler, fieldString, "spellcheck"))
                .attr("data-user-syntax", getActiveValue(corpus, formHandler, fieldString, "syntax"))
                .attr("data-matching-lines", getMatchingArray(formElement.getMatchingMap()));
        hp
                .SECTION(formHandler.getEntryAttributes(formElement, "section", "ficheform-section-Entry"))
                .__breakLine();
        hp
                .DIV("ficheform-section-Label")
                .LABEL(CommonFormHtml.addTooltip(HA.forId(textId).attr("data-ficheform-role", "label"), formElement.getAttributes(), formHandler.getWorkingLang()))
                .__escape(formElement.getLabel())
                ._LABEL()
                .SPAN("ficheform-section-Colon")
                .__colon()
                ._SPAN()
                ._DIV();
        hp
                .DIV(HA.attr("data-ficheform-role", "section-area").classes("ficheform-section-Area").attr("lang", specificLang))
                .__breakLine()
                .TEXTAREA(textAreaAttributes)
                .__escape(formElement.getFormattedText(), true)
                ._TEXTAREA()
                .__breakLine()
                ._DIV()
                ._SECTION();
        return true;
    }

    private static String getMatchingArray(Map<String, Integer> matchingMap) {
        boolean next = false;
        StringBuilder buf = new StringBuilder();
        buf.append('[');
        for (Map.Entry<String, Integer> entry : matchingMap.entrySet()) {
            if (next) {
                buf.append(',');
            } else {
                next = true;
            }
            buf.append('\"');
            buf.append(entry.getKey());
            buf.append("\",");
            buf.append(entry.getValue());
        }
        buf.append(']');
        return buf.toString();
    }

    private static String getEntryType(ItemFieldElement formElement) {
        Attribute entryType = formElement.getAttributes().getAttribute(FicheFormSpace.ENTRYTYPE_KEY);
        if (entryType != null) {
            String val = entryType.getFirstValue();
            if (val.equals("none")) {
                return null;
            } else {
                return val;
            }
        }
        String type = getEntryTypeFromFicheItemType(formElement);
        if (type != null) {
            return type;
        }
        if (isMaxLengthField(formElement.getCorpusField())) {
            Attribute maxlength = formElement.getAttributes().getAttribute(FicheFormSpace.MAXLENGTH_KEY);
            if (maxlength != null) {
                try {
                    int maxLengthValue = Integer.parseInt(maxlength.getFirstValue());
                    if (maxLengthValue > 0) {
                        return "text-maxlength";
                    }
                } catch (NumberFormatException nfe) {

                }
            }
        }
        return null;
    }

    private static String getEntryTypeFromFicheItemType(ItemFieldElement formElement) {
        CorpusField corpusField = formElement.getCorpusField();
        switch (corpusField.getFicheItemType()) {
            case CorpusField.PERSON_FIELD:
                return "user-code";
            case CorpusField.LANGUAGE_FIELD:
                return "language-code";
            case CorpusField.COUNTRY_FIELD:
                return "country-code";
            case CorpusField.DATE_FIELD:
                if (corpusField.isProp()) {
                    return "date-unique";
                } else {
                    return null;
                }
            default:
                return null;
        }
    }

    private static boolean isMaxLengthField(CorpusField corpusField) {
        switch (corpusField.getFicheItemType()) {
            case CorpusField.ITEM_FIELD:
            case CorpusField.PARA_FIELD:
                return true;
            default: {
                switch (corpusField.getFieldString()) {
                    case FieldKey.SPECIAL_TITLE:
                        return true;
                    default:
                        return false;
                }
            }
        }
    }

    private static String getPiocheLimit(CorpusField corpusField) {
        if (corpusField.isProp()) {
            return "1";
        } else {
            return "-1";
        }
    }

    private static String getActiveValue(Corpus corpus, FormHandler formHandler, String fieldString, String type) {
        Map<String, String> storeMap = formHandler.getFormParameters().getStoreMap(corpus.getSubsetKey());
        String value = storeMap.get(fieldString + "_" + type);
        if (value != null) {
            if (StringUtils.isTrue(value)) {
                return "active";
            } else {
                return "inactive";
            }
        }
        AttributeKey attributeKey = null;
        switch (type) {
            case "spellcheck":
                attributeKey = BdfUserSpace.toSpellcheckAttributeKey(corpus);
                break;
            case "syntax":
                attributeKey = BdfUserSpace.toSyntaxAttributeKey(corpus);
                break;
        }
        if (attributeKey != null) {
            return getActiveValue(formHandler.getFormParameters().getUserAttributes(), attributeKey, fieldString);
        } else {
            return null;
        }
    }

    private static String getActiveValue(Attributes userAttributes, AttributeKey attributeKey, String fieldString) {
        Attribute attribute = userAttributes.getAttribute(attributeKey);
        if (attribute == null) {
            return null;
        }
        String inactiveField = "!" + fieldString;
        for (String value : attribute) {
            if (value.equals(fieldString)) {
                return "active";
            } else if (value.equals(inactiveField)) {
                return "inactive";
            }
        }
        return null;
    }


    private static boolean startSubFieldRow(HtmlPrinter hp, String messageKey, String inputId) {
        hp
                .TR()
                .TD()
                .__doublespace()
                .LABEL_for(inputId)
                .__localize(messageKey)
                ._LABEL()
                ._TD()
                .TD();
        return true;
    }

    private static boolean startCurrencySubFieldRow(HtmlPrinter hp, ExtendedCurrency currency, String currencyId) {
        hp
                .TR()
                .TD()
                .__doublespace()
                .LABEL_for(currencyId)
                .__escape(currency.toString())
                ._LABEL()
                ._TD()
                .TD();
        return true;
    }

    private static boolean endSubfieldRow(HtmlPrinter hp) {
        hp
                ._TD()
                ._TR();
        return true;
    }

    public static boolean printStandardLabel(HtmlPrinter hp, String labelText, String inputId) {
        hp
                .__breakLine()
                .LABEL(HA.forId(inputId).attr("data-ficheform-role", "label").classes("ficheform-standard-Label"))
                .__escape(labelText)
                ._LABEL()
                .__breakLine()
                .SPAN("ficheform-standard-Colon")
                .__escape(':')
                ._SPAN()
                .__breakLine();
        return true;
    }

    private static String getSpecificLang(FormElement formElement, FormHandler formHandler) {
        Attribute attribute = formElement.getAttributes().getAttribute(FicheFormSpace.LANG_KEY);
        if (attribute != null) {
            return attribute.getFirstValue();
        }
        Lang ficheLang = formHandler.getFormParameters().ficheLang();
        if (ficheLang != null) {
            String langString = ficheLang.toString();
            switch (langString) {
                case "und":
                case "zxx":
                    return null;
                default:
                    return langString;
            }
        } else {
            return null;
        }
    }

    private static boolean isNoSpellCheck(FormElement formElement) {
        Attribute attribute = formElement.getAttributes().getAttribute(FicheFormSpace.SPELLCHECK_KEY);
        if (attribute == null) {
            return false;
        } else {
            return !attribute.isTrue();
        }
    }

    private static String getSpellcheckValue(CorpusField corpusField, Attributes attributes) {
        boolean isWithDefault = withDefaultSpellCheck(corpusField);
        Attribute attribute = attributes.getAttribute(FicheFormSpace.SPELLCHECK_KEY);
        if (attribute == null) {
            if (isWithDefault) {
                return "true";
            } else {
                return null;
            }
        } else {
            if (attribute.isTrue()) {
                return "true";
            } else {
                return "false";
            }
        }
    }

    private static boolean withDefaultSpellCheck(CorpusField corpusField) {
        if (corpusField.isType(CorpusField.PARA_FIELD)) {
            return true;
        }
        if (corpusField.getFieldKey().equals(FieldKey.TITLE)) {
            return true;
        }
        return false;
    }

}
