/*
 * 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 nat;

import gestionnaires.GestionnaireErreur;

import java.io.FileInputStream;
//import java.io.InputStreamReader;
import java.nio.channels.FileChannel;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
//import java.io.InputStream;
import java.io.Serializable;
import java.util.Properties;
import nat.OptNames;
import java.lang.Boolean;
import java.lang.Integer;
import java.io.File;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import outils.FileToolKit;
import outils.HyphenationToolkit;
import outils.regles.RulesToolKit;


/**
 * Cette classe contient l'ensemble des paramètres de configuration de NAT et
 * gère la sauvegarde et la récupération des différentes configurations
 * @author Bruno Mascret
 */
public class ConfigNat implements Serializable
{
    /** Filter Properties */
    private Properties fiConf;
    /** UI Properties */
    private Properties uiConf;
    /** UI configuration filename */
    private static final String uiConfFilename = "nat-gui.conf";
	/** filters (conf files) directory */
    private static final String dirFilters = "filters/";
	/** tmp directory */
    private static final String dirTmp = "tmp/";
	/** tables braille user */
    private static final String dirTablesBraille = "tablesBraille/";
	/** tables embosseuses user */
    private static final String dirTablesEmboss = "tablesEmbosseuse/";
    
    

    /** serial version UID */
    private static final long serialVersionUID = 1L;

    /** constante pour représenter le mode garder toutes les lignes vides */
    public static final int AllEmptyLinesMode = -1;
    /** constante pour représenter le mode supprimer toutes les lignes vides */
    public static final int NoEmptyLinesMode = 0;
    /** constante pour représenter le mode de gestion paramétrée des lignes vides */
    public static final int ParametricEmptyLinesMode = 1;
    /** constante contenant l'adresse du dico de coupure par défaut */
	private static final String dicoCoupDefautName = ConfigNat.getInstallFolder()+"xsl/dicts/hyph_fr_nat.dic";

    /** Le fichier contenant la configuration */
    private String fichierConf;
	
    //************* configuration générale **************
    /** Numéro de version */
    private static final String version = "2.0rc3";
    /** Nom de version long */
    private static final String versionLong = "2.0rc3 (svn r1449) La Détranscription à l'Honneur";
    /** Nom de la version svn correspondante */
	private static final int svnVersion = 1449;

    //************* configuration des fichiers E/S ********
    /** adresse du dernier fichier source utilisé */
    private String fichNoir="";
    /** adresse du dernier fichier cible (sortie) utilisé */
    private String fichBraille="";
    /** encoding du fichier source */
    private String sourceEncoding="automatique";
    /** encoding du fichier de sortie */
    private String sortieEncoding="UTF-8";
    /** l'instance singleton de ConfigNat*/  
    private static ConfigNat cn=null;
    
    /**
     * Constructor
     * Creates user-specific configuration folders
     */
    private ConfigNat()
    {
    	/* constructeur statique vide */
    }
 
	
    /**
     * @return the path of the system-wide configuration filters folder
     */
    public static String getSystemConfigFilterFolder()
    {
		String scf = getInstallFolder()+"configurations/";
		return scf;
    }
    /**
     * @return the path of the user-specific configuration folder 
     */
    public static String getUserConfigFolder()
    {
			return FileToolKit.getSysDepPath(ConfigNat.getWorkingDir());
			//return ucf.getPath();
    		//return new File(System.getProperty("user.home")+"/.nat-braille/").getAbsolutePath()+"/";
    }
  
    /**
     * @return the path of the user-specific configuration filters folder 
     */
    public static String getUserConfigFilterFolder()
    {
		//String ucf = getUserConfigFolder() + "filters/";
		return getUserConfigFolder()+dirFilters;
    }
    
    /**
     * @return the path of the user-specific temporary folder 
     */
    public static String getUserTempFolder()
    {
		/*String ucf = getUserConfigFolder() + "tmp/";
		return ucf;*/
		return getUserConfigFolder()+dirTmp;
    }
    
    /**
     * @return the path of the user-specific braille table folder 
     */
    public static String getUserBrailleTableFolder()
    {
		/*String ucf = getUserConfigFolder() + "tablesBraille/";
		return ucf;*/
    	return getUserConfigFolder()+dirTablesBraille;
    }
    
    /**
     * @return the path of the user-specific embossing table folder 
     */
    public static String getUserEmbossTableFolder()
    {
		/*String ucf = getUserConfigFolder() + "tablesEmbosseuse/";
		return ucf;*/
		return getUserConfigFolder()+dirTablesEmboss;
    }
    
    /**
     * @return the path of install folder 
     */
    public static String getInstallFolder()
    {
		return FileToolKit.getSysDepPath("");
    }
	
    /** nom par défaut du fichier temporaire tan */
    public static final String fichTmpTan = getUserTempFolder() + "nouveau.tan" ;
    
    /*
     * Méthodes d'accès
     */
	
    /* général */

    /** @return {@link #versionLong} */
    public static String getVersionLong(){return versionLong;}
    /** @return {@link #version}*/
    public static String getVersion(){return version;}
    /** @return {@link #svnVersion}*/
    public static int getSvnVersion() {return svnVersion;}
    
    /** @return true si vérification en ligne l'existence d'une nouvelle version */
    public boolean getUpdateCheck(){ return new Boolean(fiConf.getProperty(OptNames.ge_check_update,"true")).booleanValue();}
    /** @param uc true si vérification en ligne l'existence d'une nouvelle version */
    public void setUpdateCheck(boolean uc){ fiConf.setProperty(OptNames.ge_check_update,Boolean.toString(uc));}

    /* Fichiers E/S */
    /** @return {@link #fichNoir}*/
    public String getFichNoir(){return fichNoir;}
    /** @param fNoir valeur pour {@link #fichNoir}*/
    public void setFNoir(String fNoir){fichNoir = fNoir;}
    /** @return {@link #fichBraille}*/
    public String getFBraille(){return fichBraille;}
    /** @param fc valeur pour {@link #fichBraille}*/
    public void setFBraille(String fc){fichBraille = fc;}
    /** @param f valeur pour {@link #fichierConf}*/
    public void setFichierConf(String f){fichierConf = f;}
    /** @return {@link #fichierConf}*/
    public String getFichierConf(){return fichierConf;}
    /** @return le nom court de la configuration courante, par exemple default */
    public String getShortFichierConf()
    {
	    String name = (new File(fichierConf).getName());
	    return name;
    }
    /* Filter Configuration */
    /** @return version de configuration  */
    public String getConfVersion(){return fiConf.getProperty(OptNames.conf_version,"0");}
    /** @param v version de configuration  */
    public void setConfVersion(String v) {fiConf.setProperty(OptNames.conf_version, v);}
    /** @return encodage du fichier noir*/
    public String getNoirEncoding(){return fiConf.getProperty(OptNames.en_in,"UTF-8");}
    /** @param se valeur pour l'encodage du fichier noir*/
    public void setNoirEncoding(String se){fiConf.setProperty(OptNames.en_in, se);}
    /** @return encodage du fichier braille*/
    public String getBrailleEncoding(){return fiConf.getProperty(OptNames.en_out,"UTF-8");}
    /** @param se valeur pour l'encodage du fichier braille*/
    public void setBrailleEncoding(String se){fiConf.setProperty(OptNames.en_out, se);}
    
