var treeConfig = {
	loadIcon		: baseUrl + 'tree/loading.gif',
	errorIcon		: baseUrl + 'tree/error.gif',
	defaultIcon		: baseUrl + 'tree/folder.gif',
	defaultIconOpen	: baseUrl + 'tree/openfolder.gif',
	iIcon           : baseUrl + 'tree/i.gif',
	lIcon           : baseUrl + 'tree/l.gif',
	lMinusIcon      : baseUrl + 'tree/lminus.gif',
	lPlusIcon       : baseUrl + 'tree/lplus.gif',
	tIcon           : baseUrl + 'tree/t.gif',
	tMinusIcon      : baseUrl + 'tree/tminus.gif',
	tPlusIcon       : baseUrl + 'tree/tplus.gif',
	blankIcon		: baseUrl + 'tree/blank.gif',
	checkboxIcon	: baseUrl + 'tree/check_disabled.gif',
	checkboxCheckedFullIcon : baseUrl + 'tree/check_full.gif',
	checkboxCheckedPartialIcon : baseUrl + 'tree/check_partial.gif',
	topLinkImage 	: baseUrl + 'Images/AllTIme_Top_Ten.gif',
	newLinkImage	: baseUrl + 'Images/recent_Top_Ten.gif',
	issueLinkImage  : baseUrl + 'Images/SampleIssue.gif',
	infoLinkImage   : baseUrl + 'Images/info.gif',
	defaultLabel    : 'new node',
	defaultAction   : 'javascript:void(0);',
	//defaultAction   : '',
	defaultOnNodeSelectEventHandler : function(){void(0)},
	defaultOnNodeDragStartHandler : function(){return true},
	defaultOnNodeDragEndHandler : function(){void(0)},
	selectOnReload : false
};

function oNode_onMousedown(){}

function onNodeSelect(){
	window.status = mytreeview.selectedNode.label;
}


function treeview(id,parentNode,src,onNodeSelectEventHandler){
	this.parentNode = parentNode;
	this.id = id;
	this.src = src;
	this.treeview = this;
	this.selectedNode = null;
	this.selectOnReload = treeConfig.selectOnReload;
	this.onNodeSelectEventHandler = onNodeSelectEventHandler ? onNodeSelectEventHandler : treeConfig.defaultOnNodeSelectEventHandler;
	this.onNodeDragStartHandler = treeConfig.defaultOnNodeDragStartHandler;
	this.onNodeDragEndHandler = treeConfig.defaultOnNodeDragEndHandler;	
	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);
	
	var self = this;
    this._onunload = function(){self.dispose()};
	if(document.addEventListener) { 
    	window.addEventListener("unload",this._onunload,false ); // Moz
   	}else if(window.attachEvent) {
     	window.attachEvent("onunload",this._onunload); // IE
   	}
	
	this.append();
	
	if(this.src){
		if(!this.load){
			alert('error:on demand library missing');
		}else{
			this.load();
		}
	}
}

treeview.prototype.dispose = function(){
	
	if(document.removeEventListener) {
	  window.removeEventListener("unload",this._onunload,false ); // Moz
	}else if(window.detachEvent) { 
	  window.detachEvent("onunload",this._onunload); // IE
	}
		
	this.selectOnReload = null;
	this.onNodeSelectEventHandler = null;
	this.onNodeDragStartHandler = null;
	this.onNodeDragEndHandler = null;	
	
	// nodechilds
	this.oNodeChilds = null;
	
	// node
	this.oNode.obj = null;
	this.oNode.oNodeChilds = null;
	this.oNode = null;
				
	this._onunload = null;
}


treeview.prototype.append = function(){
	this.parentNode.appendChild(this.oNode);
	this.selectedNode = this;
}

