/*
Copyright 2012-2014 Samuel Gesche

This file is part of the Greek Reuse Toolkit.

The Greek Reuse Toolkit is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

The Greek Reuse Toolkit is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with the Greek Reuse Toolkit.  If not, see <http://www.gnu.org/licenses/>.
*/

package fr.cnrs.liris.drim.grt.modele.listes;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import fr.cnrs.liris.drim.grt.modele.convertisseurs.ConvertisseurTexteUnicodeVersUnicode;
import fr.cnrs.liris.drim.grt.modele.convertisseurs.ConvertisseurUnicodeVersMinuscules;
import fr.cnrs.liris.drim.grt.modele.lemmatiseurs.BibleWorks;
import fr.cnrs.liris.drim.grt.modele.lemmatiseurs.Perseus;
import fr.cnrs.liris.drim.grt.modele.lemmatiseurs.SourcesChretiennes;
import org.apache.commons.lang.StringUtils;

/**
 *
 * @author Sam
 */
public class Lemmatiseurs {
    public final static int ARCHIMEDES = 0;
    public final static int BIBLEWORKS = 1;
    public final static int SOURCESCHRETIENNES = 2;
    public final static int PERSEUS = 3;
    
    private final static Set<String> formesSansLemmes = new HashSet<>();
    private final static Set<String> formesAvecLemmes = new HashSet<>();
    private final static Set<String> formesSpecifiquesASC = new HashSet<>();
    private final static Set<String> formesSpecifiquesABW = new HashSet<>();
    private final static Set<String> formesSpecifiquesAP = new HashSet<>();
    private final static Set<String> formesTrouveesParSC = new HashSet<>();
    private final static Set<String> formesTrouveesParBW = new HashSet<>();
    private final static Set<String> formesTrouveesParP = new HashSet<>();
    private final static Set<String> formesTrouveesParTous = new HashSet<>();
    private final static Set<String> formesDemandees = new HashSet<>();
    
    
    public static String[] getToutesFormesLemmatisees(String termeALemmatiser) {
        
        termeALemmatiser = StringUtils.replace(termeALemmatiser, " ", "");
        termeALemmatiser = StringUtils.replace(termeALemmatiser, "|", "");
        termeALemmatiser = StringUtils.replace(termeALemmatiser, "-", "");
        
        String terme = ConvertisseurUnicodeVersMinuscules.conversion(
                ConvertisseurTexteUnicodeVersUnicode.conversion(termeALemmatiser, true));
        if(terme.isEmpty()) {
            return new String[]{terme};
        }
        formesDemandees.add(terme);
        Set<String> res = new HashSet<>();
        int nb = 0;
        int qt = 0;
        int lem = 0;
        res.addAll(Arrays.asList(SourcesChretiennes.getInstance().getFormesLemmatisees(terme)));
        int nb2 = res.size();
        if(nb2 > nb) {
            formesTrouveesParSC.add(terme);
            qt++;
            lem = SOURCESCHRETIENNES;
        }
        nb = nb2;
        res.addAll(Arrays.asList(BibleWorks.getInstance().getFormesLemmatisees(terme)));
        nb2 = res.size();
        if(nb2 > nb) {
            formesTrouveesParBW.add(terme);
            qt++;
            lem = BIBLEWORKS;
        }
        nb = nb2;
        res.addAll(Arrays.asList(Perseus.getInstance().getFormesLemmatisees(terme)));
        nb2 = res.size();
        if(nb2 > nb) {
            formesTrouveesParP.add(terme);
            qt++;
            lem = PERSEUS;
        }
        if(qt == 3) {
            formesTrouveesParTous.add(terme);
        }
        if(qt == 1) {
            switch(lem) {
                case SOURCESCHRETIENNES:
                    formesSpecifiquesASC.add(terme);
                    break;
                case BIBLEWORKS:
                    formesSpecifiquesABW.add(terme);
                    break;
                case PERSEUS:
                    formesSpecifiquesAP.add(terme);
            }
        }
        if(res.isEmpty()) {
            formesSansLemmes.add(terme);
            res.add(terme);
        } else {
            formesAvecLemmes.add(terme);
        }
        String[] resultat = new String[res.size()];
        res.toArray(resultat);
        return resultat;
    }
    
