Subversion Repositories eFlore/Applications.cel

Rev

Rev 1292 | Blame | Last modification | View Log | RSS feed

package org.tela_botanica.client.vues.observation.filtres;

import java.util.Comparator;
import java.util.Iterator;

import org.tela_botanica.client.interfaces.Filtrable;
import org.tela_botanica.client.interfaces.Rafraichissable;
import org.tela_botanica.client.modeles.objets.DateObservation;
import org.tela_botanica.client.modeles.objets.ListeDate;
import org.tela_botanica.client.modeles.objets.Observation;
import org.tela_botanica.client.observation.ObservationMediateur;
import org.tela_botanica.client.util.Util;

import com.gwtext.client.data.Node;
import com.gwtext.client.data.NodeTraversalCallback;
import com.gwtext.client.data.Tree;
import com.gwtext.client.widgets.Component;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.event.PanelListenerAdapter;
import com.gwtext.client.widgets.tree.TreeNode;
import com.gwtext.client.widgets.tree.TreePanel;
import com.gwtext.client.widgets.tree.event.TreeNodeListenerAdapter;
import com.gwtext.client.widgets.tree.event.TreePanelListenerAdapter;
import com.gwtext.client.core.EventObject;

/**
 * fenêtre de recherche affichant l'arbre des mots clés en lecture et un bouton
 * cliquable
 * 
 * @author aurelien
 * 
 */
