/*
editeurconfig - Editeur de Fichiers de Config de Jaxe

Copyright (C) 2011 Observatoire de Paris-Meudon

Ce programme est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier conformément aux dispositions de la Licence Publique Générale GNU, telle que publiée par la Free Software Foundation ; version 2 de la licence, ou encore (à votre choix) toute version ultérieure.

Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ; sans même la garantie implicite de COMMERCIALISATION ou D'ADAPTATION A UN OBJET PARTICULIER. Pour plus de détail, voir la Licence Publique Générale GNU .

Vous devez avoir reçu un exemplaire de la Licence Publique Générale GNU en même temps que ce programme ; si ce n'est pas le cas, écrivez à la Free Software Foundation Inc., 675 Mass Ave, Cambridge, MA 02139, Etats-Unis.
*/

package editeurconfig;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import javax.swing.border.*;
import java.util.*;
import org.w3c.dom.*;
import javax.swing.text.BadLocationException;
import javax.swing.filechooser.FileFilter;
import java.io.*;
import java.net.*;


/**
* Classe pour créer ou éditer les Exports
*/
public class EditeurDesExports extends JFrame {
	private FenetreEdition fe;
    private Document doc;
    private Element racine;
    private Element exports;
    private File fichierXML;
    
    private static final String[] sorties = {"HTML", "XML", "PDF"};
    
    JTextField nomFichier_t;
    
    private JPanel listePanelExport;
    
    
    public EditeurDesExports(final FenetreEdition fe, final Document doc, final Element racine, final File fichierXML) {
        super(Strings.get("titre.EditeurDesExports"));
        this.fe = fe;
        this.doc = doc;
        this.racine = racine;
        this.fichierXML = fichierXML;
        
        exports = Outils.premierEnfantDeNom(racine, "EXPORTS");
        if (exports == null) {
            exports = doc.createElement("EXPORTS");
            racine.insertBefore(exports, Outils.premierEnfantDeNom(racine, "STRINGS"));
        }
        
        setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        afficher();
    }
    
    
    private void afficher() {
        
        setLayout(new BorderLayout());
        //setPreferredSize(new Dimension(700,400));
        
        listePanelExport = new JPanel();
        listePanelExport.setLayout(new BoxLayout(listePanelExport, BoxLayout.Y_AXIS));
        final JScrollPane defilementExports = new JScrollPane(listePanelExport);
        add(defilementExports,BorderLayout.CENTER);
        recupererExport();
        
        final JPanel panelBoutonsBas = new JPanel(new FlowLayout());
        add(panelBoutonsBas,BorderLayout.SOUTH);
        final JButton bTester = new JButton(new AbstractAction("Tester") {
            public void actionPerformed(ActionEvent e) {
                EditeurFichierConfig.convertToString(doc);
            }
        });
        //panelBoutonsBas.add(bTester);
        
        final JButton bFermer = new JButton(new AbstractAction(Strings.get("bouton.Fermer")) {
            public void actionPerformed(ActionEvent e) {
                nettoyerDOM();
                setVisible(false);
                fe.afficher();
            }
        });
        panelBoutonsBas.add(bFermer);
        
        pack();
        final Dimension dim = getSize();
        final Dimension ecran = getToolkit().getScreenSize();
        setLocation((ecran.width - dim.width)/2, (ecran.height - dim.height)/2);
        setVisible(true);
    }
        
