/**
Jaxe - Editeur XML en Java

Copyright (C) 2002 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 jelements;


import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;

import javax.swing.BorderFactory;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.text.Position;

import jaxe.JaxeElement;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * Fichier ou Répertoire externe. Le fichier ou le répertoire n'est pas affiché.
 * Il s'agit d'une méthode pour obtenir un chemin à partir d'un popup pour le placer dans un champ XML.
 * Type d'élément Jaxe: 'JEChemin'
 * Valeur : le nom de l'attribut donnant le nom du fichier ou du répertoire
 * paramètre: type: FILE (defaut) DIRECTORY BOTH
 * paramètre: absolute: nom du champ texte où se trouve la valeur saisie du chemin de base absolu (le premier)
 *
 *
 * Usage:
<AFFICHAGE_ELEMENT element="cheminbase" type="plugin">
<PARAMETRE nom="classe" valeur="jelements.JEChemin"/>
<PARAMETRE nom="type" valeur="DIRECTORY"/>
</AFFICHAGE_ELEMENT>

<AFFICHAGE_ELEMENT element="chemin" type="plugin">
<PARAMETRE nom="classe" valeur="jelements.JEChemin"/>
<PARAMETRE nom="type" valeur="BOTH"/>
<PARAMETRE nom="absolute" valeur="cheminbase"/>
</AFFICHAGE_ELEMENT>

<AFFICHAGE_ELEMENT element="chemin2" type="plugin">
<PARAMETRE nom="classe" valeur="jelements.JEChemin"/>
<PARAMETRE nom="type" valeur="FILE"/>
</AFFICHAGE_ELEMENT>

 */
public class JEChemin extends JaxeElement {

    public final static String defaultTypeAttr = "type";
    public String typeAttr = "FILE";
    public int type = JFileChooser.FILES_ONLY;
    public final static String defaultAbsAttr = "absolute";
    public String absAttr = null;
    public boolean absReady = false;
    public String absolute = null;

    JPanel panel = null;
    JLabel label = null;
    JTextField chemin = null;
    private JEFichierMouseListener listener;

    /**
     * Renvoit le titre qui sera affiché sur les balises de début et de fin :
     * nom de l'élément ou titre, en fonction des options d'affichage.
     */
    public String titreElement() {
        if (refElement != null)
            return(doc.cfg.titreElement(refElement));
        else if (noeud != null)
            return(noeud.getNodeName());
        else if (refElement != null)
            return(doc.cfg.nomElement(refElement));
        else
            return(null);
    }

    // initialisation de l'affichage pour un élément DOM
    public void init(Position pos, Node noeud) {
        // lecture de la valeur de l'élément
        String titre = titreElement();//el.getTagName();
        Node child = noeud.getFirstChild();
        String texte = null;
        if (child != null)
            texte = child.getNodeValue();

        // création du composant Swing
        panel = new JPanel();
        Border border = BorderFactory.createBevelBorder(BevelBorder.LOWERED);
        panel.setBorder(border);
        label = new JLabel(titre);
        chemin = new JTextField(texte);
        panel.add(label);
        panel.add(chemin);
        listener = new JEFichierMouseListener(this, doc.jframe);
        chemin.addMouseListener(listener);

        // insertion du composant dans le texte (insertComponent est une méthode de JaxeElement)
        insertComponent(pos, panel);
    }


    // création d'un nouvel élément DOM
    public Node nouvelElement(Element refElement) {
        if (refElement != null) {
            // récupére le type
            typeAttr = doc.cfg.valeurParametreElement(refElement, defaultTypeAttr, "FILE");
            absAttr = doc.cfg.valeurParametreElement(refElement, defaultAbsAttr, "");
            absReady = true;
            if (absAttr == null || absAttr.length() == 0) {
                absAttr = null;
                absolute = null;
            }
        }
        if (typeAttr.compareToIgnoreCase("FILE") == 0) {
            type = JFileChooser.FILES_ONLY;
        } else if (typeAttr.compareToIgnoreCase("DIRECTORY") == 0) {
            type = JFileChooser.DIRECTORIES_ONLY;
        } else if (typeAttr.compareToIgnoreCase("BOTH") == 0) {
            type = JFileChooser.FILES_AND_DIRECTORIES;
        } else {
            JOptionPane.showMessageDialog(doc.jframe,
                    "Type not specified: FILE by default",
                    defaultTypeAttr+": FILE, DIRECTORY, BOTH",
                    JOptionPane.INFORMATION_MESSAGE);
        }
        Element newel = nouvelElementDOM(doc, refElement);
        String newchemin = selectionnerFichier(null);
        Node textnode = doc.DOMdoc.createTextNode(newchemin);
        newel.appendChild(textnode);
        return (newel);
    }

    // mise à jour de l'affichage des attributs en fonction du DOM
    public void majAffichage() {
        Node child = noeud.getFirstChild();
        if (child != null) {
            String valeur = child.getNodeValue();
            chemin.setText(valeur);
        }
    }

    @Override
    public void afficherDialogue(final JFrame jframe) {
        String newchemin = selectionnerFichier(chemin.getText());
        if (newchemin != null) {
            setValeur(newchemin);
            majAffichage();
        }
    }

    public void setValeur(String valeur) {
        Element el = (Element)noeud;
        Node child = noeud.getFirstChild();
        if (child != null)
            child.setNodeValue(valeur);
        else {
            Node textnode = doc.DOMdoc.createTextNode(valeur);
            el.appendChild(textnode);
        }
        doc.setModif(true);
    }


    public String selectionnerFichier(String oldchemin) {
        String newchemin = oldchemin == null ? "" : oldchemin;
        if (!absReady) {
            absAttr = doc.cfg.valeurParametreElement(refElement, defaultAbsAttr, "");
            absReady = true;
            if (absAttr == null || absAttr.length() == 0) {
                absAttr = null;
                absolute = null;
            }
        }
        if (absAttr != null && absAttr.length() > 0) {
            NodeList list = doc.DOMdoc.getElementsByTagName(absAttr);
            if (list != null && list.getLength() > 0) {
                absolute = list.item(0).getTextContent();
                File file = new File(newchemin);
                if (! file.isAbsolute()) {
                    newchemin = absolute+"/"+newchemin;
                }
            } else {
                absolute = null;
            }
        } else {
            absolute = null;
        }
        JFileChooser fileChooser = new JFileChooser(newchemin);
        fileChooser.setFileSelectionMode(type);
        String title = "Choose a ";
        if (type == JFileChooser.FILES_ONLY) {
            title += "File";
        } else if (type == JFileChooser.DIRECTORIES_ONLY) {
            title += "Directory";
        } else {
            title += "File or Directory";
        }
        int returnVal = fileChooser.showDialog(this.doc.jframe, title);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            newchemin = fileChooser.getSelectedFile().getAbsolutePath();
            if (absolute != null) {
                if (newchemin.startsWith(absolute)) {
                    newchemin = newchemin.substring(absolute.length()+1);
                }
            }
            return newchemin;
        }
        return null;
    }

    class JEFichierMouseListener extends MouseAdapter {
        JEChemin jei;
        JFrame jframe;
        public JEFichierMouseListener(final JEChemin obj, final JFrame jframe) {
            super();
            jei = obj;
            this.jframe = jframe;
        }
        @Override
        public void mouseClicked(final MouseEvent e) {
            jei.afficherDialogue(jframe);
        }

    }
}
