TreeListControlHandler = {
	nextID					: 0,
	getUniqueID				: function() { return this.nextID++; },
	allTrees				: new Array(),
	preventRowClick			: false,
	callExpand				: function(treeID, nodeID) { this.allTrees[treeID].allNodes[nodeID].expand(); },
	callCollapse			: function(treeID, nodeID) { this.allTrees[treeID].allNodes[nodeID].collapse(); },
	callRowClick			: function(treeID, nodeID) { this.allTrees[treeID].allNodes[nodeID].click(); },
	
	imgConnectMore			: 'connect.more.gif',
	imgConnectEnd			: 'connect.end.gif',
	imgConnectBridge		: 'connect.bridge.gif',
	imgHandleCollapseMore	: 'handle.collapse.more.gif',
	imgHandleCollapseEnd	: 'handle.collapse.end.gif',
	imgHandleExpandMore		: 'handle.expand.more.gif',
	imgHandleExpandEnd		: 'handle.expand.end.gif',
	imgEmpty				: 'empty.gif',
	imgIconDefault			: 'icon.folder.gif',
	
	xmlHTTPStateChange		: function(treeID, nodeID) { this.allTrees[treeID].allNodes[nodeID].xmlCallback(); }
}

function TreeListControl(sRootLabel, sIconSrc, hideColumnHeadings, hideRootNode) {
	this.ID						= TreeListControlHandler.getUniqueID();
	TreeListControlHandler.allTrees[this.ID] = this;
	this.all					= new Array(); //user indices
	this.allNodes				= new Array(); //system indices
	this.columns				= new Array();
	this.rootNode				= new TreeListControlNode(true, sIconSrc, null, 1);
	this.rootNode.columnText[0]	= sRootLabel;
	this.rootNode.depth			= 0;
	this.rootNode.bShowHandle	= false;
	this.rootNode.oTree			= this;
	this.allNodes[this.rootNode.ID] = this.rootNode;
	this.rendered				= false;
	this.nLabelColumn			= 0; //this is the column in which the icons and branches are drawn
	this.iconPath				= 'images/';
	this.showColumnHeadings		= hideColumnHeadings ? false : true;
	this.showRootNode			= hideRootNode ? false : true;
	this.disableRecalc			= false;
}

TreeListControl.prototype.toString = function() {
	var str, x;
	str = '';
	x = 0;
	

	for(var i=0; i<this.columns.length; i++) {
		str += '<div class="tlc_columnheading" style="visibility:hidden; width:' + this.columns[i].width + 'px; left:' + x + 'px; ' +
			   '">' + this.columns[i].name + "</div>";
		x += this.columns[i].width;
	}
	str = '<div id="treelistcontrol' + this.ID + '" class="treelistcontrol" style="width:' + (x + 4) +
		  'px;"><div class="tlc_headings" style="display:expression(TreeListControlHandler.allTrees[' + this.ID +
			   '].showColumnHeadings ? \'block\' : \'none\');">' + str + '</div>' + this.rootNode + '</div>';
	
	this.rendered = true;
	return str;
}

TreeListControl.prototype.redraw = function() {
	//redraw all icons in the tree
}

TreeListControl.prototype.add = function(oNode) {
	
	this.rootNode.add(oNode);
}

TreeListControl.prototype.addColumn = function(oColumn) {
	this.columns[this.columns.length] = oColumn;
}

//
//NEW
TreeListControl.prototype.getTreeStructure = function() {

	return this.rootNode.getTreeStructure();
}

function TreeListControlColumn(width, name, onclickdisabled) {
	this.name = name;
	this.width = width ? width : '100';
	this.onclickdisabled = onclickdisabled ? true : false;
	
}

