//
//  TreeInterfaceController.java
//  Structure
//
//  Created by Luc-Henri Barthélémy on Thu Nov 30 2006.
//  Copyright (c) 2001 __MyCompanyName__. All rights reserved.
//


package Structure.client;

import com.webobjects.foundation.*;
import com.webobjects.eocontrol.*;
import com.webobjects.eoapplication.*;
import com.webobjects.eodistribution.client.*;
import com.webobjects.eointerface.*;
import com.webobjects.eointerface.swing.*;

import java.util.Enumeration;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;

import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import java.lang.reflect.*;

public class TreeInterfaceController extends EOInterfaceController {

	//
	// les outlets sont publics
	//
	public JScrollPane scrollPane; /* outline du parcours */
	public EODisplayGroup treeDG; /* DG du treeView */
	
	protected JTree tree; /* arbre de choix */
	protected EOTreeAssociation treeAssoc;
	protected DefaultTreeModel treeModel;
	protected String entityName;
	protected String toSonsRelation;
	protected String libelAttribute;
	protected String isLeafMethod;
	protected EOGenericRecord recordRacine;
	protected EOGenericRecord selectedRecord;
	protected EOInterfaceController senderInterface;
	protected TreeSelectionListener tsl;
	
    public TreeInterfaceController() {
        super();
    }

    public TreeInterfaceController(EOEditingContext substitutionEditingContext) {
        super(substitutionEditingContext);
    }

	/**
	public TreeInterfaceController(EOEditingContext substitutionEditingContext, String entity, String toSons, String libelle, EOGenericRecord racine) {
        super(substitutionEditingContext);
		entityName = entity;
		toSonsRelation = toSons;
		recordRacine = racine;
		libelAttribute = libelle;
    }
	**/
	
	public TreeInterfaceController(EOEditingContext substitutionEditingContext, String entity, String toSons, String isLeaf, String libelle, EOGenericRecord racine) {
        super(substitutionEditingContext);
		entityName = entity;
		toSonsRelation = toSons;
		recordRacine = racine;
		isLeafMethod = isLeaf;
		libelAttribute = libelle;
    }
	
	//
	// en fait l entite ne sert a rien
	// elle est forcee par le record affecte
	//
	
	public TreeInterfaceController(EOEditingContext substitutionEditingContext, String toSons, String isLeaf, String libelle, EOGenericRecord racine) {
        super(substitutionEditingContext);
		toSonsRelation = toSons;
		recordRacine = racine;
		isLeafMethod = isLeaf;
		libelAttribute = libelle;
    }
	
	//
	// le meme avec l interfaceController appelant
	//
	public TreeInterfaceController(EOEditingContext substitutionEditingContext, String toSons, String isLeaf, String libelle, EOGenericRecord racine, EOInterfaceController sender) {
        super(substitutionEditingContext);
		toSonsRelation = toSons;
		recordRacine = racine;
		isLeafMethod = isLeaf;
		libelAttribute = libelle;
		senderInterface = sender;
    }
	


	public void connectionWasEstablished()
	{
		//System.out.println("TreeInterfaceController2 connectionWasEstablished ! ");
		if ( !(entityName == null) && !(entityName.equals("")))
			treeDG.setDataSource(new EODistributedDataSource(editingContext(), entityName));
		//affectButton.setEnabled(false);
		activate();
	}
	
	public void componentDidBecomeVisible()
	{
		//System.out.println("componentDidBecomeVisible ");
	}
	
	public NSArray displayGroupDisplayArrayForObjects (EODisplayGroup group, NSArray objects)
	{
		//NSLog.out.appendln("displayGroupDisplayArrayForObjects !");
		return objects;
	}
		
