/* FichothequeLib_Import - 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.handlers;

import net.fichotheque.corpus.fiche.Cdatadiv;
import net.fichotheque.corpus.fiche.FicheBlock;
import net.fichotheque.corpus.fiche.H;
import net.fichotheque.corpus.fiche.P;
import net.fichotheque.corpus.fiche.ParagraphBlock;
import net.fichotheque.tools.from.html.BlockConversion;
import net.fichotheque.tools.from.html.ElementHandler;
import net.fichotheque.tools.from.html.FlowBuffer;
import net.fichotheque.tools.from.html.TagUtils;
import net.mapeadores.util.html.TrustedHtml;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;


/**
 *
 * @author Vincent Calame
 */
public class DefaultHandler extends ElementHandler {

    public final static DefaultHandler INSTANCE = new DefaultHandler();

    private DefaultHandler() {

    }

    @Override
    public int handle(Element element, FlowBuffer flowBuffer) {
        if (element.tagName().equals("br")) {
            return testBr(element, flowBuffer);
        }
        switch (TagUtils.getTagType(element)) {
            case TagUtils.INLINE_TYPE:
                return 0;
            case TagUtils.CDATA_TYPE:
                flowBuffer.flushInline();
                Cdatadiv cdatadiv = new Cdatadiv();
                cdatadiv.setCdata(new TrustedHtml(element.outerHtml()));
                flowBuffer.addFicheBlock(cdatadiv);
                return 1;
        }
        flowBuffer.flushInline();
        switch (element.tagName()) {
            case "p":
            case "h1":
            case "h2":
            case "h3":
            case "h4":
            case "h5":
            case "h6":
                ParagraphBlock paragraphBlock = getParagraphBlock(element);
                BlockConversion.populate(element, paragraphBlock);
                flowBuffer.addFicheBlock((FicheBlock) paragraphBlock);
                break;
            case "pre":
                flowBuffer.addFicheBlock(BlockConversion.fromPre(element));
                break;
            case "ol":
                flowBuffer.addFicheBlock(BlockConversion.fromList(element, true));
                break;
            case "ul":
                flowBuffer.addFicheBlock(BlockConversion.fromList(element, false));
                break;
            case "table":
                flowBuffer.addFicheBlock(BlockConversion.fromTable(element));
                break;
            case "blockquote":
                flowBuffer.addFicheBlocks(BlockquoteHandler.INSTANCE.convertChildNodes(element));
                break;
            default:
                flowBuffer.addFicheBlocks(INSTANCE.convertChildNodes(element));
        }
        return 1;
    }

    private int testBr(Element element, FlowBuffer flowBuffer) {
        Node nextNode = element.nextSibling();
        int skip = 1;
        while (true) {
            if (nextNode == null) {
                return 0;
            } else if (nextNode instanceof TextNode) {
                if (!((TextNode) nextNode).text().trim().isEmpty()) {
                    return 0;
                }
            } else if (nextNode instanceof Element) {
                if (!(((Element) nextNode).tagName().equals("br"))) {
                    return 0;
                } else {
                    skip++;
                    break;
                }
            }
            skip++;
            nextNode = nextNode.nextSibling();
        }
        flowBuffer.flushInline();
        return skip;
    }

    private static ParagraphBlock getParagraphBlock(Element element) {
        switch (element.tagName()) {
            case "p":
                return new P();
            case "h1":
                return new H(1);
            case "h2":
                return new H(2);
            case "h3":
                return new H(3);
            case "h4":
                return new H(4);
            case "h5":
                return new H(5);
            case "h6":
                return new H(6);
            default:
                return null;
        }
    }

}
