treeview.prototype.load = function(){
	if(this.loaded || this.loading){
		return;
	}
	
	if(this.src){
		this.loading = true;
		this.setLoading();
		loadXML(this);
	}else{
		alert(labels.errors.throwError.format('treeview load',labels.errors.noDatasource.format(this.label)));
	}
	this.eventManager.dispatch('load');
}
treeview.prototype.reload = function(){
	if(this.src){
		this.loaded = false;
		
		// hard index op 0 zetten want i verandert na elke remove
		for(i=this.oNode.oNodeChilds.childNodes.length;i>0;i--){
			this.oNode.oNodeChilds.childNodes[i-1].obj.remove(true);
		}
		
		this.loading = true;
		this.setLoading();
		loadXML(this);
	}else{
		alert(labels.errors.throwError.format('treeview reload',labels.errors.noDatasource.format(this.label)));
	}
	this.eventManager.dispatch('reload');
}

treeview.prototype.hasDatasource = function(){
	if(this.src != null){
		return true;
	}else{
		return false;
	}
}
treeview.prototype.setDatasource = function(sUrl){
	this.src = sUrl;
}
treeview.prototype.getDatasource = function(){
	return this.src;
}

treeview.prototype.setLoading = function(){
	this.loadNode = new treenode(labels.loading,this);
	this.currentRetryCount = 0;
}

treeview.prototype.onloaded = function(){
	this.loadNode.remove();
	this.loaded = true;
	this.loading = false;
	
	this.eventManager.dispatch('onload');
}

treeview.prototype.onloadedEmpty = function(){
	this.loadNode.remove();
	this.loaded = false;
	this.loading = false;
	
	this.eventManager.dispatch('onload');
}

treeview.prototype.onError = function(){
	if(this.currentRetryCount >= treeConfig.maxRetryCount){
	    this.loadNode.oNodeIcon.src = treeConfig.errorIcon;
		switch(this.error.type){
			case 'undefined':
				this.loadNode.setLabel('Error: ' + this.error.src + ' ' + this.error.status + ' ' + this.error.statusText + '');
			break;
			case 'parser':
				this.loadNode.setLabel('Error: ' + this.error.src + ' ' + this.error.reason + ' ' + this.error.srcText + ' ' + this.error.errorCode + '');
			break;
		}
	}else{
		this.currentRetryCount++;
	    this.loadNode.setLabel('retrying '+this.currentRetryCount);
		if(this.src.indexOf('?') < 0){
		    this.src += '?nocache='+new Date().getTime();
	    }else{
		    this.src += '&nocache='+new Date().getTime();
	    }
        
        var self = this;
        window.setTimeout(function(){loadXML(self)},treeConfig.retryDelayTime);      
    }
	
	this.eventManager.dispatch('onerror');
}

treenode.prototype.load = function(){
	if(this.loaded || this.loading){
		return;
	}
		
	if(this.src){
		this.loading = true;
		this.setLoading();
		loadXML(this);
	}else{
		alert(labels.errors.throwError.format('treenode load',labels.errors.noDatasource.format(this.label)));
	}
	this.eventManager.dispatch('load');
}
treenode.prototype.reload = function(){
	if(this.src){
		this.loaded = false;
		
		// hard index op 0 zetten want i verandert na elke remove
		for(i=this.oNode.oNodeChilds.childNodes.length;i>0;i--){
			this.oNode.oNodeChilds.childNodes[i-1].obj.remove(true);
		}
		
		this.loading = true;
		this.setLoading();
		loadXML(this);
	}else{
		alert(labels.errors.throwError.format('treenode reload',labels.errors.noDatasource.format(this.label)));
	}
	this.eventManager.dispatch('reload');
}

treenode.prototype.setLoading = function(){
	this.oNodeIcon = document.createElement("IMG");
	this.oNodeIcon.className = 'icon';
	this.oNodeIcon.src = treeConfig.loadIcon;
	this.oNode.oNodeIcon = this.oNode.appendChild(this.oNodeIcon);
	
	this.currentRetryCount = 0;
}
treenode.prototype.onloaded = function(){
	this.loaded = true;
	this.loading = false;
	this.expand();
	if(this.treeview.selectOnReload){
		this.select();
	}
	
	this.oNode.removeChild(this.oNodeIcon);
	delete this.oNodeIcon;
	
	this.eventManager.dispatch('onload');
}

treenode.prototype.onloadedEmpty = function(){
	this.loaded = true;
	this.loading = false;
	
	// remove plus icons there are no childs
	// set L icon if this node is the last in the current level
	if(this.getNextSibling()){
		this.oNodeImg.src = treeConfig.tIcon;
	}else{
		this.oNodeImg.src = treeConfig.lIcon;
	}
	
	this.oNode.removeChild(this.oNodeIcon);
	delete this.oNodeIcon;

	this.eventManager.dispatch('onload');
}

treenode.prototype.onError = function(){
	if(this.currentRetryCount >= treeConfig.maxRetryCount){
	    this.oNode.oNodeIcon.src = treeConfig.errorIcon;
	    switch(this.error.type){
		    case 'undefined':
			    this.setLabel('Error: ' + this.error.src + ' ' + this.error.status + ' ' + this.error.statusText + '');
		    break;
		    case 'parser':
			    this.setLabel('Error: ' + this.error.src + ' ' + this.error.reason + ' ' + this.error.srcText + ' ' + this.error.errorCode + '');
		    break;
	    }
    }else{
        this.currentRetryCount++;
		this.setLabel('retrying '+this.currentRetryCount);
		
        if(this.src.indexOf('?') < 0){
		    this.src += '?nocache='+new Date().getTime();
	    }else{
		    this.src += '&nocache='+new Date().getTime();
	    }
                  
        var self = this;
        window.setTimeout(function(){loadXML(self)},treeConfig.retryDelayTime);  
    }
	this.eventManager.dispatch('onerror');
}
treenode.prototype.hasDatasource = function(){
	if(this.src != null){
		return true;
	}else{
		return false;
	}
}
treenode.prototype.setDatasource = function(sUrl){
	this.src = sUrl;
}
treenode.prototype.getDatasource = function(){
	return this.src;
}