    public static String getFormeLemmatisee(String termeALemmatiser) {
        String terme = ConvertisseurUnicodeVersMinuscules.conversion(
                ConvertisseurTexteUnicodeVersUnicode.conversion(termeALemmatiser, true));
        if(terme.isEmpty()) {
            return terme;
        }
        formesDemandees.add(terme);
        String resultat = "";
        int qt = 0;
        int lem = 0;
        String[] s = SourcesChretiennes.getInstance().getFormesLemmatisees(terme);
        if(s.length > 0) {
            formesTrouveesParSC.add(terme);
            qt++;
            lem = SOURCESCHRETIENNES;
            if(resultat.isEmpty()) {
                if(Arrays.asList(s).contains(terme)) {
                    resultat = terme;
                } else {
                    resultat = s[0];
                }
            }
        }
        s = BibleWorks.getInstance().getFormesLemmatisees(terme);
        if(s.length > 0) {
            formesTrouveesParBW.add(terme);
            qt++;
            lem = BIBLEWORKS;
            if(resultat.isEmpty()) {
                if(Arrays.asList(s).contains(terme)) {
                    resultat = terme;
                } else {
                    resultat = s[0];
                }
            }
        }
        s = Perseus.getInstance().getFormesLemmatisees(terme);
        if(s.length > 0) {
            formesTrouveesParP.add(terme);
            qt++;
            lem = PERSEUS;
            if(resultat.isEmpty()) {
                if(Arrays.asList(s).contains(terme)) {
                    resultat = terme;
                } else {
                    resultat = s[0];
                }
            }
        }
        if(qt == 3) {
            formesTrouveesParTous.add(terme);
        }
        if(qt == 1) {
            switch(lem) {
                case SOURCESCHRETIENNES:
                    formesSpecifiquesASC.add(terme);
                    break;
                case BIBLEWORKS:
                    formesSpecifiquesABW.add(terme);
                    break;
                case PERSEUS:
                    formesSpecifiquesAP.add(terme);
            }
        }
        if(resultat.isEmpty()) {
            resultat = terme;
            formesSansLemmes.add(terme);
        } else {
            formesAvecLemmes.add(terme);
        }
        return resultat;
    }
    
    public static String[] listeFormesDemandees() {
        String[] resultat = new String[formesDemandees.size()];
        formesDemandees.toArray(resultat);
        Arrays.sort(resultat, new OrdreAlphabetiqueGrec());
        return resultat;
    }
    
    public static String[] listeFormesDemandeesAvecLemme() {
        String[] resultat = new String[formesAvecLemmes.size()];
        formesAvecLemmes.toArray(resultat);
        Arrays.sort(resultat, new OrdreAlphabetiqueGrec());
        return resultat;
    }
    
    public static String[] listeFormesDemandeesSansLemme() {
        String[] resultat = new String[formesSansLemmes.size()];
        formesSansLemmes.toArray(resultat);
        Arrays.sort(resultat, new OrdreAlphabetiqueGrec());
        return resultat;
    }
    
    public static boolean aLemmePour(String forme) {
        String[] test = getToutesFormesLemmatisees(forme);
        boolean resultat = true;
        for(String s: listeFormesDemandeesSansLemme()) {
            if(s.equals(forme)) {
                resultat = false;
                break;
            }
        }
        return resultat;
    }
    
    public static String[] listeFormesTrouveesParTous() {
        String[] resultat = new String[formesTrouveesParTous.size()];
        formesTrouveesParTous.toArray(resultat);
        Arrays.sort(resultat, new OrdreAlphabetiqueGrec());
        return resultat;
    }
    
    public static String[] listeFormesSpecifiquesA(int procedeLemmatisation) {
        Set<String> formes;
        switch(procedeLemmatisation) {
            case SOURCESCHRETIENNES:
                formes = formesSpecifiquesASC;
                break;
            case BIBLEWORKS:
                formes = formesSpecifiquesABW;
                break;
            case PERSEUS:
                formes = formesSpecifiquesAP;
                break;
            default:
                formes = new HashSet<>();
        }
        String[] resultat = new String[formes.size()];
        formes.toArray(resultat);
        Arrays.sort(resultat, new OrdreAlphabetiqueGrec());
        return resultat;
    }
    
    public static String[] listeFormesTrouveesPar(int procedeLemmatisation) {
        Set<String> formes;
        switch(procedeLemmatisation) {
            case SOURCESCHRETIENNES:
                formes = formesTrouveesParSC;
                break;
            case BIBLEWORKS:
                formes = formesTrouveesParBW;
                break;
            case PERSEUS:
                formes = formesTrouveesParP;
                break;
            default:
                formes = new HashSet<>();
        }
        String[] resultat = new String[formes.size()];
        formes.toArray(resultat);
        Arrays.sort(resultat, new OrdreAlphabetiqueGrec());
        return resultat;
    }
}
