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

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.FieldUi;
import fr.exemole.bdfserver.api.ui.SpecialIncludeUi;
import fr.exemole.bdfserver.api.ui.SubsetIncludeUi;
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.ui.UiUtils;
import java.io.IOException;
import java.util.List;
import net.fichotheque.FichothequeConstants;
import net.fichotheque.SubsetKey;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.metadata.CorpusMetadata;
import net.fichotheque.corpus.metadata.FieldKey;


/**
 *
 * @author Vincent Calame
 */
public class SimpleFicheXsltWriter extends AbstractFicheXsltWriter {

    public SimpleFicheXsltWriter(BdfServer bdfServer, int extractVersion) {
        super(bdfServer, extractVersion);
    }

    public void add(Corpus corpus, boolean withCorpusCondition) throws IOException {
        if (corpus == null) {
            openMatchXslTemplate("fiche", null);
            closeXslTemplate();
            return;
        }
        UiComponents uiComponents = uiManager.getMainUiComponents(corpus);
        List<Corpus> includedCorpusList = BdfServerUtils.getIncludeSatelliteList(corpus);
        List<UiComponent> uiComponentList = uiComponents.getUiComponentList();
        if (!includedCorpusList.isEmpty()) {
            uiComponentList = UiUtils.filter(uiComponentList, UiUtils.MAIN_COMPONENTPREDICATE);
        }
        if (withCorpusCondition) {
            openMatchXslTemplate("fiche[@corpus='" + corpus.getSubsetName() + "']", null);
        } else {
            openMatchXslTemplate("fiche", null);
        }
        appendMainUiComponents(corpus, uiComponents, uiComponentList, includedCorpusList);
        closeXslTemplate();
        addSeparator();
        for (Corpus satellite : includedCorpusList) {
            UiComponents satelliteUiComponents = uiManager.getMainUiComponents(satellite);
            List<UiComponent> satelliteList = UiUtils.filter(satelliteUiComponents.getUiComponentList(), UiUtils.SATELLITE_COMPONENTPREDICATE);
            openMatchXslTemplate("fiche[@corpus='" + satellite.getSubsetName() + "']", "_satellite");
            addSatelliteUiComponents(satellite, satelliteList);
            closeXslTemplate();
            addSeparator();
        }
    }

    private void appendMainUiComponents(Corpus corpus, UiComponents uiComponents, List<UiComponent> filteredList, List<Corpus> includedCorpusList) throws IOException {
        CorpusMetadata corpusMetadata = corpus.getCorpusMetadata();
        String subsetName = corpus.getSubsetName();
        addXslVariable("label", "$LABELS[@corpus='" + subsetName + "']/label", false);
        addSeparator();
        openTag("article");
        addSeparator();
        startOpenTag("header");
        addAttribute("class", "fiche-Header");
        endOpenTag();
        apply(".", "component-Header");
        if (uiComponents.contains(FieldKey.SUBTITLE)) {
            apply(tagNames.getSubtitleTagName(), "component-Header");
        }
        closeTag("header");
        addSeparator();
        appendUiComponentList(filteredList, corpusMetadata);
        for (Corpus satellite : includedCorpusList) {
            addXslApplyTemplates("fiche[@corpus='" + satellite.getSubsetName() + "']", "_satellite", true);
            addSeparator();
        }
        appendChrono();
        closeTag("article");
        addSeparator();
    }

    private void addSatelliteUiComponents(Corpus satellite, List<UiComponent> satelliteList) throws IOException {
        CorpusMetadata corpusMetadata = satellite.getCorpusMetadata();
        String subsetName = satellite.getSubsetName();
        addXslVariable("label", "$LABELS/satellite[@corpus='" + subsetName + "']/label", false);
        addSeparator();
        startOpenTag("section");
        addAttribute("class", "fiche-satellite-Block");
        addAttribute("data-bdf-milestone", "satellite");
        addAttribute("data-bdf-satellite", subsetName);
        endOpenTag();
        startOpenTag("h1");
        addAttribute("class", "fiche-satellite-Title");
        endOpenTag();
        addXslValueOf("$LABELS/satellite[@corpus='" + subsetName + "']/@title");
        addXslApplyTemplates(tagNames.getSubtitleTagName());
        closeTag("h1", false);
        appendUiComponentList(satelliteList, corpusMetadata);
        closeTag("section");
    }

    private void appendUiComponentList(List<UiComponent> uiComponentList, CorpusMetadata corpusMetadata) throws IOException {
        for (UiComponent uiComponent : uiComponentList) {
            if (uiComponent instanceof FieldUi) {
                appendFieldUi((FieldUi) uiComponent, corpusMetadata);
            } else if (uiComponent instanceof SpecialIncludeUi) {
                appendSpecialIncludeUi((SpecialIncludeUi) uiComponent);
            } else if (uiComponent instanceof SubsetIncludeUi) {
                appendSubsetIncludeUi((SubsetIncludeUi) uiComponent);
            } else if (uiComponent instanceof CommentUi) {
                appendCommentUi((CommentUi) uiComponent);
            } else if (uiComponent instanceof DataUi) {
                appendDataUi((DataUi) uiComponent);
            }
        }
    }

    private void appendSpecialIncludeUi(SpecialIncludeUi includeUi) throws IOException {
        switch (includeUi.getName()) {
            case FichothequeConstants.LIAGE_NAME:
                apply(tagNames.getSubsetTagName(SubsetKey.CATEGORY_CORPUS) + "[@name='" + FichothequeConstants.LIAGE_NAME + "']", "component-Listitem", includeUi.getName());
                break;
            case FichothequeConstants.PARENTAGE_NAME:
                apply(".", "component-Parentage", includeUi.getName());
                break;
        }
    }

}
