/*
 * 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 java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.channels.FileChannel;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.Properties;
import nat.OptNames;
import java.lang.Boolean;
import java.lang.Integer;


//import javax.print.PrintService;

//import gestionnaires.GestionnaireErreur;

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

    /** serial version UID */
    private static final long serialVersionUID = 1L;
    /** Le fichier contenant la configuration */
    private String fichierConf;
	
    //************* configuration générale **************
    /** Numéro de version */
    private final String version = "1.5.0";
    /** Nom de version long */
    private final String versionLong = "1.5.0  \"Claude\"";
    /** Nom de la version svn correspondante */
	private final String svnVersion = "r213";

    //************* configuration des fichiers E/S ********
    /** adresse du dernier fichier source utilisé */
    private String fsource="";
    /** adresse du dernier fichier cible (sortie) utilisé */
    private String fcible="";
    /** encoding du fichier source */
    private String sourceEncoding="automatique";
    /** encoding du fichier de sortie */
    private String sortieEncoding="UTF-8";

    private static ConfigNat cn=null;
    
    private ConfigNat(){fichierConf = "default";}
    /*
     * Méthodes d'accès
     */
	
    /* général */

    public String getVersionLong(){return versionLong;}
    public String getVersion(){return version;}
	public String getSvnVersion() {return svnVersion;}

    /* Fichiers E/S */
    public String getFsource(){return fsource;}
    public void setFsource(String fs){fsource = fs;}
    public String getFcible(){return fcible;}
    public void setFcible(String fc){fcible = fc;}
    
    public void setFichierConf(String f){fichierConf = f;}
    public String getFichierConf(){return fichierConf;}
    /** renvoie le nom court de la configuration courante, par exemple default */
    public String getShortFichierConf(){return fichierConf.substring(fichierConf.lastIndexOf("/")+1, fichierConf.lastIndexOf("."));}
   
    /* Filter Configuration */
    public String getSourceEncoding(){return fiConf.getProperty(OptNames.en_in,"UTF-8");}
    public void setSourceEncoding(String se){fiConf.setProperty(OptNames.en_in, se);}
    public String getSortieEncoding(){return fiConf.getProperty(OptNames.en_out,"UTF-8");}
    public void setSortieEncoding(String se){fiConf.setProperty(OptNames.en_out, se);}
    
    public void setNiveauLog(int lg){fiConf.setProperty(OptNames.ge_log_verbosity, (new Integer(lg)).toString());}
    public int getNiveauLog(){return ((new Integer(fiConf.getProperty(OptNames.ge_log_verbosity,"1"))).intValue());}
    public String getDTD(){return (fiConf.getProperty(OptNames.fi_dtd_filename,"./mmlents/windob.dtd"));}   
    public void setDTD(String dtd){fiConf.setProperty(OptNames.fi_dtd_filename,dtd);} 
    public String getXSL(){return (fiConf.getProperty(OptNames.fi_filter_filename,"./xsl/xsl.xsl"));}
    public void setXSL(String xslfn){fiConf.setProperty(OptNames.fi_filter_filename,xslfn);}
    public String getTableBraille(){return (fiConf.getProperty(OptNames.fi_braille_table,"Brltab"));}

    /**
     * Met à jour le nom de la table braille et copie la nouvelle table dans le
     * fichier Brltab.ent
     * méthode d'accès
     * @param tb le nom de la table braille à utiliser
     * @exception IOException Erreur d'entrée sortie lors de la lecture de la table ou de la copie
     */
    public void setTableBraille(String tableBraille)
    {
	fiConf.setProperty(OptNames.fi_braille_table,tableBraille);
	FileChannel in = null; // canal d'entrée
	FileChannel out = null; // canal de sortie
	try 
	    {
		// Init
		in = new FileInputStream("xsl/tablesBraille/"+tableBraille+".ent").getChannel();
		out = new FileOutputStream("xsl/tablesBraille/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
	    }
    }
    public boolean getAbreger(){return ((new Boolean(fiConf.getProperty(OptNames.fi_litt_abbreg,"false"))).booleanValue()); }
    public void setAbreger(boolean a){fiConf.setProperty(OptNames.fi_litt_abbreg,Boolean.toString(a));}
    public boolean getTraiterMaths(){return ((new Boolean(fiConf.getProperty(OptNames.fi_math_transcribe,"true"))).booleanValue()); }
    public void setTraiterMaths(boolean m){fiConf.setProperty(OptNames.fi_math_transcribe,Boolean.toString(m));}
    public boolean getTraiterLiteraire(){return ((new Boolean(fiConf.getProperty(OptNames.fi_litt_transcribe,"true"))).booleanValue());}
    public void setTraiterLiteraire(boolean l){fiConf.setProperty(OptNames.fi_litt_transcribe,Boolean.toString(l));}
    public boolean getTraiterMusique(){return ((new Boolean(fiConf.getProperty(OptNames.fi_music_transcribe,"true"))).booleanValue()); }
    public void setTraiterMusique(boolean m){fiConf.setProperty(OptNames.fi_music_transcribe,Boolean.toString(m));}
    public boolean getMathTrigoSpec(){return ((new Boolean(fiConf.getProperty(OptNames.fi_math_use_trigo_spec,"true"))).booleanValue()); }
    public void setMathTrigoSpec(boolean m){fiConf.setProperty(OptNames.fi_math_use_trigo_spec,Boolean.toString(m));}
    public void setLongueurLigne(int lg){fiConf.setProperty(OptNames.fi_line_lenght, (new Integer(lg)).toString());}
    public int getLongueurLigne(){return ((new Integer(fiConf.getProperty(OptNames.fi_line_lenght,"40"))).intValue());}
    public void setCoupure(boolean c){fiConf.setProperty(OptNames.fi_hyphenation,Boolean.toString(c));	}
    public boolean getCoupure(){return ((new Boolean(fiConf.getProperty(OptNames.fi_hyphenation,"true"))).booleanValue()); }
    public void setModeCoupureSagouin(boolean m){fiConf.setProperty(OptNames.fi_hyphenation_dirty,Boolean.toString(m));}
    public boolean getModeCoupureSagouin(){return ((new Boolean(fiConf.getProperty(OptNames.fi_hyphenation_dirty,"false"))).booleanValue());}
    public String getXSL_g1(){return (fiConf.getProperty(OptNames.fi_litt_fr_int_filter_filename,"fr-g1.xsl"));}    
    public void setXSL_g1(String filename){fiConf.setProperty(OptNames.fi_litt_fr_int_filter_filename,filename);}
    public String getXSL_g2(){return (fiConf.getProperty(OptNames.fi_litt_fr_abbreg_filter_filename,"fr-g2.xsl"));}    
    public void setXSL_g2(String filename){fiConf.setProperty(OptNames.fi_litt_fr_abbreg_filter_filename,filename);}
    public String getXSL_maths(){return (fiConf.getProperty(OptNames.fi_math_filter_filename,"fr-maths.xsl"));}    
    public void setXSL_maths(String filename){fiConf.setProperty(OptNames.fi_math_filter_filename,filename);}
    public String getXSL_musique(){return (fiConf.getProperty(OptNames.fi_music_filter_filename,"musique.xsl"));}    
    public void setXSL_musique(String filename){fiConf.setProperty(OptNames.fi_music_filter_filename,filename);}
	public boolean getLitMajDouble(){return ((new Boolean(fiConf.getProperty(OptNames.tr_litt_double_upper,"true"))).booleanValue());}
	public void setLitMajDouble(boolean lmd){fiConf.setProperty(OptNames.tr_litt_double_upper,Boolean.toString(lmd));}
	public boolean getLitMajPassage(){return ((new Boolean(fiConf.getProperty(OptNames.tr_litt_part_upper,"true"))).booleanValue());}
	public void setLitMajPassage(boolean lmp){fiConf.setProperty(OptNames.tr_litt_part_upper,Boolean.toString(lmp));}
	public boolean getLitMajMelange(){return ((new Boolean(fiConf.getProperty(OptNames.tr_litt_mixed_upper,"true"))).booleanValue());}
	public void setLitMajMelange(boolean lmp){fiConf.setProperty(OptNames.tr_litt_mixed_upper,Boolean.toString(lmp));}
	public boolean getLitEvidenceMot(){return ((new Boolean(fiConf.getProperty(OptNames.tr_litt_word_emph,"true"))).booleanValue());}
	public void setLitEvidenceMot(boolean lmp){fiConf.setProperty(OptNames.tr_litt_word_emph,Boolean.toString(lmp));}
	public boolean getLitEvidencePassage(){return ((new Boolean(fiConf.getProperty(OptNames.tr_litt_part_emph,"true"))).booleanValue());}
	public void setLitEvidencePassage(boolean lmp){fiConf.setProperty(OptNames.tr_litt_part_emph,Boolean.toString(lmp));}
	public boolean getLitEvidenceDansMot(){return ((new Boolean(fiConf.getProperty(OptNames.tr_litt_in_word_emph,"true"))).booleanValue());}
	public void setLitEvidenceDansMot(boolean lmp){fiConf.setProperty(OptNames.tr_litt_in_word_emph,Boolean.toString(lmp));}
    /* Options graphiques mais dépendantes de la configuration 
     * Graphical options but depending of the current configuration
     * */
    public void setPoliceEditeur(String pe){fiConf.setProperty(OptNames.ui_editor_font,pe);}
    public String getPoliceEditeur(){return (fiConf.getProperty(OptNames.ui_editor_font,"Braille Antoine"));}
    public void setPolice2Editeur(String pe2){fiConf.setProperty(OptNames.ui_editor_font2,pe2);}
    public String getPolice2Editeur(){return (fiConf.getProperty(OptNames.ui_editor_font2,"Courrier"));}
	public void setTaillePolice(int t){fiConf.setProperty(OptNames.ui_editor_font_size, (new Integer(t)).toString());}
	public int getTaillePolice(){return ((new Integer(fiConf.getProperty(OptNames.ui_editor_font_size,"24"))).intValue());}
	public void setTaillePolice2(int tp2){fiConf.setProperty(OptNames.ui_editor_font2_size,(new Integer(tp2)).toString());}
	public int getTaillePolice2(){return ((new Integer(fiConf.getProperty(OptNames.ui_editor_font2_size,"24"))).intValue());}
	public void setSaxonAsXsltProcessor(boolean saxp){fiConf.setProperty(OptNames.tr_use_saxon_processor,Boolean.toString(saxp));}
	public boolean getSaxonAsXsltProcessor(){return new Boolean(fiConf.getProperty(OptNames.tr_use_saxon_processor,"true")).booleanValue();}
   
    /** GUI options **/
    public void setOuvreEditeurApresTranscription(boolean o){uiConf.setProperty(OptNames.ui_editor_auto_open,Boolean.toString(o));}
    public boolean getOuvrirEditeur(){return ((new Boolean(uiConf.getProperty(OptNames.ui_editor_auto_open,"true"))).booleanValue());} 
    public boolean getAfficheLigneSecondaire(){return ((new Boolean(uiConf.getProperty(OptNames.ui_editor_zone2_display,"true"))).booleanValue());}
    public void setAfficheLigneSecondaire(boolean als){uiConf.setProperty(OptNames.ui_editor_zone2_display,Boolean.toString(als));}
    public String getEditeur(){return uiConf.getProperty(OptNames.ui_editor_external,"");}
    public void setEditeur(String e){uiConf.setProperty(OptNames.ui_editor_external,e);}
    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  */
    public String getLastSource(){return (uiConf.getProperty(OptNames.last_source_filename,""));}    
    public void setLastSource(String filename){uiConf.setProperty(OptNames.last_source_filename,filename);}
    public String getLastSourceEncoding(){return (uiConf.getProperty(OptNames.last_source_encoding,"automatique"));}    
    public void setLastSourceEncoding(String enc){uiConf.setProperty(OptNames.last_source_encoding,enc);}
    public String getLastDest(){return (uiConf.getProperty(OptNames.last_dest_filename,""));}    
    public void setLastDest(String filename){uiConf.setProperty(OptNames.last_dest_filename,filename);}
    public String getLastDestEncoding(){return (uiConf.getProperty(OptNames.last_dest_encoding,"automatique"));}    
    public void setLastDestEncoding(String enc){uiConf.setProperty(OptNames.last_dest_encoding,enc);}
    public void setLastFilterConfigurationFilename(String conffn){uiConf.setProperty(OptNames.last_filter_configuration_filename,conffn);}
    public String getLastFilterConfigurationFilename(){return (uiConf.getProperty(OptNames.last_filter_configuration_filename));}
    /* emboss */
    public void setTableEmbossage(String te)
    {
		fiConf.setProperty(OptNames.pr_emboss_table,te);
		FileChannel in = null; // canal d'entrée
		FileChannel out = null; // canal de sortie
		try 
	    {
			// Init
			in = new FileInputStream("xsl/tablesEmbosseuse/"+te+".ent").getChannel();
			out = new FileOutputStream("xsl/tablesEmbosseuse/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
	    }
    }
    public String getTableEmbossage(){return (fiConf.getProperty(OptNames.pr_emboss_table,""));}
    public void setOs(String o){fiConf.setProperty(OptNames.pr_os,o);}
    public String getOs(){return (fiConf.getProperty(OptNames.pr_os,"Linux"));}
    public void setCommande(String c){fiConf.setProperty(OptNames.pr_emboss_command,c);}
    public String getCommande(){return (fiConf.getProperty(OptNames.pr_emboss_command,""));}
    public boolean getUtiliserCommandeEmbossage(){return ((new Boolean(fiConf.getProperty(OptNames.pr_use_emboss_command,"false"))).booleanValue());}
    public void setUtiliserCommandeEmbossage(boolean uce){fiConf.setProperty(OptNames.pr_use_emboss_command,Boolean.toString(uce));}
    public boolean getUtiliserEmbosseuse() {return ((new Boolean(fiConf.getProperty(OptNames.pr_emboss_auto,"false"))).booleanValue());}
    public void setUtiliserEmbosseuse(boolean uce){fiConf.setProperty(OptNames.pr_emboss_auto,Boolean.toString(uce));}
    public void setPrintService(String c)
    {
    	if(c!=null){fiConf.setProperty(OptNames.pr_emboss_print_service,c);}
    	else{fiConf.setProperty(OptNames.pr_emboss_print_service,"");}
    }
    public String getPrintservice(){return (fiConf.getProperty(OptNames.pr_emboss_print_service,""));}
	public boolean getMemoriserFenetre(){return new Boolean(uiConf.getProperty(OptNames.ui_remember_windows_size,"true")).booleanValue();}
	public void setMemoriserFenetre(boolean rms){uiConf.setProperty(OptNames.ui_remember_windows_size,Boolean.toString(rms));}
	public boolean getCentrerFenetre() {return new Boolean(uiConf.getProperty(OptNames.ui_center_windows,"true")).booleanValue();}
	public void setCentrerFenetre(boolean cf){uiConf.setProperty(OptNames.ui_center_windows,Boolean.toString(cf));}
	public int getHeightEditeur(){return new Integer(uiConf.getProperty(OptNames.ui_y_editor,"0").toString());}
	public void setHeightEditeur(int he){uiConf.setProperty(OptNames.ui_y_editor,""+he);}
	public int getWidthEditeur(){return new Integer(uiConf.getProperty(OptNames.ui_x_editor,"0").toString());}
	public void setWidthEditeur(int we){uiConf.setProperty(OptNames.ui_x_editor,""+we);}
	
 
    /**
     * Enregistre la configuration par serialisation dans le fichier {@link ConfigNat#fichierConf}
     * @exception IOException Erreur d'écriture lors de la sérialisation
     */
    public void sauvegarder()
    {
		saveUiConf();
		saveFilterConf(fichierConf);
    }

    /**
     * Crée une configuration à partir du fichier sérialisé fconf
     * @param fconf
     * @return Un objet {@link ConfigNat} créé à partir de fconf
     * @exception IOException Erreur E/S lors de la lecture du fichier fconf
     * @exception ClassNotFoundException Erreur lors du cast de la sortie de <code>ObjectInputStream.readObject()</code>
     */
    public static ConfigNat charger(String fconf)
    {	
		if(cn != null) 
	    // config already exists : replace config (for gui only)
	    {
		//il existe déjà une conf
		//cn.fiConf = null;
		cn.loadFilterConf(fconf);
		cn.setFichierConf(fconf);
	    }
		else
	    // config does not exist : create
	    {
			if (fconf == null)
			{
			    // last config filename is to be found in the last gui config file
			    cn = new ConfigNat();
			    cn.loadUiConf();
			    cn.loadFilterConf(cn.getLastFilterConfigurationFilename());
			    cn.setFichierConf(cn.getLastFilterConfigurationFilename());
			}
			else
			{
			    // config filename is to be found in the factory argument (from the command line)
			    cn = new ConfigNat();
			    cn.loadFilterConf(fconf);
			    cn.setFichierConf(fconf);
			}
	    }
		/* remplacement des tables brailles */
		cn.setTableBraille(cn.getTableBraille());
		cn.setTableEmbossage(cn.getTableEmbossage());
		return cn;
    }
    /** Renvoie la configuration en cours */
    public static ConfigNat getCurrentConfig(){return cn;}
    /** load and save ui and filter configuration **/
    public void loadFilterConf(String configfile)
    {
		fiConf = new Properties();
		if (configfile != null) 
		{
		    try {fiConf.load(new InputStreamReader(new FileInputStream(configfile),"UTF-8"));}
		    catch (IOException ioe) 
			{
			    ioe.printStackTrace(); 
			    System.err.println("1-Exception while reading filter configuration file\n");
			}
		}	
    }
    /** save configuration in file named configFile */
    public void saveFilterConf (String configFile)
    {
		try {fiConf.store(new FileOutputStream(configFile), null);}
		catch (IOException ioe) 
	    {
			ioe.printStackTrace(); 
			System.out.println("Exception while writing filter configuration file\n");
	    }	
    }
    /** load user interface configuration file **/
    public void loadUiConf () 
    {
		uiConf = new Properties(); 
		try {uiConf.load(new InputStreamReader(new FileInputStream(uiConfFilename),"UTF-8"));}
		catch (IOException ioe){System.err.println("Exception while reading UI configuration file\n");}
		setFsource(getLastSource());
		//setSourceEncoding(getLastSourceEncoding());
		setFcible(getLastDest());
		//setSortieEncoding(getLastDestEncoding());
    }
    /** save user interface configuration file **/
    public void saveUiConf ()
    {
		setLastSource(fsource);
		setLastSourceEncoding(sourceEncoding);
		setLastDest(fcible);
		setLastDestEncoding(sortieEncoding);
		setLastFilterConfigurationFilename(fichierConf);	
		try {uiConf.store(new FileOutputStream(uiConfFilename), null);}
		catch (IOException ioe) {System.out.println("Exception while writing UI configuration file\n");}	
    }


}
