/*
 * NAT - An universal Translator
 * Copyright (C) 2005 Bruno Mascret
 * Contact: bmascret@free.fr
 * 
 * This program 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 2
 * of the License.
 * 
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package ui;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.UIManager;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.ArrayList;
import javax.swing.ImageIcon;

import outils.Embosseur;
import outils.EmbosseurInstalle;
import outils.EmbosseurLDC;
import outils.FileToolKit;
import ui.ConfigurationsComboBoxRenderer;

//*** Gestionnaires ***
import gestionnaires.GestionnaireOuvrir;
import gestionnaires.GestionnaireErreur;
import gestionnaires.GestionnaireOuvrirFenetre;
import nat.ConfigNat;
import nat.Nat;
import nat.NatThread;

/**
 * Fenêtre principale de l'interface graphique
 * @author bruno
 *
 */
public class FenetrePrinc extends JFrame implements ActionListener, FocusListener, WindowListener, ComponentListener
{
    /** numéro de version pour la sérialisation (inutilisé par NAT) */
    private static final long serialVersionUID = 1L;
    /** JTextField pour l'adresse du fichier noir */
    private JTextField  jtfNoir = new JTextField("./licence.txt",30);
    /** Label associé à jtfNoir
     * @see FenetrePrinc#jtfNoir
     * */
    private JLabel lJtfNoir = new JLabel("Document en noir");
    /** Bouton ouvrant le JFileChooser pour l'adresse du fichier noir 
     * @see FenetrePrinc#jtfNoir
     * @see GestionnaireOuvrir
     * */
    private JButton btSelectNoir = new JButton("Sélectionner le fichier en noir",new ImageIcon("ui/icon/document-open.png"));
    /** JTextField pour l'adresse du fichier braille */
    private JTextField  jtfBraille = new JTextField("",30);
    /** Label associé à {@link #jtfBraille}
    * @see FenetrePrinc#jtfBraille
    * */
    private JLabel lJtfBraille = new JLabel("Document braille");
    /**
     * Label contenant l'icône correspondant la la transcription ou à la détranscription
     */
    private JLabel lIcone = new JLabel(new ImageIcon("ui/nat.png"));
    /** Bouton ouvrant le JFileChooser pour l'adresse du fichier braille 
     * @see FenetrePrinc#jtfBraille
     * @see GestionnaireOuvrir
     * */
    private JButton btSelectBraille = new JButton("Sélectionner le fichier en braille",new ImageIcon("ui/icon/document-open.png"));
    /** Bouton lançant la transcription 
     * @see Nat#fabriqueTranscriptions
     * @see Nat#lanceScenario()
     * */
    private JButton btTranscrire = new JButton("Transcrire",new ImageIcon("ui/icon/system-run.png"));
    /** Bouton ouvrant l'éditeur de fichier transcrit
     * @see FenetrePrinc#afficheFichier(String adresse)
     */
    private JButton btEditeur = new JButton("Ouvrir le fichier transcrit",new ImageIcon("ui/icon/gtk-edit.png"));
    /** Bouton ouvrant l'éditeur de fichier pré-transcrit
     * @see FenetrePrinc#afficheFichierMep(String adresse)
     * @since 2.0
     */
    private JButton btEditeurMep = new JButton("Ouvrir un fichier à mettre en page",new ImageIcon("ui/icon/document-page-setup.png"));
    /** Bouton ouvrant l'éditeur avec un fichier déjà transcrit
     * @see FenetrePrinc#afficheFichier(String adresse)
     * @since 2.0
     */
    private JButton btEditeurTrans = new JButton("Ouvrir un fichier déjà transcrit",new ImageIcon("ui/icon/gtk-edit.png"));
    /**
     * filte xsl à utiliser pour la transcription
     * @deprecated 2.0
     */
    @Deprecated
	private JTextField  filtre = new JTextField("xsl.xsl",20);
    /**
     * pour activer le mode débugage
     * <p>Pas encore actif!</p>
     */
    private JCheckBox debug = new JCheckBox();
    /**
     * Afficheur graphique de logs
     * @since 2.0
     */
    private AfficheurJTASwing panneauLog;// = new JTextArea (15,40);

    /**
     * Label associé à jcbConfig
     * @see FenetrePrinc#jcbConfig
     */
    private JLabel lConfig = new JLabel("Configuration active:");
    /** JComboBox listant les configurations possibles  */
    private JComboBox jcbConfig = new JComboBox();
    /**
     * Bouton ouvrant la fenetre d'options
     * @see GestionnaireOuvrirFenetre
     */
    private JButton btOption = new JButton("Options",new ImageIcon("ui/icon/document-properties.png"));
    /**
     * Bouton ouvrant la fenetre d'aide
     * @see GestionnaireOuvrirFenetre
     */
    private JButton btAide = new JButton("Aide",new ImageIcon("ui/icon/help-browser.png"));
    /**
     * Bouton ouvrant la fenetre de renseignements sur Nat
     * @see GestionnaireOuvrirFenetre
     */
    private JButton btAPropos = new JButton("A propos...",new ImageIcon("ui/icon/help-about.png"));
    /** Bouton permettant de quitter le programme */
    private JButton btQuitter = new JButton("Quitter",new ImageIcon("ui/icon/exit.png"));
    /** Bouton activant l'interface de rapport d'erreur*/
    private JButton btSignalBug = new JButton("Rapporter une erreur",new ImageIcon("ui/icon/script-error.png"));
    /** Bouton activant le sens de transcription de noir vers braille */
    private JButton btSens = new JButton(new ImageIcon("ui/icon/go-down.png"));    
    
    /** JMenu contenant les actions possibles sur la fenêtre principale  */
    private JMenu jmAction = new JMenu("Menu");
    /** JMenu contenant les raccourcis vers les actions d'information de la fenêtre principale  */
    private JMenu jmAPropos = new JMenu("Aide");
    /** JMenuBar de la fenêtre principale */
    private JMenuBar jmb = new JMenuBar();
    /**
     * Elément de menu Choisir fichier noir
     * @see FenetrePrinc#jmAction
     * @see GestionnaireOuvrir
     */
    private JMenuItem jmiSelectNoir;
    /**
     * Elément de menu Choisir fichier braille
     * @see FenetrePrinc#jmAction
     * @see GestionnaireOuvrir
     */
    private JMenuItem jmiSelectBraille;
    /**
     * Elément de menu Ouvrir options
     * @see FenetrePrinc#jmAction
     * @see GestionnaireOuvrirFenetre
     */
    private JMenuItem jmiOptions;
    /**
     * Elément de menu sens de transcription
     * @see FenetrePrinc#jmAction
     */
    private JMenuItem jmiSensTr;
    /**
     * Elément de menu Transcrire
     * @see Nat#fabriqueTranscriptions
     * @see Nat#lanceScenario()
     */
    private JMenuItem jmiTranscrire;
    /**
     * Elément de menu Ouvrir l'éditeur
     * @see FenetrePrinc#jmAction
     * @see GestionnaireOuvrirFenetre
     */
    private JMenuItem jmiOuvrirTrans;
    /**
     * Elément de menu Quitter
     * @see FenetrePrinc#jmAction
     */
    private JMenuItem jmiQuitter;
    /**
     * Elément de menu Aide
     * @see FenetrePrinc#jmAPropos
     */
    private JMenuItem jmiAide;
    /**
     * Elément de menu A propos de NAT
     * @see FenetrePrinc#jmAPropos
     */
    private JMenuItem jmiAPropos;
    /**
     * Elément de menu Ouvrir fichier à mettre en page
     * @see FenetrePrinc#jmAction
     * @see GestionnaireOuvrir
     */
    //private JMenuItem jmiOuvrirMEP;
    /**
     * Elément de menu Ouvrir fichier déjà transcrit
     * @see FenetrePrinc#jmAction
     * @see GestionnaireOuvrir
     */
	private JMenuItem jmiOuvrirDejaTrans;
	/**
	 * Elément de menu Signaler un Bug
	 * @see FenetrePrinc#jmAction
	 */
	private JMenuItem jmiSignalBug;
	/**
	 * Elément de menu détranscription
	 * @see FenetrePrinc#jmiTan
	 */
	private JMenuItem jmiTan;
    
