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

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import nat.ConfigNat;
/**
 * Onglet de configuration des options avancées
 * @author bruno
 *
 */
public class ConfAvance extends OngletConf implements ActionListener
{
	/** pour la sérialisation (non utilisé)*/
	private static final long serialVersionUID = 1L;
	/** case à cocher activant ou non Saxon plutôt que Xalan
	 * <p>Saxon est normallement l'implémentation xsl à utiliser, car xalan ne fait pas de xsl2</p>
	 */
	private JCheckBox jcbXsltProc = new JCheckBox("Saxon au lieu de Xalan (devrait rester coché dans le cas d'une utilisation normale de NAT)");
	/** JSpinner nombre de fichiers de log */
	JSpinner jsNbFichLog;
	/** JSpinner taille max en Ko du fichier de log */
	JSpinner jsTailleLog;
	/** case à cocher activant ou non les optimisations; pour l'instant, lance une transcription vide à l'ouverture*/
	private JCheckBox jcbOpti = new JCheckBox("Optimiser le temps de traitement (par ex.: lance une transcription vide au lancement de NAT)");
	
	/** JTextField pour l'adresse du fichier source */
    private JTextField  workingDir = new JTextField("",30);
    /** Label associé à workingDir
     * @see #workingDir
     * */
    private JLabel lWorkingDir = new JLabel("Dossier de travail de NAT :");
    /** Bouton ouvrant le JFileChooser pour l'adresse du fichier source 
     * @see GestionnaireOuvrir
     * */
    private JButton jbWorkingDir = new JButton("Parcourir",new ImageIcon("ui/icon/document-open.png"));
    
    /** Bouton pour effacer les fichiers temporaires */
    private JButton jbEraseTemp = new JButton ("Effacer les fichiers temporaires...");
    
    /** jcheckbox vérifier l'existence d'une MAJ"*/
    private JCheckBox jcbVerifMAJ = new JCheckBox("Vérifier l'existence de mises à jour sur Internet au lancement de NAT");
	