    /** @param lg valeur pour le niveau de log*/
    public void setNiveauLog(int lg){fiConf.setProperty(OptNames.ge_log_verbosity, (new Integer(lg)).toString());}
    /**
     * Change le niveau de log et répercute la modification au GestionnaireErreur ge
     * @param lg le nouveau niveau de log
     * @param ge le gestionnaire à mettre à jour
     */
    public void setNiveauLog(int lg, GestionnaireErreur ge)
    {
    	fiConf.setProperty(OptNames.ge_log_verbosity, (new Integer(lg)).toString());
    	if(ge != null){ge.setNiveauLog(lg);}
    }
    /** @return le niveau de log*/
    public int getNiveauLog(){return ((new Integer(fiConf.getProperty(OptNames.ge_log_verbosity,"1"))).intValue());}
    /** @return adresse de la dtd */
    public String getDTD(){return (fiConf.getProperty(OptNames.fi_dtd_filename,getInstallFolder()+"xsl/mmlents/windob.dtd"));}
    //public String getDTD(){return (getInstallFolder()+"xsl/mmlents/windob.dtd");}
    /** @param dtd valeur pour adresse de la dtd*/
    public void setDTD(String dtd){fiConf.setProperty(OptNames.fi_dtd_filename,dtd);} 
    /** @return adresse de la feuille xsl principale de transcription*/
    public String getXSL(){return (fiConf.getProperty(OptNames.fi_filter_filename,getUserTempFolder()+"xsl.xsl"));}
    //public String getXSL(){return (getUserTempFolder()+"xsl.xsl");}
    /** @param xslfn valeur pour l'adresse de la feuille xsl principale de transcription*/
    public void setXSL(String xslfn){fiConf.setProperty(OptNames.fi_filter_filename,xslfn);}
    /** @return le nom de la table Braille utilisée*/
    public String getTableBraille(){return (fiConf.getProperty(OptNames.fi_braille_table,"brailleUTF8.ent"));}
    /**
     * Met à jour le nom de la table braille et copie la nouvelle table dans les
     * fichiers Brltab.ent et tmp/Table_pour_chaines.ent (comme une table embosseuse)
     * méthode d'accès
     * @param tableBraille le nom de la table braille à utiliser
     * @param sys true si table système
     */
    public void setTableBraille(String tableBraille, boolean sys)
    {
		fiConf.setProperty(OptNames.fi_braille_table,tableBraille);
		fiConf.setProperty(OptNames.fi_is_sys_braille_table, Boolean.toString(sys));
		FileChannel in = null; // canal d'entrée
		FileChannel out = null; // canal de sortie
		try 
		{
			// Init
			String fichTable;
			if (!(tableBraille.endsWith(".ent"))){tableBraille=tableBraille+".ent";}
			if(sys){fichTable = ConfigNat.getInstallFolder()+"xsl/tablesBraille/"+tableBraille;}
			else{fichTable = ConfigNat.getUserBrailleTableFolder()+tableBraille;}
			in = new FileInputStream(fichTable).getChannel();
			out = new FileOutputStream(getUserBrailleTableFolder()+"Brltab.ent").getChannel();
			
			// Copie depuis le in vers le out
			in.transferTo(0, in.size(), out);
			in.close();
			out.close();
			
		}
		catch (IOException e){e.printStackTrace();} // n'importe quelle exception
		
		// Copie de la table équivalente embosseuse vers tmp/Table_pour_chaines.ent
		try 
	    {
	    	String fichTable;
			if(sys){fichTable = ConfigNat.getInstallFolder()+"/xsl/tablesEmbosseuse/"+tableBraille;}
			else{fichTable = ConfigNat.getUserEmbossTableFolder()+"/"+tableBraille;}
			in = new FileInputStream(fichTable).getChannel();
		    out = new FileOutputStream(ConfigNat.getUserTempFolder()+"Table_pour_chaines.ent").getChannel();
			
		    // Copie depuis le in vers le out
		    in.transferTo(0, in.size(), out);
		    in.close();
		    out.close();
	    }
	    catch (IOException e){e.printStackTrace();} // n'importe quelle exception}
    }
    /** @return true si Table Braille système */
    public boolean getIsSysTable() {return new Boolean(fiConf.getProperty(OptNames.fi_is_sys_braille_table,"true")).booleanValue();}
    /** @param a vrai si la table braille est une table système*/
    public void setIsSysTable(boolean a){fiConf.setProperty(OptNames.fi_is_sys_braille_table,Boolean.toString(a));}
    /** @return true si Table Braille système */
    public boolean getIsSysEmbossTable() {return new Boolean(fiConf.getProperty(OptNames.fi_is_sys_emboss_table,"true")).booleanValue();}
    /** @param a vrai si la table braille est une table système*/
    public void setIsSysEmbossTable(boolean a){fiConf.setProperty(OptNames.fi_is_sys_emboss_table,Boolean.toString(a));}
    /** @return nom de la configuration*/
    public String getName(){return (fiConf.getProperty(OptNames.fi_name,"* base *"));}
    /** @param name valeur pour le nom de la configuration*/
    public void setName(String name){fiConf.setProperty(OptNames.fi_name,name);}
    /** @return description de la configuration*/
    public String getInfos(){return (fiConf.getProperty(OptNames.fi_infos,"* configuration de base  * "));}    
    /** @param infos valeur pour la description de la configuration*/
    public void setInfos(String infos){fiConf.setProperty(OptNames.fi_infos,infos);}
    /** @return vrai si la configuration est une configuration système*/
    public boolean getIsSysConfig(){return ((new Boolean(fiConf.getProperty(OptNames.fi_is_sys_config,"false"))).booleanValue()); }
    /** @param a vrai si la configuration est une configuration système*/
    public void setIsSysConfig(boolean a){fiConf.setProperty(OptNames.fi_is_sys_config,Boolean.toString(a));}
    /** @return true if optimization enabled */
	public boolean getOptimize() {return ((new Boolean(fiConf.getProperty(OptNames.fi_optimize,"false"))).booleanValue()); }
	/** @param o vrai si activation des optimisations*/
    public void setOptimize(boolean o){fiConf.setProperty(OptNames.fi_optimize,Boolean.toString(o));}
    
	/** @return renvoit vrai si détranscription, faux si transcription */
    public boolean isReverseTrans(){return ((new Boolean(uiConf.getProperty(OptNames.ui_reverse_trans,"false"))).booleanValue());}
    /** @param r vrai si transcription inverse*/
    public void setReverseTrans(boolean r){uiConf.setProperty(OptNames.ui_reverse_trans,Boolean.toString(r));}
    