    //private JProgressBar jpb = new JProgressBar();
    /**
     * Indique si le Thread du scénario de transcription est lancé
     */
    private boolean running = false;
   
    /** Le gestionnaire d'erreur de NAT utilisé */
    private GestionnaireErreur gestErreur;
    /** L'instance de Nat */
    private Nat nat;
    /**
     * Vrai si la fenêtre option est ouverte
     * @see GestionnaireOuvrirFenetre
     * @see Configuration
     */
    private boolean optionsOuvertes = false;
	
    /**
     * Constructeur de FenetrePrinc
     * @param n une instance de Nat
     */
    public FenetrePrinc(Nat n)
    {
    	/* initialisation de propriétés générales aux interfaces graphiques*/
		UIManager.put("FileChooser.lookInLabelMnemonic", new Integer(KeyEvent.VK_R));
	    setIconImage(new ImageIcon("ui/nat.png").getImage());
	    addComponentListener(this);
	    nat = n;
	    panneauLog = new AfficheurJTASwing(15, 40);
	    panneauLog.setEditable(false);
	    panneauLog.setLineWrap(true);
	    gestErreur = n.getGestionnaireErreur();
	    gestErreur.addAfficheur(panneauLog);
	    /*gestErreur.addAfficheur(new AfficheurConsole());
	    gestErreur.addAfficheur(new AfficheurLog());
	    gestErreur.setModeDebugage(debug.isSelected());*/
	    fabriqueFenetre();

    	//pour optimisation
	    if(ConfigNat.getCurrentConfig().getOptimize())
	    {
	    	gestErreur.afficheMessage("Optimisation: chargement des composants en mémoire...", Nat.LOG_SILENCIEUX);
	    	new NatThread(nat).start();
	    }
	    //vérif si update disponible
	    if(ConfigNat.getCurrentConfig().getUpdateCheck())
	    {
	    	if(nat.checkUpdate())
	    	{
				 if (nat.isUpdateAvailable())
				 {
					 panneauLog.setText("**************************************************\n" +
							 			"*      Une nouvelle version est disponible       \n" +
							 			"*              sur le site de NAT                \n" +
					 					"**************************************************\n");
				 }
				 else
				 {
					 gestErreur.afficheMessage("Vous disposez de la dernière version de NAT", Nat.LOG_VERBEUX);
				 }
            }
	    }
    }

    /** @return FenetrePrinc#entreeXML}*/
    public JTextField getEntree(){return jtfNoir;}
    /** @return FenetrePrinc#filtre}
     * @deprecated 2.0
     * */
    @Deprecated
	public JTextField getFiltre(){return filtre;}
    /** @return FenetrePrinc#sortie}*/
    public JTextField getSortie(){return jtfBraille;}
    /** 
     * Change la valeur du texte de {@link FenetrePrinc#jtfNoir}
     * @param entree la nouvelle entrée
     */
    public void setEntree(String entree)
    {
    	jtfNoir.setText(entree);
    	if(ConfigNat.getCurrentConfig().getSortieAuto() && !ConfigNat.getCurrentConfig().isReverseTrans())
    	{
    		setSortieAuto(false);
    	}
    }
    /** 
     * Change la valeur du texte de {@link FenetrePrinc#filtre}
     * @param f le nouveau filtre
     * @deprecated 2.0
     */
    @Deprecated
	public void setFiltre(String f){filtre.setText(f);}
    /** 
     * Change la valeur du texte de {@link FenetrePrinc#jtfBraille}
     * et active le bouton {@link FenetrePrinc#btEditeur} si l'adresse donnée est valide
     * @param tgt la nouvelle sortie
     */
    public void setSortie(String tgt)
    {
    	jtfBraille.setText(tgt);
    	verifieBtEditeur();
    	if(ConfigNat.getCurrentConfig().getSortieAuto() && ConfigNat.getCurrentConfig().isReverseTrans())
    	{
    		setSortieAuto(true);
    	}
    }
    /** @return {@link FenetrePrinc#optionsOuvertes}*/
    public boolean getOptionsOuvertes(){return optionsOuvertes;}
    /** @param oo la valeur de {@link FenetrePrinc#optionsOuvertes}*/
    public void setOptionsOuvertes(boolean oo){optionsOuvertes=oo;}
	
