/* FichothequeLib_Tools - Copyright (c) 2013-2022 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.extraction.corpus;

import java.util.Locale;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.corpus.fiche.FicheAPI;
import net.fichotheque.corpus.fiche.FicheItem;
import net.fichotheque.corpus.fiche.FicheItems;
import net.fichotheque.corpus.fiche.Item;
import net.fichotheque.corpus.fiche.ParaItem;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.croisement.Croisement;
import net.fichotheque.extraction.def.FicheFilter;
import net.fichotheque.extraction.def.GroupClause;
import net.fichotheque.extraction.run.FicheExtractInfo;
import net.fichotheque.extraction.run.FicheGroup;
import net.fichotheque.extraction.run.FieldsGroupParams;
import net.mapeadores.util.text.alphabet.Alphabet;
import net.mapeadores.util.text.alphabet.AlphabeticEntry;
import net.mapeadores.util.text.collation.group.CollationGroupBuilder;
import net.mapeadores.util.text.collation.group.ObjectWrapper;


/**
 *
 * @author Vincent Calame
 */
public class FieldsEngine extends GroupEngine {

    private final GroupClause groupClause;
    private final GroupEngineProvider subGroupEngineProvider;
    private boolean alphabetMode = false;
    private final FieldKey[] fieldKeyArray;
    private final CollationGroupBuilder collationGroupBuilder;

    FieldsEngine(GroupClause groupClause, GroupEngineProvider subGroupEngineProvider) {
        this.groupClause = groupClause;
        this.subGroupEngineProvider = subGroupEngineProvider;
        FieldsGroupParams groupParams = (FieldsGroupParams) groupClause.getGroupParams();
        this.alphabetMode = (groupParams.getMode() == FieldsGroupParams.ALPHABET_MODE);
        this.collationGroupBuilder = new CollationGroupBuilder(Locale.getDefault());
        this.fieldKeyArray = groupParams.getFieldKeyArray();
    }

    @Override
    public void add(FicheMeta ficheMeta, FicheFilter ficheFilter, Croisement croisement) {
        String titre = getStringValue(ficheMeta);
        Object groupClauseObject = null;
        if (alphabetMode) {
            AlphabeticEntry alphabeticEntry = Alphabet.newInstance(titre, ficheMeta.getLang());
            titre = alphabeticEntry.getEntryString();
            groupClauseObject = alphabeticEntry;
        }
        FicheExtractInfo info = GroupBuilder.toFicheExtractInfo(ficheMeta, ficheFilter, croisement, groupClauseObject);
        ObjectWrapper objectWrapper = ObjectWrapper.newCleanedInstance(titre, info);
        collationGroupBuilder.addObjectWrapper(objectWrapper);
    }

    @Override
    public FicheGroup[] toFicheGroupArray() {
        return toGroupArray(collationGroupBuilder, groupClause, subGroupEngineProvider);
    }

    private String getStringValue(FicheMeta ficheMeta) {
        FicheAPI fiche = ficheMeta.getFicheAPI(false);
        for (FieldKey fieldKey : fieldKeyArray) {
            Object obj = fiche.getValue(fieldKey);
            if (obj == null) {
                continue;
            }
            String value = "";
            if (obj instanceof String) {
                value = (String) obj;
            } else if (obj instanceof FicheItem) {
                value = getStringValue((FicheItem) obj);
            } else if (obj instanceof FicheItems) {
                value = getStringValue((FicheItems) obj);
            }
            if (value.length() > 0) {
                return value;
            }
        }
        return "";
    }

    private String getStringValue(FicheItem ficheItem) {
        if (ficheItem == null) {
            return "";
        }
        if (ficheItem instanceof Item) {
            return ((Item) ficheItem).getValue();
        }
        if (ficheItem instanceof ParaItem) {
            return ((ParaItem) ficheItem).contentToString();
        }
        return "";
    }

    private String getStringValue(FicheItems ficheItems) {
        int size = ficheItems.size();
        for (int i = 0; i < size; i++) {
            String value = getStringValue(ficheItems.get(i));
            if (value.length() > 0) {
                return value;
            }
        }
        return "";
    }

}
