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

import fr.exemole.bdfserver.api.ui.CommentUi;
import java.text.ParseException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import net.mapeadores.util.annotation.Nullable;
import net.mapeadores.util.attr.AttributeChangeBuilder;
import net.mapeadores.util.attr.Attributes;
import net.mapeadores.util.html.HtmlCleaner;
import net.mapeadores.util.html.TrustedHtml;
import net.mapeadores.util.localisation.Lang;
import net.mapeadores.util.localisation.Langs;
import net.mapeadores.util.localisation.LangsUtils;


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

    private final HtmlCleaner htmlCleaner;
    private final Map<Lang, TrustedHtml> htmlMap = new LinkedHashMap<Lang, TrustedHtml>();
    private final AttributeChangeBuilder attributeChangeBuilder = new AttributeChangeBuilder();
    private final Attributes previousAttributes;
    private final String name;
    private int location = CommentUi.ALL_MASK;

    public CommentUiBuilder(HtmlCleaner htmlCleaner, String name) {
        this(htmlCleaner, name, null);
    }

    public CommentUiBuilder(HtmlCleaner htmlCleaner, String name, @Nullable Attributes previousAttributes) {
        try {
            CommentUi.checkCommentName(name);
        } catch (ParseException pe) {
            throw new IllegalArgumentException("Wrong name: " + name);
        }
        this.htmlCleaner = htmlCleaner;
        this.name = name;
        this.previousAttributes = previousAttributes;
    }

    public CommentUiBuilder(HtmlCleaner htmlCleaner, CommentUi commentUi) {
        this.htmlCleaner = htmlCleaner;
        this.name = commentUi.getCommentName();
        this.previousAttributes = commentUi.getAttributes();
        this.location = commentUi.getLocation();
        for (Lang lang : commentUi.getLangs()) {
            htmlMap.put(lang, commentUi.getHtmlByLang(lang));
        }
    }

    public CommentUiBuilder setLocation(int location) {
        if ((location < 1) || (location > CommentUi.ALL_MASK)) {
            location = CommentUi.ALL_MASK;
        }
        this.location = location;
        return this;
    }

    public CommentUiBuilder putHtml(Lang lang, String htmlString) {
        if ((htmlString == null) || (htmlString.length() == 0)) {
            htmlMap.remove(lang);
        } else {
            putHtml(lang, htmlCleaner.cleanHtml(htmlString));
        }
        return this;
    }

    public CommentUiBuilder putHtml(Lang lang, TrustedHtml html) {
        if ((html == null) || (html.length() == 0)) {
            htmlMap.remove(lang);
        } else {
            htmlMap.put(lang, html);
        }
        return this;
    }

    public AttributeChangeBuilder getAttributeChangeBuilder() {
        return attributeChangeBuilder;
    }

    public CommentUi toCommentUi() {
        if (name == null) {
            throw new IllegalStateException("name is null");
        }
        int size = htmlMap.size();
        Lang[] langArray = new Lang[size];
        Map<Lang, TrustedHtml> finalMap = new HashMap<Lang, TrustedHtml>();
        int p = 0;
        for (Map.Entry<Lang, TrustedHtml> entry : htmlMap.entrySet()) {
            langArray[p] = entry.getKey();
            finalMap.put(entry.getKey(), entry.getValue());
            p++;
        }
        return new InternalCommentUi(name, LangsUtils.wrap(langArray), finalMap, location, attributeChangeBuilder.toAttributes(previousAttributes));
    }

    public static CommentUiBuilder init(HtmlCleaner htmlCleaner, String name) {
        return new CommentUiBuilder(htmlCleaner, name, null);
    }

    public static CommentUiBuilder init(HtmlCleaner htmlCleaner, String name, Attributes attributes) {
        return new CommentUiBuilder(htmlCleaner, name, attributes);
    }

    public static CommentUiBuilder init(HtmlCleaner htmlCleaner, CommentUi commentUi) {
        return new CommentUiBuilder(htmlCleaner, commentUi);
    }


    private static class InternalCommentUi implements CommentUi {

        private final Map<Lang, TrustedHtml> htmlMap;
        private final Langs langs;
        private final String name;
        private final int location;
        private final Attributes attributes;

        public InternalCommentUi(String name, Langs langs, Map<Lang, TrustedHtml> htmlMap, int location, Attributes attributes) {
            this.name = name;
            this.langs = langs;
            this.htmlMap = htmlMap;
            this.location = location;
            this.attributes = attributes;
        }

        @Override
        public int getLocation() {
            return location;
        }

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

        @Override
        public String getName() {
            return CommentUi.toComponentName(name);
        }

        @Override
        public Langs getLangs() {
            return langs;
        }

        @Override
        public TrustedHtml getHtmlByLang(Lang lang) {
            return htmlMap.get(lang);
        }

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

    }

}