    /** Fabrique la fenêtre {@link FenetrePrinc} */
    private void fabriqueFenetre()
    {
	    // titre de la fenêtre 
	    this.setTitle("NAT " + nat.getVersionLong());
	    
	    jmiSelectNoir= new JMenuItem("Sélectionner le fichier noir");
	    jmiSelectNoir.setMnemonic('e');
	    jmiSelectNoir.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
	    jmiSelectNoir.addActionListener(new GestionnaireOuvrir(this,GestionnaireOuvrir.OUVRIR_SOURCE));
	    jmAction.add(jmiSelectNoir);
		
	    jmiSelectBraille= new JMenuItem("Sélectionner le fichier braille");
	    jmiSelectBraille.setMnemonic('s');
	    jmiSelectBraille.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
	    jmiSelectBraille.addActionListener(new GestionnaireOuvrir(this,GestionnaireOuvrir.OUVRIR_SORTIE));
	    jmAction.add(jmiSelectBraille);
		
	    jmAction.addSeparator();
		
	    jmiOptions= new JMenuItem("Options");
	    jmiOptions.setMnemonic('o');
	    jmiOptions.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
	    jmiOptions.addActionListener(new GestionnaireOuvrirFenetre(GestionnaireOuvrirFenetre.OUVRIR_OPTIONS,this));
	    jmAction.add(jmiOptions);
		
	    jmiSensTr = new JMenuItem("Inverser le sens");
	    jmiSensTr.setMnemonic('i');
	    jmiSensTr.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
	    jmiSensTr.addActionListener(this);
	    jmAction.add(jmiSensTr);
	    
	    jmiTranscrire = new JMenuItem("Transcrire");
	    jmiTranscrire.setMnemonic('t');
	    jmiTranscrire.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
	    jmiTranscrire.addActionListener(this);
	    jmAction.add(jmiTranscrire);
		
	    jmAction.addSeparator();
		
	    jmiOuvrirTrans = new JMenuItem("Ouvrir la transcription");
	    jmiOuvrirTrans.setMnemonic('l');
	    jmiOuvrirTrans.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
	    jmiOuvrirTrans.addActionListener(this);
	    jmAction.add(jmiOuvrirTrans);
	    
	    jmiTan = new JMenuItem("Ouvrir l'éditeur de détranscription");
	    jmiTan.setMnemonic('n');
	    jmiTan.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
	    jmiTan.addActionListener(this);
	    jmAction.add(jmiTan);
		
		//jmiOuvrirMEP = new JMenuItem("Ouvrir un fichier à mettre en page");
		//jmiOuvrirMEP.setMnemonic('m');
		//jmiOuvrirMEP.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
		//jmiOuvrirMEP.addActionListener(new GestionnaireOuvrir(this,GestionnaireOuvrir.OUVRIR_MEP));
		//jmAction.add(jmiOuvrirMEP);
		
		jmiOuvrirDejaTrans = new JMenuItem("Ouvrir un fichier déjà transcrit");
		jmiOuvrirDejaTrans.setMnemonic('d');
		jmiOuvrirDejaTrans.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
		jmiOuvrirDejaTrans.addActionListener(new GestionnaireOuvrir(this,GestionnaireOuvrir.OUVRIR_TRANS));
		jmAction.add(jmiOuvrirDejaTrans);
		
		jmiSignalBug = new JMenuItem("Rapporter une erreur");
		jmiSignalBug.setMnemonic('p');
		jmiSignalBug.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
		jmiSignalBug.addActionListener(this);
		jmAction.add(jmiSignalBug);
			
		jmAction.addSeparator();
		
	    jmiQuitter = new JMenuItem("Quitter");
	    jmiQuitter.setMnemonic('q');
	    jmiQuitter.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
	    jmiQuitter.addActionListener(this);
	    jmAction.add(jmiQuitter);
		
	    jmiAide = new JMenuItem("Aide");
	    jmiAide.setMnemonic(KeyEvent.VK_F6);
	    jmiAide.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F6, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
	    jmiAide.addActionListener(new GestionnaireOuvrirFenetre(GestionnaireOuvrirFenetre.OUVRIR_AIDE,this));
	    jmAPropos.add(jmiAide);
		
	    jmAPropos.addSeparator();
		
	    jmiAPropos = new JMenuItem("A propos");
	    jmiAPropos.setMnemonic(java.awt.event.KeyEvent.VK_F11);
	    jmiAPropos.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F11, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
	    jmiAPropos.addActionListener(new GestionnaireOuvrirFenetre(GestionnaireOuvrirFenetre.OUVRIR_APROPOS,this));
	    jmAPropos.add(jmiAPropos);
		
	    jmAction.setMnemonic('m');
	    jmAPropos.setMnemonic('a');
		
	    jmb.add(jmAction);
	    jmb.add(jmAPropos);
		
	    setName("NAT: fenêtre principale");
	    getAccessibleContext().setAccessibleName("NAT: fenêtre principale");
	    getAccessibleContext().setAccessibleDescription("Fenêtre d'exécution des transcriptions");
			
	    // fichier d'entrée : label, champ, bouton
	    lJtfNoir.setLabelFor(jtfNoir);
	    if(ConfigNat.getCurrentConfig().getFichNoir().length()>0)
	    {
		    jtfNoir.setText(ConfigNat.getCurrentConfig().getFichNoir());
	    }
	    lJtfNoir.setDisplayedMnemonic('u');
	    jtfNoir.setName("Fichier en noir");
	    jtfNoir.getAccessibleContext().setAccessibleName("Champ de saisie du fichier en noir");
	    jtfNoir.setToolTipText("Emplacement du fichier en noir (Alt+u)");
	    //entreeXML.getAccessibleContext().setAccessibleDescription(entreeXML.getToolTipText());
	    jtfNoir.addFocusListener(this);
	    btSelectNoir.addActionListener(new GestionnaireOuvrir(this,GestionnaireOuvrir.OUVRIR_SOURCE));
	    btSelectNoir.setMnemonic('e');
	    btSelectNoir.setToolTipText("Pour choisir le fichier en noir dans l'arborescence de votre système de fichiers (alt+e) ou (ctrl+e)");
			
	    // fichier de sortie : label, champ, bouton
	    lJtfBraille.setLabelFor(jtfBraille);
	    lJtfBraille.setDisplayedMnemonic('r');
	    if(ConfigNat.getCurrentConfig().getFBraille().length()>0)
	    {
		    jtfBraille.setText(ConfigNat.getCurrentConfig().getFBraille());
	    }
	    jtfBraille.setName("Fichier braille");
	    jtfBraille.getAccessibleContext().setAccessibleName("Champ de saisie du fichier braille");
	    //sortie.getAccessibleContext().setAccessibleDescription("Entrer l'adresse du fichier transcrit");
	    jtfBraille.setToolTipText("Entrer l'adresse de sauvegarde pour le fichier braille (Alt+r)");
	    jtfBraille.addFocusListener(this);
	    btSelectBraille.addActionListener(new GestionnaireOuvrir(this,GestionnaireOuvrir.OUVRIR_SORTIE));
	    btSelectBraille.setMnemonic('s');
	    btSelectBraille.setToolTipText("Pour choisir le fichier braille dans l'arborescence de votre système de fichiers (Alt+s) ou (Ctrl+s)");
	
	    btSens.addActionListener(this);
	    btSens.getAccessibleContext().setAccessibleName("inversion du sens de transcription");
	    btSens.setMnemonic('i');
	    setReverseTrans(ConfigNat.getCurrentConfig().isReverseTrans());
	
	    // bouton pour lancer la transcription
	    btTranscrire.addActionListener(this);
	    btTranscrire.setMnemonic('t');
	    //transcrire.getAccessibleContext().setAccessibleName("Transcrire");
	    //transcrire.getAccessibleContext().setAccessibleDescription("Pour lancer la transcription");
	    btTranscrire.setToolTipText("Pour lancer la transcription (Alt+t) ou (Ctrl+t)");
		
	    /*
	      jpb.getAccessibleContext().setAccessibleName("Barre de progression de la transcription");
	      jpb.getAccessibleContext().setAccessibleDescription("Barre de progression indiquant l'état d'avancement de la transcription");
	    */
	    /* c'est quoi ça? 
	     * Bruno: c'est pour cacher / montrer la fenetre de log. C'est pas implémenté: je commente
	 * ********** 
	    voir_log.addActionListener(this);
	    voir_log.setMnemonic('a');
	    voir_log.getAccessibleContext().setAccessibleName("Bouton transcrire2");
	    voir_log.getAccessibleContext().setAccessibleDescription("Valider pou2r lancer la transcription");
	    voir_log.setToolTipText("Lancer la transcri2ption");
	    /* ***********/
	    btEditeur.addActionListener(this);
	    btEditeur.setMnemonic('l');
	    //btEditeur.getAccessibleContext().setAccessibleName("Ouvrir le fichier transcrit");
	    //btEditeur.getAccessibleContext().setAccessibleDescription("Pour ouvrir le fichier transcrit avec l'application choisie");
	    btEditeur.setToolTipText("Ouvrir le fichier transcrit avec l'application choisie (Alt+l) ou (Ctrl+l)");
	    verifieBtEditeur();
		
		btEditeurMep.addActionListener(new GestionnaireOuvrir(this,GestionnaireOuvrir.OUVRIR_MEP));
		//btEditeurMep.setMnemonic('m');
		//btEditeurMep.getAccessibleContext().setAccessibleName("Ouvrir un fichier à mettre en page");
		//btEditeurMep.getAccessibleContext().setAccessibleDescription("Pour ouvrir un fichier à mettre en page");
		btEditeurMep.setToolTipText("Pour ouvrir un fichier à mettre en page (Alt+m) ou (Ctrl+m)");
		btEditeurMep.setEnabled(false);
		
		
		btEditeurTrans.addActionListener(new GestionnaireOuvrir(this,GestionnaireOuvrir.OUVRIR_TRANS));
		btEditeurTrans.setMnemonic('d');
		//btEditeurTrans.getAccessibleContext().setAccessibleName("Ouvrir un fichier déjà transcrit");
		//btEditeurTrans.getAccessibleContext().setAccessibleDescription("Pour ouvrir un fichier déjà transcrit");
		btEditeurTrans.setToolTipText("Pour ouvrir un fichier déjà transcrit (Alt+d) ou (Ctrl+d)");
		verifieBtEditeur();
		
		// panneau de log
		debug.setText("Debugage actif");
	
	    JScrollPane scrollLog = new JScrollPane (panneauLog);
	    scrollLog.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
	    scrollLog.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
	    scrollLog.getAccessibleContext().setAccessibleName("Panneau d'affichage des messages de la transcription");
	    scrollLog.getAccessibleContext().setAccessibleDescription("Ici sont affichées les messages de la transcription");
	    scrollLog.setToolTipText("Affichage des messages de la transcription");
	
	    // bouton pour la fenêtre d'options
	    btOption.addActionListener(new GestionnaireOuvrirFenetre(GestionnaireOuvrirFenetre.OUVRIR_OPTIONS,this));
	    btOption.setMnemonic('o');
	    //btOption.getAccessibleContext().setAccessibleName("Options");
	    //btOption.getAccessibleContext().setAccessibleDescription("Pour ouvrir la fenêtre de paramétrage");
	    btOption.setToolTipText("Ouvrir la fenêtre de paramétrage (Alt+o) ou (Ctrl+o)");
	
	    // bouton pour la fenêtre d'aide
	    btAide.addActionListener(new GestionnaireOuvrirFenetre(GestionnaireOuvrirFenetre.OUVRIR_AIDE,this));
	    btAide.setMnemonic(java.awt.event.KeyEvent.VK_F6);
	    //btAide.getAccessibleContext().setAccessibleName("Aide");
	    //btAide.getAccessibleContext().setAccessibleDescription("Pour ouvrir la fenêtre d'aide de NAT");
	    btAide.setToolTipText("Ouvrir la fenêtre d'aide (Alt+F6) ou (Ctrl+F6)");
	
	    // bouton pour la fenêtre a propos
	    btAPropos.addActionListener(new GestionnaireOuvrirFenetre(GestionnaireOuvrirFenetre.OUVRIR_APROPOS,this));
	    btAPropos.setMnemonic(java.awt.event.KeyEvent.VK_F11);
	    //btAPropos.getAccessibleContext().setAccessibleName("Bouton à propos de NAT");
	    //btAPropos.getAccessibleContext().setAccessibleDescription("Valider pour ouvrir la fenêtre d'information sur le développement de NAT");
	    btAPropos.setToolTipText("Ouvrir la fenêtre d'information sur NAT (Alt+F11) ou (Ctrl+F11)");
	    
	    // bouton pour la fenêtre de rapport de bug
	    btSignalBug.addActionListener(this);
	    btSignalBug.setMnemonic('p');
	    //btSignalBug.getAccessibleContext().setAccessibleName("Bouton rapporter une erreur");
	    //btSignalBug.getAccessibleContext().setAccessibleDescription("Valider pour ouvrir la fenêtre de rapport d'erreur");
	    btSignalBug.setToolTipText("Ouvrir la fenêtre de rapport d'erreur (Alt+p) ou (Ctrl+p)");
	
	    // bouton pour quitter
	    btQuitter.addActionListener(this);
	    btQuitter.setMnemonic('q');
	    //btQuitter.getAccessibleContext().setAccessibleName("Quitter NAT");
	    //btQuitter.getAccessibleContext().setAccessibleDescription("Pour quitter NAT");
	    btQuitter.setToolTipText("Quitter NAT (Alt+q) ou (Ctrl+q) ou (Alt+F4)");
			
	    // label de config
	    lConfig.setLabelFor(jcbConfig);
	    lConfig.setDisplayedMnemonic('c');
	    chargeConfigurations();//jcbConfig);
	    //		jcbConfig.addActionListener(this);
	
	    // combo de choix de la config
	    jcbConfig.setEditable(false);
	    jcbConfig.getAccessibleContext().setAccessibleName("Configuration choisie");
	    //jcbConfig.getAccessibleContext().setAccessibleDescription("Sélectionner à l'aide des flèches la configuration à utiliser");
	    jcbConfig.setToolTipText("Choisissez la configuration dans la liste (Alt+c)");
	    jcbConfig.setRenderer(new ConfigurationsComboBoxRenderer());
	    //	jcbConfig.addActionListener(this);
	    
	    //désactivation des composants liés au fichier cible si option automatique activée
	    /*if(ConfigNat.getCurrentConfig().getSortieAuto())
	    {
	    	setSortieAuto(ConfigNat.getCurrentConfig().isReverseTrans());
	    }*/
	
	    setLayout(new GridBagLayout());
	    GridBagConstraints c = new GridBagConstraints();
	    //menu
	    setJMenuBar(jmb);
	    // l 1
	    c.insets = new Insets(0,3,0,3);
	    c.anchor = GridBagConstraints.LINE_END;
	    c.gridx = 0;
	    c.gridy = 1;
	    c.gridwidth = 1;
	    add(lJtfNoir,c);
	
	    c.fill = GridBagConstraints.HORIZONTAL;
	    c.anchor = GridBagConstraints.CENTER;
	    c.gridx = 1;
	    c.weightx = 1.0;
	    add(jtfNoir,c);
		
	    c.gridx = 2;
	    c.weightx = 0.0;
	    add(btSelectNoir,c);
	
	    // l 1-2
	    c.gridx = 1;
	    c.gridy++;
	    c.insets = new Insets(0,3,0,3);
	    c.fill = GridBagConstraints.NONE;
	    c.anchor = GridBagConstraints.CENTER;
	    add(btSens,c);
	    // l 2
	    c.insets = new Insets(0,3,3,3);
	    c.anchor = GridBagConstraints.LINE_END;
	    c.fill = GridBagConstraints.NONE;
	    c.gridx = 0;
	    c.gridy++;
	    add(lJtfBraille,c);
	    c.anchor = GridBagConstraints.CENTER;
	    c.fill = GridBagConstraints.HORIZONTAL;
	    c.gridx = 1;
	    add(jtfBraille,c);
	    c.gridx = 2;
	    add(btSelectBraille,c);
	
		
		// l 3	
	    c.insets = new Insets(10,3,3,3);
		c.gridx = 0;
		c.gridy++;
		c.gridheight = 2;
		add(lIcone,c);
		
		c.gridx++;
		c.gridheight = 1;
		add(btTranscrire,c);
		c.gridx = 2;
		add(btEditeur,c);
		
		// l 3	bis
		c.gridx = 1;
		c.gridy++;
		add(btEditeurMep,c);
		c.gridx = 2;
		add(btEditeurTrans,c);
		
	    // l 4
	    c.anchor = GridBagConstraints.LINE_END;
	    c.fill = GridBagConstraints.NONE;
	    c.gridx = 0;
	    c.gridy++;
	    c.weightx = 0.0;
	    add(lConfig,c);
	
	    c.fill = GridBagConstraints.HORIZONTAL;
	    c.anchor = GridBagConstraints.CENTER;
	    c.gridx = 1;
	    c.weightx = 1.0;
	    add(jcbConfig,c);
		
	    c.gridx = 2;
	    c.weightx = 0.0;
	    add(btOption,c);
		
	    /*/l 4 bis		
	      c.gridx = 1;
	      c.gridy++;
	      add(jpb,c);*/
	
	    // l 5
	    c.gridx = 0;
	    c.gridy++;
	    //	add(voir_log,c);
		
	    // l 6
	    JPanel panneauAffichage = new JPanel();
	    panneauAffichage.add(scrollLog);
	    //JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);

	    //nom et description devraient appartenir au scrollPane scrollLog ?
	    panneauAffichage.getAccessibleContext().setAccessibleName("Panneau d'affichage");
	    panneauAffichage.getAccessibleContext().setAccessibleDescription("Panneau d'affichage dynamique des traitements (logs)");
	    //	panneauAffichage.setPreferredSize(new Dimension(600,300));
	
	    c.fill = GridBagConstraints.BOTH;
	    c.weightx = 1.0;
	    c.weighty = 1.0;
	    c.gridx = 0;
	    c.gridy++;
	    c.gridwidth = 3;
	    //	add(panneauAffichage,c);
	    //add(splitPane);
	    //c.gridy++;
	    add(scrollLog,c);
	
	    // l 7 (boutons du bas)
	    JPanel pBoutons = new JPanel(new GridBagLayout());
	    
	    c.gridx=0;
	    c.anchor = GridBagConstraints.WEST;
	    c.gridy++;
	    c.weightx = 0.0;
	    c.weighty = 0.0;
	    c.gridwidth = 3;
	    c.insets = new Insets(3,3,3,3);
	    add(pBoutons,c);	    
	    
	    c.anchor = GridBagConstraints.LINE_START;
	    c.gridwidth = 1;
	    c.weightx = 1.0;
	    c.weighty = 1.0;
	    c.gridx=0;
	    c.ipadx=0;
	    c.insets = new Insets(3,20,3,20);
	    pBoutons.add(btAide,c);
	    
	    c.gridx++;
	    pBoutons.add(btAPropos,c);
	    c.gridx++;
	    c.weightx = 2.0;
	    c.weighty = 2.0;
	    pBoutons.add(btSignalBug,c);
	    c.gridx++;
	    pBoutons.add(btQuitter,c);
	    
	    
	    //c'est la méthode de windowslistener qui va gérer la fermeture
	    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
	    addWindowListener(this);
	    //position et taille de la fenêtre
	    if(ConfigNat.getCurrentConfig().getMemoriserFenetre())
	    {
	    	int x= ConfigNat.getCurrentConfig().getWidthPrincipal();
	    	int y=ConfigNat.getCurrentConfig().getHeightPrincipal();
	    	if(x+y != 0){setPreferredSize(new Dimension(x,y));}
	    }
	    if(ConfigNat.getCurrentConfig().getCentrerFenetre())
        {
		    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		    Dimension size = this.getPreferredSize();
		    screenSize.height = screenSize.height/2;
		    screenSize.width = screenSize.width/2;
		    size.height = size.height/2;
		    size.width = size.width/2;
		    int y = screenSize.height - size.height;
		    int x = screenSize.width - size.width;
		    setLocation(x, y);
        }
    }
	