	/** Constructeur*/
	public ConfAvance()
	{
		super();	
		getAccessibleContext().setAccessibleDescription("Afficher les options avancées");
		getAccessibleContext().setAccessibleName("Onglet contenant les options avancées (experts)");
		
		jcbXsltProc.setSelected(ConfigNat.getCurrentConfig().getSaxonAsXsltProcessor());
		jcbXsltProc.getAccessibleContext().setAccessibleName("Utiliser Saxon");
		jcbXsltProc.getAccessibleContext().setAccessibleDescription("Pour utiliser saxon");
		jcbXsltProc.setToolTipText("Utiliser le processeur xslt Saxon et pas Xalan (usage normal de NAT) (Alt+x)");
		jcbXsltProc.setMnemonic('x');
		
		jsNbFichLog = new JSpinner(new SpinnerNumberModel(ConfigNat.getCurrentConfig().getNbLogFiles(), 1, 5, 1));
		jsNbFichLog.getAccessibleContext().setAccessibleName("Nombre de fichiers de log à utiliser");
		jsNbFichLog.getAccessibleContext().setAccessibleDescription("Sélectionnez avec les flèches le nombre de fichiers de log à utiliser");
		jsNbFichLog.setToolTipText("Sélectionnez le nombre de fichiers de log à utiliser (Alt+b)");
		
		JLabel lJsNbFichLog = new JLabel("Nombre de fichiers tournants de log:");
		lJsNbFichLog.setLabelFor(jsNbFichLog);
		lJsNbFichLog.setDisplayedMnemonic('b');
		
		jsTailleLog = new JSpinner(new SpinnerNumberModel(ConfigNat.getCurrentConfig().getLogFileSize(), 1, 3000, 100));
		jsTailleLog.getAccessibleContext().setAccessibleName("Taille minimale en Ko déclenchant la rotation des logs");
		jsTailleLog.getAccessibleContext().setAccessibleDescription("Sélectionnez avec les flèches la taille minimale déclenchant la rotation des logs");
		jsTailleLog.setToolTipText("Sélectionnez la taille minimale déclenchant la rotation des fichiers de log (Alt+m)");
		
		JLabel lJsTailleLog = new JLabel("Taille minimale pour rotation des logs (en Ko):");
		lJsTailleLog.setLabelFor(jsTailleLog);
		lJsTailleLog.setDisplayedMnemonic('m');
		
		
		jcbOpti.setSelected(ConfigNat.getCurrentConfig().getOptimize());
		jcbOpti.getAccessibleContext().setAccessibleName("Optimiser");
		jcbOpti.getAccessibleContext().setAccessibleDescription("Pour utiliser les optimisations");
		jcbOpti.setToolTipText("Utiliser les optimisations du temps de traitement (Alt+o)");
		jcbOpti.setMnemonic('o');
		
		lWorkingDir.setLabelFor(workingDir);
		jbWorkingDir.addActionListener(this);
		jbWorkingDir.getAccessibleContext().setAccessibleName("Parcourir");
		jbWorkingDir.setToolTipText("Choisir le dossier de travail de NAT (Alt+r)");
		jbWorkingDir.getAccessibleContext().setAccessibleDescription(getToolTipText());
		jbWorkingDir.setMnemonic('r');
		ConfigNat.getCurrentConfig();
		workingDir.setText(ConfigNat.getWorkingDir());
		workingDir.setEditable(false);
		workingDir.setToolTipText("Dossier de travail de NAT actuel");
		workingDir.getAccessibleContext().setAccessibleDescription(getToolTipText());
		
		jcbVerifMAJ.setSelected(ConfigNat.getCurrentConfig().getUpdateCheck());
		jcbVerifMAJ.getAccessibleContext().setAccessibleName("Vérifier les maj");
		jcbVerifMAJ.getAccessibleContext().setAccessibleDescription("Pour vérifier au démarrage l'existence de mises à jour");
		jcbVerifMAJ.setToolTipText("Vérifier au démarrage l'existence de mises à jour sur internet (Alt+j)");
		jcbVerifMAJ.setMnemonic('j');
		
		jbEraseTemp.addActionListener(this);
		
		/*********
		 * Mise en page
		 */
		
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.anchor = GridBagConstraints.WEST;
		gbc.insets = new Insets(15,3,3,3);
		GridBagLayout gbl = new GridBagLayout();
		
		//setLayout(gbl);
		
		JPanel p = new JPanel();
		p.setLayout(gbl);
		
		gbc.gridx=1;
		gbc.gridy = 0;
		gbc.gridwidth = 3;
		p.add(jbEraseTemp,gbc);
		
		gbc.gridx=0;
		gbc.gridy++;
		//gbc.gridheight = 3;
		p.add(jcbXsltProc,gbc);
		
		
		gbc.gridy++;
		gbc.gridwidth = 2;
		p.add(lJsNbFichLog,gbc);
		
		
		gbc.gridwidth = 1;
		gbc.gridx+=2;
		p.add(jsNbFichLog,gbc);
		
		gbc.insets = new Insets(3,3,3,3);
		gbc.gridy++;
		gbc.gridx=0;
		gbc.gridwidth = 2;
		p.add(lJsTailleLog,gbc);
		
		gbc.gridx+=2;
		gbc.gridwidth = 1;
		p.add(jsTailleLog,gbc);
		
		gbc.insets = new Insets(15,3,3,3);
		gbc.gridx=0;
		gbc.gridy++;
		gbc.gridwidth = 4;
		p.add(jcbOpti,gbc);
		
		gbc.gridx=0;
		gbc.gridy++;
		gbc.gridwidth=1;
		p.add(lWorkingDir,gbc);
		gbc.gridx++;
		gbc.gridwidth=2;
		p.add(workingDir,gbc);
		
		gbc.gridx+=2;
		p.add(jbWorkingDir,gbc);
		
		gbc.gridx=0;
		gbc.gridy++;
		gbc.gridwidth = 4;
		p.add(jcbVerifMAJ,gbc);
		add(p);
	}