    /** @return vrai si abreger*/
    public boolean getAbreger(){return ((new Boolean(fiConf.getProperty(OptNames.fi_litt_abbreg,"false"))).booleanValue()); }
    /** @param a valeur pour abreger*/
    public void setAbreger(boolean a){fiConf.setProperty(OptNames.fi_litt_abbreg,Boolean.toString(a));}
    /** @return vrai si traiter maths */
    public boolean getTraiterMaths(){return ((new Boolean(fiConf.getProperty(OptNames.fi_math_transcribe,"true"))).booleanValue()); }
    /** @param m traiter maths*/
    public void setTraiterMaths(boolean m){fiConf.setProperty(OptNames.fi_math_transcribe,Boolean.toString(m));}
    /** @return vrai si traiter littéraire */
    public boolean getTraiterLiteraire(){return ((new Boolean(fiConf.getProperty(OptNames.fi_litt_transcribe,"true"))).booleanValue());}
    /** @param l traiter littéraire */
    public void setTraiterLiteraire(boolean l){fiConf.setProperty(OptNames.fi_litt_transcribe,Boolean.toString(l));}
    /** @return traiter musique */
    public boolean getTraiterMusique(){return ((new Boolean(fiConf.getProperty(OptNames.fi_music_transcribe,"true"))).booleanValue()); }
    /** @param m traiter musique*/
    public void setTraiterMusique(boolean m){fiConf.setProperty(OptNames.fi_music_transcribe,Boolean.toString(m));}
    
    /** @return utilisation de la notation spécifique trigo */
    public boolean getMathTrigoSpec(){return ((new Boolean(fiConf.getProperty(OptNames.fi_math_use_trigo_spec,"true"))).booleanValue()); }
    /** @param m utilisation de la notation spécifique trigo */
    public void setMathTrigoSpec(boolean m){fiConf.setProperty(OptNames.fi_math_use_trigo_spec,Boolean.toString(m));}
    /** @return true si préfixage systématique des maths */
    public boolean getMathPrefixAlways() {return ((new Boolean(fiConf.getProperty(OptNames.fi_math_force_prefix,"false"))).booleanValue());}
    /** @param mp true si préfixage systématique des maths */
    public void setMathPrefixAlways(boolean mp){fiConf.setProperty(OptNames.fi_math_force_prefix,Boolean.toString(mp));}
    
    /** @param lg longueur de la ligne */
    public void setLongueurLigne(int lg){fiConf.setProperty(OptNames.fi_line_lenght, (new Integer(lg)).toString());}
    /** @return longueur de la ligne */
    public int getLongueurLigne(){return ((new Integer(fiConf.getProperty(OptNames.fi_line_lenght,"40"))).intValue());}
    /** @param ln nombre de lignes par page*/
    public void setNbLigne(int ln){fiConf.setProperty(OptNames.fi_line_number, (new Integer(ln)).toString());}
    /** @return nombre de lignes par page*/
    public int getNbLigne(){return ((new Integer(fiConf.getProperty(OptNames.fi_line_number,"40"))).intValue());}
    /** @param m activer la mise en page*/
    public void setMep(boolean m) {fiConf.setProperty(OptNames.pf_do_layout,Boolean.toString(m));}
    /** @return activer la mise en page*/
    public boolean getMep(){return ((new Boolean(fiConf.getProperty(OptNames.pf_do_layout,"true"))).booleanValue()); }
    /** @param c coupure active*/
    public void setCoupure(boolean c){fiConf.setProperty(OptNames.fi_hyphenation,Boolean.toString(c));	}
    /** @return coupure active */
    public boolean getCoupure(){return ((new Boolean(fiConf.getProperty(OptNames.fi_hyphenation,"true"))).booleanValue()); }
    
    /**@param c coupure littéraire*/
    public void setCoupureLit(boolean c){fiConf.setProperty(OptNames.fi_hyphenation_lit,Boolean.toString(c));	}
    /**@return coupure littéraire*/
    public boolean getCoupureLit(){return ((new Boolean(fiConf.getProperty(OptNames.fi_hyphenation_lit,"false"))).booleanValue()); }
    /**@param m mode sagouin*/
    public void setModeCoupureSagouin(boolean m){fiConf.setProperty(OptNames.fi_hyphenation_dirty,Boolean.toString(m));}
    /**@return mode sagouin*/
    public boolean getModeCoupureSagouin(){return ((new Boolean(fiConf.getProperty(OptNames.fi_hyphenation_dirty,"false"))).booleanValue());}
    /** @return adresse dico de coupure */
    public String getDicoCoup(){return (fiConf.getProperty(OptNames.fi_hyphenation_rulefile_name,getInstallFolder()+"xsl/dicts/hyph_fr_nat.dic"));} 
    /** @param dc adresse dico de coupure*/
    public void setDicoCoup(String dc){fiConf.setProperty(OptNames.fi_hyphenation_rulefile_name,dc);}
    //public String getDicoDesc(){return (fiConf.getProperty(OptNames.fi_hyphenation_rulefile_desc,"Dictionnaire Open-Office, v2.0, 18/03/08"));} 
    //public void setDicoDesc(String dd){fiConf.setProperty(OptNames.fi_hyphenation_rulefile_desc,dd);}
    /** @return feuille pour g1*/
    public String getXSL_g1(){return (fiConf.getProperty(OptNames.fi_litt_fr_int_filter_filename,getInstallFolder()+"xsl/fr-g1.xsl"));}
    //public String getXSL_g1(){return (getInstallFolder()+"xsl/fr-g1.xsl");}
    /** @param filename feuilel pour g1*/
    public void setXSL_g1(String filename){fiConf.setProperty(OptNames.fi_litt_fr_int_filter_filename,filename);}
    /** @return feuille pour g2*/
    public String getXSL_g2(){return (fiConf.getProperty(OptNames.fi_litt_fr_abbreg_filter_filename,getInstallFolder()+"xsl/fr-g2.xsl"));}    
    //public String getXSL_g2(){return (getInstallFolder()+"xsl/fr-g2.xsl");}
    /** @param filename feuilel pour g2*/
    public void setXSL_g2(String filename){fiConf.setProperty(OptNames.fi_litt_fr_abbreg_filter_filename,filename);}
    /**
     * Renvoie l'adresse du fichier de règle d'abrégé de l'utilisateur;
     * Si ce fichier n'existe pas, le fabrique à partir du fichier de référence
     * @return l'adresse du fichier de règles d'abrégé 
     * TODO: permettre le paramétrage plus fin et l'utilisation de fichiers différents
     */
    public String getXSL_g2_Rules()
    {
    	String adresse = fiConf.getProperty(OptNames.fi_litt_fr_abbreg_rules_filter_filename,getUserTempFolder()+"fr-g2-rules.xsl");
    	if(!new File(adresse).exists())//le fichier n'existe pas
    	{
    		//création du fichier
    		System.err.println("Pas de fichier xsl de règles pour l'abrégé; création à partir du fichier utilisateur");
    		RulesToolKit.writeRules(RulesToolKit.getRules(new File(getRulesFrG2Perso()).toURI().toString()));
    	}
		return adresse;
	}
    
