package tree;

import java.io.FileNotFoundException;

import org.gnu.gdk.Pixbuf;
import org.gnu.glib.JGException;
import org.gnu.gtk.CellRenderer;
import org.gnu.gtk.CellRendererPixbuf;
import org.gnu.gtk.CellRendererText;
import org.gnu.gtk.CellRendererToggle;
import org.gnu.gtk.DataColumn;
import org.gnu.gtk.DataColumnBoolean;
import org.gnu.gtk.DataColumnInt;
import org.gnu.gtk.DataColumnPixbuf;
import org.gnu.gtk.DataColumnString;
import org.gnu.gtk.Gtk;
import org.gnu.gtk.TreeIter;
import org.gnu.gtk.TreeStore;
import org.gnu.gtk.TreeView;
import org.gnu.gtk.TreeViewColumn;
import org.gnu.gtk.Window;
import org.gnu.gtk.WindowType;
import org.gnu.gtk.event.LifeCycleEvent;
import org.gnu.gtk.event.LifeCycleListener;

/**
 * An example of the use of the tree widget
 */
public class TreeExample {

    public TreeExample() throws FileNotFoundException, JGException {
        Window window = new Window(WindowType.TOPLEVEL);
        window.setTitle("Tree Example");
        window.addListener(new LifeCycleListener() {
            public void lifeCycleEvent(LifeCycleEvent event) {
            }

            public boolean lifeCycleQuery(LifeCycleEvent event) {
                if (event.isOfType(LifeCycleEvent.Type.DESTROY)
                        || event.isOfType(LifeCycleEvent.Type.DELETE)) {
                    Gtk.mainQuit();
                }
                return false;
            }
        });

        // Make some data blocks to refer to the data for the tree
        DataColumnString dataString = new DataColumnString();
        DataColumnInt dataInt = new DataColumnInt();
        DataColumnBoolean dataBool = new DataColumnBoolean();
        DataColumnPixbuf dataPix = new DataColumnPixbuf();

        // Construct a new store for the data of the tree.
        TreeStore store = new TreeStore(new DataColumn[] { dataString, dataInt,
                dataBool, dataPix });

        // create a new row in the column
        TreeIter iter = store.appendRow(null);
        store.setValue(iter, dataString, "First added");
        store.setValue(iter, dataInt, 12345);
        store.setValue(iter, dataBool, true);
        store.setValue(iter, dataPix, new Pixbuf("tree/test.xpm"));

        // add a second row before the first
        TreeIter iter2 = store.insertRowBefore(iter, null);
        store.setValue(iter2, dataString, "inserted before first");
        store.setValue(iter2, dataInt, 00001);
        store.setValue(iter2, dataBool, false);

        // Add a child to that node
        TreeIter iter3 = store.appendRow(iter2);
        store.setValue(iter3, dataString, "First Child");
        store.setValue(iter3, dataInt, 908);
        store.setValue(iter3, dataBool, true);
        store.setValue(iter3, dataPix, new Pixbuf("tree/test.xpm"));

        // Give that child a brother
        TreeIter iter4 = store.appendRow(iter2);
        store.setValue(iter4, dataString, "First Child's brother");
        store.setValue(iter4, dataInt, 909);
        store.setValue(iter4, dataBool, true);

        // make a grandchild from that last one.
        TreeIter iter5 = store.appendRow(iter4);
        store.setValue(iter5, dataString, "First Child's brother's child ;)");
        store.setValue(iter5, dataInt, 5463);
        store.setValue(iter5, dataBool, false);

        // finally insert a node at the specified position (1: after 0, before
        // 1) in
        // the children
        TreeIter iter6 = store.insertRow(iter2, 1);
        store.setValue(iter6, dataString, "Another child");
        store.setValue(iter6, dataInt, 5463);
        store.setValue(iter6, dataBool, false);

        // /////////////////////////////////////////////////////////////
        // Construct the widget, using teh above defined store.
        TreeView treeWidget = new TreeView(store);

        // create a new column to be visible in the output, set a title for it
        // and
        // append it to the tree.
        TreeViewColumn column1 = new TreeViewColumn();
        column1.setTitle("Main Data");
        treeWidget.appendColumn(column1);

        // Add renderers to that column to display the data and associate the
        // data
        // blocks in the store with the renderer attributes.
        CellRenderer renderer = new CellRendererText();
        column1.packStart(renderer, true);
        column1.addAttributeMapping(renderer, CellRendererText.Attribute.TEXT,
                dataString);

        CellRenderer renderer2 = new CellRendererText();
        column1.packStart(renderer2, true);
        column1.addAttributeMapping(renderer2, CellRendererText.Attribute.TEXT,
                dataInt);

        // Lets have the boolean value's on another column...
        TreeViewColumn column2 = new TreeViewColumn();
        column2.setTitle("Completed?");
        treeWidget.appendColumn(column2);

        // add the renderer and associate data - we're using the same data as in
        // the
        // first column - that's no problem.
        CellRendererToggle renderer3 = new CellRendererToggle();
        renderer3.setUserEditable(true);
        column2.packStart(renderer3, true);
        column2.addAttributeMapping(renderer3,
                CellRendererToggle.Attribute.ACTIVE, dataBool);

        // A third column to demonstrate the use of pixmaps
        TreeViewColumn column3 = new TreeViewColumn();
        column3.setTitle("Pixbufs");
        treeWidget.appendColumn(column3);

        // And for the renderer...
        CellRendererPixbuf pixRenderer = new CellRendererPixbuf();
        column3.packStart(pixRenderer, true);
        column3.addAttributeMapping(pixRenderer,
                CellRendererPixbuf.Attribute.PIXBUF, dataPix);

        // Make the columns resizable and reorderable.
        column1.setResizable(true);
        column1.setReorderable(true);
        column2.setResizable(true);
        column2.setReorderable(true);
        column3.setResizable(true);
        column3.setReorderable(false);

        window.add(treeWidget);
        treeWidget.show();
        window.show();

    }

    public static void main(String[] args) {
        Gtk.init(args);
        try {
            TreeExample te = new TreeExample();
        } catch (FileNotFoundException e) {
            System.out.println(e);
            System.out.println("Unable to find pixmaps");
            Gtk.mainQuit();
        } catch (JGException jge) {
            System.out.println(jge);
            System.out.println("Error loading pixmaps");
            Gtk.mainQuit();
        }

        Gtk.main();
    }
}
