/* BdfServer - Copyright (c) 2009-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.tools.ficheform.builders;

import fr.exemole.bdfserver.api.ficheform.FicheFormParameters;
import fr.exemole.bdfserver.api.ficheform.ThesaurusIncludeElement;
import fr.exemole.bdfserver.api.ui.SubsetIncludeUi;
import fr.exemole.bdfserver.tools.L10nUtils;
import fr.exemole.bdfserver.tools.externalsource.ExternalSourceUtils;
import fr.exemole.bdfserver.tools.ficheform.FicheFormUtils;
import java.util.Collection;
import java.util.List;
import net.fichotheque.SubsetKey;
import net.fichotheque.croisement.Liaison;
import net.fichotheque.pointeurs.FichePointeur;
import net.fichotheque.pointeurs.SubsetItemPointeur;
import net.fichotheque.thesaurus.Thesaurus;
import net.mapeadores.util.annotation.Nullable;
import net.mapeadores.util.attr.Attribute;
import net.mapeadores.util.attr.AttributeUtils;
import net.mapeadores.util.attr.Attributes;


/**
 *
 * @author Vincent Calame
 */
public class TextThesaurusIncludeElementBuilder {

    private final String name;
    private final Thesaurus thesaurus;
    private final MotcleEntryListBuilder motcleEntryListBuilder = new MotcleEntryListBuilder();
    private String label = "";
    private boolean mandatory = false;
    private String value = "";
    private SubsetKey destinationSubsetKey;
    private boolean redimAllowed;
    private int rows;
    private String widthType;
    private Attribute idalphaStyle = null;
    private boolean withExternalSource;
    private Attributes attributes = AttributeUtils.EMPTY_ATTRIBUTES;


    public TextThesaurusIncludeElementBuilder(String name, Thesaurus thesaurus) {
        this.name = name;
        this.thesaurus = thesaurus;
    }

    public TextThesaurusIncludeElementBuilder setLabel(String label) {
        if (label == null) {
            throw new IllegalArgumentException("label is null");
        }
        this.label = label;
        return this;
    }

    public TextThesaurusIncludeElementBuilder setMandatory(boolean mandatory) {
        this.mandatory = mandatory;
        return this;
    }

    public TextThesaurusIncludeElementBuilder setAttributes(Attributes attributes) {
        if (attributes == null) {
            this.attributes = AttributeUtils.EMPTY_ATTRIBUTES;
        } else {
            this.attributes = attributes;
        }
        return this;
    }

    public TextThesaurusIncludeElementBuilder setIdalphaStyle(Attribute idalphaStyle) {
        this.idalphaStyle = idalphaStyle;
        return this;
    }

    public TextThesaurusIncludeElementBuilder setDestinationSubsetKey(SubsetKey destinationSubsetKey) {
        this.destinationSubsetKey = destinationSubsetKey;
        return this;
    }

    public TextThesaurusIncludeElementBuilder setValue(String value) {
        if (value == null) {
            throw new IllegalArgumentException("value is null");
        }
        this.value = value;
        return this;
    }

    public TextThesaurusIncludeElementBuilder setRedimAllowed(boolean redimAllowed) {
        this.redimAllowed = redimAllowed;
        return this;
    }

    public TextThesaurusIncludeElementBuilder setRows(int rows) {
        this.rows = rows;
        return this;
    }

    public TextThesaurusIncludeElementBuilder setWidthType(String widthType) {
        this.widthType = widthType;
        return this;
    }

    public TextThesaurusIncludeElementBuilder setWithExternalSource(boolean withExternalSource) {
        this.withExternalSource = withExternalSource;
        return this;
    }

    public ThesaurusIncludeElement.Text toTextThesaurusIncludeElement() {
        return new InternalTextThesaurusIncludeElement(name, label, mandatory, attributes, thesaurus, idalphaStyle, destinationSubsetKey, value, redimAllowed, rows, widthType, withExternalSource, motcleEntryListBuilder.toList());
    }

