/* BdfServer - Copyright (c) 2016-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.xml.dyn;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.ui.CommentUi;
import fr.exemole.bdfserver.api.ui.DataUi;
import fr.exemole.bdfserver.api.ui.IncludeUi;
import fr.exemole.bdfserver.api.ui.UiComponent;
import fr.exemole.bdfserver.api.ui.UiComponents;
import fr.exemole.bdfserver.tools.BdfServerUtils;
import fr.exemole.bdfserver.tools.L10nUtils;
import fr.exemole.bdfserver.tools.ui.UiUtils;
import java.io.IOException;
import java.util.List;
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.CorpusMetadata;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.utils.CorpusMetadataUtils;
import net.mapeadores.util.localisation.Lang;
import net.mapeadores.util.text.Label;
import net.mapeadores.util.xml.XMLPart;
import net.mapeadores.util.xml.XMLWriter;


/**
 *
 * @author Vincent Calame
 */
public class LabelsXMLPart extends XMLPart {

    private final BdfServer bdfServer;
    private final Lang lang;

    public LabelsXMLPart(XMLWriter xmlWriter, BdfServer bdfServer, Lang lang) {
        super(xmlWriter);
        this.bdfServer = bdfServer;
        this.lang = lang;
    }

    public void appendLabels(Subset subset) throws IOException {
        SubsetKey subsetKey = subset.getSubsetKey();
        startOpenTag("labels");
        addAttribute(subsetKey.getCategoryString(), subsetKey.getSubsetName());
        endOpenTag();
        if (subset instanceof Corpus) {
            Corpus corpus = (Corpus) subset;
            appendFields(corpus.getCorpusMetadata());
            UiComponents uiComponents = bdfServer.getUiManager().getMainUiComponents(corpus);
            appendInclude(uiComponents);
            List<Corpus> satelliteList = BdfServerUtils.getIncludeSatelliteList(corpus);
            for (Corpus satellite : satelliteList) {
                appendSatelliteLabels(satellite);
            }
        } else if (subset instanceof Thesaurus) {
            Thesaurus thesaurus = (Thesaurus) subset;
            appendMotcleList(thesaurus.getFirstLevelList());
        }
        closeTag("labels");
    }

    private void appendSatelliteLabels(Corpus satellite) throws IOException {
        SubsetKey subsetKey = satellite.getSubsetKey();
        startOpenTag("satellite");
        addAttribute(subsetKey.getCategoryString(), subsetKey.getSubsetName());
        addAttribute("title", CorpusMetadataUtils.getSatelliteLabel(satellite, lang));
        endOpenTag();
        appendFields(satellite.getCorpusMetadata());
        UiComponents uiComponents = bdfServer.getUiManager().getMainUiComponents(satellite);
        appendInclude(uiComponents);
        closeTag("satellite");
    }


    public void appendLabels(Thesaurus thesaurus) throws IOException {
        startOpenTag("labels");
        addAttribute("thesaurus", thesaurus.getSubsetName());
        endOpenTag();
    }

    private void appendMotcleList(List<Motcle> motcleList) throws IOException {
        for (Motcle motcle : motcleList) {
            startOpenTag("label");
            addAttribute("motcle-id", motcle.getId());
            String idalpha = motcle.getIdalpha();
            if (idalpha != null) {
                addAttribute("idalpha", idalpha);
            }
            endOpenTag();
            Label label = motcle.getLabels().getLangPartCheckedLabel(lang);
            if (label != null) {
                addText(label.getLabelString());
            }
            closeTag("label", false);
            appendMotcleList(motcle.getChildList());
        }
    }

    private void appendFields(CorpusMetadata corpusMetadata) throws IOException {
        appendLabel(corpusMetadata.getCorpusField(FieldKey.ID));
        appendLabel(corpusMetadata.getCorpusField(FieldKey.LANG));
        appendLabel(corpusMetadata.getCorpusField(FieldKey.OWNERS));
        appendLabel(corpusMetadata.getCorpusField(FieldKey.TITLE));
        appendLabel(corpusMetadata.getCorpusField(FieldKey.SUBTITLE));
        for (CorpusField corpusField : corpusMetadata.getPropList()) {
            appendLabel(corpusField);
        }
        for (CorpusField corpusField : corpusMetadata.getInfoList()) {
            appendLabel(corpusField);
        }
        for (CorpusField corpusField : corpusMetadata.getSectionList()) {
            appendLabel(corpusField);
        }
    }

