/*
** FILE:   xt_DocumentTreeSplitPane.java
**
** (c) 1998 Steve Withall.
**
** HISTORY:
**    14Jun98  stevew  Created, split from xt_DocumentTreeFrame.
*/
package xt;

import xc.xc_CustomizerCreationException;
import xc.xc_CustomizerFactory;
import xc.xc_NodeCustomizer;

import xm.xm_DocumentModel;

import xg.xg_Node;

import eh.eh_Debug;

//import com.sun.java.swing.event.DocumentEvent;
//import com.sun.java.swing.event.DocumentListener;
import com.sun.java.swing.event.TreeModelEvent;
import com.sun.java.swing.event.TreeModelListener;
import com.sun.java.swing.event.TreeSelectionEvent;
import com.sun.java.swing.event.TreeSelectionListener;

import com.sun.java.swing.tree.DefaultTreeModel;
import com.sun.java.swing.tree.TreePath;

import com.sun.java.swing.JPanel;
import com.sun.java.swing.JSplitPane;
import com.sun.java.swing.JTree;

import java.awt.BorderLayout;
import java.awt.Container;

//*****************************************************************************
/** A split pane, whose left pane displays a JTree and whose right pane
 *  displays a node customizer for whichever node is currently selected in the
 *  tree. The tree has knowledge of the xm_DocumentModel which it displays, and
 *  it can be notified of document change events relating to it.
 */
public class xt_DocumentTreeSplitPane extends    JSplitPane
                                      implements TreeSelectionListener,
                                                 TreeModelListener
