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

import fr.cnrs.liris.drim.grt.ihm.exceptions.InteractionRefuseeException;
import fr.cnrs.liris.drim.grt.modele.Citation;
import fr.cnrs.liris.drim.grt.modele.OrdreStrict;
import fr.cnrs.liris.drim.grt.modele.Passage;
import fr.cnrs.liris.drim.grt.modele.exceptions.ListeStatistiqueNonInitialiseeException;
import fr.cnrs.liris.drim.grt.proc.ComparateurCitations;
import fr.cnrs.liris.drim.grt.proc.ReferencesDeCitation;
import fr.cnrs.liris.drim.grt.proc.exceptions.DOMCreationFailureException;
import fr.cnrs.liris.drim.grt.proc.parsers.ImportFichier;
import fr.cnrs.liris.drim.grt.proc.parsers.PassageType;
import fr.cnrs.liris.drim.grt.proc.parsers.Temps;
import fr.cnrs.liris.drim.grt.proc.recherche.Recherche;
import fr.cnrs.liris.drim.grt.proc.recherche.RechercheNLexes;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.Timer;
import javax.swing.text.BadLocationException;

/**
 *
 * @author Sam
 */
public class FenetreEvaluation extends javax.swing.JFrame {
    private PassageType citant;
    private PassageType cite;
    private Citation[] temoin;
    private OrdreStrict granulariteCitant;
    private OrdreStrict granulariteCite;
    
    
    private final ArrayList<RechercheNLexes> recherches;
    
