/*
 * Java-Gnome Bindings Library
 *
 * Copyright 1998-2004 the Java-Gnome Team, all rights reserved.
 *
 * The Java-Gnome bindings library is free software distributed under
 * the terms of the GNU Library General Public License version 2.
 */

package org.gnu.gtk;
import org.gnu.glib.Boxed;

/**
 * A path refers to a single row in a {@link TreeStore}. In this respect, it is
 * similar to a {@link TreeIter}, however a path also contains details of the
 * structure of the tree (TreeIter is a generic object for the entire TreeView
 * family, including flat lists and tables.)
 */
public class TreePath extends Boxed 
{
	/**
	 * Construct path from native handle
	 */
	protected TreePath(int handle){
		this.handle = handle;
	}

	/**
	 * Constructs a new path.
	 */
	public TreePath(){
		handle = gtk_tree_path_new ();
	}

	/**
	 * Creates a new TreePath initialized to <code>path</code>. <code>path</code>
	 * is expected to be a colon separated list of numbers. For example, the 
	 * string "10:4:0" would create a path of depth 3 pointing to the 11th child 
	 * of the root node, the 5th child of that 11th child, and the 1st child of 
	 * that 5th child. If an invalid path string is passed in, NULL is returned.
	 * TODO: throw an exception on null response.
	 */
	public TreePath(String path){
		handle = gtk_tree_path_new_from_string(path);
	}

	/**
	 * Generates a string representation of the path. This string is a ':' 
	 * separated list of numbers. For example, "4:10:0:3" would be an 
	 * acceptable return value for this string.
	 * @return String representation of the path.
	 */
	public String toString(){
		return gtk_tree_path_to_string(handle);
	}

	/**
	 * Returns the current depth of path.
	 */
	public int getDepth(){
		return gtk_tree_path_get_depth(handle);
	}

	/**
	 * TODO: gtk_tree_path_get_indices ()
	 */

	/**
	 * Compares the path with another path. If the other path appears before this 
	 * one in a tree, then -1 is returned. If this one appears before the other, 
	 * then 1 is returned. If the two nodes are equal, then 0 is returned.
	 */
	public int compare(TreePath other){
		return gtk_tree_path_compare(other.getHandle(), handle);
	}

	/**
	 * Moves the path to point to the next node at the current depth.
	 */
	public void next(){
		 gtk_tree_path_next(handle);
	}

	/**
	 * Moves the path to point to the previous node at the current depth, if it 
	 * exists.
	 * @return TRUE if path has a previous node, and the move was made.
	 */
	public boolean previous(){
		return	gtk_tree_path_prev(handle);
	}

	/**
	 * Moves the path to point to it's parent node, if it has a parent.
	 * @return TRUE if path has a parent, and the move was made.
	 */
	public boolean up(){
		return gtk_tree_path_up(handle);
	}

	/**
	 * Moves path to point to the first child of the current path.
	 */
	public void down(){
		gtk_tree_path_down(handle);
	}

	/**
	 * Returns TRUE if descendant is a descendant of path.
	 * @param descendant Another TreePath
	 * @return TRUE if descendant is contained inside path
	 */
	public boolean isAncestor(TreePath descendant){
		return gtk_tree_path_is_ancestor(handle, descendant.getHandle());
	}

	/**
	 * Returns TRUE if path is a descendant of ancestor.
	 * @param ancestor Another TreePath
	 * @return TRUE if ancestor contains path somewhere below it
	 */
	public boolean isDescendant(TreePath ancestor){
		return gtk_tree_path_is_descendant(handle, ancestor.getHandle());
	}
	
	/**
	 * Appends a new index to the path. As a result, the depth of the
	 * path is increased
	 * @param index
	 */
	public void appendIndex(int index) {
		gtk_tree_path_append_index(handle, index);
	}
	
	/**
	 * Prepends a new index to the path. As a result, the depth of the
	 * path is increased
	 * @param index
	 */
	public void prependIndex(int index) {
		gtk_tree_path_prepend_index(handle, index);
	}
	
	/**
	 * Returns the current indices of the path.
	 * @return  An array of ints, each representing a node in the tree.
	 */
	public int[] getIndices() {
		return gtk_tree_path_get_indices(handle);
	}


    /****************************************
     * BEGINNING OF JNI CODE
     ****************************************/
    native static final protected int gtk_tree_path_new ();
    native static final protected int gtk_tree_path_new_from_string (String path);
    native static final protected String gtk_tree_path_to_string (int path);
    native static final protected int gtk_tree_path_new_first ();
    native static final protected void gtk_tree_path_append_index (int path, int index);
    native static final protected void gtk_tree_path_prepend_index (int path, int index);
    native static final protected int gtk_tree_path_get_depth (int path);
    native static final protected int[] gtk_tree_path_get_indices(int path);
    native static final protected int gtk_tree_path_compare (int a, int b);
    native static final protected void gtk_tree_path_next (int path);
    native static final protected boolean gtk_tree_path_prev (int path);
    native static final protected boolean gtk_tree_path_up (int path);
    native static final protected void gtk_tree_path_down (int path);
    native static final protected boolean gtk_tree_path_is_ancestor (int path, int descendant);
    native static final protected boolean gtk_tree_path_is_descendant (int path, int ancestor);
    /****************************************
     * END OF JNI CODE
     ****************************************/
}

