var treeConfig = {
	loadIcon	: './data/images/menu/hourglass.gif',
	defaultIcon	: './data/images/menu/folder.gif',
	defaultIconOpen	: './data/images/menu/openfolder.gif',
	iIcon           : './data/images/menu/i.gif',
	lIcon           : './data/images/menu/l.gif',
	lMinusIcon      : './data/images/menu/lminus.gif',
	lPlusIcon       : './data/images/menu/lplus.gif',
	tIcon           : './data/images/menu/t.gif',
	tMinusIcon      : './data/images/menu/tminus.gif',
	tPlusIcon       : './data/images/menu/tplus.gif',
	blankIcon	: './data/images/menu/blank.gif',
	defaultLabel    : 'new node',
	defaultAction   : 'javascript:void(0);'
};

function treeview(id,parentNode,src) {
	this.parentNode = parentNode;
	this.id = id;
	this.src = src;
	this.init();
}

treeview.prototype.init = function() {
	this.oNode = document.createElement("DIV");
	this.oNode.id = this.id;
	this.oNode.className = 'tree';
	this.oNode.obj = this;
	this.loaded = false;
	this.loading = false;
	
	this.oNodeChilds = document.createElement("DIV");
	
	this.oNode.oNodeChilds = this.oNode.appendChild(this.oNodeChilds);
	
	this.append();
	
	if (this.src) {
		if (!this.load) {
			alert('error:on demand loading (ondemand.js) lib missing');
		} else {
			this.load();
		}
	}
}

treeview.prototype.append = function() {
	this.parentNode.appendChild(this.oNode);
	selectedNode = this;
}

function treenode(label,parentNode,src,href,target,icon,iconOpen,nodeId) {
	this.label = label || treeConfig.defaultLabel;
	this.parentNode = parentNode;
	this.groupname = 'a';
	this.icon = icon || treeConfig.defaultIcon;;
	this.openIcon = iconOpen || treeConfig.defaultIconOpen;
	this.opened = false;
	this.loaded = false;
	this.loading = false;
	this.src = src;
	this.href = href;
	this.nodeId = nodeId;
	this.init();
}

treenode.prototype.init = function() {
	// node container
	this.oNode = document.createElement("DIV");
	this.oNode.className = 'node';
						
	// toggle / t / l sections
	this.oNodeImg = document.createElement("IMG");
	this.oNodeImg.className = 'toggle';
	this.oNodeImg.src = treeConfig.blankIcon;
	this.oNodeImg.id = 'imgToggle-' + this.nodeId;
	
	// icon
	this.oNodeIcon = document.createElement("IMG");
	this.oNodeIcon.src = this.icon;
	this.oNodeIcon.className = 'icon';

	// checkbox
	//this.oNodeCheckbox = document.createElement("IMG");
	//this.oNodeCheckbox.className = 'checkbox';
	//this.oNodeCheckbox.src = './data/images/menu/check_disabled.gif';
	//this.oNodeCheckbox.state = 0;

	// node label
	this.oNodeLabel = document.createElement("A");
	this.oNodeLabel.innerHTML = this.label;
	this.oNodeLabel.href = null || this.href;
	this.oNodeLabel.className = 'label';
	this.oNodeLabel.id = 'label-' + this.nodeId;

	// childnodes container
	this.oNodeChilds = document.createElement("DIV");
	this.oNodeChilds.style.display = 'none';
	
	// add node parts
	this.oNode.oNodeImg = this.oNode.appendChild(this.oNodeImg);
	this.oNode.oNodeIcon = this.oNode.appendChild(this.oNodeIcon);
	//this.oNode.oNodeCheckbox = this.oNode.appendChild(this.oNodeCheckbox);
	this.oNode.oNodeLabel = this.oNode.appendChild(this.oNodeLabel);
	this.oNode.oNodeChilds = this.oNode.appendChild(this.oNodeChilds);
	
	// add events and listeners
	this.oNode.obj = this;
	//this.oNodeCheckbox.obj = this;
	this.oNodeLabel.obj = this;
	this.oNodeImg.obj = this;
	
	this.oNodeLabel.onclick = oNodeLabel_onClick;
	this.oNodeImg.onclick = oNodeImg_onClick;
	//this.oNodeCheckbox.onclick = oNodeCheckbox_onClick;

	if ( (null || this.href) == 'javascript:void(0);' ) {
		this.oNodeLabel.onclick = oNodeImg_onClick;
	}
	
	this.append();
}

function oNodeLabel_onClick() {
	this.obj.select();
	
	if ( this.href && (this.href != '#') ) {
		if ( document.getElementById('mainFrame').contentDocument ) {
			document.getElementById('mainFrame').contentDocument.location.href = this.href;
			return false;
		} else if ( document.getElementById('mainFrame').document ) {
			document.getElementById('mainFrame').src = this.href;
			return false;
		}
	} else {
		return false;
	}
}

function oNodeLabel_onRename() {
	this.obj.onRename();
}

function oNodeImg_onClick() {
	this.obj.toggle();
}

function oNodeCheckbox_onClick() {
	this.obj.toggleCheckbox();
}