function loadXML(parentNode){
	parentNode.error = null;
	
	var xmlHttp = XmlHttp.create();

	// prevent caching by browser, add &nocache if ? exists, else ?nocache
	var xmlUrl = parentNode.src 
	if(parentNode.src.indexOf('?') < 0){
		xmlUrl += '?nocache='+new Date().getTime();
	}else{
		xmlUrl += '&nocache='+new Date().getTime();
	}

	xmlHttp.open("GET", xmlUrl, true);
	xmlHttp.onreadystatechange = function () {
		if (xmlHttp.readyState == 4) {
			onXMLLoaded(xmlHttp,parentNode);
		}
	};
	xmlHttp.send(null);
}

function onXMLLoaded(oXML,parentNode) {
	
	var oXmlDoc = oXML.responseXML;
	var error;
	
	if(!oXmlDoc || oXmlDoc.parserError && oXmlDoc.parseError.errorCode != 0 || !oXmlDoc.documentElement){
		if (!oXmlDoc || oXmlDoc.parseError.errorCode == 0){
			error = {
				src : parentNode.src,
				status : oXML.status,
				statusText : oXML.statusText,
				type : 'undefined'
			}
		}else{
			error = {
				src : parentNode.src,
				reason : oXmlDoc.parseError.reason,
				srcText : oXmlDoc.parseError.srcText,
				errorCode : oXmlDoc.parseError.errorCode,
				type : 'parser'
			}
		}
		parentNode.error = error;
		parentNode.onError();
	}else{
		var root = oXmlDoc.documentElement;
		var cs = root.childNodes;
		var l = cs.length;
	
	
		// use first node in the xml file as the rootnode
		if(treeConfig.createRootNode && parentNode.treeview == parentNode){
			parentNode = xmlNodeToJsNode(root,parentNode);
			parentNode.treeview.onloaded();
		}else{
			for (var i = 0; i < l; i++) {
				if (cs[i].tagName == treeConfig.tagName) {
					xmlNodeToJsNode(cs[i],parentNode);
				}
			}
			
		
		}
		
		if(cs.length <= 0){
			// remove plus icons, this prevents overlapping of background dots forming a solid line
			parentNode.onloadedEmpty();
		}else{
			parentNode.onloaded();
		}
		//alert(parentNode.getFirstChild().label);

	}
	
	delete oXML.onreadystatechange;
	oXML.abort();
	oXML = null;
	delete oXML;
	
}
function xmlNodeToJsNode(oNode,parentNode) {
	
	var label = oNode.getAttribute("label") ? oNode.getAttribute("label") : treeConfig.defaultLabel;
	var itemId = oNode.getAttribute("itemId") ? oNode.getAttribute("itemId") : "itemId";
	var itemLanguage = oNode.getAttribute("itemLanguage") ? oNode.getAttribute("itemLanguage") : "itemLanguage";
	var itemText = oNode.getAttribute("itemText") ? oNode.getAttribute("itemText") : "itemText";
	var typeId = oNode.getAttribute("typeId") ? oNode.getAttribute("typeId") : "typeId";
	var label = oNode.getAttribute("label") ? oNode.getAttribute("label") : treeConfig.defaultLabel;
	var src = oNode.getAttribute("src") ? parseVariables(oNode,oNode.getAttribute("src")) : null;
	var href = oNode.getAttribute("href") ? oNode.getAttribute("href") : treeConfig.defaultAction;
	var target = oNode.getAttribute("target") ? oNode.getAttribute("target") : null; 
	var icon = oNode.getAttribute("icon") ? oNode.getAttribute("icon") : treeConfig.defaultIcon;
	var iconOpen = oNode.getAttribute("iconopen") ? oNode.getAttribute("iconopen") : treeConfig.defaultIconOpen;
	var additionalicons = oNode.getAttribute("additionalicons") ? oNode.getAttribute("additionalicons") : '';
	var onloadevent = oNode.getAttribute("onloadevent") ? oNode.getAttribute("onloadevent") : null;
	var parent = null;
	var vat = oNode.getAttribute("vat") ? oNode.getAttribute("vat") : "0";
	var currency = oNode.getAttribute("currency") ? oNode.getAttribute("currency") : null;
	
	var newNode = new treenode(label,parentNode,src,href,target,icon,iconOpen,additionalicons,onloadevent,true,typeId,itemId, itemText, itemLanguage, vat, currency);
	newNode.setXMLAttributeCollection(oNode);
	newNode.render();
	
	var cs = oNode.childNodes;
	var l = cs.length;
	for (var i = 0; i < l; i++) {
		if (cs[i].tagName == "tree") {
			xmlNodeToJsNode(cs[i],newNode);
		}
	}
	return newNode;
}
function parseVariables(oNode,src){
	var attrs = oNode.attributes;
	var i = attrs.length;while(i--){
		src = src.replace(new RegExp("\\{"+attrs[i].nodeName+"\\}","gi"),attrs[i].nodeValue);
	}
	return src;
}