/* FichothequeLib_Tools - Copyright (c) 2006-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.valueresolvers;

import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.corpus.fiche.FicheAPI;
import net.fichotheque.corpus.fiche.FicheItem;
import net.fichotheque.corpus.fiche.Item;
import net.fichotheque.corpus.metadata.FieldKey;
import net.mapeadores.util.localisation.Lang;
import net.mapeadores.util.text.AccoladeArgument;
import net.mapeadores.util.text.AccoladePattern;
import net.mapeadores.util.text.ValueResolver;
import net.fichotheque.corpus.fiche.Prop;


/**
 *
 * @author Vincent Calame
 */
public class FicheValueResolver implements ValueResolver {

    public final static String CORPUS = "corpus";
    private final FicheMeta ficheMeta;
    private final Corpus corpus;
    private FicheAPI fiche;

    public FicheValueResolver(FicheMeta ficheMeta) {
        this.ficheMeta = ficheMeta;
        this.corpus = ficheMeta.getCorpus();
    }

    @Override
    public final String getValue(AccoladeArgument accoladeArgument) {
        if (accoladeArgument.getName().equals(CORPUS)) {
            return corpus.getSubsetName();
        }
        if (accoladeArgument instanceof FicheAccoladeArgument) {
            return getValue((FicheAccoladeArgument) accoladeArgument);
        } else {
            FicheAccoladeArgument fichePatternArgument = parse(accoladeArgument.getName(), accoladeArgument.getMode());
            if (fichePatternArgument != null) {
                return getValue(fichePatternArgument);
            } else {
                return AccoladePattern.toString(accoladeArgument);
            }
        }
    }

    private String getValue(FicheAccoladeArgument ficheAccoladeArgument) {
        FieldKey fieldKey = ficheAccoladeArgument.getFieldKey();
        switch (fieldKey.getKeyString()) {
            case FieldKey.SPECIAL_ID:
                return String.valueOf(ficheMeta.getId());
            case FieldKey.SPECIAL_LANG:
                Lang lang = ficheMeta.getLang();
                if (lang != null) {
                    return lang.toString();
                } else {
                    return "";
                }
            case FieldKey.SPECIAL_TITLE:
                return ficheMeta.getTitle();
        }
        if (fieldKey.isProp()) {
            if (fiche == null) {
                fiche = ficheMeta.getFicheAPI(false);
            }
            Prop prop = fiche.getProp(fieldKey);
            if (prop == null) {
                return "";
            }
            FicheItem ficheItem = prop.getFicheItem();
            if (ficheItem instanceof Item) {
                return ((Item) ficheItem).getValue();
            }
            return AccoladePattern.toString(ficheAccoladeArgument);
        }
        return AccoladePattern.toString(ficheAccoladeArgument);
    }

    private static FicheAccoladeArgument parse(String name, String mode) {
        if (name.equals(CORPUS)) {
            return new FicheAccoladeArgument(name, mode, null);
        }
        try {
            FieldKey fieldKey = FieldKey.parse(name);
            return new FicheAccoladeArgument(name, mode, fieldKey);
        } catch (java.text.ParseException pe) {
            return null;
        }
    }


    private static class FicheAccoladeArgument implements AccoladeArgument {

        private final String name;
        private final String mode;
        private final FieldKey fieldKey;

        private FicheAccoladeArgument(String name, String mode, FieldKey fieldKey) {
            this.name = name;
            this.mode = mode;
            this.fieldKey = fieldKey;
        }

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

        @Override
        public String getMode() {
            return mode;
        }

        public FieldKey getFieldKey() {
            return fieldKey;
        }

    }

}
