/* BdfServer - Copyright (c) 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.ui.components;

import fr.exemole.bdfserver.api.ui.DataUi;
import java.text.ParseException;
import net.fichotheque.externalsource.ExternalSourceDef;
import net.fichotheque.tools.externalsource.ExternalSourceDefBuilder;
import net.mapeadores.util.annotation.Nullable;
import net.mapeadores.util.attr.AttributeChangeBuilder;
import net.mapeadores.util.attr.Attributes;
import net.mapeadores.util.text.LabelChangeBuilder;
import net.mapeadores.util.text.Labels;


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

    private final String dataName;
    private final AttributeChangeBuilder attributeChangeBuilder = new AttributeChangeBuilder();
    private final ExternalSourceDefBuilder externalSourceDefBuilder;
    private final LabelChangeBuilder labelChangeBuilder = new LabelChangeBuilder();
    private final Attributes previousAttributes;

    public DataUiBuilder(String dataName, String type) {
        this(dataName, type, null);
    }

    public DataUiBuilder(String dataName, String type, @Nullable Attributes previousAttributes) {
        try {
            DataUi.checkDataName(dataName);
        } catch (ParseException pe) {
            throw new IllegalArgumentException("Wrong name: " + dataName);
        }
        this.dataName = dataName;
        this.previousAttributes = previousAttributes;
        this.externalSourceDefBuilder = new ExternalSourceDefBuilder(type);
    }

    public DataUiBuilder(DataUi dataUi) {
        ExternalSourceDef externalSourceDef = dataUi.getExternalSourceDef();
        this.dataName = dataUi.getDataName();
        this.externalSourceDefBuilder = new ExternalSourceDefBuilder(externalSourceDef.getType());
        this.previousAttributes = dataUi.getAttributes();
        labelChangeBuilder.putLabels(dataUi.getLabels());
        for (String paramName : externalSourceDef.getParamNameSet()) {
            externalSourceDefBuilder.addParam(paramName, externalSourceDef.getParam(paramName));
        }
    }

    public AttributeChangeBuilder getAttributeChangeBuilder() {
        return attributeChangeBuilder;
    }

    public LabelChangeBuilder getLabelChangeBuilder() {
        return labelChangeBuilder;
    }

    public ExternalSourceDefBuilder getExternalSourceDefBuilder() {
        return externalSourceDefBuilder;
    }

    public DataUi toDataUi() {
        return new InternalDataUi(dataName, externalSourceDefBuilder.toExternalSourceDef(), labelChangeBuilder.toLabels(), attributeChangeBuilder.toAttributes(previousAttributes));
    }

    public static DataUiBuilder init(String name, String type) {
        return new DataUiBuilder(name, type, null);
    }

    public static DataUiBuilder init(String name, String type, @Nullable Attributes initAttributes) {
        return new DataUiBuilder(name, type, initAttributes);
    }

    public static DataUiBuilder init(DataUi dataUi) {
        return new DataUiBuilder(dataUi);
    }


    private static class InternalDataUi implements DataUi {

        private final String dataName;
        private final ExternalSourceDef externalSourceDef;
        private final Labels labels;
        private final Attributes attributes;

        private InternalDataUi(String dataName, ExternalSourceDef externalSourceDef, Labels labels, Attributes attributes) {
            this.dataName = dataName;
            this.externalSourceDef = externalSourceDef;
            this.labels = labels;
            this.attributes = attributes;
        }

        @Override
        public String getName() {
            return DataUi.toComponentName(dataName);
        }

        @Override
        public String getDataName() {
            return dataName;
        }

        @Override
        public ExternalSourceDef getExternalSourceDef() {
            return externalSourceDef;
        }

        @Override
        public Labels getLabels() {
            return labels;
        }

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

    }

}