function treenode(label,parentNode,src,href,target,icon,iconOpen,additionalIcons,strType,lngId,mainLink,topLink,newLink,issueLink,infoLink,onloadEvent){
	this.label = prepareSafari(label) || treeConfig.defaultLabel;
	this.parentNode = parentNode;
	this.treeview = parentNode.treeview;
	this.groupname = 'a';
	this.icon = icon || treeConfig.defaultIcon;;
	this.openIcon = iconOpen || treeConfig.defaultIconOpen;
	this.additionalIcons = additionalIcons || '';
	this.action = href || treeConfig.defaultAction;
	this.opened = false;
	this.loaded = false;
	this.loading = false;
	this.src = src;
	this.strType = strType;
	this.lngId = lngId;
	this.mainLink = mainLink;
	this.topLink = topLink;
	this.newLink = newLink;
	this.issueLink = issueLink;
	this.infoLink = infoLink;
	
	if(onloadEvent){
		this.onloadEvent = function(){eval(onloadEvent)};
	}
	
	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;
	
	// icon
	this.oNodeIcon = document.createElement("IMG");
	this.oNodeIcon.src = this.icon;
	this.oNodeIcon.className = 'icon';
	if(this.icon == 'none'){
		this.oNodeIcon.style.display = 'none';
	}	
	
	// checkbox
	//this.oNodeCheckbox = document.createElement("IMG");
	//this.oNodeCheckbox.className = 'checkbox';
	//this.oNodeCheckbox.src = treeConfig.checkboxIcon;
	//this.oNodeCheckbox.state = 0;

	// We look for the type to define the class
	var strClass;
	if(this.strType){
		if (this.strType.toUpperCase() == "NETWORK")
			strClass = 'label';
		else if (this.strType.toUpperCase() == "JOURNAL")
			strClass = 'journal_label';
	}
	else{
		// This is one of the major networks
		strClass = 'major_label';
	}
	
	// node label
	this.oNodeLabel = document.createElement("SPAN");
	
	if (this.href && this.href.length > 0)	{
		this.oNodeLabel.innerHTML = prepareSafari(this.label);
		this.oNodeLabel.action = this.href;
		this.oNodeLabel.className = strClass;
	}
	else if (this.mainLink && this.mainLink.length > 0){
		// if we have a link
		var tmp = document.createElement("A");
		tmp.innerHTML = prepareSafari(this.label);
		tmp.href = prepareSafari(this.mainLink);
		tmp.target = '_blank';
		tmp.className = strClass;
		this.oNodeLabel.appendChild(tmp);
	}
	else {
		this.oNodeLabel.innerHTML = prepareSafari(this.label);
		this.oNodeLabel.className = strClass;
	}
	
	
	// Insert the ISSUE SAMPLE image link 
	if (this.issueLink && this.issueLink.length > 0)	{
		
		// insert a space
		var space = document.createTextNode(" ");
		this.oNodeLabel.appendChild(space);
		
		// Create the link element
		var slink = prepareSafari(this.issueLink);
		var aLink = document.createElement("A");
		aLink.href = slink;
		aLink.target = '_blank';
		
		// Add the image to it
		var tmp = document.createElement("IMG");
		tmp.src = treeConfig.issueLinkImage;
		tmp.title = 'Click to view journal sample issue.';
		tmp.border = 0;
		aLink.appendChild(tmp);
		
		//tmp.onclick = function(){alert('link: ' + slink);}
		this.oNodeLabel.appendChild(aLink);
	}		
	
	// Insert the TOP image link 
	if (this.topLink && this.topLink.length > 0)	{
		
		// insert a space
		var space = document.createTextNode(" ");
		this.oNodeLabel.appendChild(space);
		
		// Create the link element
		var slink = prepareSafari(this.topLink);
		var aLink = document.createElement("A");
		aLink.href = slink;
		aLink.target = '_blank';
		
		// Add the image to it
		var tmp = document.createElement("IMG");
		tmp.src = treeConfig.topLinkImage;
		tmp.title = 'Top Downloads All Time / Recent.';
		tmp.border = 0;
		aLink.appendChild(tmp);
		
		//tmp.onclick = function(){alert('link: ' + slink);}
		this.oNodeLabel.appendChild(aLink);
	}
	
	// Insert the NEW image link 
	if (this.newLink && this.newLink.length > 0)	{
		
		// insert a space
		var space = document.createTextNode(" ");
		this.oNodeLabel.appendChild(space);
		
		// Create the link element
		var slink = prepareSafari(this.newLink);
		var aLink = document.createElement("A");
		aLink.href = slink;
		aLink.target = '_blank';
		
		// Add the image to it
		var tmp = document.createElement("IMG");
		tmp.src = treeConfig.newLinkImage;
		tmp.title = '500 Most Recent Entries.';
		tmp.border = 0;
		aLink.appendChild(tmp);
		
		//tmp.onclick = function(){alert('link: ' + slink);}
		this.oNodeLabel.appendChild(aLink);
	}
	
	// Insert the INFO image link 
	if (this.infoLink && this.infoLink.length > 0)	{
		
		// insert a space
		var space = document.createTextNode(" ");
		this.oNodeLabel.appendChild(space);
		
		// Create the link element
		var slink = prepareSafari(this.infoLink);
		var aLink = document.createElement("A");
		aLink.href = slink;
		aLink.target = '_blank';
		
		// Add the image to it
		var tmp = document.createElement("IMG");
		tmp.src = treeConfig.infoLinkImage;
		tmp.title = 'Click to view a description of the journal.';
		tmp.border = 0;
		aLink.appendChild(tmp);
		
		//tmp.onclick = function(){alert('link: ' + slink);}
		this.oNodeLabel.appendChild(aLink);
	}	
	

	
	// childnodes container
	this.oNodeChilds = document.createElement("DIV");
	this.oNodeChilds.style.display = 'none';
	
	// reference to the element (oNodeImg = reference to the object)
	this.oNode.oNodeImg = this.oNode.appendChild(this.oNodeImg);
	
	this.oNode.oNodeIcon = this.oNode.appendChild(this.oNodeIcon);
	var aIcons = this.additionalIcons.split(',');
	
	if(this.additionalIcons.length){
		if(aIcons.length > 0){
			for(i=0;i<aIcons.length;i++){
				var tmp = document.createElement("IMG");
				tmp.src = aIcons[i];
				tmp.className = 'icon';
				tmp.alt = 'Links were found broken, click the icon for more information about the meaning of it';
				this.oNode.appendChild(tmp);
	
			}
		}
	}
	
	//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.oNodeIcon.obj = this;
	
	this.oNodeLabel.onmousedown = oNodeLabel_onMousedown;	
	this.oNodeImg.onmousedown = oNodeImg_onMousedown;
	this.oNode.onmouseover = oNode_onMouseover;
	
	var self = this;
    this._onunload = function(){self.dispose()};
	if(document.addEventListener) { 
    	window.addEventListener("unload",this._onunload,false ); // Moz
   	}else if(window.attachEvent) {
     	window.attachEvent("onunload",this._onunload); // IE
   	}
	
	//eventhandler for drag & drop
	this.oNode.onmousedown = oNode_onMousedown;
	
	//eventhandler for checkboxes
	//this.oNodeCheckbox.onclick = oNodeCheckbox_onClick;
	
	this.append();
}