	public void activate()
	{
		
		tree = new JTree();
		treeModel = (DefaultTreeModel)tree.getModel();
		
		
		//
		// Ajout dans le JScrollPane du nib
		//
		scrollPane.getViewport().add(tree);
		
		//setAutosizingMask(Component component, int autosizingMask);
		
		//
		// config du tree
		//
		tree.setRootVisible(false);
		tree.setScrollsOnExpand(true);
		tree.setShowsRootHandles(true);
		tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
		//
		tree.setExpandsSelectedPaths(true);
		//
		// Le JTree est inconnu de la palette IB-EOF
		// par contre l interface de programmation existe bien
		// 
		
		
		treeAssoc = new EOTreeAssociation(tree);
		
		//
		// on cree les EOAssociations et les binds
		// a la mano aussi
		//
		
		//
		// ce bind est essentiel
		// sons est la relation
		// to many vers les sous classes
		//
		
		treeAssoc.bindAspect("children",treeDG,toSonsRelation);
		//treeAssoc.bindAspect("children",treeDG,"toGroupesFils");
		
		// le libelle affiche dans le tree
		treeAssoc.bindAspect("value",treeDG,libelAttribute);
		
		//
		// la methode pour determiner s il s agit d un noeud
		//
		// methode ajoute ds l objet d entreprise
		// ici (VStructurePere) est une vue et isLeaf est cree ds la def de la vue
		//
		
		if(isLeafMethod == null || isLeafMethod.equals(""))
			treeAssoc.bindAspect("isLeaf",treeDG,"isLeaf");
		else
			treeAssoc.bindAspect("isLeaf",treeDG,isLeafMethod);
		
		
		//
		// tout se fait ici
		//
		//
		// LHB Tests de filtre
		//
		
		treeAssoc.establishConnection();
		
		// prevoir la desallocation de l assoc
		disposableRegistry().addObject(treeAssoc);
		
		//
		// oldies : dans IB on associe un qualifier au DG pour qu il ne retourne
		// que la racine : (cStructure = '16721')
		// 
		//treeDG.setSelectsFirstObjectAfterFetch(true);
		
		//
		// le DG renvoie les structures parentes d elles memes (qualifier ds le modele)
		//
		//treeDG.fetch();
		if(recordRacine != null)
			treeDG.setObjectArray(new NSArray(recordRacine));
		
		//
		// on gere la selection a la mano 
		//
		// on ne peut pas se servir du DG
		// car dans celui-ci il n y a qu un seul objet : la racine
		//
		
		tree.addTreeSelectionListener(tsl = new TreeSelectionListener() {
			public void valueChanged(TreeSelectionEvent e) {
				//
				// on passe dans cette classe en cas de selection d un item
				// ds le treeView
				//
				
				//
				// le Jtree est constitue de DefaultMutableTreeNodes
				// qui pointent vers un userObject de type EOSwingTreePlugin._TreeNode
				// qui lui meme pointe vers un objet de type EOEntreprise
				// ici un VStructurePere
				//
				DefaultMutableTreeNode node;
				TreePath treePath;
				//STStructureUlr  myObject = null;
				selectedRecord = null;
				//structure = null;
				//System.out.println("Value changed ! " + e.toString());
				
				node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
				//System.out.println("Path complet "+(selectedPath.toString()));
			    if(node!=null)
				{
					//
					// recuperation du record structure courant
					// putain ca craint !!!
					// il a fallut decompiler le EOSwingTreePlugin
					//
					selectedRecord = (EOGenericRecord)((EOSwingTreePlugin._TreeNode)node.getUserObject()).object();
					_notify_associations(controllerDisplayGroup());
					//affectButton.setEnabled(true);
					//sourceDG.setObjectArray(new NSArray(selectedAssociation));
					//System.out.println("STAssociation selectionnee ! " + selectedAssociation.toString());
				}
			}
		});
		
		
	}
	
	public EOGenericRecord selectedRecord()
	{
		return selectedRecord;
	}
	
	public boolean isSelected()
	{
		if(selectedRecord == null)
			return false;
		else
			return true;
	}
	//
	// Ce truc sert a rafraichir les champs
	//
	protected void _notify_associations (EODisplayGroup  
										 a_display_group) {
		java.util.Enumeration en = a_display_group.observingAssociations ().objectEnumerator();
		while (en.hasMoreElements ()) {
			EOAssociation myAss = (EOAssociation)en.nextElement();
			myAss.subjectChanged ();
		}
		//a_display_group.redisplay();
		a_display_group.updateDisplayedObjects();
	}
	
	public void dispose ()
	{
		if(component().getTopLevelAncestor() != null)
			component().getTopLevelAncestor().setVisible(false);
		tree.removeTreeSelectionListener(tsl);
		super.dispose();
	}
	
	/**
	public void chooseFromSearch()
	{
		NSSelector sel;
		
		if(objetAppelant == null)
			return;
		
		sel = new NSSelector("chooseFromSearch",new Class [] {EOGenericRecord.class});
		try{
			sel.invoke(objetAppelant,(EOGenericRecord)treeController.structure());
		}
		catch (NoSuchMethodException e1)
		{
			System.out.println("Methode non connue");
		}		
		catch (IllegalAccessException e2)
		{
			System.out.println("Access illegal");
		}
		catch (InvocationTargetException e3)
		{
			System.out.println("Cible interdite");
		}
	}
	**/
}
