/* DefaultTreeModel.java -- 
   Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
 
This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */

package javax.swing.tree;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.EventListener;

import javax.swing.event.EventListenerList;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;

/**
 * DefaultTreeModel
 * 
 * @author Andrew Selkirk
 */
public class DefaultTreeModel
    implements Serializable, TreeModel
{
  static final long serialVersionUID = -2621068368932566998L;

  /**
   * root
   */
  protected TreeNode root;

  /**
   * listenerList
   */
  protected EventListenerList listenerList = new EventListenerList();

  /**
   * asksAllowsChildren
   */
  protected boolean asksAllowsChildren;

  /**
   * Constructor DefaultTreeModel where any node can have children.
   * 
   * @param root the tree root.
   */
  public DefaultTreeModel(TreeNode root)
  {
    this (root, false);
  }

  /**
   * Create the DefaultTreeModel that may check if the nodes can have
   * children or not.
   * 
   * @param aRoot the tree root.
   * @param asksAllowsChildren if true, each node is asked if it can have 
   * children. If false, the model does not care about this, supposing, that
   * any node can have children.
   */
  public DefaultTreeModel(TreeNode aRoot, boolean asksAllowsChildren)
  {
    if (aRoot == null)
      aRoot = new DefaultMutableTreeNode();
    this.root = aRoot;
    this.asksAllowsChildren = asksAllowsChildren;
  }

  /**
   * writeObject
   * 
   * @param obj the object.
   * @exception IOException TODO
   */
  private void writeObject(ObjectOutputStream obj) throws IOException
  {
    // TODO
  }

  /**
   * readObject
   * 
   * @param value0 TODO
   * @exception IOException TODO
   * @exception ClassNotFoundException TODO
   */
  private void readObject(ObjectInputStream value0) throws IOException,
      ClassNotFoundException
  {
    // TODO
  }

  /**
   * asksAllowsChildren
   * 
   * @return boolean
   */
  public boolean asksAllowsChildren()
  {
    return asksAllowsChildren;
  }

  /**
   * setAsksAllowsChildren
   * 
   * @param value TODO
   */
  public void setAsksAllowsChildren(boolean value)
  {
    asksAllowsChildren = value;
  }

  /**
   * setRoot
   * 
   * @param root the root node.
   */
  public void setRoot(TreeNode root)
  {
    this.root = root;
  }

  /**
   * getRoot
   * 
   * @return Object
   */
  public Object getRoot()
  {
    return root;
  }

  /**
   * getIndexOfChild
   * 
   * @param parent TODO
   * @param child TODO
   * @return int
   */
  public int getIndexOfChild(Object parent, Object child)
  {
    for (int i = 0; i < getChildCount(parent); i++)
      {
        if (getChild(parent, i).equals(child))
          return i;
      }
    return -1;
  }

  /**
   * getChild
   * 
   * @param node TODO
   * @param idx TODO
   * @return Object
   */
  public Object getChild(Object node, int idx)
  {
    if (node instanceof TreeNode)
      return ((TreeNode) node).getChildAt(idx);
    else
      return null;
  }

  /**
   * getChildCount
   * 
   * @param node TODO
   * @return int
   */
  public int getChildCount(Object node)
  {
    if (node instanceof TreeNode)
      return ((TreeNode) node).getChildCount();
    else
      return 0;
  }

  /**
   * isLeaf
   * 
   * @param node TODO
   * @return boolean
   */
  public boolean isLeaf(Object node)
  {
    if (node instanceof TreeNode)
      return ((TreeNode) node).isLeaf();
    else
      return true;
  }

  /**
   * <p>
   * Invoke this method if you've modified the TreeNodes upon which this model
   * depends. The model will notify all of its listeners that the model has
   * changed. It will fire the events, necessary to update the layout caches and
   * repaint the tree. The tree will <i>not</i> be properly refreshed if you
   * call the JTree.repaint instead.
   * </p>
   * <p>
   * This method will refresh the information about whole tree from the root. If
   * only part of the tree should be refreshed, it is more effective to call
   * {@link #reload(TreeNode)}.
   * </p>
   */
  public void reload()
  {
    // Need to duplicate the code because the root can formally be
    // no an instance of the TreeNode.
    int n = getChildCount(root);
    int[] childIdx = new int[n];
    Object[] children = new Object[n];

    for (int i = 0; i < n; i++)
      {
        childIdx[i] = i;
        children[i] = getChild(root, i);
      }

    fireTreeStructureChanged(this, new Object[] { root }, childIdx, children);
  }

  /**
   * Invoke this method if you've modified the TreeNodes upon which this model
   * depends. The model will notify all of its listeners that the model has
   * changed. It will fire the events, necessary to update the layout caches and
   * repaint the tree. The tree will <i>not</i> be properly refreshed if you
   * call the JTree.repaint instead.
   * 
   * @param node - the tree node, from which the tree nodes have changed
   *          (inclusive). If you do not know this node, call {@link #reload()}
   *          instead.
   */
  public void reload(TreeNode node)
  {
    int n = getChildCount(node);
    int[] childIdx = new int[n];
    Object[] children = new Object[n];

    for (int i = 0; i < n; i++)
      {
        childIdx[i] = i;
        children[i] = getChild(node, i);
      }

    fireTreeStructureChanged(this, getPathToRoot(node), childIdx, children);
  }

  /**
   * Messaged when the user has altered the value for the item 
   * identified by path to newValue. If newValue signifies a truly new 
   * value the model should post a treeNodesChanged event.
   * This sets the user object of the TreeNode identified by 
   * path and posts a node changed. If you use custom user objects 
   * in the TreeModel you're going to need to subclass this and set 
   * the user object of the changed node to something meaningful.
   * 
   * @param path - path to the node that the user has altered
   * @param newValue - the new value from the TreeCellEditor
   */
  public void valueForPathChanged(TreePath path, Object newValue)
  {
    Object node = path.getLastPathComponent();
    if (node instanceof MutableTreeNode)
      {
        ((MutableTreeNode) node).setUserObject(newValue);
        int[] ci = null;
        Object[] c = null; 
        Object[] parentPath = path.getPath();
        if (path.getPathCount() > 1)
          {
            Object parent = ((TreeNode) node).getParent();
            ci = new int[1];
            ci[0] = getIndexOfChild(parent, node);
            node = newValue;
            path = path.getParentPath().pathByAddingChild(node);
            c = new Object[1];
            c[0] = node;
            parentPath = path.getParentPath().getPath();
          }
        
        fireTreeNodesChanged(this, parentPath, ci, c);
      }
    }

  /**
   * Invoked this to insert newChild at location index in parents children.
   * This will then message nodesWereInserted to create the appropriate event. 
   * This is the preferred way to add children as it will create the 
   * appropriate event.
   * 
   * @param newChild is the node to add to the parent's children
   * @param parent is the parent of the newChild
   * @param index is the index of the newChild
   */
  public void insertNodeInto(MutableTreeNode newChild, MutableTreeNode parent,
                             int index)
  {
    newChild.setParent(parent);
    parent.insert(newChild, index);
    int[] childIndices = new int[1];
    childIndices[0] = index;
    nodesWereInserted(parent, childIndices);
  }

  /**
   * Message this to remove node from its parent. This will message 
   * nodesWereRemoved to create the appropriate event. This is the preferred 
   * way to remove a node as it handles the event creation for you.
   * 
   * @param node to be removed
   */
  public void removeNodeFromParent(MutableTreeNode node)
  {
    TreeNode parent = node.getParent();
    Object[] children = new Object[1];
    children[0] = node;
    int[] childIndices = new int[1];
    childIndices[0] = getIndexOfChild(parent, node);
    node.removeFromParent();
    nodesWereRemoved(parent, childIndices, children);
  }

  /**
   * Invoke this method after you've changed how node is to be represented
   * in the tree.
   * 
   * @param node that was changed
   */
  public void nodeChanged(TreeNode node)
  {
    TreeNode parent = node.getParent();
    int[] childIndices = new int[1];
    childIndices[0] = getIndexOfChild(parent, node);
    Object[] children = new Object[1];
    children[0] = node;
    fireTreeNodesChanged(this, getPathToRoot(node), childIndices, children);
  }

  /**
   * Invoke this method after you've inserted some TreeNodes 
   * into node. childIndices should be the index of the new elements and must 
   * be sorted in ascending order.
   * 
   * @param parent that had a child added to
   * @param childIndices of the children added
   */
  public void nodesWereInserted(TreeNode parent, int[] childIndices)
  {
    Object[] children = new Object[childIndices.length];
    for (int i = 0; i < children.length; i++)
      children[i] = getChild(parent, childIndices[i]);
    fireTreeNodesInserted(this, getPathToRoot(parent), childIndices, children);
  }

  /**
   * Invoke this method after you've removed some TreeNodes from node. 
   * childIndices should be the index of the removed elements and 
   * must be sorted in ascending order. And removedChildren should be the 
   * array of the children objects that were removed.
   * 
   * @param parent that had a child added to
   * @param childIndices of the children added
   * @param removedChildren are all the children removed from parent.
   */
  public void nodesWereRemoved(TreeNode parent, int[] childIndices, 
                               Object[] removedChildren)
  {
    fireTreeNodesRemoved(this, getPathToRoot(parent), childIndices, 
                         removedChildren);
  }

  /**
   * Invoke this method after you've changed how the children identified by 
   * childIndices are to be represented in the tree.
   * 
   * @param node that is the parent of the children that changed in a tree.
   * @param childIndices are the child nodes that changed.
   */
  public void nodesChanged(TreeNode node, int[] childIndices)
  {
    Object[] children = new Object[childIndices.length];
    for (int i = 0; i < children.length; i++)
      children[i] = getChild(node, childIndices[i]);
    fireTreeNodesChanged(this, getPathToRoot(node), childIndices, children);
  }

  /**
   * Invoke this method if you've totally changed the children of node and 
   * its childrens children. This will post a treeStructureChanged event.
   * 
   * @param node that had its children and grandchildren changed.
   */
  public void nodeStructureChanged(TreeNode node)
  {
    int n = getChildCount(root);
    int[] childIdx = new int[n];
    Object[] children = new Object[n];

    for (int i = 0; i < n; i++)
      {
        childIdx[i] = i;
        children[i] = getChild(root, i);
      }

    fireTreeStructureChanged(this, new Object[] { root }, childIdx, children);
  }

  /**
   * Builds the parents of node up to and including the root node, where 
   * the original node is the last element in the returned array. The 
   * length of the returned array gives the node's depth in the tree.
   * 
   * @param node - the TreeNode to get the path for
   * @return TreeNode[] - the path from node to the root
   */
  public TreeNode[] getPathToRoot(TreeNode node)
  {
    return getPathToRoot(node, 0);
  }

  /**
   * Builds the parents of node up to and including the root node, where 
   * the original node is the last element in the returned array. The 
   * length of the returned array gives the node's depth in the tree.
   * 
   * @param node - the TreeNode to get the path for
   * @param depth - an int giving the number of steps already taken 
   * towards the root (on recursive calls), used to size the returned array
   * @return an array of TreeNodes giving the path from the root to the 
   * specified node
   */
  protected TreeNode[] getPathToRoot(TreeNode node, int depth)
  {
    if (node == null)
      {
        if (depth == 0)
          return null;
        
        return new TreeNode[depth];
      }

    TreeNode[] path = getPathToRoot(node.getParent(), depth + 1);
    path[path.length - depth - 1] = node;
    return path;
  }

  /**
   * Registers a listere to the model.
   * 
   * @param listener the listener to add
   */
  public void addTreeModelListener(TreeModelListener listener)
  {
    listenerList.add(TreeModelListener.class, listener);
  }

  /**
   * Removes a listener from the model.
   * 
   * @param listener the listener to remove
   */
  public void removeTreeModelListener(TreeModelListener listener)
  {
    listenerList.remove(TreeModelListener.class, listener);
  }

  /**
   * Returns all registered <code>TreeModelListener</code> listeners.
   * 
   * @return an array of listeners.
   * 
   * @since 1.4
   */
  public TreeModelListener[] getTreeModelListeners()
  {
    return (TreeModelListener[]) listenerList
        .getListeners(TreeModelListener.class);
  }

  /**
   * Notifies all listeners that have registered interest for notification 
   * on this event type. The event instance is lazily created using the parameters 
   * passed into the fire method.
   * 
   * @param source the node being changed
   * @param path the path to the root node
   * @param childIndices the indices of the changed elements
   * @param children the changed elements
   */
  protected void fireTreeNodesChanged(Object source, Object[] path,
      int[] childIndices, Object[] children)
  {
    TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
        children);

    TreeModelListener[] listeners = getTreeModelListeners();

    for (int i = listeners.length - 1; i >= 0; --i)
      listeners[i].treeNodesChanged(event);
  }

  /**
   * fireTreeNodesInserted
   * 
   * @param source the node where new nodes got inserted
   * @param path the path to the root node
   * @param childIndices the indices of the new elements
   * @param children the new elements
   */
  protected void fireTreeNodesInserted(Object source, Object[] path,
      int[] childIndices, Object[] children)
  {
    TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
        children);
    TreeModelListener[] listeners = getTreeModelListeners();

    for (int i = listeners.length - 1; i >= 0; --i)
      listeners[i].treeNodesInserted(event);
  }

  /**
   * fireTreeNodesRemoved
   * 
   * @param source the node where nodes got removed-
   * @param path the path to the root node
   * @param childIndices the indices of the removed elements
   * @param children the removed elements
   */
  protected void fireTreeNodesRemoved(Object source, Object[] path,
      int[] childIndices, Object[] children)
  {
    TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
        children);
    TreeModelListener[] listeners = getTreeModelListeners();

    for (int i = listeners.length - 1; i >= 0; --i)
      listeners[i].treeNodesRemoved(event);
  }

  /**
   * fireTreeStructureChanged
   * 
   * @param source the node where the model has changed
   * @param path the path to the root node
   * @param childIndices the indices of the affected elements
   * @param children the affected elements
   */
  protected void fireTreeStructureChanged(Object source, Object[] path,
      int[] childIndices, Object[] children)
  {
    TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
        children);
    TreeModelListener[] listeners = getTreeModelListeners();

    for (int i = listeners.length - 1; i >= 0; --i)
      listeners[i].treeStructureChanged(event);
  }

  /**
   * Returns the registered listeners of a given type.
   *
   * @param listenerType the listener type to return
   *
   * @return an array of listeners
   *
   * @since 1.3
   */
  public EventListener[] getListeners(Class listenerType)
  {
    return listenerList.getListeners(listenerType);
  }
}