    /** @return renvoie l'adresse du fichier XML de règles de référence */
    public String getRulesFrG2() {return fiConf.getProperty(OptNames.fi_litt_fr_abbreg_rules_filename,getInstallFolder()+"xsl/dicts/fr-g2.xml");}
    
    /** @return renvoie l'adresse du fichier XML de règles de l'utilisateur ou le fichier de référence si ce dernier n'existe pas */
    public String getRulesFrG2Perso(){return fiConf.getProperty(OptNames.fi_litt_fr_abbreg_rules_filename_perso,getInstallFolder()+"xsl/dicts/fr-g2.xml");}
    /** @param rulesFrG2Perso adresse du fichier XML de règles de l'utilisateur, situé dans le répertoire temporaire de l'utilisateur*/
    public void setRulesFrG2Perso(String rulesFrG2Perso) {fiConf.setProperty(OptNames.fi_litt_fr_abbreg_rules_filename_perso, new File(rulesFrG2Perso).getAbsolutePath());}
    
    /** @return feuille pour maths*/
    public String getXSL_maths(){return (fiConf.getProperty(OptNames.fi_math_filter_filename,getInstallFolder()+"xsl/fr-maths.xsl"));}
    //public String getXSL_maths(){return (getInstallFolder()+"xsl/fr-maths.xsl");}
    /** @param filename feuilel pour maths*/
    public void setXSL_maths(String filename){fiConf.setProperty(OptNames.fi_math_filter_filename,filename);}
    /** @return feuille pour musique*/
    public String getXSL_musique(){return (fiConf.getProperty(OptNames.fi_music_filter_filename,getInstallFolder()+"xsl/musique.xsl"));}    
    //public String getXSL_musique(){return (getInstallFolder()+"xsl/musique.xsl");}
    /** @param filename feuilel pour musique*/
    public void setXSL_musique(String filename){fiConf.setProperty(OptNames.fi_music_filter_filename,filename);}
    /** @return LitMajDouble*/
    public boolean getLitMajDouble(){return ((new Boolean(fiConf.getProperty(OptNames.tr_litt_double_upper,"true"))).booleanValue());}
    /** @param lmd LitMajDouble*/
    public void setLitMajDouble(boolean lmd){fiConf.setProperty(OptNames.tr_litt_double_upper,Boolean.toString(lmd));}
    /** @return LitMajPassage*/
    public boolean getLitMajPassage(){return ((new Boolean(fiConf.getProperty(OptNames.tr_litt_part_upper,"true"))).booleanValue());}
    /** @param lmp LitMajPassage*/
    public void setLitMajPassage(boolean lmp){fiConf.setProperty(OptNames.tr_litt_part_upper,Boolean.toString(lmp));}
    /** @return LitMajMelange*/
    public boolean getLitMajMelange(){return ((new Boolean(fiConf.getProperty(OptNames.tr_litt_mixed_upper,"true"))).booleanValue());}
    /** @param lmp LitMajMelange*/
    public void setLitMajMelange(boolean lmp){fiConf.setProperty(OptNames.tr_litt_mixed_upper,Boolean.toString(lmp));}
    /** @return LitEvidenceMot*/
    public boolean getLitEvidenceMot(){return ((new Boolean(fiConf.getProperty(OptNames.tr_litt_word_emph,"true"))).booleanValue());}
    /** @param lmp LitEvidenceMot*/
    public void setLitEvidenceMot(boolean lmp){fiConf.setProperty(OptNames.tr_litt_word_emph,Boolean.toString(lmp));}
    /** @return LitEvidencePassage*/
    public boolean getLitEvidencePassage(){return ((new Boolean(fiConf.getProperty(OptNames.tr_litt_part_emph,"true"))).booleanValue());}
    /** @param lmp LitEvidencePassage*/
    public void setLitEvidencePassage(boolean lmp){fiConf.setProperty(OptNames.tr_litt_part_emph,Boolean.toString(lmp));}
    /** @return LitEvidenceDansMot*/
    public boolean getLitEvidenceDansMot(){return ((new Boolean(fiConf.getProperty(OptNames.tr_litt_in_word_emph,"true"))).booleanValue());}
    /** @param lmp LitEvidenceDansMot*/
    public void setLitEvidenceDansMot(boolean lmp){fiConf.setProperty(OptNames.tr_litt_in_word_emph,Boolean.toString(lmp));}
    /** @return true if images are transcripted into braille*/
    public boolean getTranscrireImages() {return ((new Boolean(fiConf.getProperty(OptNames.tr_image_processing,"false"))).booleanValue());}
    /** @param ti true if images must be transcripted into braille*/
    public void setTranscrireImages(boolean ti) {fiConf.setProperty(OptNames.tr_image_processing,Boolean.toString(ti));}
    /** @param imd adresse du répertoire d'installation d'image magick*/
	public void setImageMagickDir(String imd) {fiConf.setProperty(OptNames.tr_image_magick_dir,imd);}
	/** @return l'adresse du répertoire d'installation de Image Magick*/
    public String getImageMagickDir(){return fiConf.getProperty(OptNames.tr_image_magick_dir,"");}
    /** @param nta Niveau de titre à partir duquel on abrège */
    public void setNiveauTitreAbrege(int nta){fiConf.setProperty(OptNames.tr_min_title_contracted, ""+nta);}
    /** @return le niveau de titre à partir duquel on abrège */
    public int getNiveauTitreAbrege(){return Integer.parseInt(fiConf.getProperty(OptNames.tr_min_title_contracted, "1"));}
    
    /** @return MepModelignes*/
    public int getMepModelignes(){return ((new Integer(fiConf.getProperty(OptNames.pf_empty_line_mode,"3"))).intValue());}
    /** @param mml MepModelignes*/
    public void setMepModelignes(int mml){fiConf.setProperty(OptNames.pf_empty_line_mode, (new Integer(mml)).toString());}
	/** @return MepMinLigne1*/
    public int getMepMinLigne1(){return ((new Integer(fiConf.getProperty(OptNames.pf_min_empty_line_1,"2"))).intValue());}
    /** @param mml1 MepMinLigne1*/
    public void setMepMinLigne1(int mml1){fiConf.setProperty(OptNames.pf_min_empty_line_1, (new Integer(mml1)).toString());}
	/** @return MepMinLigne2*/
    public int getMepMinLigne2(){return ((new Integer(fiConf.getProperty(OptNames.pf_min_empty_line_2,"3"))).intValue());}
    /** @param mml2 MepMinLigne2*/
    public void setMepMinLigne2(int mml2){fiConf.setProperty(OptNames.pf_min_empty_line_2, (new Integer(mml2)).toString());}
	/** @return MepMinLigne3*/
    public int getMepMinLigne3(){return ((new Integer(fiConf.getProperty(OptNames.pf_min_empty_line_3,"4"))).intValue());}
    /** @param mml3 MepMinLigne3*/
    public void setMepMinLigne3(int mml3){fiConf.setProperty(OptNames.pf_min_empty_line_3, (new Integer(mml3)).toString());}
    /** @return MepMinLignePB*/
    public int getMepMinLignePB(){return ((new Integer(fiConf.getProperty(OptNames.pf_min_page_break,"5"))).intValue());}
    /** @param mmlpb MepMinLignePB*/
    public void setMepMinLignePB(int mmlpb){fiConf.setProperty(OptNames.pf_min_page_break, (new Integer(mmlpb)).toString());}
	/** @return GeneratePB*/
    public boolean getGeneratePB() {return ((new Boolean(fiConf.getProperty(OptNames.pf_generate_page_break,"false"))).booleanValue());}
    /** @param sgpb GeneratePB*/
    public void setGeneratePB(boolean sgpb){fiConf.setProperty(OptNames.pf_generate_page_break,Boolean.toString(sgpb));}
	/** @return SautPageFin*/
    public boolean getSautPageFin() {return ((new Boolean(fiConf.getProperty(OptNames.pf_add_form_feed,"true"))).booleanValue());}
    /** @param spf SautPageFin*/
    public void setSautPageFin(boolean spf){fiConf.setProperty(OptNames.pf_add_form_feed,Boolean.toString(spf));}
    /** @param n Numerotation*/
    public void setNumerotation(String n) {fiConf.setProperty(OptNames.pf_numbering_style,n);}
	/** @return Numerotation*/
    public String getNumerotation() {return fiConf.getProperty(OptNames.pf_numbering_style,"'nn'");}
    /** @param snf NumeroteFirst*/
    public void setNumeroteFirst(boolean snf) {fiConf.setProperty(OptNames.pf_number_first_page,Boolean.toString(snf));}
	/** @return NumeroteFirst*/
    public boolean getNumeroteFirst() {return ((new Boolean(fiConf.getProperty(OptNames.pf_number_first_page ,"false"))).booleanValue());}
	
