/*
 * 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;
import org.gnu.glib.Type;
import org.gnu.glib.Handle;

/**
 * A tree iterator refers to a particular row of a {@link TreeView} object. They
 * are used internally by many methods, but don't have any useful methods
 * themselves.
 */
public class TreeIter extends Boxed {
    private TreeModel model;

    /**
     * construct iter from handle to native resources.
     */
    public TreeIter(Handle handle, TreeModel model) {
        super(handle);
        this.model = model;
    }

    protected static TreeIter getTreeIter(Handle handle, TreeModel model) {
        if (handle == null) {
            return null;
        }
        TreeIter treeIter = (TreeIter) Boxed.getBoxedFromHandle(handle);
        if (treeIter == null) {
            treeIter = new TreeIter(handle, model);
        }
        return treeIter;
    }

    /**
     * Returns the TreeModel which this Iter is associated with
     */
    public TreeModel getModel() {
        return model;
    }

    /**
     * Returns a newly-created {@link TreePath} referenced by this iter.
     */
    public TreePath getPath() {
        Handle handle = gtk_tree_model_get_path(model.getHandle(), getHandle());
        return TreePath.getTreePath(handle);
    }

    /**
     * Returns the next <code>iter</code> pointing to the node following the
     * TreeIter provided at the same level. If there is no next iter it will
     * return null.
     * <p>
     * Use this in combination with {@link TreeModel#getFirstIter()} to loop
     * through all values in the model.
     */
    public TreeIter getNextIter() {
        Handle hndl = gtk_tree_model_iter_next(model.getHandle(), getHandle());
        return iterFromHandle(hndl);
    }

    /**
     * Returns TRUE if iter has children, FALSE otherwise.
     */
    public boolean getHasChild() {
        return gtk_tree_model_iter_has_child(model.getHandle(), getHandle());
    }

    /**
     * Returns an iterator for the first child of the given iterator, or
     * <code>null</code> if the iter has no children.
     */
    public TreeIter getFirstChild() {
        Handle hndl = gtk_tree_model_iter_children(model.getHandle(),
                getHandle());
        return iterFromHandle(hndl);
    }

    /**
     * Returns an iterator for the child of the given parent at a position
     * identified by index.
     */
    public TreeIter getChild(int index) {
        Handle hndl = gtk_tree_model_iter_nth_child(model.getHandle(),
                getHandle(), index);
        return iterFromHandle(hndl);
    }

    /**
     * Return the parent iterator of the given child.
     */
    public TreeIter getParent() {
        Handle hndl = gtk_tree_model_get_parent(model.getHandle(), getHandle());
        return iterFromHandle(hndl);
    }

    /**
     * Returns the number of children that <code>iter</code> has
     */
    public int getChildCount() {
        return gtk_tree_model_iter_n_children(model.getHandle(), getHandle());
    }

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

    private TreeIter iterFromHandle(Handle hndl) {
        return TreeIter.getTreeIter(hndl, model);
    }

    /**
     * Retrieve the runtime type used by the GLib library.
     */
    public static Type getType() {
        return new Type(gtk_tree_iter_get_type());
    }

    native static final protected int gtk_tree_iter_get_type();

    native static final protected void gtk_tree_iter_free(Handle iter);

    native static final protected String gtk_tree_model_get_string_from_iter(
            Handle treeModel, Handle iter);

    native static final protected Handle gtk_tree_model_get_path(
            Handle treeModel, Handle iter);

    native static final protected Handle gtk_tree_model_get_parent(
            Handle treeModel, Handle iter);

    native static final protected Handle gtk_tree_model_iter_next(
            Handle treeModel, Handle iter);

    native static final protected Handle gtk_tree_model_iter_children(
            Handle treeModel, Handle parent);

    native static final protected boolean gtk_tree_model_iter_has_child(
            Handle treeModel, Handle iter);

    native static final protected int gtk_tree_model_iter_n_children(
            Handle treeModel, Handle iter);

    native static final protected Handle gtk_tree_model_iter_nth_child(
            Handle treeModel, Handle parent, int n);

    native static final protected Handle gtk_tree_model_iter_parent(
            Handle treeModel, Handle child);
}