    /** Ajoute les configurations du répertoire "configurations" dans {@link FenetrePrinc#jcbConfig} 
     * et sélectionne la configuration active.
     */
    public void chargeConfigurations()//JComboBox jcb)
    {
    	jcbConfig.removeActionListener(this);         
        jcbConfig.removeAllItems();                   

        File repertoireSysteme = new File(ConfigNat.getSystemConfigFilterFolder());
        File repertoireUser   = new File(ConfigNat.getUserConfigFilterFolder());   
        ArrayList<File> both = new ArrayList<File>();                        

        try {Collections.addAll(both,repertoireSysteme.listFiles());}
        catch (NullPointerException npe){npe.printStackTrace();}                                                          

        try {Collections.addAll(both, repertoireUser.listFiles());}
        catch (NullPointerException npe){npe.printStackTrace();}                                                        

			File[] listConfs = both.toArray(new File[] {});
			
			ConfigurationsListItem selectedConfig = null;
			for(int i=0;i<listConfs.length;i++)
			    {
			        try
				    {
				        ConfigurationsListItem cli = new ConfigurationsListItem(listConfs[i].getCanonicalPath());
				        if (cli.getIsValid())
					    {
						jcbConfig.addItem(cli);    
						if(cli.getFilename().equals(ConfigNat.getCurrentConfig().getFichierConf())) {
						    selectedConfig = cli;
						}
						
				        }
				    }
				catch (IOException ieo){ieo.printStackTrace();}
			    }
			
			jcbConfig.addActionListener(this);
			if (selectedConfig != null){jcbConfig.setSelectedItem(selectedConfig);}
    }

