/* BdfServer - Copyright (c) 2014-2023 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.tools;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.ficheform.FicheFormParameters;
import fr.exemole.bdfserver.api.managers.L10nManager;
import fr.exemole.bdfserver.api.ui.CommentUi;
import fr.exemole.bdfserver.api.ui.DataUi;
import fr.exemole.bdfserver.api.ui.FieldUi;
import fr.exemole.bdfserver.api.ui.IncludeUi;
import fr.exemole.bdfserver.api.ui.SpecialIncludeUi;
import fr.exemole.bdfserver.api.ui.SubsetIncludeUi;
import fr.exemole.bdfserver.api.ui.UiComponent;
import net.fichotheque.FichothequeConstants;
import net.fichotheque.Subset;
import net.fichotheque.SubsetKey;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.metadata.CorpusField;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.include.ExtendedIncludeKey;
import net.fichotheque.thesaurus.metadata.ThesaurusFieldKey;
import net.fichotheque.utils.FichothequeUtils;
import net.mapeadores.util.annotation.Nullable;
import net.mapeadores.util.exceptions.SwitchException;
import net.mapeadores.util.html.TrustedHtml;
import net.mapeadores.util.localisation.Lang;
import net.mapeadores.util.localisation.Langs;
import net.mapeadores.util.localisation.MessageLocalisation;
import net.mapeadores.util.text.Label;
import net.mapeadores.util.text.LabelChangeBuilder;
import net.mapeadores.util.text.Labels;


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

    private L10nUtils() {

    }

    @Nullable
    public static String getTitle(BdfServer bdfServer, Corpus corpus, UiComponent componentUi, Lang lang) {
        if (componentUi instanceof FieldUi) {
            CorpusField corpusField = corpus.getCorpusMetadata().getCorpusField(((FieldUi) componentUi).getFieldKey());
            if (corpusField != null) {
                return getCorpusFieldTitle(corpusField, lang);
            } else {
                return null;
            }
        } else if (componentUi instanceof IncludeUi) {
            return getIncludeTitle(bdfServer, (IncludeUi) componentUi, lang);
        } else if (componentUi instanceof CommentUi) {
            return getCommentTitle((CommentUi) componentUi, lang);
        } else if (componentUi instanceof DataUi) {
            return getDataTitle((DataUi) componentUi, lang);
        }
        return null;
    }

    @Nullable
    public static String getCommentTitle(CommentUi commentUi, Lang lang) {
        TrustedHtml html = commentUi.getHtmlByLang(lang);
        if (html != null) {
            String htmlString = html.toString();
            if (htmlString.length() > 33) {
                htmlString = htmlString.substring(0, 32) + "…";
            }
            htmlString = htmlString.replace('\n', ' ');
            return htmlString;
        } else {
            return null;
        }
    }

    @Nullable
    public static String getCorpusFieldTitle(CorpusField corpusField, Lang lang) {
        Label label = corpusField.getLabels().getLangPartCheckedLabel(lang);
        if (label != null) {
            return label.getLabelString();
        } else {
            return null;
        }
    }

    @Nullable
    public static String getIncludeTitle(BdfServer bdfServer, IncludeUi includeUi, Lang lang) {
        Labels labels = includeUi.getCustomLabels();
        if (labels != null) {
            Label label = labels.getLangPartCheckedLabel(lang);
            if (label != null) {
                return label.getLabelString();
            }
        }
        if (includeUi instanceof SpecialIncludeUi) {
            return getSpecialIncludeTitle(bdfServer, includeUi.getName(), lang);
        }
        if (!(includeUi instanceof SubsetIncludeUi)) {
            return null;
        }
        ExtendedIncludeKey includeKey = ((SubsetIncludeUi) includeUi).getExtendedIncludeKey();
        SubsetKey subsetKey = includeKey.getSubsetKey();
        Subset subset = bdfServer.getFichotheque().getSubset(subsetKey);
        if (subset == null) {
            return null;
        }
        String title = FichothequeUtils.getTitle(subset, lang);
        if (title.equals(subsetKey.getKeyString())) {
            return null;
        }
        int weightFilter = includeKey.getWeightFilter();
        String mode = includeKey.getMode();
        if ((mode.length() == 0) && (weightFilter < 1)) {
            return title;
        } else {
            StringBuilder buf = new StringBuilder();
            buf.append(title);
            buf.append(" <");
            if (mode.length() > 0) {
                buf.append(mode);
                if (weightFilter > 0) {
                    buf.append(", ");
                    buf.append(weightFilter);
                }
            } else {
                buf.append(weightFilter);
            }
            buf.append('>');
            return buf.toString();
        }
    }

    @Nullable
    public static String getSpecialIncludeTitle(BdfServer bdfServer, String specialIncludeName, Lang lang) {
        String messageKey = L10nUtils.getMessageKey(specialIncludeName);
        MessageLocalisation messageLocalisation = bdfServer.getL10nManager().getMessageLocalisation(lang);
        return messageLocalisation.toString(messageKey);
    }

    @Nullable
    public static String getDataTitle(DataUi dataUi, Lang lang) {
        Label label = dataUi.getLabels().getLangPartCheckedLabel(lang);
        if (label != null) {
            return label.getLabelString();
        } else {
            return null;
        }
    }

    public static String toLabelString(FicheFormParameters ficheFormParameters, CorpusField corpusField) {
        String label = getCorpusFieldTitle(corpusField, ficheFormParameters.getWorkingLang());
        if (label != null) {
            return label;
        } else {
            return corpusField.getFieldString();
        }
    }

    public static String toLabelString(FicheFormParameters ficheFormParameters, IncludeUi includeUi) {
        String label = L10nUtils.getIncludeTitle(ficheFormParameters.getBdfServer(), includeUi, ficheFormParameters.getWorkingLang());
        if (label != null) {
            return label;
        } else {
            return includeUi.getName();
        }
    }

    public static Labels toLabels(L10nManager l10nManager, ThesaurusFieldKey thesaurusFieldKey, Langs langs) {
        LabelChangeBuilder builder = new LabelChangeBuilder();
        String messageKey = getMessageKey(thesaurusFieldKey);
        for (Lang lang : langs) {
            MessageLocalisation messageLocalisation = l10nManager.getMessageLocalisation(lang);
            Object value = null;
            if (thesaurusFieldKey.isLabelThesaurusFieldKey()) {
                value = messageLocalisation.toString(thesaurusFieldKey.getLang().toString());
            }
            String labelString;
            if (value == null) {
                labelString = messageLocalisation.toString(messageKey);
            } else {
                labelString = messageLocalisation.toString(messageKey, value);
            }
            if (labelString != null) {
                builder.putLabel(lang, labelString);
            }
        }
        return builder.toLabels();
    }

    public static Labels toLabels(L10nManager l10nManager, String specialIncludeName, Langs langs) {
        LabelChangeBuilder builder = new LabelChangeBuilder();
        String messageKey = getMessageKey(specialIncludeName);
        for (Lang lang : langs) {
            MessageLocalisation messageLocalisation = l10nManager.getMessageLocalisation(lang);
            String labelString = messageLocalisation.toString(messageKey);
            if (labelString != null) {
                builder.putLabel(lang, labelString);
            }
        }
        return builder.toLabels();
    }

    public static String getMessageKey(ThesaurusFieldKey thesaurusFieldKey) {
        if (thesaurusFieldKey.equals(ThesaurusFieldKey.ID)) {
            return "_ alias.motcle.id";
        } else if (thesaurusFieldKey.equals(ThesaurusFieldKey.IDALPHA)) {
            return "_ alias.motcle.idalpha";
        } else if (thesaurusFieldKey.equals(ThesaurusFieldKey.PARENT_ID)) {
            return "_ alias.motcle.parent_id";
        } else if (thesaurusFieldKey.equals(ThesaurusFieldKey.PARENT_IDALPHA)) {
            return "_ alias.motcle.parent_idalpha";
        } else if (thesaurusFieldKey.equals(ThesaurusFieldKey.BABELIENLABEL)) {
            return "_ alias.motcle.label";
        } else if (thesaurusFieldKey.equals(ThesaurusFieldKey.BABELIENLANG)) {
            return "_ alias.motcle.lang";
        } else if (thesaurusFieldKey.equals(ThesaurusFieldKey.POSITION_LOCAL)) {
            return "_ alias.motcle.pos_loc";
        } else if (thesaurusFieldKey.equals(ThesaurusFieldKey.POSITION_GLOBAL)) {
            return "_ alias.motcle.pos_glob";
        } else if (thesaurusFieldKey.equals(ThesaurusFieldKey.LEVEL)) {
            return "_ alias.motcle.level";
        } else if (thesaurusFieldKey.equals(ThesaurusFieldKey.THIS)) {
            return "_ alias.motcle.this";
        } else if (thesaurusFieldKey.equals(ThesaurusFieldKey.STATUS)) {
            return "_ alias.motcle.status";
        } else if (thesaurusFieldKey.isLabelThesaurusFieldKey()) {
            return "_ alias.motcle.label_lang";
        } else {
            throw new SwitchException("Unknown thesaurusFieldKey: " + thesaurusFieldKey.toString());
        }
    }

    public static String getMessageKey(FieldKey fieldKey) {
        switch (fieldKey.getKeyString()) {
            case FieldKey.SPECIAL_TITLE:
                return "_ alias.fiche.title";
            case FieldKey.SPECIAL_SUBTITLE:
                return "_ alias.fiche.subtitle";
            case FieldKey.SPECIAL_LANG:
                return "_ alias.fiche.lang";
            case FieldKey.SPECIAL_OWNERS:
                return "_ alias.fiche.owners";
            case FieldKey.SPECIAL_ID:
                return "_ alias.fiche.id";
            default:
                throw new IllegalArgumentException("Not a special field key: " + fieldKey.getKeyString());
        }
    }

    public static String getMessageKey(String specialIncludeName) {
        switch (specialIncludeName) {
            case FichothequeConstants.LIAGE_NAME:
                return "_ alias.include.liage";
            case FichothequeConstants.PARENTAGE_NAME:
                return "_ alias.include.parentage";
            case FichothequeConstants.DATECREATION_NAME:
                return "_ alias.include.date_creation";
            case FichothequeConstants.DATEMODIFICATION_NAME:
                return "_ alias.include.date_modification";
            default:
                throw new SwitchException("Unknown include name: " + specialIncludeName);

        }
    }

}
