function TreeView(elementid,name,imageroot) {
	this.elementid = elementid;
	this.container = layer.get(elementid);
	this.imageroot = imageroot;
	this.name = name;
	this.idindex = new Array();
	this.selectednode = null;
	
	this.onfetchitems = null;
	this.candragnodes = false;
}

TreeView.prototype.clear = function() {
	while (this.container.childNodes.length>0) {
		var node = this.container.childNodes[ this.container.childNodes.length-1 ];
		this.container.removeChild(node);
		node = undefined;
	}
	this.selectednode = null;
	this.idindex = new Array();
}

TreeView.prototype.delete_node = function(nodeindex) {
	var node = this.container.childNodes[nodeindex];
	this.container.removeChild(node);
}
TreeView.prototype.hide_node = function(nodeindex) {
	var node = this.container.childNodes[nodeindex];
	node.style.display = 'none';
}
TreeView.prototype.show_node = function(nodeindex) {
	var node = this.container.childNodes[nodeindex];
	node.style.display = 'block';
}

TreeView.prototype.add_node = function(parentid,node,expandparent) {
	var el = document.createElement('div');
	el.className = 'treenode';
	el.owner = this;
	//if (node.children) el.className += ' treenode_collapsed';

	if (this.candragnodes) {
		el.candrag = true;
		el.ondraggrab = this.node_draggrab;
	}	
	var stateimage = document.createElement('img');
	stateimage.onclick = this.node_imageclicked;
	stateimage.owner = el;
	stateimage.style.width = '18px';
	stateimage.style.height = '18px';
	stateimage.src = node.children ? this.imageroot + 'images/collapsed.gif' : this.imageroot + 'images/spacer.gif';
	stateimage.align = 'absmiddle';
	el.appendChild(stateimage);
	el.stateimage = stateimage;

	var typeimage = document.createElement('img');
	typeimage.onclick = this.node_imageclicked;
	typeimage.owner = el;
	typeimage.style.width = '18px';
	typeimage.style.height = '18px';
	typeimage.align = 'absmiddle';
	typeimage.src = node.children ? this.imageroot + 'images/folder.gif' : this.imageroot + 'images/page.gif';
	el.appendChild(typeimage);
	el.typeimage = typeimage;

	
	var caption = document.createElement('span');
	caption.innerHTML = node.name;
	caption.onclick = this.node_captionclicked;
	caption.ondblclick = this.node_imageclicked;
	caption.style.whiteSpace = 'nowrap';
	caption.className = 'treenode_caption';
	caption.owner = el;
	el.caption = caption;
	el.appendChild(caption);
	
	
	
	el.owner = this;
	el.tree_url = node.url;
	el.tree_id = node.id;
	el.tree_parent = parentid>0 ? this.idindex[parentid] : null;
	el.tree_haschildren = node.children;
	el.tree_populated = false
	el.tree_collapsed = true;
	el.style.whiteSpace = 'nowrap';
	if (node.children) {
		el.tree_childnodes = document.createElement('div');
		el.tree_childnodes.className = 'treechildren';
		el.tree_childnodes.style.display = 'none';
		el.appendChild(el.tree_childnodes);
	}

	
	this.idindex[node.id] = el;
	
	if (el.tree_parent) {
		el.tree_parent.tree_childnodes.appendChild(el);
		el.tree_parent.tree_populated = true;
		if (expandparent) this.set_collapsed(el.tree_parent,false);	
	} else {
		this.container.appendChild(el);
	}
	
	return el;
}

TreeView.prototype.set_items = function(parentid,values) {
	this.container.style.cursor = 'default';
	for (var i=0; i<values.length; i++) {
		this.add_node(parentid,values[i],i==values.length-1);
	}
}

TreeView.prototype.set_collapsed = function(node,iscollapsed) {
	if (node.tree_childnodes) {
		node.tree_collapsed = iscollapsed;
		node.tree_childnodes.style.display = iscollapsed ? 'none' : 'block';
		node.stateimage.src = iscollapsed ? this.imageroot + 'images/collapsed.gif' : this.imageroot + 'images/expanded.gif';
		node.typeimage.src = iscollapsed ? this.imageroot + 'images/folder.gif' : this.imageroot + 'images/folderopen.gif';
	}
}

TreeView.prototype.expand_node = function(node) {
	if (node.tree_haschildren) {
		if (node.tree_populated) {
			this.set_collapsed(node,!node.tree_collapsed);
		} else {
			this.container.style.cursor = 'wait';
			this.onfetchitems(node.tree_id);
		}
	}
}

TreeView.prototype.get_first_node = function() {
	var i = 0;
	while (i<this.container.childNodes.length) {
		node = this.container.childNodes[i];
		if (node && node.style && (node.style.display != 'none') ) return node;
		i++;
	}
	return false;
}

TreeView.prototype.get_node_by_id = function(id) {
	return this.idindex[id];
}