//                                                 DocumentListener
{
	/** The document currently being worked on. */
	xm_DocumentModel      TheDocumentModel      = null;

	/** Factory to create a customizer to display a particular type of node. */
	xc_CustomizerFactory  TheCustomizerFactory  = new xc_CustomizerFactory();

    /** Panel to display the document tree. */
    xt_DocumentTreePanel  DocumentTreePanel     = null;

    /** Panel to display details about the entity currently selected in the tree. */
    xc_NodeCustomizer     CurrentNodeCustomizer = null;

    /** The node which is currently selected in the tree. */
    xg_Node               CurrentNode           = null;

    //*****************************************************************************
    /** Constructor.
      */
    public xt_DocumentTreeSplitPane(xm_DocumentModel  InputDocumentModel)
    {
        super(JSplitPane.HORIZONTAL_SPLIT);
//	    eh_Debug.add(7, "xt_DocumentTreeSplitPane:");  //TEMP
        TheDocumentModel  = InputDocumentModel;

        DocumentTreePanel = new xt_DocumentTreePanel(TheDocumentModel);  // Left hand side

        JTree  DocumentTree = DocumentTreePanel.getTree();
        DocumentTree.addTreeSelectionListener(this);

        CurrentNodeCustomizer = new xc_NodeCustomizer();                 // Right hand side
        //TEMP Use the factory to create a customizer for the root document.

	    setLeftComponent(DocumentTreePanel);
	    setRightComponent(CurrentNodeCustomizer);

//	    TheDocumentModel.addDocumentListener(TheDocumentTree);  //TBD

        DefaultTreeModel  DocumentTreeModel = TheDocumentModel.getDocumentTreeModel();
    	DocumentTreeModel.addTreeModelListener(this);  // Let's be told of changes!
    }

    //*****************************************************************************
    /** Stop listening to tree model changes.
     */
    public void removeTreeModelListener()
    {
	    DefaultTreeModel  DocumentTreeModel = TheDocumentModel.getDocumentTreeModel();
    	DocumentTreeModel.removeTreeModelListener(this);
    }

    //*****************************************************************************
    /** Get the tree scroll pane.
     *
     *  @return  The tree scroll pane
     */
/*    public JScrollPane getTreeScrollPane()
    {
        return TreeScrollPane;
    }
*/
    //*****************************************************************************
    //***Tree*selection*listener*methods*******************************************
    //*****************************************************************************
    /** Invoked when a different node in the tree is selected.
     */
    public void valueChanged(TreeSelectionEvent  InputTreeSelectionEvent)
    {
	    TreePath  NewTreePath = InputTreeSelectionEvent.getNewLeadSelectionPath();
	    eh_Debug.add(6, "xt_DocumentTreeSplitPane.valueChanged: " + NewTreePath.toString() );
	    CurrentNode = (xg_Node)NewTreePath.getLastPathComponent();
	    if (CurrentNode == null)
            eh_Debug.add(2, "xt_DocumentTreeSplitPane.valueChanged: No current node");

	    // Record what is the currently-selected tab, so we can try to maintain
	    // continuity for the next node.
//	    int  CurrentTabIndex = 0;
//	    if (CurrentNodeCustomizer != null)
//            CurrentTabIndex = CurrentNodeCustomizer.getSelectedIndex();

        try
        {
	        // Create a customizer suitable for displaying the newly-selected node.
	        // (This call re-uses the existing customizer if it can.)
	        CurrentNodeCustomizer = TheCustomizerFactory.createCustomizer(CurrentNode,
	                                                                      CurrentNodeCustomizer);
//            CurrentNodeCustomizer.setSelectedIndex(CurrentTabIndex);

	        setRightComponent(CurrentNodeCustomizer);
            updateUI();
        }
        catch (xc_CustomizerCreationException  InputException)
        {
            eh_Debug.add(2, "xt_DocumentTreeSplitPane.valueChanged: Error creating customizer for node "
                                 + CurrentNode.toString() + " (" + InputException + ")");
        }
    }

    //*****************************************************************************
    //***Tree*model*listener*methods***********************************************
    //*****************************************************************************
    /** <p>Invoked after a node (or a set of siblings) has changed in some way. The
     *  node(s) have not changed locations in the tree or altered their children
     *  arrays, but other attributes have changed and may affect presentation.
     *  Example: the name of a file has changed, but it is in the same location in
     *  the file system.</p>
     *
     *  <p>InputTreeModelEvent.path() returns the path the parent of the changed node(s).</p>
     *
     *  <p>InputTreeModelEvent.childIndices() returns the index(es) of the changed node(s).</p>
     */
    public void treeNodesChanged(TreeModelEvent  InputTreeModelEvent)
    {
	    eh_Debug.add(5, "xt_DocumentTreeSplitPane.treeNodesChanged:");
    }

    //*****************************************************************************
    /** <p>Invoked after nodes have been inserted into the tree.</p>
     *
     *  <p>InputTreeModelEvent.path() returns the parent of the new nodes
     *  <p>InputTreeModelEvent.childIndices() returns the indices of the new nodes in
     *  ascending order.
     */
    public void treeNodesInserted(TreeModelEvent  InputTreeModelEvent)
    {
	    eh_Debug.add(5, "xt_DocumentTreeSplitPane.treeNodesInserted:");
    }

    //*****************************************************************************
    /** <p>Invoked after nodes have been removed from the tree.  Note that
     *  if a subtree is removed from the tree, this method may only be
     *  invoked once for the root of the removed subtree, not once for
     *  each individual set of siblings removed.</p>
     *
     *  <p>InputTreeModelEvent.path() returns the former parent of the deleted nodes.</p>
     *
     *  <p>InputTreeModelEvent.childIndices() returns the indices the nodes had before they were deleted in ascending order.</p>
     */
    public void treeNodesRemoved(TreeModelEvent  InputTreeModelEvent)
    {
	    eh_Debug.add(5, "xt_DocumentTreeSplitPane.treeNodesRemoved:");
    }

    //*****************************************************************************
    /** <p>Invoked after the tree has drastically changed structure from a
     *  given node down.  If the path returned by e.getPath() is of length
     *  one and the first element does not identify the current root node
     *  the first element should become the new root of the tree.<p>
     *
     *  <p>InputTreeModelEvent.path() holds the path to the node.</p>
     *  <p>InputTreeModelEvent.childIndices() returns null.</p>
     */
    public void treeStructureChanged(TreeModelEvent  InputTreeModelEvent)
    {
	    eh_Debug.add(5, "xt_DocumentTreeSplitPane.treeStructureChanged:");
    }

    //*****************************************************************************
    //***DocumentListener*methods**************************************************
    //*****************************************************************************
    /** Gives notification that there was an insert into the document. The given
     *  range bounds the freshly inserted region.
     *
     *  @param  InputDocumentEvent - the document event
     */
/*    public void insertUpdate(DocumentEvent  InputDocumentEvent)
    {
	    eh_Debug.add(5, "xt_DocumentTreeSplitPane.insertUpdate: Tree has been told something has been inserted in document");
    }
*/
    //*****************************************************************************
    /** Gives notification that a portion of the document has been removed. The
     *  range is given in terms of what the view last saw (that is, before updating
     *  sticky positions).
     *
     *  @param  InputDocumentEvent - the document event
     */
/*    public void removeUpdate(DocumentEvent  InputDocumentEvent)
    {
	    eh_Debug.add(5, "xt_DocumentTreeSplitPane.removeUpdate: Tree has been told something has been removed from document");
    }
*/
    //*****************************************************************************
    /** Gives notification that an attribute or set of attributes changed.
     *
     *  @param  InputDocumentEvent - the document event
     */
/*    public void changedUpdate(DocumentEvent  InputDocumentEvent)
    {
	    eh_Debug.add(5, "xt_DocumentTreeSplitPane.changedUpdate: Tree has been told something has been changed in document");
    }
*/
}

//*****************************************************************************