    /** @return TitresStricts*/
    public boolean getTitresStricts() {return ((new Boolean(fiConf.getProperty(OptNames.pf_strict_titles,"true"))).booleanValue());}
    /** @param ts TitresStricts*/
    public void setTitresStricts(boolean ts) {fiConf.setProperty(OptNames.pf_strict_titles,Boolean.toString(ts));}
	/** @return NiveauxTitres*/
    public String getNiveauxTitres() {return fiConf.getProperty(OptNames.pf_titles_levels,"1,2,3,4,5,5,5,5,5");}
    /** @param levels NiveauxTitres
     * @throws NumberFormatException problème de format du niveau de titre*/
    public void setNiveauxTitres(String levels) throws NumberFormatException
	{
		int i=0;
		String[] decoup = levels.split(",");
		try{for(i=0;i<decoup.length;i++){Integer.parseInt(decoup[i]);}}
		catch(NumberFormatException nfe){throw nfe;}
		fiConf.setProperty(OptNames.pf_titles_levels,levels);
	}
	
	/*public int getMepRetraitPar(){return ((new Integer(fiConf.getProperty(OptNames.pf_par_indent,"2"))).intValue());}
	public void setMepRetraitPar(int mrp){fiConf.setProperty(OptNames.pf_par_indent, (new Integer(mrp)).toString());}*/
	/** @return LineariseTable*/
    public boolean getLineariseTable() {return ((new Boolean(fiConf.getProperty(OptNames.pf_linearise_table,"false"))).booleanValue());}
    /** @param lt LineariseTable*/
    public void setLineariseTable(boolean lt) {fiConf.setProperty(OptNames.pf_linearise_table,Boolean.toString(lt));}
    /** @param mcl MinCellLin*/
    public void setMinCellLin(int mcl) {fiConf.setProperty(OptNames.pf_min_cell_linearise,Integer.toString(mcl));}
	/** @return MinCellLin*/
    public int getMinCellLin() {return ((new Integer(fiConf.getProperty(OptNames.pf_min_cell_linearise,"4"))).intValue());}
 /**
     * Splits a string using a separator which is regarded as a single caracter if doubled
     * @return a String[] of splited values
     * @param  s   : the string
     * @param  sep : the separator
     */
    static public String[] intelliSplit(String s,String sep)
    {
		ArrayList<String> z = new ArrayList<String>();
		String curString="";
		String[] ca = s.split(""); // each letter is an array element
		int i=0;
		while (i<(ca.length-1))
		{
		    String c = ca[i];
		    String n = ca[i+1];
		    if (c.equals(sep))
		    {
				if (n.equals(sep))
				{ // double separateur => caractere simple
				    curString += c; 
				    i++;
				}
				else 
				{            // veritable separateur => nouvelle string
				    z.add(curString);
				    curString = new String();
				}
		    }
		    else{ curString += c;}// caractere normal
		    i++;
		}
		// dernier element
		if (i<=ca.length){curString += ca[i];}
		z.add(curString);
		return z.toArray(new String[0]);
    }
    /** @return Rajout*/
    public String getRajout() {return fiConf.getProperty(OptNames.pf_strings_addons,"'','','','','','','','','','','',''");}
    /** @param r Rajout*/
    public void setRajout(String r) {fiConf.setProperty(OptNames.pf_strings_addons,r);}
	/** @return RajoutCompte*/
    public String getRajoutCompte() {return fiConf.getProperty(OptNames.pf_strings_addons_count,"false,false,false,false,false,false,false,false,false,false,false,false");}
    /** @param rc RajoutCompte*/
    public void setRajoutCompte(String rc) {fiConf.setProperty(OptNames.pf_strings_addons_count,rc);}
    /** @return Chaine_in*/
    public String getChaineIn() {return fiConf.getProperty(OptNames.pf_string_replace_in,"");}
    /** @param ci Chaine_in*/
    public void setChaineIn(String ci) {fiConf.setProperty(OptNames.pf_string_replace_in,ci);}
	/** @return Chaine_out*/
    public String getChaineOut() {return fiConf.getProperty(OptNames.pf_string_replace_out,"");}
    /** @param co Chaine_out*/
    public void setChaineOut(String co) {fiConf.setProperty(OptNames.pf_string_replace_out,co);}
    
    /* Options graphiques mais dépendantes de la configuration 
     * Graphical options but depending of the current configuration
     * */
    /** @param pe PoliceEditeur*/
    public void setPoliceEditeur(String pe){fiConf.setProperty(OptNames.ui_editor_font,pe);}
    /** @return PoliceEditeur*/
    public String getPoliceEditeur(){return (fiConf.getProperty(OptNames.ui_editor_font,"Braille Antoine"));}
    /** @param pe2 PoliceEditeur2*/
    public void setPolice2Editeur(String pe2){fiConf.setProperty(OptNames.ui_editor_font2,pe2);}
    /** @return PoliceEditeur2*/
    public String getPolice2Editeur(){return (fiConf.getProperty(OptNames.ui_editor_font2,"Courrier"));}
    /** @param t TaillePolice*/
    public void setTaillePolice(int t){fiConf.setProperty(OptNames.ui_editor_font_size, (new Integer(t)).toString());}
    /** @return TaillePolice*/
    public int getTaillePolice(){return ((new Integer(fiConf.getProperty(OptNames.ui_editor_font_size,"24"))).intValue());}
    /** @param tp2 TaillePolice2*/
    public void setTaillePolice2(int tp2){fiConf.setProperty(OptNames.ui_editor_font2_size,(new Integer(tp2)).toString());}
    /** @return TaillePolice2*/
    public int getTaillePolice2(){return ((new Integer(fiConf.getProperty(OptNames.ui_editor_font2_size,"24"))).intValue());}
    