TreeView.prototype.launch_node = function(node) {
	if (this.callback) this.callback(node.tree_url);
	this.selectednode = node;
}

TreeView.prototype.node_captionclicked = function() {
	var mytreeview = this.owner.owner;
	mytreeview.set_selected(this.owner);
	mytreeview.launch_node(this.owner);
}

TreeView.prototype.node_imageclicked = function() {
	var mytreeview = this.owner.owner;
	mytreeview.expand_node(this.owner);
}

TreeView.prototype.set_selected = function(node) {
	if (this.selectednode && this.selectednode.caption) {
		if (this.selectednode==node) return;
		this.selectednode.caption.className = 'treenode_caption';
	}
	node.caption.className = 'treenode_caption_selected';
}

TreeView.prototype.launch_without_callback = function(node) {
	this.set_selected(node);
	this.selectednode = node;
}

TreeView.prototype.scroll_to_node = function(node) {
	var tvtop = layer.position(this.container);
	var nodetop = layer.position(node);
	var distance = nodetop.y - (tvtop.y+this.container.scrollTop);
	this.container.scrollTop = distance;
}

TreeView.prototype.open_to_node = function(targetnode) {
	node = targetnode;
	while (node.tree_parent!=null) {
		node = node.tree_parent;
		if (node.tree_collapsed) this.set_collapsed(node,false);
	}
	this.launch_without_callback(targetnode);
	this.scroll_to_node(targetnode);
}

TreeView.prototype.spawn_draggable_node = function(node) {
	var p = layer_get_pos(node);
	if (!IE4) p.y -= this.container.scrollTop;

	var nodewidth = this.container.offsetWidth+'px';
	var itemcount = 0;
	
	var el = node.cloneNode(true);
	el.className = 'treenode_dragging';
	el.id = this.elementid+'_dragnode';
	el.style.position = 'absolute';
	el.style.left = p.x+'px';
	el.style.top = p.y+'px';
	if (el.childNodes.length>=3) el.childNodes[2].className = 'treenode_caption';
	
	el.style.width = nodewidth;
	document.body.insertBefore(el,document.body.childNodes[0]);
	el.style.height = (parseInt(el.offsetHeight)-2)+'px'

	return el;
}

TreeView.prototype.node_draggrab = function(obj) {
	if (!obj.owner) return false;
	if (obj.owner.onnodegrab) {
		if (!obj.owner.onnodegrab(obj)) return false;
	}

	var dragdata = {
		"dataclass": "treenode",
		"data": obj,
		"dragelement": obj.owner.spawn_draggable_node(obj),
		"dragelement_dispose": true,
		"dragelement_class_candrop": "treenode_candrop",
		"dragelement_class_cantdrop": "treenode_cantdrop",
		"offset_top": obj.owner.container.scrollTop,
		"offset_left": obj.owner.container.scrollLeft
	};
	
//	alert ('Returning '+dragdata);
	
	return dragdata;
}

TreeView.prototype.drop_appendnode = function(targetcaption,dragdata) {
	var dragnode = dragdata.data;

	var targetnode = targetcaption.owner;
	
	if (dragnode==targetnode) return;

	try {
		if (dragnode.tree_parent==null) {
			this.owner.owner.container.removeChild(dragnode);
		} else {
			dragnode.tree_parent.tree_childnodes.removeChild(dragnode);
			if (dragnode.tree_parent.tree_childnodes.childNodes.length==0) {
				dragnode.tree_parent.removeChild(dragnode.tree_parent.tree_childnodes);
				dragnode.tree_parent.tree_childnodes = null;
				dragnode.tree_parent.tree_haschildren = false;
				dragnode.tree_parent.stateimage.src = this.owner.owner.imageroot + 'images/spacer.gif';
				dragnode.tree_parent.typeimage.src = this.owner.owner.imageroot + 'images/page.gif';
			}
		}
	} catch(e) {
		return;
	}
	dragnode.tree_parent = targetnode;
	
	targetnode.tree_populated = true;

	if (!targetnode.tree_haschildren) {
		targetnode.tree_childnodes = document.createElement('div');
		targetnode.tree_childnodes.className = 'treechildren';
		targetnode.tree_childnodes.style.display = 'none';
		targetnode.appendChild(targetnode.tree_childnodes);
		targetnode.tree_haschildren = true;
	}
	targetnode.tree_childnodes.appendChild(dragnode);
	this.owner.owner.set_collapsed(targetnode,false);
}

TreeView.prototype.dragzone_enter = function() {
	this.orig_className = this.className;
	this.className += ' treenode_caption_draghover';
}
TreeView.prototype.dragzone_exit = function() {
	this.className = this.orig_className;
}

function make_tree_node(id,name,url,children) {
	this.id = id;
	this.name = name;
	this.url = url;
	this.children = children;
	return this;
}

