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

import fr.exemole.bdfserver.api.ficheform.FicheFormParameters;
import fr.exemole.bdfserver.api.ficheform.GeopointPropSubfieldsElement;
import fr.exemole.bdfserver.api.ui.FieldUi;
import fr.exemole.bdfserver.tools.L10nUtils;
import net.fichotheque.corpus.fiche.FicheItem;
import net.fichotheque.corpus.fiche.GeopointItem;
import net.fichotheque.corpus.metadata.CorpusField;
import net.fichotheque.pointeurs.FichePointeur;
import net.fichotheque.syntax.FormSyntax;
import net.mapeadores.util.attr.AttributeUtils;
import net.mapeadores.util.attr.Attributes;
import net.mapeadores.util.text.MultiStringable;


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

    private final CorpusField corpusField;
    private String label = "";
    private boolean mandatory = false;
    private String latitude = "";
    private String longitude = "";
    private MultiStringable addressFieldNames;
    private Attributes attributes = AttributeUtils.EMPTY_ATTRIBUTES;

    public GeopointPropSubfieldsElementBuilder(CorpusField corpusField) {
        this.corpusField = corpusField;
    }

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

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

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

    public GeopointPropSubfieldsElementBuilder setLatitude(String latitude) {
        if (latitude == null) {
            throw new IllegalArgumentException("latitude is null");
        }
        this.latitude = latitude;
        return this;
    }

    public GeopointPropSubfieldsElementBuilder setLongitude(String longitude) {
        if (longitude == null) {
            throw new IllegalArgumentException("longitude is null");
        }
        this.longitude = longitude;
        return this;
    }

    public GeopointPropSubfieldsElementBuilder setAddressFieldNames(MultiStringable adressFieldNames) {
        this.addressFieldNames = adressFieldNames;
        return this;
    }


    public GeopointPropSubfieldsElement toGeopointPropSubfieldsElement() {
        return new InternalGeopointPropSubfieldsElement(corpusField, label, mandatory, attributes, latitude, longitude, addressFieldNames);
    }

    public static GeopointPropSubfieldsElementBuilder check(FichePointeur fichePointeur, FicheFormParameters ficheFormParameters, CorpusField corpusField, FieldUi fieldUi) {
        FormSyntax.Parameters parameters = ficheFormParameters.getFicheItemFormSyntaxParameters();
        GeopointPropSubfieldsElementBuilder builder = init(corpusField);
        FicheItem ficheItem = (FicheItem) fichePointeur.getValue(corpusField);
        if (ficheItem != null) {
            if (ficheItem instanceof GeopointItem) {
                GeopointItem geopoint = (GeopointItem) ficheItem;
                builder.setLatitude(FormSyntax.toString(geopoint.getLatitude(), parameters));
                builder.setLongitude(FormSyntax.toString(geopoint.getLongitude(), parameters));
            } else {
                builder.setLatitude(FormSyntax.toString(ficheItem, fichePointeur.getFichotheque(), parameters));
            }
        } else if (fieldUi.isObsolete()) {
            return null;
        }
        MultiStringable addressFieldNames = corpusField.getAddressFieldNames();
        if (addressFieldNames != null) {
            builder.setAddressFieldNames(addressFieldNames);
        }
        return builder
                .setMandatory(fieldUi.isMandatory())
                .setAttributes(fieldUi.getAttributes())
                .setLabel(L10nUtils.toLabelString(ficheFormParameters, corpusField));
    }

    public static GeopointPropSubfieldsElementBuilder init(CorpusField corpusField) {
        return new GeopointPropSubfieldsElementBuilder(corpusField);
    }


    private static class InternalGeopointPropSubfieldsElement implements GeopointPropSubfieldsElement {

        private final CorpusField corpusField;
        private final String label;
        private final boolean mandatory;
        private final Attributes attributes;
        private final String latitude;
        private final String longitude;
        private final MultiStringable addressFieldNames;

        private InternalGeopointPropSubfieldsElement(CorpusField corpusField, String label, boolean mandatory, Attributes attributes, String latitude, String longitude, MultiStringable addressFieldNameArray) {
            this.corpusField = corpusField;
            this.label = label;
            this.mandatory = mandatory;
            this.attributes = attributes;
            this.latitude = latitude;
            this.longitude = longitude;
            this.addressFieldNames = addressFieldNameArray;
        }

        @Override
        public CorpusField getCorpusField() {
            return corpusField;
        }

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

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

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

        @Override
        public String getLatitude() {
            return latitude;
        }

        @Override
        public String getLongitude() {
            return longitude;
        }

        @Override
        public MultiStringable getAddressFieldNames() {
            return addressFieldNames;
        }

    }

}