    /** @param saxp SaxonAsXsltProcessor*/
    public void setSaxonAsXsltProcessor(boolean saxp){fiConf.setProperty(OptNames.tr_use_saxon_processor,Boolean.toString(saxp));}
    /** @return SaxonAsXsltProcessor*/
    public boolean getSaxonAsXsltProcessor(){return new Boolean(fiConf.getProperty(OptNames.tr_use_saxon_processor,"true")).booleanValue();}
    /** @param nlf NbLogFiles*/
    public void setNbLogFiles(int nlf) {fiConf.setProperty(OptNames.ad_nb_log_files,Integer.toString(nlf));}
	/** @return NbLogFiles*/
    public int getNbLogFiles() {return ((new Integer(fiConf.getProperty(OptNames.ad_nb_log_files,"3"))).intValue());}
    /** @param lfs LogFileSize*/
    public void setLogFileSize(int lfs) {fiConf.setProperty(OptNames.ad_log_file_size,Integer.toString(lfs));}
	/** @return LogFileSize*/
    public int getLogFileSize() {return ((new Integer(fiConf.getProperty(OptNames.ad_log_file_size,"10"))).intValue());}
	
    /** GUI options **/
    /** @param o OuvreEditeurApresTranscription*/
    public void setOuvreEditeurApresTranscription(boolean o){uiConf.setProperty(OptNames.ui_editor_auto_open,Boolean.toString(o));}
    /** @return OuvreEditeurApresTranscription*/
    public boolean getOuvrirEditeur(){return ((new Boolean(uiConf.getProperty(OptNames.ui_editor_auto_open,"true"))).booleanValue());} 
    /** @return AfficheLigneSecondaire*/
    public boolean getAfficheLigneSecondaire(){return ((new Boolean(uiConf.getProperty(OptNames.ui_editor_zone2_display,"true"))).booleanValue());}
    /** @param als AfficheLigneSecondaire*/
    public void setAfficheLigneSecondaire(boolean als){uiConf.setProperty(OptNames.ui_editor_zone2_display,Boolean.toString(als));}
    /** @return Editeur*/
    public String getEditeur(){return fiConf.getProperty(OptNames.ui_editor_external,"");}
    /** @param e Editeur*/
    public void setEditeur(String e){fiConf.setProperty(OptNames.ui_editor_external,e);}
    /** @return UseNatEditor*/
    public boolean getUseNatEditor() {return new Boolean(fiConf.getProperty(OptNames.ui_editor_nat,"true")).booleanValue();}
    /** @param une UseNatEditor*/
    public void setUseNatEditor(boolean une) {fiConf.setProperty(OptNames.ui_editor_nat,""+une);}
	/** @return UseDefaultEditor*/
    public boolean getUseDefaultEditor() {return new Boolean(fiConf.getProperty(OptNames.ui_editor_default,"false")).booleanValue();}
    /** @param ude UseDefaultEditor*/
    public void setUseDefaultEditor(boolean ude) {fiConf.setProperty(OptNames.ui_editor_default,""+ude);}
    /*public String getConfDir(){return (uiConf.getProperty(OptNames.ui_editor_external,"configurations"));}    
    public void setConfDir(String dir){uiConf.setProperty(OptNames.ui_editor_external,dir);}*/
    

    /* remember last nat session  */
	/** @return LastSource*/
    public String getLastSource(){return (uiConf.getProperty(OptNames.last_source_filename,""));}    
    /** @param filename LastSource*/
    public void setLastSource(String filename){uiConf.setProperty(OptNames.last_source_filename,filename);}
    /** @return LastSourceEncoding*/
    public String getLastSourceEncoding(){return (uiConf.getProperty(OptNames.last_source_encoding,"automatique"));}    
    /** @param enc LastSourceEncoding*/
    public void setLastSourceEncoding(String enc){uiConf.setProperty(OptNames.last_source_encoding,enc);}
    /** @return LastDest*/
    public String getLastDest(){return (uiConf.getProperty(OptNames.last_dest_filename,""));}    
    /** @param filename LastDest*/
    public void setLastDest(String filename){uiConf.setProperty(OptNames.last_dest_filename,filename);}
    /** @return LastDestEncoding*/
    public String getLastDestEncoding(){return (uiConf.getProperty(OptNames.last_dest_encoding,"automatique"));}    
    /** @param enc LastDestEncoding*/
    public void setLastDestEncoding(String enc){uiConf.setProperty(OptNames.last_dest_encoding,enc);}
    /** @param conffn LastFilterConfigurationFilename*/
    public void setLastFilterConfigurationFilename(String conffn){uiConf.setProperty(OptNames.last_filter_configuration_filename,conffn);}
    /** @return LastFilterConfigurationFilename*/
    public String getLastFilterConfigurationFilename(){return (uiConf.getProperty(OptNames.last_filter_configuration_filename));}