function TreeListControlNode(bShowChildren, sIconSrc, sXMLSrc, refKey) {
	//refKey is an optional user-specified value which will be matched to this node for easy reference later
	this.columnText			= new Array();
	this.bShowChildren 		= bShowChildren ? true : false;
	this.sIconSrc			= sIconSrc ? sIconSrc : null;
	this.sXMLSrc			= (typeof(sXMLSrc) == 'string') ? sXMLSrc : '';
	this.bDynamicNode		= this.sXMLSrc.length > 0 ? true : false; //set to false once children are loaded to prevent sXMLSrc being used to dynamically load the children
	this.bShowHandle		= true; //this is the + or - icon
	this.refKey				= (refKey || refKey == 0) ? refKey : null;
	this.ID					= TreeListControlHandler.getUniqueID();
	this.sImages			= '';
	this.sHandle			= '';
	this.onclick			= '';
	this.useIcon			= true;

	this.nextSibling		= null;
	this.previousSibling	= null;
	this.firstChild			= null;
	this.lastChild			= null;
	this.parentNode			= null;
	this.oTree				= null;
	this.rendered			= false;
	
	
	this.aData	   	        = new Object();
	
	//this.className			= 'tlc_node_row';
	//this.classNameHover		= 'tlc_node_row_hover';
	//this.classNameClick		= 'tlc_node_row_click';		
}

TreeListControlNode.prototype.toString = function() {
		
	var ie5 = (document.getElementById&&document.all); 
    var n6 	= (document.getElementById&&!document.all); 
       
	var str = '<div class="tlc_node" id="tlcnode' + this.ID + '" >';

	
	
	str += '<div id="' + this.ID + '" class="tlc_node_row" onmouseover="this.className=\'tlc_node_row_hover\'" onmouseout="this.className=\'tlc_node_row\';" style="cursor:default;' +
		   (this.parentNode == null ? 'display:expression(TreeListControlHandler.allTrees[' + this.oTree.ID +
			   '].showRootNode ? \'block\' : \'none\');' : '') + '" onclick="if(!TreeListControlHandler.preventRowClick) { ' + this.onclick + ' };"' +
		   ' onmousedown="if(!TreeListControlHandler.preventRowClick) this.className=\'tlc_node_row_click\'; "' +
		   ' ondblclick="renameme('+ this.ID +')"'+
		   ' onmouseup="this.className=\'tlc_node_row_hover\';'+ (n6?'showMenu(event, '+this.ID+' );"':'"') +
		   (ie5?' oncontextmenu="showMenu(event, '+this.ID+' );"  >':' >');

	
	var c = this.oTree.columns;
	var x = 0;
	for(var i=0; i<c.length; i++) {
		str += '<div  class="tlc_node_text" style="width:' + c[i].width + 'px; left:' + x + 'px;"' +
				(c[i].onclickdisabled ? ' onmouseover="TreeListControlHandler.preventRowClick=true;" onmouseout="TreeListControlHandler.preventRowClick=false;"' : '' )+ '>';
		if(this.oTree.nLabelColumn == i) {
			if(!this.oTree.disableRecalc) this.recalcImages();
			str += '<span>'; //handle and images
			str += this.sImages + this.sHandle + '<img src="' + (this.sIconSrc ? this.sIconSrc : this.oTree.iconPath + TreeListControlHandler.imgIconDefault) + '" width="16" height="16" align="absmiddle">';
			str += '</span>&nbsp;';
			
		}
		str += '<span '+(this.oTree.nLabelColumn==i?' id="labelSpan'+this.ID+'" ':'')+'>' + (this.columnText[i] ? this.columnText[i] : '&nbsp;' + this.ID) + '</span></div>';
		x += c[i].width;
	}
	str += '</div>';
	
	
	str += '<div id="children' + this.ID + '" class="tlc_node_children" style="display:' + ((this.bShowChildren && this.firstChild) ? 'block' : 'none') + '">';
	var node = this.firstChild;
	while(node) {
		str += node;
		node = node.nextSibling;
	}
	str += "</div>"; 
	
	str +="</div>";
	
	this.rendered = true
	return str;
}