function cancelEventBubbling(e){
	if (!e){e=event}
	if(document.all){
		event.cancelBubble=true;
	}else if(e){
		e.preventDefault();
		e.stopPropagation();
	};
	return false;
};

treenode.prototype.dispose = function(){
	// internal call, no this.obj needed
	// clear event handlers, and cyclic references
	// so the garbage collector actually can collect
	
	if(document.removeEventListener) {
	  window.removeEventListener("unload",this._onunload,false ); // Moz
	}else if(window.detachEvent) { 
	  window.detachEvent("onunload",this._onunload); // IE
	}
	
	// img
	this.oNodeImg.onmousedown = null;
	this.oNodeImg.obj = null;
	this.oNodeImg = null;
						
	// label
	this.oNodeLabel.onmousedown = null;
	this.oNodeLabel.oncontextmenu = null;
	this.oNodeLabel.obj = null;
	this.oNodeLabel = null;
	
	// icon
	this.oNodeIcon.obj = null;
	this.oNodeIcon = null;
	
	// nodechilds
	this.oNodeChilds = null;
	
	// node
	this.oNode.onmouseover = null;
	this.oNode.onmousedown = null;
	this.oNode.obj = null;
	this.oNode.oNodeImg = null;
	this.oNode.oNodeLabel = null;
	this.oNode.oNodeChilds = null;
	this.oNode = 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.xmlNode = null;
	
	// remove all function calls (treeview config)
	for(var ref in this){
		this[ref] = null;
	}
	
	this.parentNode = null;
	this._onunload = null;
}