    /* emboss */
    /** @param te table embossage
     * @param sys true si table système*/
    public void setTableEmbossage(String te, boolean sys)
    {
	    fiConf.setProperty(OptNames.pr_emboss_table,te);
	    fiConf.setProperty(OptNames.fi_is_sys_emboss_table, Boolean.toString(sys));
	    FileChannel in = null; // canal d'entrée
	    FileChannel out = null; // canal de sortie
	    
	    try 
	    {
	    	String fichTable;
	    	if (!(te.endsWith(".ent"))){te=te+".ent";}
			if(sys){fichTable = ConfigNat.getInstallFolder()+"/xsl/tablesEmbosseuse/"+te;}
			else{fichTable = ConfigNat.getUserEmbossTableFolder()+"/"+te;}
			in = new FileInputStream(fichTable).getChannel();
		    out = new FileOutputStream(ConfigNat.getUserEmbossTableFolder()+"/Embtab.ent").getChannel();
			
		    // Copie depuis le in vers le out
		    in.transferTo(0, in.size(), out);
		    in.close();
		    out.close();
	    }
	    catch (IOException e){e.printStackTrace();} // n'importe quelle exception}
    }
    /** @return table Embossage*/
    public String getTableEmbossage(){return (fiConf.getProperty(OptNames.pr_emboss_table,"brailleUTF8"));}
    /** @param o OS*/
    public void setOs(String o){fiConf.setProperty(OptNames.pr_os,o);}
    /** @return OS*/
    public String getOs(){return (fiConf.getProperty(OptNames.pr_os,"Linux"));}
    /** @param c Commande*/
    public void setCommande(String c){fiConf.setProperty(OptNames.pr_emboss_command,c);}
    /** @return Commande */
    public String getCommande(){return (fiConf.getProperty(OptNames.pr_emboss_command,""));}
    /** @return UtiliserCommandeEmbossage*/
    public boolean getUtiliserCommandeEmbossage(){return ((new Boolean(fiConf.getProperty(OptNames.pr_use_emboss_command,"false"))).booleanValue());}
    /** @param uce UtiliserCommandeEmbossage*/
    public void setUtiliserCommandeEmbossage(boolean uce){fiConf.setProperty(OptNames.pr_use_emboss_command,Boolean.toString(uce));}
    /** @return UtiliserEmbosseuse*/
    public boolean getUtiliserEmbosseuse() {return ((new Boolean(fiConf.getProperty(OptNames.pr_emboss_auto,"false"))).booleanValue());}
    /** @param uce UtiliserEmbosseuse*/
    public void setUtiliserEmbosseuse(boolean uce){fiConf.setProperty(OptNames.pr_emboss_auto,Boolean.toString(uce));}
    /** @param c print service*/
    public void setPrintService(String c)
    {
    	if(c!=null){fiConf.setProperty(OptNames.pr_emboss_print_service,c);}
    	else{fiConf.setProperty(OptNames.pr_emboss_print_service,"");}
    }
    /** @return nom du print service*/
    public String getPrintservice(){return (fiConf.getProperty(OptNames.pr_emboss_print_service,""));}
    /** @return MemoriserFenetre*/
    public boolean getMemoriserFenetre(){return new Boolean(uiConf.getProperty(OptNames.ui_remember_windows_size,"true")).booleanValue();}
    /** @param rms MemoriserFenetre*/
    public void setMemoriserFenetre(boolean rms){uiConf.setProperty(OptNames.ui_remember_windows_size,Boolean.toString(rms));}
    /** @return CentrerFenetre*/
    public boolean getCentrerFenetre() {return new Boolean(uiConf.getProperty(OptNames.ui_center_windows,"true")).booleanValue();}
    /** @param cf CentrerFenetre*/
    public void setCentrerFenetre(boolean cf){uiConf.setProperty(OptNames.ui_center_windows,Boolean.toString(cf));}
    /** @return HeightEditeur*/
    public int getHeightEditeur(){return new Integer(uiConf.getProperty(OptNames.ui_y_editor,"0").toString());}
    /** @param he HeightEditeur*/
    public void setHeightEditeur(int he){uiConf.setProperty(OptNames.ui_y_editor,""+he);}
    /** @return WidthEditeur*/
    public int getWidthEditeur(){return new Integer(uiConf.getProperty(OptNames.ui_x_editor,"0").toString());}
    /** @param we WidthEditeur*/
    public void setWidthEditeur(int we){uiConf.setProperty(OptNames.ui_x_editor,""+we);}
    /** @return MaximizedEditeur*/
    public boolean getMaximizedEditeur(){return new Boolean(uiConf.getProperty(OptNames.ui_max_editor,"false")).booleanValue();}
    /** @param me MaximizedEditeur */
    public void setMaximizedEditeur(boolean me){uiConf.setProperty(OptNames.ui_max_editor,""+me);}
    /** @return HeightPrincipal*/
    public int getHeightPrincipal(){return new Integer(uiConf.getProperty(OptNames.ui_y_princ,"0").toString());}
    /** @param hp HeightPrincipal*/
    public void setHeightPrincipal(int hp){uiConf.setProperty(OptNames.ui_y_princ,""+hp);}
    /** @return WidthPrincipal*/
    public int getWidthPrincipal(){return new Integer(uiConf.getProperty(OptNames.ui_x_princ,"0").toString());}
    /** @param wp WidthPrincipal*/
    public void setWidthPrincipal(int wp){uiConf.setProperty(OptNames.ui_x_princ,""+wp);}
    /** @return MaximizedPrincipal*/
    public boolean getMaximizedPrincipal(){return new Boolean(uiConf.getProperty(OptNames.ui_max_princ,"false")).booleanValue();}
    /** @param mp MaximizedPrincipal */
    public void setMaximizedPrincipal(boolean mp){uiConf.setProperty(OptNames.ui_max_princ,""+mp);}
    /** @return HeightOptions*/
    public int getHeightOptions(){return new Integer(uiConf.getProperty(OptNames.ui_y_options,"0").toString());}
    /** @param ho HeightOptions*/
    public void setHeightOptions(int ho){uiConf.setProperty(OptNames.ui_y_options,""+ho);}
    /** @return WidthOptions*/
    public int getWidthOptions(){return new Integer(uiConf.getProperty(OptNames.ui_x_options,"0").toString());}
    /** @param wo WidthOptions*/
    public void setWidthOptions(int wo){uiConf.setProperty(OptNames.ui_x_options,""+wo);}
    /** @return MaximizedOptions*/
    public boolean getMaximizedOptions(){return new Boolean(uiConf.getProperty(OptNames.ui_max_options,"false")).booleanValue();}
    /** @param mo MaximizedOptions */
    public void setMaximizedOptions(boolean mo){uiConf.setProperty(OptNames.ui_max_options,""+mo);}
    /** @return SonPendantTranscription*/
    public boolean getSonPendantTranscription(){return new Boolean(uiConf.getProperty(OptNames.ui_sound_during_work,"false")).booleanValue();}
    /** @param spt SonPendantTranscription*/
    public void setSonPendantTranscription(boolean spt){uiConf.setProperty(OptNames.ui_sound_during_work,""+spt);}
    /** @return SonFinTranscription*/
    public boolean getSonFinTranscription() {return new Boolean(uiConf.getProperty(OptNames.ui_sound_at_end,"false")).booleanValue();}
    /** @param sft SonFinTranscription*/
    public void setSonFinTranscription(boolean sft){uiConf.setProperty(OptNames.ui_sound_at_end,""+sft);}
    /** @return Nommer automatiquement le fichier de sortie*/
    public boolean getSortieAuto() {return new Boolean(uiConf.getProperty(OptNames.ui_output_file_auto,"false")).booleanValue();}
    /** @param sa true si nommer automatiquement le fichier de sortie*/
    public void setSortieAuto(boolean sa){uiConf.setProperty(OptNames.ui_output_file_auto,""+sa);}
    
