/* FichothequeLib_API - Copyright (c) 2019-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 net.fichotheque.tools.from.html;

import java.util.ArrayList;
import java.util.List;
import net.fichotheque.corpus.fiche.S;
import net.fichotheque.corpus.fiche.TextContentBuilder;
import net.fichotheque.tools.parsers.TextContentParser;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;


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

    private final List<Object> partList = new ArrayList<Object>();

    public ContentBuffer() {

    }

    public boolean isEmpty() {
        return partList.isEmpty();
    }

    public int size() {
        return partList.size();
    }

    public boolean addPart(Object part) {
        if (part instanceof String) {
            return addText((String) part);
        } else {
            partList.add(part);
            return true;
        }
    }

    public boolean isBrLast() {
        int size = partList.size();
        if (size > 0) {
            Object last = partList.get(size - 1);
            if ((last instanceof S) && (((S) last).getType() == S.BR)) {
                return true;
            }
        }
        return false;
    }

    public ContentBuffer add(List<Node> nodeList) {
        for (Node node : nodeList) {
            add(node);
        }
        return this;
    }

    public ContentBuffer add(Node node) {
        if (node instanceof TextNode) {
            addPart(((TextNode) node).text());
        } else if (node instanceof Element) {
            InlineConversion.convertInto((Element) node, this);
        }
        return this;
    }

    private boolean addText(String text) {
        if (text.isEmpty()) {
            return false;
        }
        int size = partList.size();
        if (size == 0) {
            text = text.replaceAll("^\\s+", "");
            if (!text.isEmpty()) {
                partList.add(text);
                return true;
            } else {
                return false;
            }
        } else {
            Object previousPart = partList.get(size - 1);
            boolean add = true;
            if (text.trim().isEmpty()) {
                if (previousPart instanceof String) {
                    String previousString = (String) previousPart;
                    if (Character.isWhitespace(previousString.charAt(previousString.length() - 1))) {
                        add = false;
                    }
                } else if (((S) previousPart).getType() == S.BR) {
                    add = false;
                }
            }
            if (add) {
                partList.add(text);
                return true;
            } else {
                return false;
            }
        }
    }

    public void flush(TextContentBuilder textContentBuilder) {
        TextContentParser textContentParser = new TextContentParser();
        cleanLastBr();
        int size = partList.size();
        for (int i = 0; i < size; i++) {
            Object part = partList.get(i);
            if (part instanceof String) {
                String partString = (String) part;
                if (i == (size - 1)) {
                    partString = partString.replaceAll("\\s+$", "");
                }
                textContentParser.parse(textContentBuilder, partString);
            } else if (part instanceof S) {
                textContentBuilder.addS((S) part);
            }
        }
    }

    private void cleanLastBr() {
        if (isBrLast()) {
            int size = partList.size();
            if (size > 1) {
                partList.remove(size - 1);
                cleanLastBr();
            }
        }
    }

    public static ContentBuffer init() {
        return new ContentBuffer();
    }

}