public class ArbreDateObservationFiltreVue extends Panel implements Rafraichissable,
                Filtrable {

        /**
         * Le médiateur associé à la vue
         */
        private ObservationMediateur    observationMediateur            = null;

        /**
         * Les localites en cours
         */
        private String donneesDateEnCours = "";

        /**
         * Le treepanel qui affiche l'arbre
         */
        private TreePanel arbreDonneesDates = null;

        /**
         * La structure de donnees qui stocke l'arbre. Utilisee a ce niveau car trop liee a la vue
         */
        
        /**
         * booléen d'initialisation
         */
        private boolean estInstancie = false;

        /**
         * booléen d'etat
         */
        private boolean filtreModifie = false;
        
        private boolean arbreCharge = false ;

        private String nomFiltre = "" ;
        
        /**
         * Constructeur sans argument (privé car ne doit pas être utilisé)
         */
        @SuppressWarnings("unused")
        private ArbreDateObservationFiltreVue() {
                super();
        }

        /**
         * Constructeur avec paramètres
         * 
         * @param im
         *            le médiateur à associer
         */
        public ArbreDateObservationFiltreVue(ObservationMediateur obs) {

                // on crée le panel
                super("Dates");
                
                this.observationMediateur = obs;

                arbreDonneesDates = new TreePanel();

                this.setPaddings(5);

                this.setCollapsible(true);
                this.setAutoScroll(true);
                
                // on ajoute les listeners
                ajouterListenersPanel();
                estInstancie = false;
        }

        /**
         * Ajoute les listeners pour le rendu du panel
         */
        private void ajouterListenersPanel() {
                  this.addListener(new PanelListenerAdapter() {

                        // on instancie réellement les composants au moment du rendu pour
                        // accélérer l'affichage
                        // et éviter des bugs
                        @Override
                        public void onRender(Component component) {

                                // on interdit le drag and drop dans l'arbre
                                arbreDonneesDates.setEnableDD(false);
                                arbreDonneesDates.setId("x-view-tree-filter-date");
                                
                                
                                arbreDonneesDates.setBorder(false);

                                // on crée une racine pour l'arbre
                                TreeNode root = new TreeNode("Dates");
                                root.setId("racine_date");
                                String[] usObject = { "Dates", "Dates", "racine_date" };
                                root.setUserObject(usObject);

                                arbreDonneesDates.setRootNode(root);
                                arbreDonneesDates.setRootVisible(true);
                                arbreDonneesDates.setBorder(false);
                                root.setExpandable(true) ;

                                add(arbreDonneesDates);

                                // on ajoute les listeners d'évenements
                                ajouterListeners();

                                
                                // enfin on considère le composant comme instancié
                                estInstancie = true;

                                
                        }

                });
        }

        
        
        /**
         * ajoute les listeners pour les boutons et le cochage des entites
         */
        private void ajouterListeners() {
                
                arbreDonneesDates.addListener(new TreePanelListenerAdapter() {
                        
                        @Override
                        public void onClick(TreeNode node, EventObject e) {
                                gererClicNoeud(node);
                        }
                        
                }) ;
                
                arbreDonneesDates.getRootNode().addListener(new TreeNodeListenerAdapter() {
                        
                        @Override
                        public void onExpand(Node node) {
                                if(!arbreCharge)
                                {
                                        observationMediateur.obtenirDatesObservation() ;
                                        arbreCharge = true ;
                                }
                        }
                        
                }) ;
        }
        
        private void gererClicNoeud(TreeNode node) {
                
                mettreAJourValeurEnCours(node);
                observationMediateur.obtenirNombreObservation() ;               
        }
        
        private void mettreAJourValeurEnCours(TreeNode node) {
                
                nomFiltre = "" ;
                donneesDateEnCours = "" ;
                String nomPere = "" ;
                String nomGrandPere = "" ;
                
                switch(node.getDepth()) 
                {
                        case 0:
                                if(arbreCharge) {
                                        nomFiltre = "";
                                        donneesDateEnCours = "";
                                }
                                break;
                        case 3: nomFiltre += "annee,mois,jour";
                                nomPere = ((String[])node.getParentNode().getUserObject())[1] ;
                                nomGrandPere = ((String[])node.getParentNode().getParentNode().getUserObject())[1] ;
                                donneesDateEnCours += nomGrandPere+","+nomPere+","+((String[])node.getUserObject())[1] ;
                                break;
                        case 2: nomFiltre += "annee,mois"; 
                                nomPere = ((String[])node.getParentNode().getUserObject())[1] ;
                                donneesDateEnCours += nomPere+","+((String[])node.getUserObject())[1] ;
                                break;
                        case 1: nomFiltre += "annee"; 
                                donneesDateEnCours += ((String[])node.getUserObject())[1] ;
                                break;
                        default: 
                                break;
                }
                
                filtreModifie = true ;  
        }
        
        public void initialiser() {
                
                arbreCharge = false ;
                donneesDateEnCours = "";
                arbreDonneesDates.collapseAll();
                
                // on vide l'ancien arbre
                Node[] rootChild = arbreDonneesDates.getRootNode().getChildNodes();
                for (int i = 0; i < rootChild.length; i++) {
                        
                        rootChild[i].remove();
                }
                
                arbreDonneesDates.getRootNode().addListener(new TreeNodeListenerAdapter() {
                        
                        @Override
                        public void onExpand(Node node) {
                                if(!arbreCharge)
                                {
                                        observationMediateur.obtenirDatesObservation() ;
                                        arbreCharge = true ;
                                }
                        }
                        
                }) ;
        }

        /**
         * Méthode héritée de l'interface rafraichissable
         */
        @Override
        public void rafraichir(Object nouvelleDonnees,
                        boolean repandreRaffraichissement) {
                
                if (nouvelleDonnees instanceof ListeDate) {
                        
                        String annee=null;
                        String mois=null;
                        String jour=null;
                        
                        ListeDate data = (ListeDate) nouvelleDonnees ;
                        
                                // on crée un arbre vide
                                TreeNode root = new TreeNode();
                                root.setId("racine_date");
                                root.setText("Dates");
                                String[] usObjRoot = { "Dates", "Dates", "racine_date"};
                                root.setUserObject(usObjRoot);
                                Tree nouvelArbre = new Tree();
                                nouvelArbre.setRootNode(root);
                        
                        // on la parse et on récupère les informations qui nous interessent
                        for (Iterator<String> it= data.keySet().iterator(); it.hasNext();) {
                                
                                DateObservation ent=data.get(it.next());
                                
                                annee= ent.getAnnee() ;
                                mois= ent.getMois() ;
                                String moisLettre = Util.renvoyerMois(Integer.parseInt(mois)) ;
                                jour= ent.getJour() ;
                                
                                if(annee.contains("0000")) {
                                        annee="Inconnue" ;
                                }
                                
                                if(jour.contains("00")) {
                                        jour="Inconnue" ;
                                }
                                
                                Node noeudMemeAnnee = nouvelArbre.getNodeById(""+annee);
                                // si la région existe déjà
                                        if(noeudMemeAnnee != null)
                                        {
                                                // on teste si la localité existe
                                                Node noeudMemeMois = nouvelArbre.getNodeById(""+(annee+mois));
                                                if(noeudMemeMois != null)
                                                {
                                                        // enfin on teste si le lieu dit existe
                                                        Node noeudMemeJour = nouvelArbre.getNodeById(""+(annee+mois+jour));
                                                        if(noeudMemeJour != null)
                                                        {
                                                                // tous les noeuds existent déjà, normalement ça ne devrait pas arriver
                                                        }
                                                        else
                                                        {
                                                                // enfin on ne crée que le noeud du lieu dit
                                                                TreeNode node_jour = new TreeNode();
                                                                node_jour.setId(""+(annee+mois+jour));
                                                                node_jour.setText(jour);
                                                                noeudMemeMois.appendChild(node_jour) ;
                                                                String[] usObj = {jour,jour,annee+mois+jour};
                                                                node_jour.setUserObject(usObj);
                                                        }
                                                }
                                                else
                                                {
                                                        TreeNode node_mois = new TreeNode();
                                                        node_mois.setId(""+(annee+mois));
                                                        node_mois.setText(moisLettre);
                                                        noeudMemeAnnee.appendChild(node_mois) ;
                                                        String[] usObj = {moisLettre,mois,annee+mois};
                                                        node_mois.setUserObject(usObj);
                                                        
                                                        TreeNode node_jour = new TreeNode();
                                                        node_jour.setId(""+(annee+mois+jour));
                                                        node_jour.setText(jour);
                                                        node_mois.appendChild(node_jour) ;
                                                        String[] usObj2 = {jour,jour,annee+mois+jour};
                                                        node_jour.setUserObject(usObj2);
                                                        
                                                }
                                        }
                                        else
                                        {
                                                TreeNode node_annee = new TreeNode();
                                                node_annee.setId(""+annee);
                                                node_annee.setText(annee);
                                                root.appendChild(node_annee) ;
                                                String[] usObj = {annee, annee, annee};
                                                node_annee.setUserObject(usObj);
                                                
                                                TreeNode node_mois = new TreeNode();
                                                node_mois.setId(""+(annee+mois));
                                                node_mois.setText(moisLettre);
                                                node_annee.appendChild(node_mois) ;
                                                String[] usObj2 = {moisLettre,mois,annee+mois};
                                                node_mois.setUserObject(usObj2);
                                                
                                                TreeNode node_jour = new TreeNode();
                                                node_jour.setId(""+(annee+mois+jour));
                                                node_jour.setText(jour);
                                                node_mois.appendChild(node_jour) ;
                                                String[] usObj3 = {jour,jour,annee+mois+jour};
                                                node_jour.setUserObject(usObj3);
                                        }

                                }
                        
                        
                                // on trie
                                root.sort(comparerNoeuds()) ;
                        
                                // on vide tous les noeuds
                                arbreDonneesDates.getRootNode().eachChild(new NodeTraversalCallback() {
        
                                        @Override
                                        public boolean execute(Node node) {
        
                                                node.remove();
                                                return true;
                                        }
        
                                });

                                // et on recopie le nouvel arbre
                                copierFilsNoeud(nouvelArbre.getRootNode(), arbreDonneesDates
                                                .getRootNode());
                                
                                // si l'arbre n'était pas encore considéré comme instancié
                                if (!estInstancie) {
                                        // on signale que oui
                                        estInstancie = true;
                                }
                                
        
                                // l'état du filtre est réinitialisé
                                filtreModifie = false;
                                //show() ;
                                doLayout();

                        }
                
                if(nouvelleDonnees instanceof Observation)
                {
                        // si l'arbre n'est pas encore chargé, on ne tient pas compte de l'ajout
                        // l'arbre complet sera de toute façon renvoyé plus tard lors du premier chargement
                        // de l'arbre
                        if(!arbreCharge) {
                                return;
                        }
                        
                        Observation ent = (Observation)nouvelleDonnees ;
                        String dateSpl[] = ent.getDate().split("/") ;
                        
                        String annee= dateSpl[2];
                        String mois= dateSpl[1];
                        String jour= dateSpl[0];
                        
                        String moisLettre = Util.renvoyerMois(Integer.parseInt(mois)) ;
                        
                        Node root = arbreDonneesDates.getRootNode() ;
                        
                        if(annee.contains("0000") || annee.equals(null)) {
                                annee="Inconnue" ;
                        }
                        
                        if(jour.contains("00") || jour.equals(null)) {
                                jour="Inconnue" ;
                        }
                        
                        Node noeudMemeAnnee = arbreDonneesDates.getNodeById(""+annee);
                        // si la région existe déjà
                                if(noeudMemeAnnee != null)
                                {       
                                        // on teste si la localité existe
                                        Node noeudMemeMois = arbreDonneesDates.getNodeById(""+(annee+mois));
                                        if(noeudMemeMois != null)
                                        {
                                                // enfin on teste si le lieu dit existe
                                                Node noeudMemeJour = arbreDonneesDates.getNodeById(""+(annee+mois+jour));
                                                if(noeudMemeJour != null)
                                                {
                                                        // tous les noeuds existent déjà, normalement ça ne devrait pas arriver
                                                }
                                                else
                                                {
                                                        // enfin on ne crée que le noeud du lieu dit
                                                        TreeNode node_jour = new TreeNode();
                                                        node_jour.setId(""+(annee+mois+jour));
                                                        node_jour.setText(jour);
                                                        String[] usObj = {jour,jour,annee+mois+jour};
                                                        node_jour.setUserObject(usObj);
                                                        noeudMemeMois.appendChild(node_jour) ;
                                                        
                                                        root.sort(comparerNoeuds()) ;
                                                }
                                        }
                                        else
                                        {
                                                TreeNode node_mois = new TreeNode();
                                                node_mois.setId(""+(annee+mois));
                                                node_mois.setText(moisLettre);
                                                String[] usObj = {moisLettre,mois,annee+mois};
                                                node_mois.setUserObject(usObj);
                                                noeudMemeAnnee.appendChild(node_mois) ;
                                                
                                                TreeNode node_jour = new TreeNode();
                                                node_jour.setId(""+(annee+mois+jour));
                                                node_jour.setText(jour);
                                                String[] usObj2 = {jour,jour,annee+mois+jour};
                                                node_jour.setUserObject(usObj2);
                                                node_mois.appendChild(node_jour) ;
                                                
                                                root.sort(comparerNoeuds()) ;
                                        }
                        }
                        else
                        {
                                
                                TreeNode node_annee = new TreeNode();
                                node_annee.setId(""+annee);
                                node_annee.setText(annee);
                                String[] usObj = {annee,annee,annee};
                                node_annee.setUserObject(usObj);
                                root.appendChild(node_annee) ;
                                
                                TreeNode node_mois = new TreeNode();
                                node_mois.setId(""+(annee+mois));
                                node_mois.setText(moisLettre);
                                String[] usObj2 = {moisLettre,mois,annee+mois};
                                node_mois.setUserObject(usObj2);
                                node_annee.appendChild(node_mois) ;
                                
                                TreeNode node_jour = new TreeNode();
                                node_jour.setId(""+(annee+mois+jour));
                                node_jour.setText(jour);
                                String[] usObj3 = {jour,jour,annee+mois+jour};
                                node_jour.setUserObject(usObj3);
                                node_mois.appendChild(node_jour) ;
                                
                                // TODO : améliorer la compararaison des noeuds
                                root.sort(comparerNoeuds()) ;
                        }
                                
                                arbreDonneesDates.doLayout() ;
                }
        }


        /**
         * Accesseur pour le panneau contenant l'arbre
         * 
         * @return le panneau de l'arbre des mots clés
         */
        public TreePanel getArbreMotsCles() {
                return arbreDonneesDates;
        }

        /**
         * Méthode héritée de Filtrable renvoie le nom du filtre
         */
        @Override
        public String renvoyerNomFiltre() {

                return "Dates";
        }

        /**
         * Renvoie un tableau contenant le nom du champ à filtrer et la valeur
         * 
         * @return un tableau contenant le nom du champ à filtrer et sa valeur
         */
        @Override
        public String[] renvoyerValeursAFiltrer() {

                valider();
                
                String valeursFiltrees[] = {nomFiltre, donneesDateEnCours } ;

                return valeursFiltrees;
        }

        /**
         * Fonction récursive qui prend deux noeuds d'arbre en paramètre et crée un
         * copie du sous arbre du premier noeud, qu'elle concatène au deuxième
         * 
         * @param ndPereOriginal
         *            le père des noeuds de l'arbre original
         * @param ndPereCopie
         *            le père qui va recevoir les copies
         */
        private void copierFilsNoeud(Node ndPereOriginal, TreeNode ndPereCopie) {
                if (ndPereCopie != null && ndPereOriginal != null) {
                        Node[] ndNodeFils = ndPereOriginal.getChildNodes();

                        for (int i = 0; i < ndNodeFils.length; i++) {

                                String[] usObj = (String[]) ndNodeFils[i].getUserObject();
                                TreeNode child = new TreeNode(usObj[0]);
                                child.setUserObject(usObj);
                                child.setId(""+usObj[2]);
                                ndPereCopie.appendChild(child);

                                if (!ndNodeFils[i].isLeaf()) {
                                        copierFilsNoeud(ndNodeFils[i], child);
                                }

                        }
                }
        }

        /**
         * Méthode héritée de Filtrable Renvoie l'état du filtre (modifié ou non)
         */
        @Override
        public boolean renvoyerEtatFiltre() {

                return filtreModifie;
        }

        @Override
        public void valider() {
                
                if (estInstancie) {
                        
                }
        }
        
        public Comparator<TreeNode> comparerNoeuds()
        {
                return new Comparator<TreeNode>() {

                        @Override
                        public int compare(TreeNode o1, TreeNode o2) {
                                
                                String n1 = ((String[])o1.getUserObject())[1] ;
                                String n2 = ((String[])o2.getUserObject())[1] ;
                                
                                return n1.compareTo(n2) ;
                        }
                        
                } ;
        }

        public void raz() {
                                
                arbreCharge = false ;
                arbreDonneesDates.collapseAll();
                arbreDonneesDates.clear();
                
                TreeNode root = new TreeNode("Dates");
                root.setId("racine_date");
                String[] usObject = { "Dates", "Dates", "racine_date" };
                root.setUserObject(usObject);

                arbreDonneesDates.setRootNode(root);
                
                arbreDonneesDates.getRootNode().addListener(new TreeNodeListenerAdapter() {
                        
                        @Override
                        public void onExpand(Node node) {
                                if(!arbreCharge)
                                {
                                        observationMediateur.obtenirDatesObservation() ;
                                        arbreCharge = true ;
                                }
                        }
                        
                }) ;
                
                this.doLayout() ;
                
                donneesDateEnCours = "";
                
        }

        @Override
        public void viderFiltre() {
                arbreDonneesDates.getSelectionModel().clearSelections();
                donneesDateEnCours = "";                
        }

        public void viderFiltre(String nom) {
                
                final int profondeur = calculerProfondeurPourNomFiltre(nom);
                
                // on vide tous les noeuds
                arbreDonneesDates.getRootNode().cascade(new NodeTraversalCallback() {

                        @Override
                        public boolean execute(Node node) {
                                
                                boolean continuer = true;
                                
                                TreeNode noeudArbreEncours = (TreeNode)node;
                                
                                if(arbreDonneesDates.getSelectionModel().isSelected(noeudArbreEncours)) {
                                        
                                        int profondeurDepart = noeudArbreEncours.getDepth();
                                        
                                        for(int profondeurNoeudArbreEncours = profondeurDepart; profondeurNoeudArbreEncours >= profondeur; profondeurNoeudArbreEncours--) {
                                                noeudArbreEncours = (TreeNode)noeudArbreEncours.getParentNode();
                                        }
                                        
                                        arbreDonneesDates.getSelectionModel().select(noeudArbreEncours); 
                                        mettreAJourValeurEnCours(noeudArbreEncours);
                                        
                                        continuer = false;
                                }
                                
                                return continuer;
                        }

                });
        }
        
        private int calculerProfondeurPourNomFiltre(String nom) {
                
                int profondeur = 0;
                
                if(nom.equals("annee")) {
                        profondeur = 1;
                }
                
                if(nom.equals("mois")) {
                        profondeur = 2;
                }
                
                if(nom.equals("jour")) {
                        profondeur = 3;
                }
                
                return profondeur;
        }
}