    /** @return working directory*/
    public static String getWorkingDir()
    	{
    	String wd = "";
    	try {
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(getInstallFolder()+"workingDir.txt"),"UTF-8"));
			wd = new File (br.readLine()).getAbsolutePath();
			br.close();
		} catch (FileNotFoundException e) {
			String home = System.getenv("HOME");
			if (home != null && new File(home).exists())
				wd = new File(home+"/.nat-braille/").getAbsolutePath();
			else
				// TODO Auto-generated catch block
				wd = new File(System.getProperty("user.home")+"/.nat-braille/").getAbsolutePath();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
			//System.out.println("Working directory : "+wd);
    		return wd;
    	}    
    /** @param dirname dirname*/
    public void setWorkingDir(String dirname)
    	{
    	try {
    		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(getInstallFolder()+"workingDir.txt")));
    		bw.write(dirname);
    		bw.close();
    		JOptionPane.showMessageDialog(null,"Répertoire de travail changé.\n" +
    				"Vous devez redémarrer NAT pour le prendre en considération.","Information",JOptionPane.INFORMATION_MESSAGE);
    	} catch (IOException e) {
    		JOptionPane.showMessageDialog(null,"Impossible de changer le répertoire de travail.\n" +
    				"Vous devez avoir les droits d'administrateur pour le faire","Erreur",JOptionPane.ERROR_MESSAGE);
    		e.printStackTrace();
    	}
    		
    	}
    
    /**
     * Enregistre la configuration par serialisation dans le fichier {@link ConfigNat#fichierConf}
     */
    public void sauvegarder()
    {
		saveUiConf();
		saveFilterConf(fichierConf);
    }
    /**
     * Donne l'adresse du dictionnaire de coupure par défaut
     * @return l'adresse du dictionnaire de coupure par défaut
     */
    public static String getDicoCoupDefaut() {return dicoCoupDefautName;}
    /**
     * Crée ou remplace une configuration à partir du fichier sérialisé 
     * fconf passé en parametre ou trouvé dans le fichier 
     * de conf de l'interface graphique. 
     * @param fconf ; si null, pris dans le fichier de conf d'interface.
     * @return Un objet {@link ConfigNat} créé à partir de fconf
     * <p>IOException Erreur E/S lors de la lecture du fichier fconf<p>
     * <p>ClassNotFoundException Erreur lors du cast de la sortie de <code>ObjectInputStream.readObject()</code></p>
     */
    public static ConfigNat charger(String fconf)
    {	
		if (cn == null){cn = new ConfigNat();}

		if (fconf == null)
	    {
			/* last config filename is to be found in the last gui config file */
			checkWorkingDir();
			cn.loadUiConf();
			fconf = cn.getLastFilterConfigurationFilename();
	    }
	
		cn.loadFilterConf(fconf);
		cn.setFichierConf(fconf);
		
		/* remplacement des tables brailles */
		cn.setTableBraille(cn.getTableBraille(),cn.getIsSysTable());
		cn.setTableEmbossage(cn.getTableEmbossage(), cn.getIsSysEmbossTable());	
	    //maj du fichier de coupure
	    HyphenationToolkit.fabriqueDicoNat(cn.getDicoCoup(), Transcription.xslHyphen, "UTF-8");
		return cn;
    }


	/**
	 * Vérifie la présence des répertoires nécessaires dans répertoire de travail de l'utilisateur
	 * Si non présents, essaie de créer ces répertoires
	 */
	private static void checkWorkingDir() {
		String cpn="";
		/* user configuration folder */
		try
	    {
	        cpn = (new File(ConfigNat.getUserConfigFolder()).getCanonicalPath());			   
	        boolean success = (new File(ConfigNat.getUserConfigFolder())).mkdir();
	        if (success){System.out.println("Directory: " + cpn + " created");} 
	        
	        cpn = (new File(ConfigNat.getUserConfigFilterFolder()).getCanonicalPath());			   
	        success = (new File(ConfigNat.getUserConfigFilterFolder())).mkdir();
	        if (success){System.out.println("Directory: " + cpn + " created");}
	        
	        cpn = (new File(ConfigNat.getUserTempFolder()).getCanonicalPath());			   
	        success = (new File(ConfigNat.getUserTempFolder())).mkdir();
	        if (success){System.out.println("Directory: " + cpn + " created");}
	        
	        cpn = (new File(ConfigNat.getUserBrailleTableFolder()).getCanonicalPath());			   
	        success = (new File(ConfigNat.getUserBrailleTableFolder())).mkdir();
	        if (success){System.out.println("Directory: " + cpn + " created");}
	        
	        cpn = (new File(ConfigNat.getUserEmbossTableFolder()).getCanonicalPath());			   
	        success = (new File(ConfigNat.getUserEmbossTableFolder())).mkdir();
	        if (success){System.out.println("Directory: " + cpn + " created");}
	        
	        cpn = new File(ConfigNat.getUserTempFolder()+"regles").getCanonicalPath();
	        success = (new File(ConfigNat.getUserTempFolder()+"regles")).mkdir();
	        if (success){System.out.println("Directory: " + cpn + " created");}
	    }
        catch (IOException ioe){System.err.println("Erreur lors de la création du répertoire "+cpn);}
		
	}


	/** Renvoie la configuration en cours 
     * @return {@link #cn}*/
    public static ConfigNat getCurrentConfig(){return cn;}
    /** load and save ui and filter configuration 
     * @param configfile adresse du fichier de conf**/
    public void loadFilterConf(String configfile)
    {
	    fiConf = new Properties();
	    if (configfile != null) 
        {
		    try
		    {
		    	fiConf.load(new FileInputStream(configfile));
		    	//mise à jour du fichier de règle d'abrégé
				RulesToolKit.writeRules(RulesToolKit.getRules(new File(ConfigNat.getCurrentConfig().getRulesFrG2Perso()).toURI().toString()));
		    }
		    catch (IOException ioe) 
	        {
			    ioe.printStackTrace(); 
			    System.err.println("1-Exception while reading filter configuration file");
	        }
        }	
    }
    /** save configuration in file named configFile 
     * @param configFile adresse du fichier de conf*/
    public void saveFilterConf (String configFile)
    {

	    try {fiConf.store(new FileOutputStream(configFile), null);}
	    catch (IOException ioe) 
	    {
		    ioe.printStackTrace(); 
		    System.err.println("Exception while writing filter configuration file");
	    }
	    catch(NullPointerException npe)
	    {
		    System.err.println("Sauvegarde de la configuration impossible: pas de configuration choisie");
	    }
    }
    /** load user interface configuration file **/
    public void loadUiConf () 
    {
	    uiConf = new Properties();
 	    boolean fail=false;
 	    
	    try {uiConf.load(new FileInputStream(getUserConfigFolder()+uiConfFilename));}
	    catch (IOException ioe)
	    {
		    System.err.println("Exception while reading UI configuration file "+getUserConfigFolder()+uiConfFilename + "; using default values");
		    setLastSource("license.txt");
		    fail=true;
	    }

	    if (fail){
		try {uiConf.load(new FileInputStream("nat-gui.conf-initial"));}
		catch (IOException ioe){
		    System.err.println("chargement de nat-gui.conf et .conf-initial échoué");
		}
	    }
	    setFNoir(getLastSource());
	    //setSourceEncoding(getLastSourceEncoding());
	    setFBraille(getLastDest());
	    //setSortieEncoding(getLastDestEncoding());
    }
    /** save user interface configuration file **/
    public void saveUiConf ()
    {
	    setLastSource(fichNoir);
	    setLastSourceEncoding(sourceEncoding);
	    setLastDest(fichBraille);
	    setLastDestEncoding(sortieEncoding);
	    try{setLastFilterConfigurationFilename(fichierConf);}
        catch(NullPointerException npe){System.err.println("Sauvegarde du nom du fichier de configuration de l'interface graphique impossible: pas de configuration choisie");}

	    try{uiConf.store(new FileOutputStream(getUserConfigFolder()+uiConfFilename), null);}
        catch (IOException ioe) {System.err.println("Exception while writing UI configuration file");}	
    }

}
 