/*
 * Copyright 2006, Jeffrey Palm.
 */

var tree;

Jeff.Tree = Class.create();
Jeff.Tree.prototype = {
	
	initialize: function(api,name) {
		this.api = api;
		//
		// maintain a two way map between dfNodes and jeff nodes
		//
		this.jeffNodes2dfNodes = [];
		this.dfNodes2jeffNodes = [];

		//
		// the main tree
		//
		tree = this.tree = new dFTree({name: 'tree'});
		this.nextID=1;
		var caption = 'Main';
		if (name) caption += ' (' + name + ')';
		this.root = new dNode({ id: 0, caption: caption});
		try {
			this.tree.add(this.root, -1);
		} catch (e) {alert(e);}
 		
	},

	main: function() {
		this.root.open();
	},

	addNode: function(node) {
		this._addNode(node,0);
	},

	toggle:  function(newNode,caption) {newNode.setCaption('<em>' + caption + '</em>');},
	untoggle: function(newNode,caption) {newNode.setCaption(caption);},
	
	_addNode: function(node,index) {
		var id = this.nextID++;
		var thiz = this;
		var caption = node.toString();
		var isLeaf = !node.getChildren; // this node is a leaf if it doesn't have a getChildren method
		var newNode = new dNode({ id:id, caption:caption, isLeaf:isLeaf });
		//
		// maintain a map from my nodes to the dfNodes
		// so we can find siblings, etc.
		//
		this.jeffNodes2dfNodes[node] = newNode;
		this.dfNodes2jeffNodes[id] = node;
		var toggle = function() {thiz.toggle(newNode,caption);}
		var untoggle = function() {thiz.untoggle(newNode,caption);}
		var onFirstOpen = function() {
			var msg = 'opening <em>' + node.toString() + '</em>...';
			thiz.api.showMessage(msg);
			if (node.getChildren) {
				toggle();
				try {
					node.getChildren
						(thiz,
						 function(kids) {
							if (!kids) {
								//todo
							} else {								
								for (var i=0; i<kids.length; i++) {
									var n = kids[i];
									if (n) thiz._addNode(n,id);
								}
							}
							thiz.api.showMessage(msg + 'done.');
							untoggle();
						});
				} catch (e) {
					thiz.api.showMessage(msg + 'done with errors: ' + e);
					untoggle();
				}
			} else {

				thiz.api.showMessage(msg + 'no \'open\' method!');
			}
		};
		var onClick = function() {
			if (node.onClick) {
				toggle();
				node.onClick(thiz.api);
				untoggle();
			}
			thiz.api.showOnCanvas(node);
			thiz.api.showOnMap(node,true);
		};
		var onMouseOver = function() {
			if (node.onMouseOver) node.onMouseOver(thiz.api);
		}
		newNode.onFirstOpen = onFirstOpen;
		newNode.onClick = onClick;
		newNode.onMouseOver = onMouseOver;
		this.tree.add(newNode,index);
	},

	draw: function() {
		this.tree.draw();
	},

	getNextSibling: function(node) {
		return this._getSibling(node,1);
	},
	
	getPrevSibling: function(node) {
		return this._getSibling(node,-1);
	},

	_getSibling: function(node,inc) {
		var dfNode = this.jeffNodes2dfNodes[node];
		if (!dfNode) {
			//alert('cannot find node for ' + node);
			return 0;
		}
		var dfParent = dfNode._parent;
		var i = 0;
		while (i<dfParent._children.length && dfParent._children[i].id != dfNode.id) i++;
		if (i<0 || i>=dfParent._children.length) return 0; // not found
		var j =i+inc;
		if (j<0 || j>=dfParent._children.length) return 0; // on an edge
		var dfSibling = dfParent._children[j];
		if (!dfSibling) return 0;
		var jeffNode = this.dfNodes2jeffNodes[dfSibling.id];
		return jeffNode;
	},

	_dummy: function() {}

		
};