    /**
     * Ouvre l'éditeur de fichier prêt à la mise en page dans l'éditeur associé, en passant à l'éditeur une instance d' {@link Embosseur}
     * si nécessaire. Utilise l'encoding représenté par {@link nat.OptNames} dans {@link ConfigNat}
     * @param nomFichier Le nom du fichier transcrit à ouvrir
     */
    public void afficheFichierMep(String nomFichier) 
    {
    	gestErreur.afficheMessage("Fonctionalité en développement, non implémentée\n", Nat.LOG_SILENCIEUX);
    	//new EditeurXML(gestErreur, nomFichier);
    	new EditeurXML(gestErreur);
    }
    /**
     * Ouvre l'éditeur de fichier transcrit dans l'éditeur, en passant à l'éditeur une instance d' {@link Embosseur}
     * si nécessaire. Utilise l'encoding représenté par {@link nat.OptNames} dans {@link ConfigNat}
     * @param nomFichier Le nom du fichier transcrit à ouvrir
     */
    public void afficheFichier(String nomFichier) 
    {
    	//long tps = System.currentTimeMillis(); 
	    Embosseur emb = null;
	    if(ConfigNat.getCurrentConfig().getUtiliserCommandeEmbossage())
	    {
		    emb = new EmbosseurLDC(nomFichier,gestErreur);
	    }
	    else if (ConfigNat.getCurrentConfig().getUtiliserEmbosseuse())
	    {
		    emb = new EmbosseurInstalle(nomFichier, gestErreur);
	    }
	    Editeur editeur = new Editeur(ConfigNat.getCurrentConfig().getLongueurLigne(),emb,gestErreur);
	    String sourceEncoding = ConfigNat.getCurrentConfig().getBrailleEncoding();
			
	    if (sourceEncoding.equals("automatique"))
	    {
		    sourceEncoding = nat.trouveEncodingSource(nomFichier);
		    if(sourceEncoding == null||sourceEncoding.equals(""))
		    {
			    // pas de bol, on n'a pas réussit à trouver le charset correct
			    sourceEncoding = Charset.defaultCharset().name();
			    gestErreur.afficheMessage("\n** Impossible de détecter l'encodage du fichier sortie.\n** Utilisation de l'encodage par défaut: " + sourceEncoding + "\n",Nat.LOG_NORMAL);
		    }
		    else
		    {
			    gestErreur.afficheMessage("\n** Détection automatique de l'encodage du fichier sortie: "+sourceEncoding+"\n", Nat.LOG_SILENCIEUX);
		    }
	    }
	    editeur.setEncodage(sourceEncoding);
	    //editeur.setTableBraille(ConfigNat.getCurrentConfig().getTableBraille());
		
	    editeur.setAfficheLigneSecondaire(ConfigNat.getCurrentConfig().getAfficheLigneSecondaire());
	    editeur.afficheFichier(nomFichier, ConfigNat.getCurrentConfig().getPoliceEditeur(), ConfigNat.getCurrentConfig().getTaillePolice(),ConfigNat.getCurrentConfig().getPolice2Editeur(), ConfigNat.getCurrentConfig().getTaillePolice2());
	    editeur.pack();
	    if (ConfigNat.getCurrentConfig().getMaximizedEditeur())
	    	{editeur.setExtendedState(Frame.MAXIMIZED_BOTH);}
	    editeur.setVisible(true);
	    //System.out.println("temps :" + (System.currentTimeMillis() - tps));
    }
    