TreeListControlNode.prototype.recalcImages = function() {
	var h = TreeListControlHandler;
	this.sImages = '';
	if(this.parentNode) {
		if(this.parentNode.parentNode) {
			this.sImages = this.parentNode.sImages;
			this.sImages += '<img src="' + this.oTree.iconPath +
							(this.parentNode.nextSibling ? h.imgConnectBridge : h.imgEmpty) +
							'" width="16" height="16" align="absmiddle">';
		}
		if(this.firstChild || this.bDynamicNode) {
			if(this.bShowChildren && !this.bDynamicNode) {
				this.sHandle = '<img src="' + this.oTree.iconPath +
								(this.nextSibling ? h.imgHandleCollapseMore : h.imgHandleCollapseEnd) +
								 '" style="cursor:hand;"' +
								' width="16" height="16" align="absmiddle" onmouseover="TreeListControlHandler.preventRowClick=true;" onmouseout="TreeListControlHandler.preventRowClick=false;"' +
								' onclick="TreeListControlHandler.callCollapse(' +
								this.oTree.ID + ',' + this.ID + ');">';
			} else {
				this.sHandle = '<img src="' + this.oTree.iconPath +
								(this.nextSibling ? h.imgHandleExpandMore : h.imgHandleExpandEnd) +
								 '" style="cursor:hand;"' +
								' width="16" height="16" align="absmiddle"' +
								' onmouseover="TreeListControlHandler.preventRowClick=true;"' +
								' onmouseout="TreeListControlHandler.preventRowClick=false;"' +
								' onclick="TreeListControlHandler.callExpand(' +
								this.oTree.ID + ',' + this.ID + ');">';
			}
		} else {
			this.sHandle = '<img src="' + this.oTree.iconPath +
							(this.nextSibling ? h.imgConnectMore : h.imgConnectEnd) +
							'" width="16" height="16" align="absmiddle">';
		}
	}
	if(this.rendered) {

		var o = document.getElementById('tlcnode'+this.ID).firstChild.childNodes[this.oTree.nLabelColumn].firstChild;
		o.innerHTML = this.sImages + this.sHandle + (this.useIcon ? '<img src="' + (this.sIconSrc ? this.sIconSrc : this.oTree.iconPath + TreeListControlHandler.imgIconDefault) + '" width="16" height="16" align="absmiddle">' : '');
	}
}

TreeListControlNode.prototype.recalcChildImages = function() {
	var node = this.firstChild;
	while(node) {
		node.recalcImages();
		node.recalcChildImages();
		node = node.nextSibling;
	}
}

TreeListControlNode.prototype.expand = function() {
	this.bShowChildren = true;
	var o = document.getElementById('tlcnode' + this.ID);
	o.lastChild.style.display = 'block';
	var id1 = this.oTree.ID;
	var id2 = this.ID;
	if(!this.oTree.disableRecalc) this.recalcImages();
	if(this.bDynamicNode) { 
		// Never used...
		
		document.getElementById('tlcnode' + this.ID).firstChild.className = 'tlc_node_row';
		this.bDynamicNode = false;
		var tempnode = new TreeListControlNode(false, this.oTree.iconPath + 'icon.arrow.gif');
		tempnode.setColumnText(this.oTree.nLabelColumn, '<span style="color:#FF6600">Loading...</span>');
		this.add(tempnode);
		this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		var treeid = this.oTree.ID;
		var nodeid = this.ID;
		this.xmlhttp.onreadystatechange = function() { TreeListControlHandler.xmlHTTPStateChange(treeid, nodeid); };
		try {
		this.xmlhttp.open("POST", this.sXMLSrc, true);
		this.xmlhttp.send(null);
		} catch(ex){}
	}
}