function oNode_onMouseover(e){
	if (!e){e=event}
    cancelEventBubbling(e);
	// reset previous targetNode
	if(typeof(targetNode)!='undefined'){
		window.clearTimeout(targetNode.expandTimer);
		try{
			targetNode.oNodeLabel.style.border = '';
		}catch(e){
			//alert(targetNode.oNode.innerHTML);
		}
	}
	
	targetNode = this.obj;
	if(typeof(draggingNode) != 'undefined' && draggingNode != null && document.getElementById('dragNode')){
		this.obj.oNodeLabel.style.border = '1px dotted gray';
		
		// expand node for userfriendly dragging
		var self = this.obj;
		this.obj.expandTimer = window.setTimeout(function(){self.expand();},750);
	}
	window.status = this.obj.label;
}

function oNodeLabel_onMousedown(){
	this.obj.select();
	if(this.obj.action != null){
		eval(this.obj.action);
	}
}

function oNodeImg_onMousedown(){
	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;
			}
		}
	}
	
	
	if(this.onloadEvent){
		// little timeout appended before executing the onloadEvent, 
		// or else the xml attributes of the xml node seem to be unavailable, dunno why though
		var self = this;
		setTimeout(function(){self.onloadEvent()},10);
	}
	
}

treenode.prototype.selectOnload = function(){
	if(!this.parentNode.loading){
		this.select();
	}else{
		var self = this;
		setTimeout(function(){self.selectOnload()},10);
	}
	
}

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()){
			// prevent selection of the treenode, because the moveup command 
			// can only be initialized after the loadnode has been removed
			if(this.parentNode.oNode && this.parentNode.loading){
				this.getNextSibling().obj.selectOnload();
			}else{
				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()';
	}
	
	this.oNode.removeChild(this.oNode.oNodeImg);
	this.oNode.removeChild(this.oNode.oNodeIcon);

	//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.removeChild(this.oNode.oNodeLabel);
	this.oNode.removeChild(this.oNode.oNodeChilds);
	this.parentNode.oNodeChilds.removeChild(this.oNode);
	this.dispose();
}

function getSelected(){
	return this.treeview.selectedNode;	
}

treenode.prototype.select = function(){

	if(this.treeview.selectedNode && this.treeview.selectedNode.unselect){
		this.treeview.selectedNode.unselect();
	}
	
	// We look for the type to define the class
	if(this.strType){
		if (this.strType.toUpperCase() == "NETWORK")
			this.oNode.oNodeLabel.className = 'label_selected';
		else if (this.strType.toUpperCase() == "JOURNAL")
			this.oNode.oNodeLabel.className = 'journal_label_selected';
	}
	else{
		// This is one of the major networks
		this.oNode.oNodeLabel.className = 'major_label_selected';
	}
	
	this.treeview.selectedNode = this;
	
	if(this.treeview.onNodeSelectEventHandler){
		this.treeview.onNodeSelectEventHandler();
	}
	
	
}

treenode.prototype.unselect = function(){

	if(this.treeview.selectedNode.oNode.oNodeLabel){
		// We look for the type to define the class
		if(this.strType){
			if (this.strType.toUpperCase() == "NETWORK")
				this.oNode.oNodeLabel.className = 'label';
			else if (this.strType.toUpperCase() == "JOURNAL")
				this.oNode.oNodeLabel.className = 'journal_label';
		}
		else{
			// This is one of the major networks
			this.oNode.oNodeLabel.className = 'major_label';
		}
		//this.oNode.oNodeLabel.className = 'label';
	}
	this.treeview.selectedNode = null;
}

treenode.prototype.hasChildren = function(){
	this.oNode.oNodeChilds.childNodes.length > 0 ? true : false;
}

treenode.prototype.setLabel = function(label){
	this.label = label;
	this.oNodeLabel.innerHTML = label;
}
treenode.prototype.setIcon = function(url){
	this.icon = url;
	this.oNodeIcon.src = url;
}
treenode.prototype.setOpenIcon = function(url){
	this.openIcon = url;
	this.oNodeIcon.src = url;
}

// 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;
}