/* FichothequeLib_Tools - 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 net.fichotheque.tools.format.tokenizers;

import java.util.ArrayList;
import java.util.List;
import net.fichotheque.corpus.fiche.FicheItem;
import net.fichotheque.corpus.fiche.FicheItems;
import net.fichotheque.corpus.fiche.Item;
import net.fichotheque.corpus.metadata.CorpusField;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.format.FormatSource;
import net.fichotheque.format.Tokenizer;
import net.fichotheque.format.Tokens;
import net.fichotheque.format.formatters.FicheItemFormatter;
import net.fichotheque.pointeurs.FichePointeur;
import net.fichotheque.utils.FormatterUtils;


/**
 *
 * @author Vincent Calame
 */
public abstract class FicheItemTokenizer implements Tokenizer {

    public final static short NONE_FILTER = 0;
    public final static short NOITEM_FILTER = 1;
    public final static short ONLYITEM_FILTER = 2;
    protected final CorpusField corpusField;
    protected final FicheItemFormatter ficheItemFormatter;
    private final short itemFilter;

    private FicheItemTokenizer(CorpusField corpusField, FicheItemFormatter ficheItemFormatter, short itemFilter) {
        super();
        this.corpusField = corpusField;
        this.ficheItemFormatter = ficheItemFormatter;
        this.itemFilter = itemFilter;
    }

    public boolean isSameType(String ficheItemType) {
        return (corpusField.isType(ficheItemType));
    }

    public FicheItemFormatter getFicheItemFormatter() {
        return ficheItemFormatter;
    }

    boolean testFicheItem(FicheItem ficheItem) {
        if (ficheItem == null) {
            return false;
        }
        switch (itemFilter) {
            case NOITEM_FILTER:
                if (ficheItem instanceof Item) {
                    if (!corpusField.isType(CorpusField.ITEM_FIELD)) {
                        return false;
                    }
                }
                break;
            case ONLYITEM_FILTER:
                if (!(ficheItem instanceof Item)) {
                    return false;
                }
                break;
        }
        return true;
    }

    public static FicheItemTokenizer newInstance(CorpusField corpusField, FicheItemFormatter ficheItemFormat, short itemFilter) {
        if (isPropTokenizer(corpusField)) {
            return new PropTokenizer(corpusField, ficheItemFormat, itemFilter);
        } else {
            return new InfoTokenizer(corpusField, ficheItemFormat, itemFilter);
        }
    }

    private static boolean isPropTokenizer(CorpusField corpusField) {
        if (corpusField.isProp()) {
            return true;
        }
        switch (corpusField.getFieldString()) {
            case FieldKey.SPECIAL_LANG:
            case FieldKey.SPECIAL_SUBTITLE:
                return true;
            default:
                return false;
        }
    }


    private static class PropTokenizer extends FicheItemTokenizer {

        private PropTokenizer(CorpusField corpusField, FicheItemFormatter ficheItemFormat, short itemFilter) {
            super(corpusField, ficheItemFormat, itemFilter);
        }

        @Override
        public Tokens tokenize(FormatSource formatSource) {
            FicheItem ficheItem = (FicheItem) ((FichePointeur) formatSource.getSubsetItemPointeur()).getValue(corpusField);
            if (testFicheItem(ficheItem)) {
                return FormatterUtils.toTokens(ficheItemFormatter.formatFicheItem(ficheItem, formatSource));
            } else {
                return FormatterUtils.EMPTY_TOKENS;
            }
        }

    }


    private static class InfoTokenizer extends FicheItemTokenizer {

        private InfoTokenizer(CorpusField corpusField, FicheItemFormatter ficheItemFormat, short itemFilter) {
            super(corpusField, ficheItemFormat, itemFilter);
        }

        @Override
        public Tokens tokenize(FormatSource formatSource) {
            FicheItems ficheItems = (FicheItems) ((FichePointeur) formatSource.getSubsetItemPointeur()).getValue(corpusField);
            if (ficheItems == null) {
                return FormatterUtils.EMPTY_TOKENS;
            }
            List<String> valueList = new ArrayList<String>();
            for (FicheItem ficheItem : ficheItems) {
                if (testFicheItem(ficheItem)) {
                    valueList.add(ficheItemFormatter.formatFicheItem(ficheItem, formatSource));
                }
            }
            if (valueList.isEmpty()) {
                return FormatterUtils.EMPTY_TOKENS;
            } else {
                return FormatterUtils.toTokens(valueList);
            }
        }

    }

}