	/**
	 * enregistre les options
	 * @see ui.SavableTabbedConfigurationPane#enregistrer(java.lang.String)
	 */
	public boolean enregistrer(String f)
	{
		ConfigNat.getCurrentConfig().setFichierConf(f);
		return enregistrer();
	}
	/**
	 * enregistre les options
	 * @see ui.SavableTabbedConfigurationPane#enregistrer()
	 */
	public boolean enregistrer()
	{
		boolean retour = true;
		ConfigNat.getCurrentConfig().setSaxonAsXsltProcessor(jcbXsltProc.isSelected());
		ConfigNat.getCurrentConfig().setLogFileSize(((Integer)jsTailleLog.getValue()).intValue());
		ConfigNat.getCurrentConfig().setNbLogFiles(((Integer)jsNbFichLog.getValue()).intValue());
		ConfigNat.getCurrentConfig().setOptimize(jcbOpti.isSelected());
		ConfigNat.getCurrentConfig().setUpdateCheck(jcbVerifMAJ.isSelected());
		return retour;
	}

	/**
	 * choisit le répertoire de travail avec un JFileChooser
	 */
	private void chooseWorkingDir()
	{
		/* paramétrage du file chooser*/
		JFileChooser jfc = new JFileChooser();
		/*FiltreFichier ff = new FiltreFichier(new String [] {""},"Dossier");
		jfc.addChoosableFileFilter(ff);
		jfc.setAcceptAllFileFilterUsed(true);
		jfc.setFileFilter(ff);*/
		jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		File f = new File(".");
		jfc.setCurrentDirectory(f);
		jfc.setApproveButtonText("Choisir ce dossier"); //intitulé du bouton
		
		/* selection du dico */
		jfc.setDialogTitle("Sélection du dossier de Travail de NAT");
		if (jfc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION)
		{
			workingDir.setText(jfc.getSelectedFile().getAbsolutePath());
			ConfigNat.getCurrentConfig().setWorkingDir(workingDir.getText());
		}
	}

	/**
	 * efface les fichier d'un répertoire et récursivement les fichiers des sous-répertoires.
	 * SAUF les fichiers de log (nat_log.*)
	 * pompé (et amélioré) sur : 
	 * http://www.javafr.com/forum/sujet-SUPPRIMER-REPERTOIRE-JAVA_531086.aspx
	 * @param path dossier à effacer
	 * @return true si tout s'est bien passé
	 */
	private boolean deleteDirectory (File path)
	{
		Boolean resultat = path.exists();
		
		if( resultat )
		{
            File[] files = path.listFiles();
            for(int i=0; i<files.length; i++)
            {
                    if(files[i].isDirectory()) 
                    { resultat &= deleteDirectory(files[i]); } 

                    if (!(files[i].getName().startsWith("nat_log")))
                    	{ resultat &= files[i].delete(); }

            }
        
		}
		return resultat;
	}
	
	/**
	 * gère les évènements sur {@link #jbWorkingDir}
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(ActionEvent evt) {
		// TODO Auto-generated method stub
		if (evt.getSource()==jbWorkingDir) { chooseWorkingDir(); }
		if (evt.getSource()==jbEraseTemp)
		{
			
			File path = new File (ConfigNat.getUserTempFolder());
			
			Boolean resultat = deleteDirectory(path);
			
			if (resultat)
			{
				JOptionPane.showMessageDialog(null,"Fichiers temporaires effacés.\n" +
	    				"Veuillez redémarrer NAT pour regénérer les bons fichiers.","Information",JOptionPane.INFORMATION_MESSAGE);
			}
			else
			{
				JOptionPane.showMessageDialog(null,"Impossible de supprimer les fichiers temporaires.\n" +
	    				"Veuillez le faire \"à la main\"","Erreur",JOptionPane.ERROR_MESSAGE);
			}
		}
	}
}