    private long maxUsedMemory = 0;
    private final ActionListener timer = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            maxUsedMemory = Math.max(maxUsedMemory, 
                    Runtime.getRuntime().totalMemory() - 
                    Runtime.getRuntime().freeMemory());
            lStatutMem.setText("Mémoire utilisée : " + 
                    ((Runtime.getRuntime().totalMemory()/1024/1024) - 
                    (Runtime.getRuntime().freeMemory()/1024/1024)) +
                    "Mo (max "+maxUsedMemory/1024/1024+
                    "Mo) - Mémoire disponible : "+
                    (Runtime.getRuntime().freeMemory()/1024/1024)+"Mo / "+
                    (Runtime.getRuntime().totalMemory()/1024/1024)+"Mo (max "+
                    (Runtime.getRuntime().maxMemory()/1024/1024)+"Mo)");
        }
    };
    private final Timer memoire = new Timer(250, timer);
    
    private long debut;
    private RechercheNLexes rechercheCourante;
    private final Timer timerRecherche = new Timer(200, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            lStatutXP.setText("[" + Temps.getTexte(System.currentTimeMillis()-debut) + "] " + 
                    rechercheCourante.getStatut() + " (" +
                    ((int)(rechercheCourante.getAvancement()*10000))/100.0 + "%).");
        }
    });
    
    /**
     * Creates new form FenetreRecherche
     */
    public FenetreEvaluation() {
        initComponents();
        
        pCite.setVisible(false);
        pTemoin.setVisible(false);
        pParametres.setVisible(false);
        
        recherches = new ArrayList<>();
        
        memoire.start();
        pack();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        groupeTraitementLangue = new javax.swing.ButtonGroup();
        groupeTolerance = new javax.swing.ButtonGroup();
        tpPrincipal = new javax.swing.JTabbedPane();
        pParams = new javax.swing.JPanel();
        pCitant = new javax.swing.JPanel();
        jPanel5 = new javax.swing.JPanel();
        lTexteCitant = new javax.swing.JLabel();
        tTexteCitant = new javax.swing.JTextField();
        bChoixTexteCitant = new javax.swing.JButton();
        jPanel6 = new javax.swing.JPanel();
        lStatutCitant = new javax.swing.JLabel();
        pCite = new javax.swing.JPanel();
        jPanel7 = new javax.swing.JPanel();
        lTexteCite = new javax.swing.JLabel();
        tTexteCite = new javax.swing.JTextField();
        bChoixTexteCite = new javax.swing.JButton();
        jPanel8 = new javax.swing.JPanel();
        lStatutCite = new javax.swing.JLabel();
        pTemoin = new javax.swing.JPanel();
        jPanel16 = new javax.swing.JPanel();
        lTexteCite1 = new javax.swing.JLabel();
        cbRefs = new javax.swing.JComboBox();
        bChoixRefsTemoin = new javax.swing.JButton();
        jPanel17 = new javax.swing.JPanel();
        lStatutRefs = new javax.swing.JLabel();
        pParametres = new javax.swing.JPanel();
        pTitre = new javax.swing.JPanel();
        jLabel10 = new javax.swing.JLabel();
        pTolerance = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        tTailleInitiale = new javax.swing.JFormattedTextField();
        jLabel5 = new javax.swing.JLabel();
        jPanel11 = new javax.swing.JPanel();
        jLabel11 = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        rbStricte = new javax.swing.JRadioButton();
        jPanel3 = new javax.swing.JPanel();
        rbAbsolue = new javax.swing.JRadioButton();
        tSeuilAbsolu = new javax.swing.JFormattedTextField();
        jLabel3 = new javax.swing.JLabel();
        jPanel4 = new javax.swing.JPanel();
        rbRelative = new javax.swing.JRadioButton();
        tSeuilRelatif = new javax.swing.JFormattedTextField();
        jLabel4 = new javax.swing.JLabel();
        pTraitement = new javax.swing.JPanel();
        pSansMotsVides = new javax.swing.JPanel();
        cbSansMotsVides = new javax.swing.JCheckBox();
        pImportanceOrdre = new javax.swing.JPanel();
        cbImportanceOrdre = new javax.swing.JCheckBox();
        pTraitementLangue = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        rbBrut = new javax.swing.JRadioButton();
        rbNorm = new javax.swing.JRadioButton();
        rbLemm = new javax.swing.JRadioButton();
        pFinition = new javax.swing.JPanel();
        pFiltrerNonCitations = new javax.swing.JPanel();
        cbFiltrerNonCitations = new javax.swing.JCheckBox();
        pFusion = new javax.swing.JPanel();
        jLabel6 = new javax.swing.JLabel();
        tSeuilFusion = new javax.swing.JFormattedTextField();
        jLabel7 = new javax.swing.JLabel();
        pTailleMax = new javax.swing.JPanel();
        jLabel8 = new javax.swing.JLabel();
        tTailleMax = new javax.swing.JFormattedTextField();
        jLabel9 = new javax.swing.JLabel();
        pAjout = new javax.swing.JPanel();
        jPanel9 = new javax.swing.JPanel();
        bAjout = new javax.swing.JButton();
        jPanel10 = new javax.swing.JPanel();
        lStatutAjout = new javax.swing.JLabel();
        pExperiences = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        listeExperiences = new javax.swing.JList();
        pResultats = new javax.swing.JPanel();
        jPanel18 = new javax.swing.JPanel();
        jPanel14 = new javax.swing.JPanel();
        lStatutMem = new javax.swing.JLabel();
        jPanel12 = new javax.swing.JPanel();
        bLancer = new javax.swing.JButton();
        jPanel13 = new javax.swing.JPanel();
        lStatutXP = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        tResultats = new javax.swing.JEditorPane();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Greek Reuse Toolkit - Recherche de citations");

        pParams.setLayout(new javax.swing.BoxLayout(pParams, javax.swing.BoxLayout.PAGE_AXIS));

        pCitant.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        pCitant.setLayout(new java.awt.GridLayout(2, 1));

        lTexteCitant.setText("Texte citant : ");
        jPanel5.add(lTexteCitant);

        tTexteCitant.setEditable(false);
        tTexteCitant.setColumns(50);
        jPanel5.add(tTexteCitant);

        bChoixTexteCitant.setText("...");
        bChoixTexteCitant.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bChoixTexteCitantActionPerformed(evt);
            }
        });
        jPanel5.add(bChoixTexteCitant);

        pCitant.add(jPanel5);

        jPanel6.add(lStatutCitant);

        pCitant.add(jPanel6);

        pParams.add(pCitant);

        pCite.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        pCite.setLayout(new java.awt.GridLayout(2, 1));

        lTexteCite.setText("Texte cité : ");
        jPanel7.add(lTexteCite);

        tTexteCite.setEditable(false);
        tTexteCite.setColumns(50);
        jPanel7.add(tTexteCite);

        bChoixTexteCite.setText("...");
        bChoixTexteCite.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bChoixTexteCiteActionPerformed(evt);
            }
        });
        jPanel7.add(bChoixTexteCite);

        pCite.add(jPanel7);

        jPanel8.add(lStatutCite);

        pCite.add(jPanel8);

        pParams.add(pCite);

        pTemoin.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        pTemoin.setLayout(new java.awt.GridLayout(2, 1));

        lTexteCite1.setText("Références témoin : ");
        jPanel16.add(lTexteCite1);

        cbRefs.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Quis Dives cite la Bible", "Philon cite le Pentateuque" }));
        jPanel16.add(cbRefs);

        bChoixRefsTemoin.setText("OK");
        bChoixRefsTemoin.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bChoixRefsTemoinActionPerformed(evt);
            }
        });
        jPanel16.add(bChoixRefsTemoin);

        pTemoin.add(jPanel16);

        jPanel17.add(lStatutRefs);

        pTemoin.add(jPanel17);

        pParams.add(pTemoin);

        pParametres.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        pParametres.setLayout(new javax.swing.BoxLayout(pParametres, javax.swing.BoxLayout.PAGE_AXIS));

        jLabel10.setText("Veuillez maintenant définir des paramètres de recherche de citations pour une expérience :");
        pTitre.add(jLabel10);

        pParametres.add(pTitre);

        pTolerance.setBorder(javax.swing.BorderFactory.createTitledBorder("Tolérance"));
        pTolerance.setLayout(new java.awt.GridLayout(5, 1));

        jLabel2.setText("Ne pas considérer les passages similaires ayant moins de");
        jPanel1.add(jLabel2);

        tTailleInitiale.setColumns(3);
        tTailleInitiale.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
        tTailleInitiale.setText("3");
        jPanel1.add(tTailleInitiale);

        jLabel5.setText("termes identiques");
        jPanel1.add(jLabel5);

        pTolerance.add(jPanel1);

        jLabel11.setText("Chercher les bornes des citations en : ");
        jPanel11.add(jLabel11);

        pTolerance.add(jPanel11);

        groupeTolerance.add(rbStricte);
        rbStricte.setSelected(true);
        rbStricte.setText("Conservant des passages strictement identiques");
        rbStricte.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                rbStricteActionPerformed(evt);
            }
        });
        jPanel2.add(rbStricte);

        pTolerance.add(jPanel2);

        groupeTolerance.add(rbAbsolue);
        rbAbsolue.setText("Acceptant jusqu'à");
        jPanel3.add(rbAbsolue);

        tSeuilAbsolu.setColumns(3);
        tSeuilAbsolu.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(java.text.NumberFormat.getIntegerInstance())));
        tSeuilAbsolu.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
        tSeuilAbsolu.setText("3");
        jPanel3.add(tSeuilAbsolu);

        jLabel3.setText("termes différents entre citant et cité");
        jPanel3.add(jLabel3);

        pTolerance.add(jPanel3);

        groupeTolerance.add(rbRelative);
        rbRelative.setText("Acceptant jusqu'à");
        jPanel4.add(rbRelative);

        tSeuilRelatif.setColumns(3);
        tSeuilRelatif.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(java.text.NumberFormat.getIntegerInstance())));
        tSeuilRelatif.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
        tSeuilRelatif.setText("60");
        jPanel4.add(tSeuilRelatif);

        jLabel4.setText("% de termes différents entre citant et cité");
        jPanel4.add(jLabel4);

        pTolerance.add(jPanel4);

        pParametres.add(pTolerance);

        pTraitement.setBorder(javax.swing.BorderFactory.createTitledBorder("Traitement du texte"));
        pTraitement.setLayout(new java.awt.GridLayout(3, 1));

        cbSansMotsVides.setSelected(true);
        cbSansMotsVides.setText("Supprimer les mots vides avant l'analyse (recommandé)");
        pSansMotsVides.add(cbSansMotsVides);

        pTraitement.add(pSansMotsVides);

        cbImportanceOrdre.setSelected(true);
        cbImportanceOrdre.setText("L'ordre des mots est important dans le texte");
        pImportanceOrdre.add(cbImportanceOrdre);

        pTraitement.add(pImportanceOrdre);

        jLabel1.setText("Utiliser");
        pTraitementLangue.add(jLabel1);

        groupeTraitementLangue.add(rbBrut);
        rbBrut.setText("le texte brut");
        pTraitementLangue.add(rbBrut);

        groupeTraitementLangue.add(rbNorm);
        rbNorm.setText("le texte normalisé");
        pTraitementLangue.add(rbNorm);

        groupeTraitementLangue.add(rbLemm);
        rbLemm.setSelected(true);
        rbLemm.setText("le texte lemmatisé");
        pTraitementLangue.add(rbLemm);

        pTraitement.add(pTraitementLangue);

        pParametres.add(pTraitement);

        pFinition.setBorder(javax.swing.BorderFactory.createTitledBorder("Finitions"));
        pFinition.setLayout(new java.awt.GridLayout(3, 1));

        cbFiltrerNonCitations.setSelected(true);
        cbFiltrerNonCitations.setText("Abandonner les citations qui n'ont en commun que des termes courants dans la langue ou le corpus (recommandé)");
        pFiltrerNonCitations.add(cbFiltrerNonCitations);

        pFinition.add(pFiltrerNonCitations);

        jLabel6.setText("Fusionner les citations successives quand les passages cités et citants sont jusqu'à");
        pFusion.add(jLabel6);

        tSeuilFusion.setColumns(3);
        tSeuilFusion.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(java.text.NumberFormat.getIntegerInstance())));
        tSeuilFusion.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
        tSeuilFusion.setText("5");
        pFusion.add(tSeuilFusion);

        jLabel7.setText("mots de distance");
        pFusion.add(jLabel7);

        pFinition.add(pFusion);

        jLabel8.setText("Abandonner les citations longues de plus de ");
        pTailleMax.add(jLabel8);

        tTailleMax.setColumns(4);
        tTailleMax.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(java.text.NumberFormat.getIntegerInstance())));
        tTailleMax.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
        tTailleMax.setText("100");
        pTailleMax.add(tTailleMax);

        jLabel9.setText("mots");
        pTailleMax.add(jLabel9);

        pFinition.add(pTailleMax);

        pParametres.add(pFinition);

        pAjout.setLayout(new java.awt.GridLayout(2, 1));

        bAjout.setText("Ajouter aux expériences");
        bAjout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bAjoutActionPerformed(evt);
            }
        });
        jPanel9.add(bAjout);

        pAjout.add(jPanel9);

        jPanel10.add(lStatutAjout);

        pAjout.add(jPanel10);

        pParametres.add(pAjout);

        pParams.add(pParametres);

        tpPrincipal.addTab("Recherche", pParams);

        pExperiences.setLayout(new java.awt.BorderLayout());

        jScrollPane2.setViewportView(listeExperiences);

        pExperiences.add(jScrollPane2, java.awt.BorderLayout.CENTER);

        tpPrincipal.addTab("Expériences", pExperiences);

        pResultats.setLayout(new java.awt.BorderLayout());

        jPanel18.setLayout(new java.awt.GridLayout(3, 1));

        jPanel14.add(lStatutMem);

        jPanel18.add(jPanel14);

        bLancer.setText("Lancer les expériences");
        bLancer.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bLancerActionPerformed(evt);
            }
        });
        jPanel12.add(bLancer);

        jPanel18.add(jPanel12);

        jPanel13.add(lStatutXP);

        jPanel18.add(jPanel13);

        pResultats.add(jPanel18, java.awt.BorderLayout.NORTH);

        tResultats.setEditable(false);
        tResultats.setFont(new java.awt.Font("Courier New", 0, 11)); // NOI18N
        jScrollPane1.setViewportView(tResultats);

        pResultats.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        tpPrincipal.addTab("Résultats", pResultats);

        getContentPane().add(tpPrincipal, java.awt.BorderLayout.PAGE_START);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void bChoixTexteCitantActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bChoixTexteCitantActionPerformed
        try {
            final File fCitant = Demandes.demandeFichier("Veillez choisir le texte citant", 
                    new String[]{"xml", "rtf", "txt"}, 
                    new String[]{"Fichier biblique ou patristique xml (.xml)", "Fichier patristique RTF (.rtf)", "Fichier d'export biblique Bibleworks (.txt)"});
            new Thread() {
                @Override
                public void run() {
                    bAjout.setEnabled(false);
                    bChoixTexteCitant.setEnabled(false);
                    bChoixTexteCite.setEnabled(false);
                    bChoixRefsTemoin.setEnabled(false);
                    lStatutCitant.setText("Chargement en cours");
                    try {
                        if(fCitant.getName().endsWith("rtf")) {
                            citant = new PassageType(ImportFichier.importPatristiqueRTF(fCitant), PassageType.PASSAGE_PATRISTIQUE);
                        } else if(fCitant.getName().endsWith("txt")) {
                            citant = new PassageType(ImportFichier.importBibleTexteOuMorphoTXT(fCitant), PassageType.PASSAGE_BIBLIQUE);
                        } else {
                            Passage p = ImportFichier.importUnicodeXML(fCitant);
                            if(p.getSousCoordonneeMinimale().getSysteme().equals(OrdreStrict.getInstance(OrdreStrict.LIVRES_BIB)) || 
                               p.getSousCoordonneeMinimale().getSysteme().equals(OrdreStrict.getInstance(OrdreStrict.LIVRES_LXX)) || 
                               p.getSousCoordonneeMinimale().getSysteme().equals(OrdreStrict.getInstance(OrdreStrict.LIVRES_NTG))) {
                                citant = new PassageType(p, PassageType.PASSAGE_BIBLIQUE);
                            } else if(p.getSousCoordonneeMinimale().getSysteme().equals(OrdreStrict.getInstance(OrdreStrict.LIVRES_PHI))) {
                                citant = new PassageType(p, PassageType.PASSAGE_PHILON);
                            } else {
                                citant = new PassageType(p, PassageType.PASSAGE_PATRISTIQUE);
                            }
                        }
                        tTexteCitant.setText(fCitant.getAbsolutePath());
                        lStatutCitant.setText("Fichier chargé");
                        pCite.setVisible(true);
                        pack();
                    } catch(IOException | BadLocationException | DOMCreationFailureException ex) {
                        lStatutCitant.setText("Erreur : " + ex.getClass() + " - " + ex.getMessage());
                    }
                    bAjout.setEnabled(true);
                    bChoixTexteCitant.setEnabled(true);
                    bChoixTexteCite.setEnabled(true);
                    bChoixRefsTemoin.setEnabled(true);
                }
            }.start();
        } catch (InteractionRefuseeException ex) {
            
        }
    }//GEN-LAST:event_bChoixTexteCitantActionPerformed

    private void bChoixTexteCiteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bChoixTexteCiteActionPerformed
        try {
            final File fCite = Demandes.demandeFichier("Veillez choisir le texte cité", 
                    new String[]{"xml", "txt"}, 
                    new String[]{"Fichier biblique ou patristique xml (.xml)", "Fichier d'export biblique Bibleworks (.txt)"});
             new Thread() {
                @Override
                public void run() {
                    bAjout.setEnabled(false);
                    bChoixTexteCitant.setEnabled(false);
                    bChoixTexteCite.setEnabled(false);
                    bChoixRefsTemoin.setEnabled(false);
                    lStatutCite.setText("Chargement en cours");
                    try {
                        if(fCite.getName().endsWith("txt")) {
                            cite = new PassageType(ImportFichier.importBibleTexteOuMorphoTXT(fCite), PassageType.PASSAGE_BIBLIQUE);
                        } else {
                            cite = new PassageType(ImportFichier.importUnicodeXML(fCite), PassageType.PASSAGE_BIBLIQUE);
                        }
                        tTexteCite.setText(fCite.getAbsolutePath());
                        lStatutCite.setText("Fichier chargé");
                        pTemoin.setVisible(true);
                        pack();
                    } catch(IOException | DOMCreationFailureException ex) {
                        lStatutCite.setText("Erreur : " + ex.getClass() + " - " + ex.getMessage());
                    }
                    bAjout.setEnabled(true);
                    bChoixTexteCitant.setEnabled(true);
                    bChoixTexteCite.setEnabled(true);
                    bChoixRefsTemoin.setEnabled(true);
                }
            }.start();
        } catch (InteractionRefuseeException ex) {
            
        }
    }//GEN-LAST:event_bChoixTexteCiteActionPerformed

    
    private void bAjoutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bAjoutActionPerformed
        // TODO add your handling code here:
        tResultats.setText("");
        bAjout.setEnabled(false);
        bChoixTexteCitant.setEnabled(false);
        bChoixTexteCite.setEnabled(false);
        final RechercheNLexes recherche = new RechercheNLexes(cite, citant, granulariteCite, granulariteCitant);
        new Thread() {
            @Override
            public void run() {
                recherche.setImportanceOrdreMots(
                        cbImportanceOrdre.isSelected()?
                        Recherche.L_ORDRE_DES_MOTS_COMPTE:
                        Recherche.L_ORDRE_DES_MOTS_NE_COMPTE_PAS);
                recherche.setFiltrageMotsVides(
                        cbSansMotsVides.isSelected()?
                        Recherche.TEXTE_SANS_MOTS_VIDES:
                        Recherche.TEXTE_AVEC_MOTS_VIDES);
                recherche.setFiltrageExpressionsVides(
                        cbFiltrerNonCitations.isSelected()?
                        Recherche.FILTRAGE_SANS_LEMMES_NI_EXPRESSIONS_VIDES:
                        Recherche.FILTRAGE_AVEC_LEMMES_ET_EXPRESSIONS_VIDES);
                recherche.setTraitementTermes(
                        rbBrut.isSelected()?
                        Recherche.TERMES_BRUTS:
                        (rbNorm.isSelected()?
                        Recherche.TERMES_NORMALISES:
                        Recherche.TERMES_LEMMATISES));
                recherche.setToleranceCorrespondance(
                        rbStricte.isSelected()?
                        Recherche.CORRESPONDANCE_STRICTE:
                        (rbAbsolue.isSelected()?
                        Recherche.CORRESPONDANCE_SEUILLEE_EN_VALEUR:
                        Recherche.CORRESPONDANCE_SEUILLEE_EN_POURCENTAGE)
                        , 
                        rbStricte.isSelected()?
                        0:
                        (rbAbsolue.isSelected()?
                        Integer.parseInt(tSeuilAbsolu.getText()):
                        Integer.parseInt(tSeuilRelatif.getText())));
                recherche.setSeuilFusion(Integer.parseInt(tSeuilFusion.getText()));
                recherche.setNbMotsMaxParCitation(Integer.parseInt(tTailleMax.getText()));
                recherche.setTailleFenetre(Integer.parseInt(tTailleInitiale.getText()));
                recherches.add(recherche);
                RechercheNLexes[] rec = new RechercheNLexes[recherches.size()];
                recherches.toArray(rec);
                listeExperiences.setListData(rec);
            }
        }.start();
        bAjout.setEnabled(true);
    }//GEN-LAST:event_bAjoutActionPerformed

    private void rbStricteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rbStricteActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_rbStricteActionPerformed

    private void bChoixRefsTemoinActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bChoixRefsTemoinActionPerformed
        final File fRefs;
        final int citeur;
        if(cbRefs.getSelectedItem().equals("Quis Dives cite la Bible")) {
            fRefs = new File("CitationsQuisDives.txt");
            citeur = PassageType.PASSAGE_PATRISTIQUE;
            granulariteCitant = OrdreStrict.getInstance(OrdreStrict.MOTS);
            granulariteCite = OrdreStrict.getInstance(OrdreStrict.VERSETS);
        } else {
            fRefs = new File("CitationsPhilon.txt");
            citeur = PassageType.PASSAGE_PHILON;
            granulariteCitant = OrdreStrict.getInstance(OrdreStrict.PARAGRAPHES);
            granulariteCite = OrdreStrict.getInstance(OrdreStrict.VERSETS);
        }
        new Thread() {
            @Override
            public void run() {
                bAjout.setEnabled(false);
                bChoixTexteCitant.setEnabled(false);
                bChoixTexteCite.setEnabled(false);
                bChoixRefsTemoin.setEnabled(false);
                lStatutRefs.setText("Chargement en cours");
                try {
                    ReferencesDeCitation[] refs = ImportFichier.importCitationsTSV(fRefs, true, PassageType.PASSAGE_BIBLIQUE, citeur);
                    
                    ArrayList<Citation> cits = new ArrayList<>();
                    for (int i=0; i<refs.length; i++) {
                        ReferencesDeCitation ref = refs[i];
                        Passage txtCite = cite.getPassage().rassemblePassage(ref.getCite());
                        Passage txtCiteur = citant.getPassage().rassemblePassage(ref.getCiteur());
                        cits.add(new Citation(txtCite, txtCiteur));
                    }
                    temoin = new Citation[cits.size()];
                    cits.toArray(temoin);
                    lStatutRefs.setText("Fichier chargé");
                    pParametres.setVisible(true);
                    pack();
                } catch(IOException ex) {
                    lStatutRefs.setText("Erreur : " + ex.getClass() + " - " + ex.getMessage());
                }
                bAjout.setEnabled(true);
                bChoixTexteCitant.setEnabled(true);
                bChoixTexteCite.setEnabled(true);
                bChoixRefsTemoin.setEnabled(true);
            }
        }.start();
    }//GEN-LAST:event_bChoixRefsTemoinActionPerformed

    private void bLancerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bLancerActionPerformed
        new Thread() {
            
            @Override
            public void run() {
                for(RechercheNLexes recherche: recherches) {
                    debut = System.currentTimeMillis();
                    rechercheCourante = recherche;
                    timerRecherche.start();
                    try {
                        tResultats.setText(tResultats.getText()+recherche.toString() + "\n");
                        Citation[] resultat = recherche.chercheCitations();
                        timerRecherche.stop();
                        long tps = System.currentTimeMillis() - debut;
                        tResultats.setText(tResultats.getText()+recherche.getLogExecution() + 
                                "\n"+"La recherche a pris " + Temps.getTexte(tps) + " et a trouvé "+resultat.length+" références.\n");
                        System.gc();
                        lStatutXP.setText("Analyse des résultats en cours (1/8)");
                        int preIA = ((int)(100000.0*ComparateurCitations.getPrecision(resultat, temoin, 
                                ComparateurCitations.IDENTIQUE_SI_CHEVAUCHEMENT, ComparateurCitations.METRIQUES_BRUTES))/1000);
                        lStatutXP.setText("Analyse des résultats en cours (2/8)");
                        int nbPreIA = ComparateurCitations.getBonnesReponses(resultat, temoin, 
                                ComparateurCitations.IDENTIQUE_SI_CHEVAUCHEMENT, ComparateurCitations.METRIQUES_BRUTES);
                        tResultats.setText(tResultats.getText()+"Précision brute :  " + preIA + "% (" + nbPreIA + "/" + resultat.length + ")" + "\n");
                        lStatutXP.setText("Analyse des résultats en cours (3/8)");
                        int rapIA = ((int)(100000.0*ComparateurCitations.getRappel(resultat, temoin, 
                                ComparateurCitations.IDENTIQUE_SI_CHEVAUCHEMENT, ComparateurCitations.METRIQUES_BRUTES))/1000);
                        lStatutXP.setText("Analyse des résultats en cours (4/8)");
                        int nbRapIA = ComparateurCitations.getBienTrouvees(resultat, temoin, 
                                ComparateurCitations.IDENTIQUE_SI_CHEVAUCHEMENT, ComparateurCitations.METRIQUES_BRUTES);
                        tResultats.setText(tResultats.getText()+"Rappel brut :  " + rapIA + "% (" + nbRapIA + "/" + temoin.length + ")" + "\n");
                        lStatutXP.setText("Analyse des résultats en cours (5/8)");
                        preIA = ((int)(100000.0*ComparateurCitations.getPrecision(resultat, temoin, 
                                ComparateurCitations.IDENTIQUE_SI_CHEVAUCHEMENT, ComparateurCitations.METRIQUES_EPUREES))/1000);
                        lStatutXP.setText("Analyse des résultats en cours (6/8)");
                        nbPreIA = ComparateurCitations.getBonnesReponses(resultat, temoin, 
                                ComparateurCitations.IDENTIQUE_SI_CHEVAUCHEMENT, ComparateurCitations.METRIQUES_EPUREES);
                        tResultats.setText(tResultats.getText()+"Précision raffinée :  " + preIA + "% (" + nbPreIA + "/" + resultat.length + ")" + "\n");
                        lStatutXP.setText("Analyse des résultats en cours (7/8)");
                        rapIA = ((int)(100000.0*ComparateurCitations.getRappel(resultat, temoin, 
                                ComparateurCitations.IDENTIQUE_SI_CHEVAUCHEMENT, ComparateurCitations.METRIQUES_EPUREES))/1000);
                        lStatutXP.setText("Analyse des résultats en cours (8/8)");
                        nbRapIA = ComparateurCitations.getBienTrouvees(resultat, temoin, 
                                ComparateurCitations.IDENTIQUE_SI_CHEVAUCHEMENT, ComparateurCitations.METRIQUES_EPUREES);
                        tResultats.setText(tResultats.getText()+"Rappel raffiné :  " + rapIA + "% (" + nbRapIA + "/" + temoin.length + ")" + "\n\n");
                        lStatutXP.setText("Recherche terminée.");
                    } catch(Exception ex) {
                        lStatutXP.setText(ex.getClass() + " - " + ex.getMessage());
                        break;
                    }
                }
            }
            
        }.start();
        
    }//GEN-LAST:event_bLancerActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton bAjout;
    private javax.swing.JButton bChoixRefsTemoin;
    private javax.swing.JButton bChoixTexteCitant;
    private javax.swing.JButton bChoixTexteCite;
    private javax.swing.JButton bLancer;
    private javax.swing.JCheckBox cbFiltrerNonCitations;
    private javax.swing.JCheckBox cbImportanceOrdre;
    private javax.swing.JComboBox cbRefs;
    private javax.swing.JCheckBox cbSansMotsVides;
    private javax.swing.ButtonGroup groupeTolerance;
    private javax.swing.ButtonGroup groupeTraitementLangue;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel10;
    private javax.swing.JPanel jPanel11;
    private javax.swing.JPanel jPanel12;
    private javax.swing.JPanel jPanel13;
    private javax.swing.JPanel jPanel14;
    private javax.swing.JPanel jPanel16;
    private javax.swing.JPanel jPanel17;
    private javax.swing.JPanel jPanel18;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JPanel jPanel8;
    private javax.swing.JPanel jPanel9;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JLabel lStatutAjout;
    private javax.swing.JLabel lStatutCitant;
    private javax.swing.JLabel lStatutCite;
    private javax.swing.JLabel lStatutMem;
    private javax.swing.JLabel lStatutRefs;
    private javax.swing.JLabel lStatutXP;
    private javax.swing.JLabel lTexteCitant;
    private javax.swing.JLabel lTexteCite;
    private javax.swing.JLabel lTexteCite1;
    private javax.swing.JList listeExperiences;
    private javax.swing.JPanel pAjout;
    private javax.swing.JPanel pCitant;
    private javax.swing.JPanel pCite;
    private javax.swing.JPanel pExperiences;
    private javax.swing.JPanel pFiltrerNonCitations;
    private javax.swing.JPanel pFinition;
    private javax.swing.JPanel pFusion;
    private javax.swing.JPanel pImportanceOrdre;
    private javax.swing.JPanel pParametres;
    private javax.swing.JPanel pParams;
    private javax.swing.JPanel pResultats;
    private javax.swing.JPanel pSansMotsVides;
    private javax.swing.JPanel pTailleMax;
    private javax.swing.JPanel pTemoin;
    private javax.swing.JPanel pTitre;
    private javax.swing.JPanel pTolerance;
    private javax.swing.JPanel pTraitement;
    private javax.swing.JPanel pTraitementLangue;
    private javax.swing.JRadioButton rbAbsolue;
    private javax.swing.JRadioButton rbBrut;
    private javax.swing.JRadioButton rbLemm;
    private javax.swing.JRadioButton rbNorm;
    private javax.swing.JRadioButton rbRelative;
    private javax.swing.JRadioButton rbStricte;
    private javax.swing.JEditorPane tResultats;
    private javax.swing.JFormattedTextField tSeuilAbsolu;
    private javax.swing.JFormattedTextField tSeuilFusion;
    private javax.swing.JFormattedTextField tSeuilRelatif;
    private javax.swing.JFormattedTextField tTailleInitiale;
    private javax.swing.JFormattedTextField tTailleMax;
    private javax.swing.JTextField tTexteCitant;
    private javax.swing.JTextField tTexteCite;
    private javax.swing.JTabbedPane tpPrincipal;
    // End of variables declaration//GEN-END:variables
}