    /**
     * génère un nom de fichier de sortie automatiquement
     * @param reverse vrai si détranscription (donc renommage fichier noir)
     * et faux si transcription (donc renommage fichier braille)
     */
    public void setSortieAuto(boolean reverse)
    {
    	if(!reverse)
    	{
    		//lJtfBraille.setEnabled(false);
    		//jtfBraille.setEnabled(false);
    		//btSelectBraille.setEnabled(false);
    		//jmiSelectBraille.setEnabled(false);
    		if (!(jtfBraille.getText().toLowerCase().endsWith("_nat.txt")))
    		{jtfBraille.setText(FileToolKit.nomSortieAuto(jtfNoir.getText()));}
    	}
    	else
    	{
    		/*lJtfBraille.setEnabled(true);
    		jtfBraille.setEnabled(true);
    		btSelectBraille.setEnabled(true);
    		jmiSelectBraille.setEnabled(true);*/
    		if (!(jtfNoir.getText().toLowerCase().endsWith(".xhtml")))
    		{ jtfNoir.setText(jtfNoir.getText()+".xhtml");}
    	}
    }
    /**
     * Renvoie le gestionnaire d'erreur utilisé dnas cette fenêtre 
     * @return le gestionnaire d'erreur utilisé
     */
	public GestionnaireErreur getGestErreur() {return gestErreur;}

	/**
	 * Méthode d'accès à {@link #running}
	 * @param r valeur pour {@link #running}
	 */
	public void setRunning(boolean r) {running = r;}

	/**
	 * Méthode d'accès à {@link #running}
	 * @return true si {@link #running} est vrai
	 */
	public boolean getRunning() {return running;}

	/**
	 * Méthode d'accès à {@link #nat}
	 * @return l'instance de nat utilisée
	 */
	public Nat getNat() {return nat;}

	/**
	 * Méthode d'accès à {@link #btEditeur}
	 * @return le bouton {@link #btEditeur}
	 */
	public JButton getBtEditeur() {return btEditeur;}

	/**
	 * Active ou désactive les composants liés à la transcription
	 * @param b true si activation, false sinon
	 */
	public void activeTrans(boolean b)
	{
		btTranscrire.setEnabled(b);
		jmiTranscrire.setEnabled(b);
	}
	
    /** implémentation de actionPerformed(ActionEvent evt) de l'interface ActionListener
     * gère tous les boutons, tous les items des menus, et le changement de configuration par {@link FenetrePrinc#jcbConfig}
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    public void actionPerformed(ActionEvent evt)
    {
	    //lancer transcription
	    if (evt.getSource() == btTranscrire || evt.getSource() == jmiTranscrire)    
        {
	    	boolean go = true;
	    	if(new File(jtfNoir.getText()).exists()&& ConfigNat.getCurrentConfig().isReverseTrans())
	    	{
	    		go= JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(this, "Voulez-vous écraser le fichier noir?",
                        "Fichier noir existant", JOptionPane.YES_NO_OPTION);
	    	}
	    	else if(new File(jtfBraille.getText()).exists()&& !ConfigNat.getCurrentConfig().isReverseTrans())
	    	{
	    		go= JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(this, "Voulez-vous écraser le fichier braille?",
                        "Fichier braille existant", JOptionPane.YES_NO_OPTION);
	    	}
		    if(go)
		    {
		    	//jpb.setValue(jpb.getMinimum());
			    Thread thr = new ThreadJPB();
			    thr.start();
			    /*
			    if(!ConfigNat.getCurrentConfig().getSaxonAsXsltProcessor())
				{
					gestErreur.afficheMessage(
							"\n***********************************" +
							"* ATTENTION, utilisation de XALAN *" +
							"\n***********************************", Nat.LOG_DEBUG);
					System.setProperty("javax.xml.transform.TransformerFactory",
							"org.apache.xalan.processor.TransformerFactoryImpl");
					//jcbXsltProc.setEnabled(false);
				}
			    else
	            {
			    	System.setProperty("javax.xml.transform.TransformerFactory",
					"net.sf.saxon.TransformerFactoryImpl");
	            }*/
				
