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 = (CellRenderer) new CellRendererText();
	column1.packStart( renderer, true );
	column1.addAttributeMapping( renderer, CellRendererText.Attribute.TEXT, dataString);

	CellRenderer renderer2 = (CellRenderer) 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();
  }
}