    /**
    * Crée le panel Export
    */
    private void creerPanelExport(final Element export, final int index) {
    
        final JPanel panExportTout = new JPanel(new FlowLayout(FlowLayout.LEFT));
        listePanelExport.add(panExportTout);
        
        JPanel panelExport = new JPanel();
        panelExport.setLayout(new BoxLayout(panelExport, BoxLayout.Y_AXIS));
        panelExport.setBorder(new TitledBorder(Strings.get("label.Export")));
        panExportTout.add(panelExport);
        
        JPanel panNomExport = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panelExport.add(panNomExport);
        JLabel nomExport = new JLabel(Strings.get("label.Nom"));
        JTextField nomExport_t = new JTextField(15);
        panNomExport.add(nomExport);
        panNomExport.add(nomExport_t);
        
        if (export != null)
            nomExport_t.setText(export.getAttribute("nom"));
        
        // écouteur sur nom d'export
        nomExport_t.getDocument().addDocumentListener(new DocumentListener() {
            public void changedUpdate(DocumentEvent de) {
                ecouteurExport(de, index);
            }
            public void insertUpdate(DocumentEvent de) {
                ecouteurExport(de, index);
            }
            public void removeUpdate(DocumentEvent de) {
                ecouteurExport(de, index);
            }
        });
        
        JPanel panSortie = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panelExport.add(panSortie);
        JLabel sortie = new JLabel(Strings.get("label.Sortie"));
        final JComboBox sortie_c = new JComboBox(sorties);
        panSortie.add(sortie);
        panSortie.add(sortie_c);
        sortie_c.setSelectedIndex(0);
        if (export != null)
            sortie_c.setSelectedItem(export.getAttribute("sortie"));
        
        // écouteur sur sortie de l'export
        sortie_c.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent ie) {
                if (sortie_c.getSelectedItem() != null) {
                    enregistrerExport(index, null, sortie_c.getSelectedItem().toString());
                }
            }
        });
        

        final JPanel panPlusMoins = new JPanel(new FlowLayout());
        panExportTout.add(panPlusMoins);
    
        final JButton bPlus = new JButton(new AbstractAction("+") {
            public void actionPerformed(ActionEvent e) {
                    Element element_export = enregistrerExport(listePanelExport.getComponentCount(), null, null);
                    creerPanelExport(element_export, listePanelExport.getComponentCount());
                    listePanelExport.revalidate();
            }
        });
        panPlusMoins.add(bPlus);
    
        final JButton bMoins = new JButton(new AbstractAction("-") {
            public void actionPerformed(ActionEvent e) {
                if (listePanelExport.getComponentCount() > 1) {
                    listePanelExport.remove(panExportTout);
                    listePanelExport.revalidate();
                    Element element_export = trouverExport(index);
                    if (element_export != null) {
                        element_export.getParentNode().removeChild(element_export);
                        EditeurFichierConfig.setModif(true);
                    }
                }
            }
        });
        panPlusMoins.add(bMoins);
        
        /** panel Fichier XSL **/
        final JPanel listePanelFichierXSL = new JPanel();
        listePanelFichierXSL.setLayout(new BoxLayout(listePanelFichierXSL, BoxLayout.Y_AXIS));
        panelExport.add(listePanelFichierXSL);
        
        recupererFichierXSL(listePanelFichierXSL, export);
    }
        

    /**
    * Crée le panel Fichier XSL
    */
    private void creerPanelFichierXSL(final JPanel panelDest, final Element export, final Element fichier_xsl, final int index) {
        
        final JPanel panFichierXSLTout = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panelDest.add(panFichierXSLTout);
        
        JPanel panFichierXSL = new JPanel();
        panFichierXSL.setLayout(new BoxLayout(panFichierXSL, BoxLayout.Y_AXIS));
        panFichierXSL.setBorder(new TitledBorder(Strings.get("label.FichierXSL")));
        panFichierXSLTout.add(panFichierXSL);
        
        final JPanel panNomFichier = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panFichierXSL.add(panNomFichier);
        JLabel nomFichier = new JLabel(Strings.get("label.Nom"));
        nomFichier_t = new JTextField(15);
        nomFichier_t.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {
                parcourir(fichier_xsl);
            }
            public void mousePressed(MouseEvent e) {
            }
            public void mouseReleased(MouseEvent e) {
            }
            public void mouseEntered(MouseEvent e) {
            }
            public void mouseExited(MouseEvent e) {
            }
        });
        
        JButton bParcourir = new JButton(new AbstractAction(Strings.get("bouton.Parcourir")) {
            public void actionPerformed(ActionEvent e) {
                    parcourir(fichier_xsl);
            }
        });
        panNomFichier.add(nomFichier);
        panNomFichier.add(nomFichier_t);
        panNomFichier.add(bParcourir);
        
        if (fichier_xsl != null)
            nomFichier_t.setText(fichier_xsl.getAttribute("nom"));
            
        // écouteur sur nom de fichier XSL
        nomFichier_t.getDocument().addDocumentListener(new DocumentListener() {
            public void changedUpdate(DocumentEvent de) {
                ecouteurFichierXSL(de, export, index);
            }
            public void insertUpdate(DocumentEvent de) {
                ecouteurFichierXSL(de, export, index);
            }
            public void removeUpdate(DocumentEvent de) {
                ecouteurFichierXSL(de, export, index);
            }
        });
        
        
        final JPanel panPlusMoins = new JPanel(new FlowLayout());
        panFichierXSLTout.add(panPlusMoins);
        
        final JButton bPlus = new JButton(new AbstractAction("+") {
            public void actionPerformed(ActionEvent e) {
                    Element element_fichier_xsl = enregistrerFichierXSL(export, panelDest.getComponentCount(), null);
                    creerPanelFichierXSL(panelDest, export, element_fichier_xsl, panelDest.getComponentCount());
                    panelDest.revalidate();
            }
        });
        panPlusMoins.add(bPlus);
        
        final JButton bMoins = new JButton(new AbstractAction("-") {
            public void actionPerformed(ActionEvent e) {
                if (panelDest.getComponentCount() > 1) {
                    panelDest.remove(panFichierXSLTout);
                    panelDest.revalidate();
                    Element element_fichier_xsl = trouverFichierXSL(export, index);
                    if (element_fichier_xsl != null) {
                        element_fichier_xsl.getParentNode().removeChild(element_fichier_xsl);
                        EditeurFichierConfig.setModif(true);
                    }
                }
            }
        });
        panPlusMoins.add(bMoins);
        
        // panel Paramètre
        final JPanel listePanelParametre = new JPanel();
        listePanelParametre.setLayout(new BoxLayout(listePanelParametre, BoxLayout.Y_AXIS));
        panFichierXSL.add(listePanelParametre);
        
        recupererParametre(listePanelParametre, fichier_xsl);
    }
    
    /**
    * Crée le panel Parametre
    */
    private void creerPanelParametre(final JPanel panelDest, final Element fichier_xsl, final Element parametre, final int index) {
        
        final JPanel panParametreTout = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panelDest.add(panParametreTout);
        
        final JPanel panParametre = new JPanel(new GridLayout(2,1));
        panParametreTout.add(panParametre);
        panParametre.setBorder(new TitledBorder(Strings.get("label.Parametre")));
        
        final JPanel panNomParametre = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panParametre.add(panNomParametre);
        JLabel nomParametre = new JLabel(Strings.get("label.Nom"));
        final JTextField nomParametre_t = new JTextField(15);
        panNomParametre.add(nomParametre);
        panNomParametre.add(nomParametre_t);
        
        if (parametre != null)
            nomParametre_t.setText(parametre.getAttribute("nom"));
            
        // écouteur sur nom parametre
        nomParametre_t.getDocument().addDocumentListener(new DocumentListener() {
            public void changedUpdate(DocumentEvent de) {
                ecouteurParametre(de, fichier_xsl, index, "nom");
            }
            public void insertUpdate(DocumentEvent de) {
                ecouteurParametre(de, fichier_xsl, index, "nom");
            }
            public void removeUpdate(DocumentEvent de) {
                ecouteurParametre(de, fichier_xsl, index, "nom");
            }
        });
        
        final JPanel panValeurParametre = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panParametre.add(panValeurParametre);
        JLabel valeurParametre = new JLabel(Strings.get("label.valeurParametre"));
        final JTextField valeurParametre_t = new JTextField(15);
        panValeurParametre.add(valeurParametre);
        panValeurParametre.add(valeurParametre_t);
        
        if (parametre != null)
            valeurParametre_t.setText(parametre.getAttribute("valeur"));
            
        // écouteur sur valeur parametre
        valeurParametre_t.getDocument().addDocumentListener(new DocumentListener() {
            public void changedUpdate(DocumentEvent de) {
                ecouteurParametre(de, fichier_xsl, index, "valeur");
            }
            public void insertUpdate(DocumentEvent de) {
                ecouteurParametre(de, fichier_xsl, index, "valeur");
            }
            public void removeUpdate(DocumentEvent de) {
                ecouteurParametre(de, fichier_xsl, index, "valeur");
            }
        });
        
        final JPanel panPlusMoins = new JPanel(new FlowLayout());
        panParametreTout.add(panPlusMoins);
        
        final JButton boutonPlus = new JButton(new AbstractAction("+") {
            public void actionPerformed(ActionEvent e) {
                //if (!("".equals(nomParametre_t.getText()))) {
                    //if (!("".equals(valeurParametre_t.getText()))) {
                        creerPanelParametre(panelDest, fichier_xsl, null, panelDest.getComponentCount());
                        panelDest.revalidate();
                    //}
                //}
            }
        });
        panPlusMoins.add(boutonPlus);
        
        JButton boutonMoins = new JButton(new AbstractAction("-") {
            public void actionPerformed(ActionEvent e) {
                if(panelDest.getComponentCount() > 1) {
                    panelDest.remove(panParametreTout);
                    panelDest.revalidate();
                    Element element_parametre = trouverParametre(fichier_xsl, index);
                    if (element_parametre != null) {
                        element_parametre.getParentNode().removeChild(element_parametre);
                        EditeurFichierConfig.setModif(true);
                    }
                }
            }
        });
        panPlusMoins.add(boutonMoins);
    }
    
    
    
    /**
    * Parcour un fichier XSL
    */
    private void parcourir(final Element fichier_xsl) {
        File repertoireSchema = null;
        if ( ! "".equals(fichier_xsl.getAttribute("nom")) )
            repertoireSchema = new File(fichierXML.getParentFile(), fichier_xsl.getAttribute("nom"));
        else 
            repertoireSchema = fichierXML;
        
        JFileChooser jfc = new JFileChooser(repertoireSchema);
        jfc.setApproveButtonText("OK");
        if ( ! "".equals(fichier_xsl.getAttribute("nom")) )
            jfc.setSelectedFile(repertoireSchema);
		jfc.setFileFilter(new FileFilter() {
			public boolean accept(File f) {
				if (f.isDirectory())
					return true;
				String s = f.getName();
				int i = s.lastIndexOf('.');

				if (i > 0 && i < s.length() - 1)
					if (s.substring(i + 1).toLowerCase().equals("xsl"))
						return true;

				return false;
			}

			public String getDescription() {
                return Strings.get("texte.FichiersXSL");
			}
		});
		
        if (jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
            final File sf = jfc.getSelectedFile();
            if (sf != null) {
                URI url = null;
                URI base = null;
                try {
                    url = new URI(sf.toString());
                }
                catch (URISyntaxException e) {
                    System.out.println(e);
                }
                
                try {
                    base = new URI(fichierXML.getParentFile().toString());
                }
                catch (URISyntaxException e) {
                    System.out.println(e);
                }
                
                try {
                    URI relative = base.relativize(url);
                    nomFichier_t.setText(relative.toString());
                }
                catch (NullPointerException e) {
                    System.out.println(e);
                }
            }
        }
    }
    
    
    /*********************************** Ecouteurs ************************************************/
    /**
    * Ecouteur sur le champ nom d'export
    * @param Un DocumentEvent
    */
    private void ecouteurExport(final DocumentEvent de, final int index) {
        javax.swing.text.Document source = de.getDocument();
        try {
            String texteNom = source.getText(0, source.getLength());
            enregistrerExport(index, texteNom, null);
            
            EditeurFichierConfig.setModif(true);
        }
        catch (BadLocationException bex) {
            System.out.println(bex);
        }
    }
    
    /**
    * Ecouteur sur le champ nom de fichier XSL
    * @param Un DocumentEvent
    */
    private void ecouteurFichierXSL(final DocumentEvent de, final Element export, final int index) {
        javax.swing.text.Document source = de.getDocument();
        try {
            String texteF = source.getText(0, source.getLength());
            //enregistrerFichierXSL(export, index, texteF);
            enregistrerFichierXSL(export, index, nomFichier_t.getText());
            
            EditeurFichierConfig.setModif(true);
        }
        catch (BadLocationException bex) {
            System.out.println(bex);
        }
    }
    
    /**
    * Ecouteur sur le champ Parametre
    * @param Un DocumentEvent
    * @param L'index
    * @param le champ désigné
    */
    private void ecouteurParametre(final DocumentEvent de, final Element fichier_xsl, final int index, final String champP) {
        javax.swing.text.Document source = de.getDocument();
        try {
            String texteP = source.getText(0, source.getLength());
            if ("nom".equals(champP))
                enregistrerParametre(fichier_xsl, index, texteP, null);
            if ("valeur".equals(champP))
                enregistrerParametre(fichier_xsl, index, null, texteP);
                
            EditeurFichierConfig.setModif(true);
        }
        catch (BadLocationException bex) {
            System.out.println(bex);
        }
    }
    
    
    
    
    
    /*********************************** Opération DOM *****************************************/
    // EXPORT
    private Element enregistrerExport(final int index, final String nom, final String sortie) {
        Element export = trouverExport(index);
        if (export == null) {
            export = doc.createElement("EXPORT");
            exports.appendChild(export);
        }
        if (nom != null)
            export.setAttribute("nom", nom);
        if(sortie != null)
            export.setAttribute("sortie", sortie);
        return export;
    }
    
    private Element trouverExport(int index) {
        if (index == -1)
            return(null);
        if (exports == null)
            return(null);
        int ie = 0;
        for (Node n = exports.getFirstChild(); n != null; n = n.getNextSibling()) {
            if (n instanceof Element) {
                if (ie == index)
                    return((Element)n);
                ie++;
            }
        }
        return(null);
    }
    
    // FICHIER_XSL
    private Element enregistrerFichierXSL(final Element export, final int index, final String nomF) {
        Element fichier_xsl = trouverFichierXSL(export, index);
        if (fichier_xsl == null) {
            fichier_xsl = doc.createElement("FICHIER_XSL");
            export.appendChild(fichier_xsl);
        }
        if (nomF != null)
            fichier_xsl.setAttribute("nom", nomF);
        return fichier_xsl;
    }
    
    private Element trouverFichierXSL(final Element export, int index) {
        if (index == -1)
            return(null);
        if (export == null)
            return(null);
        int ie = 0;
        for (Node n = export.getFirstChild(); n != null; n = n.getNextSibling()) {
            if (n instanceof Element) {
                if (ie == index)
                    return((Element)n);
                ie++;
            }
        }
        return(null);
    }
    
    // PARAMETRE
    private Element enregistrerParametre(final Element fichier_xsl, final int index, final String nomP, final String valeurP) {
        Element parametre = trouverParametre(fichier_xsl, index);
        if (parametre == null) {
            parametre = doc.createElement("PARAMETRE");
            fichier_xsl.appendChild(parametre);
        }
        if (nomP != null)
            parametre.setAttribute("nom", nomP);
        if (valeurP != null)
            parametre.setAttribute("valeur", valeurP);
            
        return parametre;
    }
    
    private Element trouverParametre(final Element fichier_xsl, int index) {
        if (index == -1)
            return(null);
        if (fichier_xsl == null)
            return(null);
        int ip = 0;
        for (Node n = fichier_xsl.getFirstChild(); n != null; n = n.getNextSibling()) {
            if (n instanceof Element) {
                if (ip == index)
                    return((Element)n);
                ip++;
            }
        }
        return(null);
    }
    
    
    
    
    /**
    * Remplie le(s) panel(s) Export à partir du DOM
    */
    private void recupererExport() {
        listePanelExport.removeAll();
        if (exports != null) {
            Element export = Outils.premierEnfantDeNom(exports, "EXPORT");
            if (export == null)
                export = enregistrerExport(0, null, null);
    
            creerPanelExport(export, 0);
            
            int enfants = exports.getChildNodes().getLength();
            for (int i = 1; i < enfants ; i++) {
                export = Outils.enfantSuivantDeMemeNom(export);
                if (export != null)
                    creerPanelExport(export, i);
            }
        }
    }
    
    /**
    * Remplie le(s) panel(s) Fichier XSL à partir du DOM
    */
    private void recupererFichierXSL(final JPanel panelDest, final Element export) {
        panelDest.removeAll();
        Element fichier_xsl = null;
        if (export != null) {
            fichier_xsl = Outils.premierEnfantDeNom(export, "FICHIER_XSL");
            if (fichier_xsl == null)
                fichier_xsl = enregistrerFichierXSL(export, 0, null);
            
            creerPanelFichierXSL(panelDest, export, fichier_xsl, 0);
            
            int enfants = export.getChildNodes().getLength();
            for (int i = 1; i < enfants ; i++) {
                fichier_xsl = Outils.enfantSuivantDeMemeNom(fichier_xsl);
                if (fichier_xsl != null)
                    creerPanelFichierXSL(panelDest, export, fichier_xsl, i);
            }
        }
    }
    
    /**
    * Remplie le(s) panel(s) Parametre à partir du DOM
    */
    private void recupererParametre(final JPanel panelDest, final Element fichier_xsl) {
        panelDest.removeAll();
        if (fichier_xsl != null) {
            Element parametre = Outils.premierEnfantDeNom(fichier_xsl, "PARAMETRE");
            if (parametre == null)
                parametre = enregistrerParametre(fichier_xsl, 0, null, null);
                
            creerPanelParametre(panelDest, fichier_xsl, parametre, 0);
            
            int enfants = fichier_xsl.getChildNodes().getLength();
            for (int i = 1; i < enfants ; i++) {
                parametre = Outils.enfantSuivantDeMemeNom(parametre);
                if (parametre != null)
                    creerPanelParametre(panelDest, fichier_xsl, parametre, i);
            }
        }
    }
    
    
    // nettoyer le DOM des éléments vide
    private void nettoyerDOM() {
        if (!exports.hasChildNodes())
            racine.removeChild(exports);
        else {
            for (Node n = exports.getFirstChild(); n != null; n = n.getNextSibling()) {
                if (n instanceof Element && "EXPORT".equals(n.getNodeName())) {
                    if (!((Element)n).hasAttribute("nom") || "".equals(((Element)n).getAttribute("nom")))
                        exports.removeChild(n);
                    else {
                        for (Node nd = n.getFirstChild(); nd != null; nd = nd.getNextSibling())
                            if (nd instanceof Element && "FICHIER_XSL".equals(nd.getNodeName()))
                                for (Node ndd = nd.getFirstChild(); ndd != null; ndd = ndd.getNextSibling())
                                    if ( "PARAMETRE".equals(ndd.getNodeName()) && (!((Element)ndd).hasAttribute("nom") || !((Element)ndd).hasAttribute("valeur") || "".equals(((Element)ndd).getAttribute("nom")) || "".equals(((Element)ndd).getAttribute("valeur"))) )
                                        nd.removeChild(ndd);
                        
                    }
                }
            }
        }
    }
    
}