    @Nullable
    public static TextThesaurusIncludeElementBuilder check(FichePointeur fichePointeur, FicheFormParameters ficheFormParameters, SubsetIncludeUi includeUi) {
        Thesaurus thesaurus = (Thesaurus) ficheFormParameters.getBdfServer().getFichotheque().getSubset(includeUi.getSubsetKey());
        if (thesaurus == null) {
            return null;
        }
        boolean isMandatory = includeUi.isMandatory();
        boolean redimAllowed = true;
        boolean withExternalSource = (ExternalSourceUtils.getExternalSource(ficheFormParameters.getBdfServer(), thesaurus) != null);
        TextThesaurusIncludeElementBuilder builder = init(includeUi.getName(), thesaurus)
                .setMandatory(isMandatory)
                .setAttributes(includeUi.getAttributes())
                .setIdalphaStyle(FicheFormUtils.getIdalphaStyle(includeUi, thesaurus))
                .setRedimAllowed(redimAllowed)
                .setWidthType(FicheFormUtils.getWidth(includeUi))
                .setLabel(L10nUtils.toLabelString(ficheFormParameters, includeUi))
                .setWithExternalSource(withExternalSource);
        SubsetItemPointeur pointeur = FicheFormUtils.checkMasterPointeur(fichePointeur, ficheFormParameters, includeUi);
        String value;
        if (pointeur.isEmpty()) {
            builder.motcleEntryListBuilder.populateDefault(ficheFormParameters, includeUi, thesaurus);
            value = FicheFormUtils.getDefVal(ficheFormParameters, includeUi);
        } else {
            Collection<Liaison> liaisons = builder.motcleEntryListBuilder.populate(pointeur.getCroisements(thesaurus), includeUi, true);
            value = FicheFormUtils.getStringValue(thesaurus, liaisons, includeUi, ficheFormParameters);
        }
        if ((builder.motcleEntryListBuilder.isEmpty()) && (includeUi.isObsolete())) {
            return null;
        }
        int rows = FicheFormUtils.checkRows(includeUi, (redimAllowed) ? value.length() : -1);
        return builder
                .setDestinationSubsetKey(pointeur.getSubsetKey())
                .setValue(value)
                .setRows(rows);
    }

    public static TextThesaurusIncludeElementBuilder init(String name, Thesaurus thesaurus) {
        return new TextThesaurusIncludeElementBuilder(name, thesaurus);
    }


    private static class InternalTextThesaurusIncludeElement implements ThesaurusIncludeElement.Text {

        private final String name;
        private final String label;
        private final boolean mandatory;
        private final Attributes attributes;
        private final Thesaurus thesaurus;
        private final Attribute idalphaStyle;
        private final SubsetKey destinationSubsetKey;
        private final String value;
        private final boolean redimAllowed;
        private final int rows;
        private final String widthType;
        private final boolean withExternalSource;
        private final List<ThesaurusIncludeElement.Entry> list;

        private InternalTextThesaurusIncludeElement(String name, String label, boolean mandatory, Attributes attributes, Thesaurus thesaurus, Attribute idalphaStyle, SubsetKey destinationSubsetKey, String value, boolean redimAllowed, int rows, String widthType, boolean withExternalSource, List<ThesaurusIncludeElement.Entry> list) {
            this.name = name;
            this.label = label;
            this.mandatory = mandatory;
            this.attributes = attributes;
            this.thesaurus = thesaurus;
            this.idalphaStyle = idalphaStyle;
            this.destinationSubsetKey = destinationSubsetKey;
            this.value = value;
            this.redimAllowed = redimAllowed;
            this.rows = rows;
            this.widthType = widthType;
            this.withExternalSource = withExternalSource;
            this.list = list;
        }

        @Override
        public String getIncludeName() {
            return name;
        }

        @Override
        public String getLabel() {
            return label;
        }

        @Override
        public boolean isMandatory() {
            return mandatory;
        }

        @Override
        public Attributes getAttributes() {
            return attributes;
        }

        @Override
        public Thesaurus getThesaurus() {
            return thesaurus;
        }

        @Override
        public Attribute getIdalphaStyle() {
            return idalphaStyle;
        }

        @Override
        public SubsetKey getDestinationSubsetKey() {
            return destinationSubsetKey;
        }

        @Override
        public String getValue() {
            return value;
        }

        @Override
        public boolean isRedimAllowed() {
            return redimAllowed;
        }

        @Override
        public int getRows() {
            return rows;
        }

        @Override
        public String getWidthType() {
            return widthType;
        }

        @Override
        public boolean isWithExternalSource() {
            return withExternalSource;
        }

        @Override
        public List<Entry> getEntryList() {
            return list;
        }

    }

}