    private void appendInclude(UiComponents uiComponents) throws IOException {
        for (UiComponent componentUi : uiComponents.getUiComponentList()) {
            if (componentUi instanceof IncludeUi) {
                IncludeUi includeUi = (IncludeUi) componentUi;
                String labelString = L10nUtils.getIncludeTitle(bdfServer, includeUi, lang);
                if (labelString == null) {
                    labelString = includeUi.getName();
                }
                appendIncludeLabel(includeUi.getName(), labelString);
                if (includeUi.getName().equals(FichothequeConstants.PARENTAGE_NAME)) {
                    appendIncludeLabel("rattachement", labelString);
                }
            } else if (componentUi instanceof DataUi) {
                DataUi dataUi = (DataUi) componentUi;
                String labelString = L10nUtils.getDataTitle(dataUi, lang);
                if (labelString == null) {
                    labelString = dataUi.getDataName();
                }
                appendDataLabel(dataUi, labelString);
            }
        }
        appendSpecialIncludeLabel(FichothequeConstants.DATECREATION_NAME);
        appendSpecialIncludeLabel(FichothequeConstants.DATEMODIFICATION_NAME);
        List<CommentUi> commentList = UiUtils.getCommentUiList(uiComponents);
        for (CommentUi commentUi : commentList) {
            appendLabel(commentUi, commentUi.getHtmlByLang(lang));
        }
    }

    private void appendLabel(CorpusField corpusField) throws IOException {
        if (corpusField == null) {
            return;
        }
        String labelString = "";
        Label label = corpusField.getLabels().getLangPartCheckedLabel(lang);
        if (label != null) {
            labelString = label.getLabelString();
        }
        appendLabel(corpusField.getFieldKey(), labelString);
    }

    private void appendLabel(FieldKey fieldKey, CharSequence labelContent) throws IOException {
        appendLabel(fieldKey.getKeyString(), labelContent);
        if (fieldKey.isProp()) {
            appendLabel("propriete_" + fieldKey.getFieldName(), labelContent);
        } else if (fieldKey.isInfo()) {
            appendLabel("information_" + fieldKey.getFieldName(), labelContent);
        } else if (fieldKey.isSpecial()) {
            switch (fieldKey.getKeyString()) {
                case FieldKey.SPECIAL_TITLE:
                    appendLabel("titre", labelContent);
                    break;
                case FieldKey.SPECIAL_SUBTITLE:
                    appendLabel("soustitre", labelContent);
                    break;
                case FieldKey.SPECIAL_OWNERS:
                    appendLabel("redacteurs", labelContent);
                    break;
            }
        }
    }

    private void appendLabel(String fieldName, CharSequence labelContent) throws IOException {
        startOpenTag("label");
        addAttribute("field-key", fieldName);
        addAttribute("name", fieldName);
        endOpenTag();
        addText(labelContent);
        closeTag("label", false);
    }

    private void appendSpecialIncludeLabel(String name) throws IOException {
        String labelString = L10nUtils.getSpecialIncludeTitle(bdfServer, name, lang);
        if (labelString == null) {
            labelString = name;
        }
        appendIncludeLabel(name, labelString);
    }

    private void appendIncludeLabel(String name, String labelString) throws IOException {
        startOpenTag("label");
        addAttribute("include-key", name);
        addAttribute("name", name);
        endOpenTag();
        addText(labelString);
        closeTag("label", false);
    }

    private void appendDataLabel(DataUi dataUi, String labelString) throws IOException {
        startOpenTag("label");
        addAttribute("data-name", dataUi.getDataName());
        addAttribute("name", dataUi.getName());
        endOpenTag();
        addText(labelString);
        closeTag("label", false);
    }

    private void appendLabel(CommentUi commentUi, CharSequence labelContent) throws IOException {
        startOpenTag("label");
        addAttribute("comment-name", commentUi.getCommentName());
        addAttribute("name", commentUi.getName());
        endOpenTag();
        addText(labelContent);
        closeTag("label", false);
    }


}