treenode.prototype.append = function() {

	this.parentNode.oNode.oNodeChilds.appendChild(this.oNode);
	
	// set toggle icons
	if (this.getPreviousSibling()) {
		if (this.getPreviousSibling().obj.src || this.getPreviousSibling().oNodeChilds.childNodes.length) {
			if (this.getPreviousSibling().obj.opened) {
				this.getPreviousSibling().oNodeImg.src = treeConfig.tMinusIcon;
				this.getPreviousSibling().style.backgroundImage = 'url('+treeConfig.iIcon+')';
			} else {
				this.getPreviousSibling().oNodeImg.src = treeConfig.tPlusIcon;
			}
		} else {
			this.getPreviousSibling().oNodeImg.src = treeConfig.tIcon;
		}
	}
	
	if (this.src) {
		this.oNodeImg.src = treeConfig.lPlusIcon;
	} else {
		this.oNodeImg.src = treeConfig.lIcon;
	}
	
	// plus icon if necessary on parentNode
	if (this.parentNode.oNode.oNodeImg) {
		if (this.parentNode.opened) {
			if (this.parentNode.getNextSibling()) {
				this.parentNode.oNode.oNodeImg.src = treeConfig.tMinusIcon;
			} else {
				this.parentNode.oNode.oNodeImg.src = treeConfig.lMinusIcon;
			}
		} else {
			if (this.parentNode.getNextSibling()) {
				this.parentNode.oNode.oNodeImg.src = treeConfig.tPlusIcon;
			} else {
				this.parentNode.oNode.oNodeImg.src = treeConfig.lPlusIcon;
			}
		}
	}
	
}

treenode.prototype.remove = function(disableBehaviour) {
	// windows explorer behavior
	// on removal, select next available node
	// if it does not exist, select the parentNode
	// disableBehaviour is used for ex. the reload method where we do not want a new node to be selected
	
	if (!disableBehaviour) {
		if (this.getNextSibling()) {
			this.getNextSibling().obj.select();
		}else if (this.parentNode.oNode && this.parentNode.select) {
			this.parentNode.select();
		}
	}
				
	// change icons for parentNode (if childs == 0)
	if (!this.getPreviousSibling() && !this.getNextSibling()) {
		if (this.parentNode.getNextSibling) {
			if (this.parentNode.getNextSibling()) {
				this.parentNode.oNodeImg.src = treeConfig.tIcon;
			} else {
				this.parentNode.oNodeImg.src = treeConfig.lIcon;
			}
		}
	}
	
	// change icons for previousSibling if it changes to a L intersection
	if (!this.getNextSibling() && this.getPreviousSibling()) {
		if (this.getPreviousSibling().obj.opened) {
			this.getPreviousSibling().oNodeImg.src = treeConfig.lMinusIcon;
		} else {
			if (this.getPreviousSibling().obj.src || this.getPreviousSibling().oNodeChilds.childNodes.length) {
				this.getPreviousSibling().oNodeImg.src = treeConfig.lPlusIcon;
			} else {
				this.getPreviousSibling().oNodeImg.src = treeConfig.lIcon;
			}
		}
		this.getPreviousSibling().style.backgroundImage = 'url()';
	}
	
	// clear event handlers, and cyclic references
	// so the garbage collector actually can collect
	
	this.oNode.oNodeImg.onclick = null;
	this.oNode.removeChild(this.oNode.oNodeImg);
	this.oNode.oNodeImg = null;
	this.oNodeLabel.obj = null;
	this.oNodeImg = null;
	
	this.oNode.removeChild(this.oNode.oNodeIcon);
	this.oNodeIcon = null;
	
	//this.oNode.oNodeCheckbox.detachEvent("onclick",oNodeCheckbox_onClick);			
	//this.oNode.removeChild(this.oNode.oNodeCheckbox);
	//this.oNode.oNodeCheckbox = null;
	//this.oNodeCheckbox.obj = null;
	//this.oNodeCheckbox = null;
	
	this.oNode.oNodeLabel.onclick = null;
	this.oNode.removeChild(this.oNode.oNodeLabel);
	this.oNode.oNodeLabel = null;
	this.oNodeLabel.obj = null;
	this.oNodeLabel = null;
	
	this.oNode.removeChild(this.oNode.oNodeChilds);
	this.oNodeChilds = null;
				
	this.parentNode.oNodeChilds.removeChild(this.oNode);
	this.parentNode = null;
	this.oNode.obj = null;
	this.oNode = null;
}

function getSelected() {
	return selectedNode;	
}

treenode.prototype.select = function() {

	if (selectedNode && selectedNode.unselect) {
		selectedNode.unselect();
		unselected = true;
	}
	
	this.oNode.oNodeLabel.className = 'label_selected';
	selectedNode = this;
}

treenode.prototype.unselect = function() {

	if (selectedNode.oNode.oNodeLabel) {
		this.oNode.oNodeLabel.className = 'label';
	}
	selectedNode = null;
}


// return previous oNode DIV (use oNode.obj to get the treenode object)
treenode.prototype.getPreviousSibling = function() {
	return this.oNode.previousSibling;
}

// return next oNode DIV (use oNode.obj to get the treenode object)
treenode.prototype.getNextSibling = function() {
	return this.oNode.nextSibling;
}