			    btEditeur.setEnabled(false);
			    this.repaint();
			    if ((jtfNoir.getText().length()<1)||(filtre.getText().length()<1)||(jtfBraille.getText().length()<1))
		        {
				    gestErreur.afficheMessage("Entrez un fichier source et un fichier cible", Nat.LOG_SILENCIEUX);
		        }
			    else
			    {
				    panneauLog.setText("");
				    panneauLog.paintImmediately(new Rectangle(0,0,panneauLog.getWidth(),panneauLog.getHeight()));
				    /*gestErreur = new GestionnaireErreur(null,ConfigNat.getCurrentConfig().getNiveauLog());*/
				    //gestErreur.addAfficheur(panneauLog);
				    /*gestErreur.addAfficheur(new AfficheurConsole());
				    gestErreur.addAfficheur(new AfficheurLog());*/
				    gestErreur.setModeDebugage(debug.isSelected());
				    ArrayList<String> sources = new ArrayList<String>();
				    ArrayList<String> sorties = new ArrayList<String>();
				    sources.add(jtfNoir.getText());
				    sorties.add(jtfBraille.getText());
				    if (nat.fabriqueTranscriptions(sources, sorties))
				    {			
				    	Thread thrTrans = new ThreadTrans();
					    thrTrans.start();
				    }
			    }
		    }
		    else{gestErreur.afficheMessage("Transcription annulée", Nat.LOG_SILENCIEUX);}
	    }

	    //ouvrir editeur
	    else if (evt.getSource() == btEditeur || evt.getSource() == jmiOuvrirTrans)
	    {
	    	ouvrirEditeur();
	    }
	    //ouvrir editeur tan
	    else if (evt.getSource() == jmiTan)
	    {
	    	ouvrirEditeur(true);
	    }
	    //ouvrir rapport de bug
	    else if (evt.getSource() == btSignalBug || evt.getSource() == jmiSignalBug)
	    {
	    	doBugReport();
	    }
	    //combo box des configurations
	    else if (evt.getSource() == jcbConfig)
	    {			
		    ConfigurationsListItem cli = (ConfigurationsListItem)jcbConfig.getSelectedItem();
		    ConfigNat.charger(cli.getFilename());
	    }
	    else if(evt.getSource() == btSens || (evt.getSource()== jmiSensTr))
	    {
	    	setReverseTrans(!ConfigNat.getCurrentConfig().isReverseTrans());
	    }
	    
	    else if(evt.getSource() == btQuitter || evt.getSource() == jmiQuitter)
	    {
		    quitter();
	    }
		
    }

    /**
     * Change les composants graphiques en fonction de <code>reverse</code>
     * <code>reverse</code> est vrai si il faut passer en mode détranscription et 
     * faux q'il faut passer en mode transcription.
     * Appelle également {@link ConfigNat#setReverseTrans(boolean)}
     * @param reverse true si passer en mode détranscription 
     * 
     */
    private void setReverseTrans(boolean reverse)
    {
    	if(!reverse)
    	{
    		btTranscrire.setText("Transcrire");
    		btSens.setIcon(new ImageIcon("ui/icon/go-down.png"));
		    btSens.setToolTipText("Passer en mode détranscription (Ctrl+i)");
		    btSens.getAccessibleContext().setAccessibleName("Sens de transcription : noir vers braille");
		    btEditeur.setText("Ouvrir la transcription");
		    btEditeurTrans.setText("Ouvrir un fichier déjà transcrit");
		    btEditeurTrans.setToolTipText("Pour ouvrir un fichier déjà transcrit (Alt+d) ou (Ctrl+d)");
		    lIcone.setIcon(new ImageIcon("ui/nat.png"));
		    lIcone.setToolTipText("En mode NAT (transcription)");
		    ConfigNat.getCurrentConfig().setReverseTrans(false);
		    //setSortieAuto(false);
    	}
    	else
    	{
    		btTranscrire.setText("Détranscrire");
    		btSens.setIcon(new ImageIcon("ui/icon/go-up.png"));
		    btSens.setToolTipText("Passer en mode transcription (Ctrl+i)");
		    btSens.getAccessibleContext().setAccessibleName("Sens de transcription : braille vers noir");
		    btEditeur.setText("Ouvrir la détranscription");
		    btEditeurTrans.setText("Ouvrir un fichier détranscrit");
		    btEditeurTrans.setToolTipText("Pour ouvrir un fichier déjà détranscrit (Alt+d) ou (Ctrl+d)");
		    btEditeurMep.setEnabled(false);
		    lIcone.setIcon(new ImageIcon("ui/tan.png"));
		    lIcone.setToolTipText("En mode TAN (détranscription)");
		    ConfigNat.getCurrentConfig().setReverseTrans(true);
		    setSortieAuto(true);
    	}
    }

	/** Méthode redéfinie de ComponentListener
	 * Ne fait rien
	 * @param arg0 Le ComponentEvent
	 */
	public void componentHidden(ComponentEvent arg0){/*do nothing*/}
	/** Méthode redéfinie de ComponentListener
	 * Ne fait rien
	 * @param arg0 Le ComponentEvent
	 */
	public void componentMoved(ComponentEvent arg0){/*do nothing*/}
	/** Méthode redéfinie de ComponentListener
	 * Ne fait rien
	 * @param arg0 Le ComponentEvent
	 */
	public void componentShown(ComponentEvent arg0){/*do nothing*/}
	/** Méthode redéfinie de ComponentListener
	 * Mise à jour de l'affichage lors du redimensionement
	 * @param arg0 Le ComponentEvent
	 */
	public void componentResized(ComponentEvent arg0)
	{
		if (getExtendedState()==Frame.MAXIMIZED_BOTH)
		{
			ConfigNat.getCurrentConfig().setMaximizedPrincipal(true);
		}
		else
		{
			ConfigNat.getCurrentConfig().setWidthPrincipal(getWidth());
			ConfigNat.getCurrentConfig().setHeightPrincipal(getHeight());
			ConfigNat.getCurrentConfig().setMaximizedPrincipal(false);
		}
		repaint();
	}
    /** 
     * implémentation de focusGained de FocusListener; ne fait rien 
     * @param foc Le FocusEvent
     * */
	public void focusGained(FocusEvent foc){/*do nothing*/} 
	
	/**
	 * implémentation de focusLost de FocusListener;
	 * positionne le curseur sur le dernier caractère des textes contenus dans {@link #jtfNoir} et {@link #jtfBraille}
     * @param foc Le FocusEvent
	 */
    public void focusLost(FocusEvent foc)
    {
	    if (foc.getSource()==jtfBraille)
	    {
		    jtfBraille.setCaretPosition(jtfBraille.getText().length());
		    verifieBtEditeur();
		    /*if(ConfigNat.getCurrentConfig().getSortieAuto() && ConfigNat.getCurrentConfig().isReverseTrans())
		    {
		    	setSortieAuto(true);
	    	}*/
	    }
	    else if (foc.getSource()==jtfNoir)
	    {
		    jtfNoir.setCaretPosition(jtfNoir.getText().length());
		    /*if(ConfigNat.getCurrentConfig().getSortieAuto() && !ConfigNat.getCurrentConfig().isReverseTrans())
	    	{
		    	setSortieAuto(false);
	    	}*/
	    }
    }
	/** Vérifie si l'adresse contenu dans {@link #jtfBraille} est valide, et si c'est le cas dégrise {@link #btEditeur}*/ 
    private void verifieBtEditeur()
    {
	    if(new File(jtfBraille.getText()).exists()){btEditeur.setEnabled(true);}
	    else{btEditeur.setEnabled(false);}
    }

	/** @see java.awt.event.WindowListener#windowActivated(java.awt.event.WindowEvent)*/
	public void windowActivated(WindowEvent arg0) {/*do nothing*/}
	/** implémentation de WindowsListener; quitte le programme
	 * @see #quitter()
	 * @see java.awt.event.WindowListener#windowClosed(java.awt.event.WindowEvent)
	 */
	public void windowClosed(WindowEvent arg0){quitter();}
	/**@see java.awt.event.WindowListener#windowClosing(java.awt.event.WindowEvent)*/
	public void windowClosing(WindowEvent arg0) {/*do nothing*/}
	/**@see java.awt.event.WindowListener#windowDeactivated(java.awt.event.WindowEvent)*/
	public void windowDeactivated(WindowEvent arg0) {/*do nothing*/}
	/** @see java.awt.event.WindowListener#windowDeiconified(java.awt.event.WindowEvent)*/
	public void windowDeiconified(WindowEvent arg0) {/*do nothing*/}
	/** @see java.awt.event.WindowListener#windowIconified(java.awt.event.WindowEvent)*/
	public void windowIconified(WindowEvent arg0) {/*do nothing*/}
	/**@see java.awt.event.WindowListener#windowOpened(java.awt.event.WindowEvent)*/
	public void windowOpened(WindowEvent arg0){/*do nothing*/}
	
	/** Quitte le programme en enregistrant les options de l'interface graphique et la configuration actuelle*/
	private void quitter()
	{
		gestErreur.afficheMessage("\n** Enregistrement de la configuration de l'interface avant de quitter...", Nat.LOG_NORMAL);
		ConfigNat.getCurrentConfig().setFBraille(jtfBraille.getText());
		ConfigNat.getCurrentConfig().setFNoir(jtfNoir.getText());
		ConfigNat.getCurrentConfig().saveUiConf();
		gestErreur.afficheMessage(" ok! \n Au revoir!" , Nat.LOG_NORMAL);
	    System.exit(0);
	}
	
	/**
	 * Open the TAN editor with an empty doc (documents/nouveau.tan) if tan param set to true,
	 * else open the classic editor
	 * @param tan if true open the TAN editor with an empty doc, else open the classic editor
	 */
	private void ouvrirEditeur(boolean tan)
	{
		if(tan)
		{
			EditeurTan et = new EditeurTan(null,ConfigNat.fichTmpTan,nat);
			et.setExtendedState(Frame.MAXIMIZED_BOTH);
			et.setState(MAXIMIZED_BOTH);
			et.setVisible(true);
		}
		else{ouvrirEditeur();}
	}
	
	/** Ouvre le bon éditeur pour le fichier de sortie en fonction des options choisies */
	public void ouvrirEditeur()
	{
		//utilisation de l'éditeur de nat
		if(ConfigNat.getCurrentConfig().getUseNatEditor())
		{
			if(ConfigNat.getCurrentConfig().isReverseTrans())
			{
				//copie du fichier noir xhtml dans le fichier temporaire de tan
				gestErreur.afficheMessage("Copie du fichier noir dans le fichier temporaire de tan", Nat.LOG_DEBUG);
				FileToolKit.copyFile(jtfNoir.getText(), EditeurTan.tmpXHTML);
				EditeurTan et = new EditeurTan(null,jtfBraille.getText(),nat);
				et.setExtendedState(Frame.MAXIMIZED_BOTH);
				et.setState(MAXIMIZED_BOTH);
				et.setVisible(true);
			}
			else{afficheFichier(jtfBraille.getText());}
		}
		//utilisation de l'éditeur par défaut de l'environnement
		else if(ConfigNat.getCurrentConfig().getUseDefaultEditor())
		{
	    	Desktop desktop = null;
	        if (Desktop.isDesktopSupported())
	        {
	        	desktop = Desktop.getDesktop();
	        	if (desktop.isSupported(Desktop.Action.OPEN))
	        	{
	        		try{desktop.open(new File(jtfBraille.getText()));}
					catch (IOException e) {gestErreur.afficheMessage("Erreur lors d'entrée-sortie avec le fichier "+ jtfBraille.getText(), Nat.LOG_SILENCIEUX);}
	        	}
	        	else{gestErreur.afficheMessage("Editeur par défaut non trouvé", Nat.LOG_SILENCIEUX);}
	
	        }
	        else{gestErreur.afficheMessage("Bureau non supporté", Nat.LOG_SILENCIEUX);}
		}
		//utilisation d'un éditeur spécifique
		else
		{
			File fsortie = new File(jtfBraille.getText());
			// la tableau cmd contient deux éléments : le chemin de l'éditeur externe et le chemin du fichier à ouvrir.
			String []cmd= new String[2];
			try
			{
	
				cmd[0] = ConfigNat.getCurrentConfig().getEditeur();
				cmd[1] = fsortie.getCanonicalPath();
				Runtime.getRuntime().exec(cmd);
			}
			catch (IOException ioe) {gestErreur.afficheMessage("Erreur d'entrée sortie par l'éditeur externe ("+cmd[0]+") avec "+ cmd[1],Nat.LOG_SILENCIEUX); }
		}
	}
	/**
	 * Prépare la fenêtre de dialogue {@link FenetreBugReport} et récupère les informations contenues dans les fichiers
	 * temporaires, les logs, et la sortie
	 */
	private void doBugReport()
	{
		/* 
		 * récupération des informations
		 */
		//fichiers temporaires
		/*String fichiers = "------ fichiers temporaires -------\n";
		File tmp = new File("tmp.xml");
		if(tmp.exists())
		{
			fichiers = fichiers + "*** tmp.xml ************************************\n"
				+ FileToolKit.loadFileToStr(tmp.getAbsolutePath()) 
				+ "\n***********************************************\n";
		}
		tmp = new File("tmp.xhtml");
		if(tmp.exists())
		{
			fichiers = fichiers + "*** tmp.xhtml ************************************\n"
				+ FileToolKit.loadFileToStr(tmp.getAbsolutePath()) 
				+ "\n***********************************************\n";
		}
		tmp = new File("tmp.mep");
		if(tmp.exists())
		{
			fichiers = fichiers + "*** tmp.mep ************************************\n"
				+ FileToolKit.loadFileToStr(tmp.getAbsolutePath()) 
				+ "\n***********************************************\n";
		}
		tmp = new File("tmp-pass2.txt");
		if(tmp.exists())
		{
			fichiers = fichiers + "*** tmp-pass2.txt ************************************\n"
				+ FileToolKit.loadFileToStr(tmp.getAbsolutePath()) 
				+ "\n***********************************************\n";
		}
		// Sortie
		tmp = new File(sortie.getText());
		if(tmp.exists())
		{
			fichiers = fichiers + "------ Sortie ----------------------------\n"
				+ FileToolKit.loadFileToStr(tmp.getAbsolutePath())+"\n";
		}
		System.out.println(fichiers);*/
		// Dernier fichier de log
		File tmp = new File(ConfigNat.getUserTempFolder()+"/nat_log.1");
		String fichiers ="";
		if(tmp.exists())
		{
			fichiers = fichiers + "------ LOGS ----------------------------\n"
				+ FileToolKit.loadFileToStr(tmp.getAbsolutePath());
		}
		fichiers = fichiers +  "\n------------ fin -----------------\n";
		
		// lancement de la fenêtre de debug
		FenetreBugReport f= new FenetreBugReport(this,fichiers);
		f.setVisible(true);
		
	}
	/**
	 * Classe interne de {@link FenetrePrinc} permettant de jouer un son à intervalle régulier pendant la transcription
	 */
    public class ThreadJPB extends Thread
    {
	    /**
	     * Joue un son toutes les 5 secondes et le son de fin quand running=false
	     * en fonction des options de l'interface graphique
	     */
	    @Override
		public void run() 
	    {
	        setRunning(true);
	        AudioClip ac;
	        int cycles = 0;
	        try 
		    {
		        File curDir = new File("");
		        ac = Applet.newAudioClip(new URL("file:"+ curDir.getAbsolutePath()+"/ui/sounds/tic.au"));
		        while(getRunning())
			    {
			        if(cycles%5==0 && ConfigNat.getCurrentConfig().getSonPendantTranscription()){ac.play();}
			        try 
				    {
				        sleep(1000);
				        cycles++;
				    } catch (InterruptedException ie) {ie.printStackTrace();}
					
			    }
		        if(ConfigNat.getCurrentConfig().getSonFinTranscription())
			    {
			        if(getGestErreur().getException()==null )
				    {
				        ac = Applet.newAudioClip(new URL("file:"+ curDir.getAbsolutePath()+"/ui/sounds/fin.au"));
				    }
			        else
				    {
				        ac = Applet.newAudioClip(new URL("file:"+ curDir.getAbsolutePath()+"/ui/sounds/erreur.au"));
				    }
			        ac.play();
			    }
		        if(ConfigNat.getCurrentConfig().getOuvrirEditeur()){ouvrirEditeur();}
		    } catch (MalformedURLException mue) 
		    {
		        mue.printStackTrace();
		    }
			
	    }
    }
    /**
	 * Classe interne de {@link FenetrePrinc} permettant de jouer un son à intervalle régulier pendant la transcription
	 */
    public class ThreadTrans extends Thread
    {
	    /**
	     * Joue un son toutes les 5 secondes et le son de fin quand running=false
	     * en fonction des options de l'interface graphique
	     */
	    @Override
		public void run() 
	    {
	    	activeTrans(false);
	    	setRunning(true);
	    	
	    	getNat().lanceScenario();
	    	
		    if (getGestErreur().getException() == null )
		    {
			    /*//mettre en place un gestionnaire
			    if (ConfigNat.getCurrentConfig().getOuvrirEditeur())
			    {
				    //afficheFichier(sortie.getText());
			    	ouvrirEditeur();
			    }*/
			    getBtEditeur().setEnabled(true);
			    //jpb.setValue(jpb.getMaximum());
		    }
		    
		    activeTrans(true);
			setRunning(false);
			
		    /*try{sleep(2000);}
		    catch (InterruptedException e)
		    {
	         e.printStackTrace();
		    }*/
	    }
    }
}