TreeListControlNode.prototype.collapse = function() {
	this.bShowChildren = false;
	var o = document.getElementById('tlcnode' + this.ID);
	o.lastChild.style.display = 'none';
	var img = o.childNodes[0].childNodes[this.oTree.nLabelColumn].firstChild.lastChild.previousSibling;
	var id1 = this.oTree.ID;
	var id2 = this.ID;
	img.onclick = function() { TreeListControlHandler.callExpand(id1, id2); return false; };
	img.src = this.oTree.iconPath + (this.nextSibling ? TreeListControlHandler.imgHandleExpandMore : TreeListControlHandler.imgHandleExpandEnd);
}

TreeListControlNode.prototype.click = function() {
	
}

TreeListControlNode.prototype.setText = function() {
	for(var i=0; i<arguments.length; i++)
		this.setColumnText(i, arguments[i]);
}

TreeListControlNode.prototype.setColumnText = function(nColumn, sText) {
	this.columnText[nColumn] = (sText ? sText : '');
	if(this.rendered) {
		var o = document.getElementById('tlcnode' + this.ID);
		o.firstChild.childNodes[nColumn].lastChild.innerHTML = this.columnText[nColumn];
	}
}

TreeListControlNode.prototype.add = function(oNode, bNoRedraw, oSibling, bInsertAfter) {


	if (!(oNode && !(bNoRedraw || oSibling || bInsertAfter ))) { 
		//alert('oNode '+oNode +'oNode.ID'+oNode.ID+' this.ID '+this.ID+', this.aData.name '+this.aData.name);
		if (!oNode) alert('Warning: unusual call to add');	
	}	
	
	if(bNoRedraw) this.oTree.disableRecalc = true;
	this.bDynamicNode = false;
	oNode.oTree = this.oTree;
	oNode.parentNode = this;
	if(oNode.refKey || oNode.refKey == 0) this.oTree.all[oNode.refKey] = oNode;
	this.oTree.allNodes[oNode.ID] = oNode;
	
	
	if(!this.firstChild) {
		this.firstChild = oNode;
		this.lastChild = oNode;
	} else {
		var node1, node2;
		
		if(oSibling) {

			if(bInsertAfter) {
				node1 = oSibling;
				node2 = oSibling.nextSibling;
			} else {
				node1 = oSibling.previousSibling;
				node2 = oSibling;
			}
		} else {
			node1 = this.lastChild;
			node2 = null;
		}
		if(node1) {
			oNode.previousSibling = node1;
			node1.nextSibling = oNode;
		} else {
			this.firstChild = oNode;
		}
		if(node2) {

			oNode.nextSibling = node2;
			node2.previousSibling = oNode;
		} else {
			this.lastChild = oNode;
		}
	}
	
	
	if(this.oTree.rendered) {
	
		
		var oSib;
		var html = oNode + '';
		var oParent = document.getElementById('tlcnode' + this.ID);
		
		if(node1) {
			oSib = document.getElementById('tlcnode' + node1.ID);
			   
						
			if (document.getElementById) {
        		if (window.HTMLElement) {
        				// Netscape/Gecko
        			           		      		
            		var range = document.createRange();
            			           			
            		range.setStartAfter(oSib);
            		df = range.createContextualFragment(html);
            		oSib.parentNode.insertBefore(df, oSib.nextSibling);
            			
            			
            			
        		} else {
        			// IE
        			
            		oSib.insertAdjacentHTML('afterEnd', html);
        		}
    		}			

			
		} else if(node2) {
			
			
			oSib = document.getElementById('tlcnode' + node2.ID);
			oSib.insertAdjacentHTML('beforeBegin', html);
		} else {
							
			
			oParent.lastChild.innerHTML = html;		
						
		}

		this.expand();
		if(!node2 && node1) {
			node1.recalcImages();
			node1.recalcChildImages();
		}
	}
	if(bNoRedraw) this.oTree.disableRecalc = false;
}




TreeListControlNode.prototype._renderChildren = function() {
	
}


TreeListControlNode.prototype.insertAfter = function(oNode, bNoRedraw) {
	this.parentNode.add(oNode, bNoRedraw, this, true);
}

function showMenu(event, id) {
	// dummy
	
}
