/*
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.proc.parsers;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import fr.cnrs.liris.drim.grt.modele.Citation;
import fr.cnrs.liris.drim.grt.modele.Coordonnee;
import fr.cnrs.liris.drim.grt.modele.OrdreStrict;
import fr.cnrs.liris.drim.grt.modele.Passage;
import fr.cnrs.liris.drim.grt.modele.Terme;
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 fr.cnrs.liris.drim.grt.modele.listes.ExpressionsRecurrentes;
import fr.cnrs.liris.drim.grt.modele.listes.ExpressionsUsuelles;
import fr.cnrs.liris.drim.grt.modele.listes.LemmesRecurrents;
import fr.cnrs.liris.drim.grt.modele.listes.LemmesUsuels;
import fr.cnrs.liris.drim.grt.modele.listes.LemmesVides;
import fr.cnrs.liris.drim.grt.modele.listes.NomsPropres;
import fr.cnrs.liris.drim.grt.proc.ReferencesDeCitation;
import fr.cnrs.liris.drim.grt.proc.Texte;

/**
 *
 * @author sgesche
 */
public class ExportFichier {
    public final static int TERMES_BRUTS = 0;
    public final static int TERMES_NORMALISES = 1;
    public final static int TERMES_LEMMATISES = 2;
    
    public static void exporteFrequencesTermes(File fichier, Map<Integer, Set<Terme>> frequences, int frequenceMax) throws IOException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fichier), "UTF-8"));
        
        for(int i=0; i<=frequenceMax; i++) {
            writer.write(i + " documents manquants");
            writer.newLine();
            writer.newLine();
            if(frequences.containsKey(i)) {
                for(Terme t: frequences.get(i)) {
                    writer.write(t.getExpression());
                    writer.newLine();
                }
            }
            writer.newLine();
            writer.newLine();
            writer.newLine();
            writer.flush();
        }
    }
    
    public static void exporteNLexes(File fichier, PassageType document, int n, int traitement, boolean avecMotsVides) throws IOException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fichier), "UTF-8"));
        Passage[] mots = avecMotsVides ? document.getPassage().getAllMots() : document.getPassage().getAllMotsNonVides();
        
        for(int i=0; i<mots.length-n; i++) {
            writer.write(i + "");
            for(int j=i; j<i+n; j++) {
                Terme terme = mots[j].getContenu();
                if(traitement == TERMES_NORMALISES) {
                    terme = terme.getFormeNormale();
                } else if(traitement == TERMES_LEMMATISES) {
                    terme = terme.getLemmePrincipal();
                }
                writer.write("\t" + terme + "(" + mots[j].getNumeroComplet() + ")");
            }
            writer.newLine();
            writer.flush();
        }
        
    }
    
    public static void exporteTableTermes(File fichierTSV, String[] termes) throws IOException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fichierTSV), "UTF-8"));
        for(String terme: termes) {
            writer.write(terme);
            writer.newLine();
        }
        writer.flush();
    }
    
    public static void exporteTableFrequences(File fichierTSV, Map<String, Integer> termes) throws IOException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fichierTSV), "UTF-8"));
        for(String terme: termes.keySet()) {
            writer.write(terme+"\t"+termes.get(terme));
            writer.newLine();
        }
        writer.flush();
    }
    
    public static void exporteTexteAvecLemmatisation(Passage doc, File fichier) throws IOException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fichier), "UTF-8"));
        writer.write("Texte complet\r\n\r\n");
        ecrisContenu(doc, writer);
        writer.write("\r\n\r\n\r\n\r\nUniquement les ambiguïtés et les vides\r\n\r\n");
        ecrisContenu2(doc, writer);
    }
    
    private static void ecrisContenu(Passage p, Writer w) throws IOException {
        w.write("[" + p.getTitre() + "] ");
        for(Passage pn: p.getSousPassages()) {
            if(pn.estUnMot()) {
                w.write(p.getContenu().getExpression() + " " + Arrays.toString(p.getContenu().getFormesLemmatisees()) + "  ");
            } else {
                w.write("\r\n");
                ecrisContenu(pn, w);
            }
        }
        w.flush();
    }
    
    private static void ecrisContenu2(Passage p, Writer w) throws IOException {
        w.write("[" + p.getTitre() + "] ");
        for(Passage pn: p.getSousPassages()) {
            if(pn.estUnMot()) {
                Terme t = p.getContenu();
                if(t.getFormesLemmatisees().length > 1) {
                    w.write(t.getExpression() + " " + Arrays.toString(t.getFormesLemmatisees()) + "  ");
                }
                if(t.getFormesLemmatisees().length == 0) {
                    w.write(t.getExpression() + " " + Arrays.toString(t.getFormesLemmatisees()) + "  ");
                }
            } else {
                w.write("\r\n");
                ecrisContenu2(pn, w);
            }
        }
        w.flush();
    }
    
    public static void exporteRemarques(File destination, String remarques) throws IOException {
        destination.createNewFile();
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destination), "UTF-8"));
        writer.write(remarques);
        writer.flush();
    }
    
    public static void exporteStatsCitations(Citation[] cits, ReferencesDeCitation[] refs, File destination) throws IOException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destination), "UTF-8"));
        writer.write(
                "Référence citée\t" +
                "Référence citante\t" + 
                "Termes communs (vides usuels récurrents significatifs)\t" + 
                "Termes communs (URS)\t" + 
                "Termes communs (RS)\t" + 
                "Termes communs (S)\t" + 
                "Termes normalisés communs (VURS)\t" + 
                "Termes normalisés communs (URS)\t" + 
                "Termes normalisés communs (RS)\t" + 
                "Termes normalisés communs (S)\t" + 
                "Lemmes communs (VURS)\t" + 
                "Lemmes communs (URS)\t" + 
                "Lemmes communs (RS)\t" + 
                "Lemmes communs (S)\t" + 
                "Termes non vides à la suite communs\t" + 
                "Termes normalisés non vides à la suite communs\t" + 
                "Lemmes non vides à la suite communs\t" + 
                "Texte cité\t" + 
                "Texte citeur\r\n"); // titres de colonnes
        for(int i=0; i<cits.length; i++) {
            Citation citation = cits[i];
            ReferencesDeCitation ref = refs[i];
            writer.write(
                    ref.getCite().toString()+"\t"+
                    ref.getCiteur().toString()+"\t"+
                    citation.getNbTermesCommuns(Citation.MODE_NORMAL, Citation.TOLERANCE_VIDES_USUELS_RECURRENTS_SIGNIFICATIFS)+"\t"+
                    citation.getNbTermesCommuns(Citation.MODE_NORMAL, Citation.TOLERANCE_USUELS_RECURRENTS_SIGNIFICATIFS)+"\t"+
                    citation.getNbTermesCommuns(Citation.MODE_NORMAL, Citation.TOLERANCE_RECURRENTS_SIGNIFICATIFS)+"\t"+
                    citation.getNbTermesCommuns(Citation.MODE_NORMAL, Citation.TOLERANCE_SIGNIFICATIFS)+"\t"+
                    citation.getNbTermesCommuns(Citation.MODE_NORMALISE, Citation.TOLERANCE_VIDES_USUELS_RECURRENTS_SIGNIFICATIFS)+"\t"+
                    citation.getNbTermesCommuns(Citation.MODE_NORMALISE, Citation.TOLERANCE_USUELS_RECURRENTS_SIGNIFICATIFS)+"\t"+
                    citation.getNbTermesCommuns(Citation.MODE_NORMALISE, Citation.TOLERANCE_RECURRENTS_SIGNIFICATIFS)+"\t"+
                    citation.getNbTermesCommuns(Citation.MODE_NORMALISE, Citation.TOLERANCE_SIGNIFICATIFS)+"\t"+
                    citation.getNbTermesCommuns(Citation.MODE_LEMMATISE, Citation.TOLERANCE_VIDES_USUELS_RECURRENTS_SIGNIFICATIFS)+"\t"+
                    citation.getNbTermesCommuns(Citation.MODE_LEMMATISE, Citation.TOLERANCE_USUELS_RECURRENTS_SIGNIFICATIFS)+"\t"+
                    citation.getNbTermesCommuns(Citation.MODE_LEMMATISE, Citation.TOLERANCE_RECURRENTS_SIGNIFICATIFS)+"\t"+
                    citation.getNbTermesCommuns(Citation.MODE_LEMMATISE, Citation.TOLERANCE_SIGNIFICATIFS)+"\t"+
                    citation.getTaillePlusGrandeChaineDeMotsCommune(Citation.MODE_NORMAL, false)+"\t"+
                    citation.getTaillePlusGrandeChaineDeMotsCommune(Citation.MODE_NORMALISE, false)+"\t"+
                    citation.getTaillePlusGrandeChaineDeMotsCommune(Citation.MODE_LEMMATISE, false)+"\t"+
                    new Texte(citation.getCite()).getTexte()+"\t"+
                    new Texte(citation.getCiteur()).getTexte()+"\r\n");
        }
        writer.flush();
    }
    
    public static void exporteCorrespondanceInterne(Map<String, Set<String>> cits, File destination) throws IOException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destination), "UTF-8"));
        writer.write(
                "Texte commun\t" +
                "Taille\t" +
                "Références\r\n"); // titres de colonnes
        for(String cit: cits.keySet()) {
            String refs = "";
            for(String r: cits.get(cit)) {
                refs += r + " ; ";
            }
            refs = refs.substring(0, refs.length()-3);
            writer.write(cit+"\t"+cit.split(" ").length+"\t"+refs+"\r\n");
        }
        writer.flush();
    }
    
    /*
        <!DOCTYPE DocBible [
            <!ELEMENT DocBible (Bible+)>
            <!ELEMENT Bible (Livre+)>
                    <!ATTLIST Bible nom CDATA #REQUIRED>
            <!ELEMENT Livre (Chapitre+)>
                    <!ATTLIST Livre nom CDATA #REQUIRED>
            <!ELEMENT Chapitre (Verset+)>
                    <!ATTLIST Chapitre no CDATA #REQUIRED>
            <!ELEMENT Verset (Mot*)>
                    <!ATTLIST Verset no CDATA #REQUIRED>
            <!ELEMENT Mot (#PCDATA)>
                    <!ATTLIST Mot no CDATA #REQUIRED>
        ]>


        <!DOCTYPE DocOeuvres [
            <!ELEMENT DocOeuvres (Oeuvre+)>
            <!ELEMENT Oeuvre (Chapitre+)>
                    <!ATTLIST Oeuvre nom CDATA #REQUIRED>
            <!ELEMENT Chapitre (Paragraphe+)>
                    <!ATTLIST Chapitre no CDATA #REQUIRED>
            <!ELEMENT Paragraphe (Ligne+)>
                    <!ATTLIST Paragraphe no CDATA #REQUIRED>
            <!ELEMENT Ligne (Mot*)>
                    <!ATTLIST Ligne no CDATA #REQUIRED>
            <!ELEMENT Mot (#PCDATA)>
                    <!ATTLIST Mot no CDATA #REQUIRED>
        ]>
     */
    public static void exportXML(Passage passage, File destination) throws IOException, IllegalArgumentException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destination), "UTF-8"));
        Map<Coordonnee, Passage> coordonnees = passage.getSousPassagesAvecCoordonnees();
        if(coordonnees.keySet().isEmpty()) {
            //Erreur : rien dans le passage
            throw new IllegalArgumentException("Passage vide non exportable");
        }
        writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n");
        Coordonnee[] coordonnees2 = new Coordonnee[coordonnees.keySet().size()];
        coordonnees.keySet().toArray(coordonnees2);
        OrdreStrict ordre = coordonnees2[0].getSysteme();
        try {
            if(ordre.equals(OrdreStrict.getInstance(OrdreStrict.LIVRES_BIB))) {
                // Bible
                exportXMLBible(passage, writer);
            } else if(ordre.equals(OrdreStrict.getInstance(OrdreStrict.CHAPITRES))) {
                // Une oeuvre unique (probablement, on verra plus tard)
                exportXMLOeuvreUnique(passage, writer);
            } else if(ordre.equals(OrdreStrict.getInstance(OrdreStrict.NUMERIQUE_ARABE))) {
                // Oeuvres (probablement, on verra plus tard)
                exportXMLOeuvres(passage, writer);
            } else {
                // Erreur : passage non exportable
                throw new IllegalArgumentException("Passage non exportable");
            }
        } catch(NumberFormatException nfe) {
            throw new IllegalArgumentException("Erreur de numérotation dans le passage", nfe);
        }
        writer.flush();
    }
    
    private static void exportXMLBible(Passage bible, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("<DocBible>\n");
        writer.write("\t<Bible nom=\""+Textes.echappeXML(bible.getTitre())+"\">\n");
        for(Passage livre: bible.getSousPassages()) {
            exportXMLLivre(livre, bible.getCoordonnee(livre).getExpression(), writer);
        }
        writer.write("\t</Bible>\n");
        writer.write("</DocBible>\n");
    }
    private static void exportXMLLivre(Passage livre, String nom, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t\t<Livre nom=\""+Textes.echappeXML(nom)+"\">\n");
        for(Passage chapitre: livre.getSousPassages()) {
            exportXMLChBible(chapitre, Integer.parseInt(livre.getCoordonnee(chapitre).getExpression()), writer);
        }
        writer.write("\t\t</Livre>\n");
    }
    private static void exportXMLChBible(Passage ch, int no, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t\t\t<Chapitre no=\""+no+"\">\n");
        for(Passage verset: ch.getSousPassages()) {
            exportXMLVerset(verset, Integer.parseInt(ch.getCoordonnee(verset).getExpression()), writer);
        }
        writer.write("\t\t\t</Chapitre>\n");
    }
    private static void exportXMLVerset(Passage v, int no, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t\t\t\t<Verset no=\""+no+"\">\n\t\t\t\t\t");
        for(Passage mot: v.getSousPassages()) {
            int n = Integer.parseInt(v.getCoordonnee(mot).getExpression());
            writer.write("<Mot no=\""+n+"\">"+mot.getContenu().getExpression()+"</Mot> ");
        }
        writer.write("\n\t\t\t\t</Verset>\n");
    }
    private static void exportXMLOeuvres(Passage oeuvres, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("<DocOeuvre>\n");
        for(Passage oeuvre: oeuvres.getSousPassages()) {
            exportXMLOeuvre(oeuvre, oeuvres.getCoordonnee(oeuvre).getExpression(), writer);
        }
        writer.write("</DocOeuvre>\n");
    }
    private static void exportXMLOeuvreUnique(Passage oeuvre, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("<DocOeuvre>\n");
        writer.write("\t<Oeuvre nom=\""+Textes.echappeXML(oeuvre.getTitre())+"\">\n");
        for(Passage chapitre: oeuvre.getSousPassages()) {
            exportXMLChOeuvre(chapitre, Integer.parseInt(oeuvre.getCoordonnee(chapitre).getExpression()), writer);
        }
        writer.write("\t</Oeuvre>\n");
        writer.write("</DocOeuvre>\n");
    }
    private static void exportXMLOeuvre(Passage oeuvre, String nom, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t<Oeuvre nom=\""+Textes.echappeXML(nom)+"\">\n");
        for(Passage chapitre: oeuvre.getSousPassages()) {
            exportXMLChOeuvre(chapitre, Integer.parseInt(oeuvre.getCoordonnee(chapitre).getExpression()), writer);
        }
        writer.write("\t</Oeuvre>\n");
    }
    private static void exportXMLChOeuvre(Passage ch, int no, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t\t<Chapitre no=\""+no+"\">\n");
        for(Passage paragraphe: ch.getSousPassages()) {
            exportXMLParagraphe(paragraphe, Integer.parseInt(ch.getCoordonnee(paragraphe).getExpression()), writer);
        }
        writer.write("\t\t</Chapitre>\n");
    }
    private static void exportXMLParagraphe(Passage p, int no, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t\t\t<Paragraphe no=\""+no+"\">\n");
        for(Passage ligne: p.getSousPassages()) {
            exportXMLLigne(ligne, Integer.parseInt(p.getCoordonnee(ligne).getExpression()), writer);
        }
        writer.write("\t\t\t</Paragraphe>\n");
    }
    private static void exportXMLLigne(Passage l, int no, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t\t\t\t<Ligne no=\""+no+"\">\n\t\t\t\t\t");
        for(Passage mot: l.getSousPassages()) {
            int n = Integer.parseInt(l.getCoordonnee(mot).getExpression());
            writer.write("<Mot no=\""+n+"\">"+mot.getContenu().getExpression()+"</Mot> ");
        }
        writer.write("\n\t\t\t\t</Ligne>\n");
    }
    
    
    
    /*
        <!DOCTYPE DocBible [
            <!ELEMENT DocBible (Bible+)>
            <!ELEMENT Bible (Book+)>
                    <!ATTLIST Bible name CDATA #REQUIRED>
            <!ELEMENT Book (Chapter+)>
                    <!ATTLIST Book name CDATA #REQUIRED>
            <!ELEMENT Chapter (Verse+)>
                    <!ATTLIST Chapter num CDATA #REQUIRED>
            <!ELEMENT Verse (Word*)>
                    <!ATTLIST Verse num CDATA #REQUIRED>
            <!ELEMENT Word (#PCDATA)>
                    <!ATTLIST Word num CDATA #REQUIRED>
        ]>


        <!DOCTYPE DocWorks [
            <!ELEMENT DocWorks (Work+)>
            <!ELEMENT Work (Chapter+)>
                    <!ATTLIST Work name CDATA #REQUIRED>
            <!ELEMENT Chapter (Paragraph+)>
                    <!ATTLIST Chapter num CDATA #REQUIRED>
            <!ELEMENT Paragraph (Line+)>
                    <!ATTLIST Paragraph num CDATA #REQUIRED>
            <!ELEMENT Line (Word*)>
                    <!ATTLIST Line num CDATA #REQUIRED>
            <!ELEMENT Word (#PCDATA)>
                    <!ATTLIST Word num CDATA #REQUIRED>
        ]>
     */
    public static void exportXMLEN(Passage passage, File destination) throws IOException, IllegalArgumentException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destination), "UTF-8"));
        Map<Coordonnee, Passage> coordonnees = passage.getSousPassagesAvecCoordonnees();
        if(coordonnees.keySet().isEmpty()) {
            //Erreur : rien dans le passage
            throw new IllegalArgumentException("Cannot export empty Passages");
        }
        writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n");
        Coordonnee[] coordonnees2 = new Coordonnee[coordonnees.keySet().size()];
        coordonnees.keySet().toArray(coordonnees2);
        OrdreStrict ordre = coordonnees2[0].getSysteme();
        try {
            if(ordre.equals(OrdreStrict.getInstance(OrdreStrict.LIVRES_BIB))) {
                // Bible
                exportXMLBibleEN(passage, writer);
            } else if(ordre.equals(OrdreStrict.getInstance(OrdreStrict.CHAPITRES))) {
                // Une oeuvre unique (probablement, on verra plus tard)
                exportXMLOeuvreUniqueEN(passage, writer);
            } else if(ordre.equals(OrdreStrict.getInstance(OrdreStrict.NUMERIQUE_ARABE))) {
                // Oeuvres (probablement, on verra plus tard)
                exportXMLOeuvresEN(passage, writer);
            } else {
                // Erreur : passage non exportable
                throw new IllegalArgumentException("Cannot export Passage");
            }
        } catch(NumberFormatException nfe) {
            throw new IllegalArgumentException("Passage has not been correctly numbered", nfe);
        }
        writer.flush();
    }
    
    private static void exportXMLBibleEN(Passage bible, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("<DocBible>\n");
        writer.write("\t<Bible name=\""+Textes.echappeXML(bible.getTitre())+"\">\n");
        for(Passage livre: bible.getSousPassages()) {
            exportXMLLivreEN(livre, bible.getCoordonnee(livre).getExpression(), writer);
        }
        writer.write("\t</Bible>\n");
        writer.write("</DocBible>\n");
    }
    private static void exportXMLLivreEN(Passage livre, String nom, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t\t<Book name=\""+Textes.echappeXML(nom)+"\">\n");
        for(Passage chapitre: livre.getSousPassages()) {
            exportXMLChBibleEN(chapitre, Integer.parseInt(livre.getCoordonnee(chapitre).getExpression()), writer);
        }
        writer.write("\t\t</Book>\n");
    }
    private static void exportXMLChBibleEN(Passage ch, int no, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t\t\t<Chapter num=\""+no+"\">\n");
        for(Passage verset: ch.getSousPassages()) {
            exportXMLVersetEN(verset, Integer.parseInt(ch.getCoordonnee(verset).getExpression()), writer);
        }
        writer.write("\t\t\t</Chapter>\n");
    }
    private static void exportXMLVersetEN(Passage v, int no, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t\t\t\t<Verse num=\""+no+"\">\n\t\t\t\t\t");
        for(Passage mot: v.getSousPassages()) {
            int n = Integer.parseInt(v.getCoordonnee(mot).getExpression());
            writer.write("<Word num=\""+n+"\">"+mot.getContenu().getExpression()+"</Word> ");
        }
        writer.write("\n\t\t\t\t</Verse>\n");
    }
    private static void exportXMLOeuvresEN(Passage oeuvres, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("<DocWorks>\n");
        for(Passage oeuvre: oeuvres.getSousPassages()) {
            exportXMLOeuvreEN(oeuvre, oeuvres.getCoordonnee(oeuvre).getExpression(), writer);
        }
        writer.write("</DocWorks>\n");
    }
    private static void exportXMLOeuvreUniqueEN(Passage oeuvre, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("<DocWorks>\n");
        writer.write("\t<Work name=\""+Textes.echappeXML(oeuvre.getTitre())+"\">\n");
        for(Passage chapitre: oeuvre.getSousPassages()) {
            exportXMLChOeuvreEN(chapitre, Integer.parseInt(oeuvre.getCoordonnee(chapitre).getExpression()), writer);
        }
        writer.write("\t</Work>\n");
        writer.write("</DocWorks>\n");
    }
    private static void exportXMLOeuvreEN(Passage oeuvre, String nom, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t<Work name=\""+Textes.echappeXML(nom)+"\">\n");
        for(Passage chapitre: oeuvre.getSousPassages()) {
            exportXMLChOeuvreEN(chapitre, Integer.parseInt(oeuvre.getCoordonnee(chapitre).getExpression()), writer);
        }
        writer.write("\t</Work>\n");
    }
    private static void exportXMLChOeuvreEN(Passage ch, int no, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t\t<Chapter num=\""+no+"\">\n");
        for(Passage paragraphe: ch.getSousPassages()) {
            exportXMLParagrapheEN(paragraphe, Integer.parseInt(ch.getCoordonnee(paragraphe).getExpression()), writer);
        }
        writer.write("\t\t</Chapter>\n");
    }
    private static void exportXMLParagrapheEN(Passage p, int no, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t\t\t<Paragraph num=\""+no+"\">\n");
        for(Passage ligne: p.getSousPassages()) {
            exportXMLLigneEN(ligne, Integer.parseInt(p.getCoordonnee(ligne).getExpression()), writer);
        }
        writer.write("\t\t\t</Paragraph>\n");
    }
    private static void exportXMLLigneEN(Passage l, int no, BufferedWriter writer) throws IOException, NumberFormatException {
        writer.write("\t\t\t\t<Line num=\""+no+"\">\n\t\t\t\t\t");
        for(Passage mot: l.getSousPassages()) {
            int n = Integer.parseInt(l.getCoordonnee(mot).getExpression());
            writer.write("<Word num=\""+n+"\">"+mot.getContenu().getExpression()+"</Word> ");
        }
        writer.write("\n\t\t\t\t</Line>\n");
    }
    
    
    public static void exportBaseLemmes(File fBible) throws IOException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("lexis_data.sql"), "UTF-8"));
        Set<String> formes = new HashSet<>();
        //formes.addAll(Arrays.asList(Archimedes.getInstance().getListeFormes()));
        formes.addAll(Arrays.asList(Perseus.getInstance().getListeFormes()));
        formes.addAll(Arrays.asList(SourcesChretiennes.getInstance().getListeFormes()));
        formes.addAll(Arrays.asList(BibleWorks.getInstance().getListeFormes()));
        
        Passage bible = ImportFichier.importBibleTexteOuMorphoTXT(fBible);
        Terme[] motsBibliques0 = bible.getEnsembleTermes();
        Set<Terme> motsBibliques = new HashSet<>(Arrays.asList(motsBibliques0));
        
        for(String f: formes) {
            String caractereUsuel = "significative";
            if(LemmesVides.contientLemme(Terme.cree(f))) {
                caractereUsuel = "vide";
            } else if(LemmesUsuels.contientLemme(Terme.cree(f))) {
                caractereUsuel = "récurrente dans la langue";
            } else if(LemmesRecurrents.contientLemme(Terme.cree(f))) {
                caractereUsuel = "récurrente en patristique";
            }
            String estNomPropre = "0";
            if(NomsPropres.getInstance().contient(Terme.cree(f))) {
                estNomPropre = "1";
            }
            String estBiblique = "0";
            if(motsBibliques.contains(Terme.cree(f))) {
                estBiblique = "1";
            }
            writer.write("INSERT INTO formes(expression, caractereusuel, langue, estNomPropre, estBiblique) VALUES ('" +
                    f + "', '"+ caractereUsuel + "', 'Grec Koinè', '" + estNomPropre + "', '" + estBiblique + "');"); writer.newLine();
        }
        writer.flush();
        
        /*for(String f: Archimedes.getInstance().getListeFormes()) {
            int n = 0;
            for(String l: Archimedes.getInstance().getFormesLemmatisees(f)) {
                n++;
                writer.write("INSERT INTO listelemmes(forme, priorite, lemme, lemmatiseur) VALUES ('"+f+"', '"+n+"', '"+l+"', 'Archimedes');"); writer.newLine();
            }
        }
        writer.flush();*/
        
        for(String f: Perseus.getInstance().getListeFormes()) {
            int n = 0;
            if(Arrays.asList(Perseus.getInstance().getFormesLemmatisees(f)).contains(f)) {
                n++;
                writer.write("INSERT INTO listelemmes(forme, priorite, lemme, lemmatiseur) VALUES ('"+f+"', '"+n+"', '"+f+"', 'Perseus');"); writer.newLine();
            }
            for(String l: Perseus.getInstance().getFormesLemmatisees(f)) {
                if(!l.equals(f)) {
                    n++;
                    writer.write("INSERT INTO listelemmes(forme, priorite, lemme, lemmatiseur) VALUES ('"+f+"', '"+n+"', '"+l+"', 'Perseus');"); writer.newLine();
                }
            }
        }
        writer.flush();
        
        Set<String> formesBWSC = new HashSet<>();
        formesBWSC.addAll(Arrays.asList(BibleWorks.getInstance().getListeFormes()));
        formesBWSC.addAll(Arrays.asList(SourcesChretiennes.getInstance().getListeFormes()));
        
        for(String f: formesBWSC) {
            int n = 0;
            Set<String> lemmes = new HashSet<>();
            if(Arrays.asList(SourcesChretiennes.getInstance().getFormesLemmatisees(f)).contains(f)) {
                n++;
                lemmes.add(f);
                writer.write("INSERT INTO listelemmes(forme, priorite, lemme, lemmatiseur) VALUES ('"+f+"', '"+n+"', '"+f+"', 'Sources Chrétiennes');"); writer.newLine();
            }
            for(String l: SourcesChretiennes.getInstance().getFormesLemmatisees(f)) {
                if(!lemmes.contains(l)) {
                    n++;
                    lemmes.add(l);
                    writer.write("INSERT INTO listelemmes(forme, priorite, lemme, lemmatiseur) VALUES ('"+f+"', '"+n+"', '"+l+"', 'Sources Chrétiennes');"); writer.newLine();
                }
            }
            if(Arrays.asList(BibleWorks.getInstance().getFormesLemmatisees(f)).contains(f)) {
                if(!lemmes.contains(f)) {
                    n++;
                    lemmes.add(f);
                    writer.write("INSERT INTO listelemmes(forme, priorite, lemme, lemmatiseur) VALUES ('"+f+"', '"+n+"', '"+f+"', 'Sources Chrétiennes');"); writer.newLine();
                }
            }
            for(String l: BibleWorks.getInstance().getFormesLemmatisees(f)) {
                if(!lemmes.contains(l)) {
                    n++;
                    lemmes.add(l);
                    writer.write("INSERT INTO listelemmes(forme, priorite, lemme, lemmatiseur) VALUES ('"+f+"', '"+n+"', '"+l+"', 'Sources Chrétiennes');"); writer.newLine();
                }
            }
        }
        writer.flush();
        
        int xp = 0;
        
        for(String x: ExpressionsUsuelles.getListe()) {
            xp++;
            String[] ff = x.split(" ");
            writer.write("INSERT INTO expressions(id, caractereusuel) VALUES ('"+xp+"', 'récurrente dans la langue');"); writer.newLine();
            int n = 0;
            for(String f: ff) {
                n++;
                writer.write("INSERT INTO termesexpressions(expression, place, forme) VALUES ('"+xp+"', '"+n+"', '"+f+"');"); writer.newLine();
            }
        }
        writer.flush();
        
        for(String x: ExpressionsRecurrentes.getListe()) {
            xp++;
            String[] ff = x.split(" ");
            writer.write("INSERT INTO expressions(id, caractereusuel) VALUES ('"+xp+"', 'récurrente en patristique');"); writer.newLine();
            int n = 0;
            for(String f: ff) {
                n++;
                writer.write("INSERT INTO termesexpressions(expression, place, forme) VALUES ('"+xp+"', '"+n+"', '"+f+"');"); writer.newLine();
            }
        }
        writer.flush();
        
    }
}
