function $() {
  var results = [], element;
  for (var i = 0; i < arguments.length; i++) {
    element = arguments[i];
    if (typeof element == 'string')
      element = document.getElementById(element);
    results.push(Element.extend(element));
  }
  return results.length < 2 ? results[0] : results;
}

MediasiteTreeViewNode = function(id, text, value, level, index, expanded, parentNode)
{
	this.id = id;
	this.nodes = new Array();
	this.text = text;
	this.value = value;
	this.level = level;
	this.expanded = expanded;
	this.parentNode = parentNode;
	this.index = index;
	this.draggable;
	this.treeView;
	
	this.RemoveNode = function(node)
	{
		for ( var i = 0; i < this.nodes.length; i++ )
		{
			if ( this.nodes[i].id == node.id ) 
			{
				this.nodes.splice(i, 1);
				break;
			}
		}
		
		for ( var i = 0; i < this.nodes.length; i++ ) 
		{
			this.nodes[i].index = i;
		}
	}

	this.SetDraggable = function()
	{
		for ( var i = 0; i < this.nodes.length; i++ )
		{
			this.nodes[i].SetDraggable();
		}

		if ( this.parentNode != null )
		{
			this.draggable = new Draggable(this.id, {revert:true});
		}
		
		Droppables.add(this.id, {accept:this.treeView.nodeHoverCssClass, onDrop: function(element, droppableElement) { eval(droppableElement.id).OnDrop(element); }});
	}
	
	this.RemoveDraggable = function() 
	{
		for ( var i = 0; i < this.nodes.length; i++ )
		{
			this.nodes[i].RemoveDraggable();
		}
	
		Droppables.remove(this.id);
		
		if ( this.draggable != null ) 
		{
			this.draggable.destroy();
		}
	}
	
	this.SetLevel = function(level)
	{
		this.level = level;
		
		for ( var i = 0; i < this.nodes.length; i++ )
		{
			this.nodes[i].SetLevel(this.level+1);
		}
	}
	
	this.OnDrop = function(droppedElement)
	{
		var dropped = eval(droppedElement.id);
		
		if ( window.confirm('Are you sure you want to move "' + dropped.text + '" to "' + this.text + '"?') ) 
		{		
			dropped.parentNode.RemoveNode(dropped);
			dropped.parentNode = eval(this.id);
			dropped.SetLevel(this.level+1);
			dropped.index = this.nodes.length;

			this.nodes.push(dropped);
			
			if ( this.treeView.onDropMethod != null )
			{
				eval(this.treeView.onDropMethod+"(droppedElement.id)");
			}
			
 			this.treeView.Render();
 		}
	}
	
	this.GetImageTypeExtension = function(element, droppableElement)
	{
		if (this.parentNode == null)
		{
			return "r";
		}

		if (this.index == (this.parentNode.nodes.length - 1))
		{
			return "l";
		}

		return "t";
	}
	
	this.GetParents = function()
	{
		var parents = new Array();
		var parent = this.parentNode;
		
		while ( parent != null )
		{
			parents.push(parent);
			parent = parent.parentNode;
		}
		
		parents.reverse();
		parents.shift();
		
		return parents;
	}
		
	this.Render = function(treeView, parentContainer)
	{
		this.treeView = treeView;
		
		var container = document.createElement('div');
		container.className = (this.level == 0 ? 'mtvTreeNodeRoot' : 'mtvTreeNode');
		
		// start I-beam filler
		if ( this.level > 1 )
		{
			var iBeamContainer = document.createElement('span');
			var parents = this.GetParents();
			
			for ( var i = 0; i < this.level-1; i++ )
			{
				var iBeamImage = document.createElement('img');
				iBeamImage.className = 'mtvNodeImage';
				iBeamImage.src = (treeView.showLines ? (parents[i].index == parents[i].parentNode.nodes.length - 1 ? treeView.imageBasePath + '/mtv_b.gif' : treeView.imageBasePath + '/mtv_i.gif') : treeView.imageBasePath + '/mtv_b.gif');
				iBeamContainer.appendChild(iBeamImage);
			}
			
			container.appendChild(iBeamContainer);
		}
		// end I-beam filler
		
		// start expand/collapse
		if ( treeView.showLines )
		{
			var expandContainer = document.createElement('span');
			
			if ( this.nodes.length > 0 ) 
			{
				expandContainer.onclick = new Function(treeView.id+".ExpandCollapse('" + this.id + "', '" + (treeView.showLines ? this.GetImageTypeExtension() : 'r') + "');");
			}
			
			var expandImage = document.createElement('img');
			expandImage.id = (this.id + '_img');
			
			if ( this.nodes.length == 0 )
			{
				expandImage.setAttribute('src', treeView.imageBasePath + '/mtv_' + (treeView.showLines ? this.GetImageTypeExtension() : 'b') + '.gif');
			}
			else if ( this.expanded )
			{
				expandImage.setAttribute('src', treeView.imageBasePath + '/mtv_collapse_' + (treeView.showLines ? this.GetImageTypeExtension() : 'b') + '.gif');
			}
			else 
			{
				expandImage.setAttribute('src', treeView.imageBasePath + '/mtv_expand_' + (treeView.showLines ? this.GetImageTypeExtension() : 'b') + '.gif');
			}
			
			expandContainer.appendChild(expandImage);
			container.appendChild(expandContainer);
		}
		// end expand/collapse
		
		// start user-supplied image
		if ( (!this.expanded && treeView.collapsedImage != null) || (this.expanded && treeView.expandedImage != null ) )
		{
			var userImage = document.createElement('img');
			userImage.id = this.id+'_uimg';
			userImage.src = treeView.imageBasePath + '/' + ((this.expanded && this.nodes.length > 0) ? treeView.expandedImage : treeView.collapsedImage);
			
			if ( this.nodes.length > 0 ) 
			{
				userImage.onclick = new Function("", treeView.id + ".ExpandCollapse('" + this.id + "', '" + (treeView.showLines ? this.GetImageTypeExtension() : 'r') + "')");
			}
			
			container.appendChild(userImage);
		}
		// end user-supplied image
		
		// start user content
		var contentContainer = document.createElement('span');
		
		contentContainer.className = (this.selected ? treeView.selectedNodeCssClass : treeView.nodeCssClass);
		contentContainer.onclick = new Function("", treeView.id + '.OnClick(this.id);');
		contentContainer.onmouseover = new Function("", treeView.id + '.OnMouseOver(this.id);');
		contentContainer.onmouseout = new Function("", treeView.id + '.OnMouseOut(this.id);');
		contentContainer.id = this.id;
		contentContainer.setAttribute('value', this.value);
		contentContainer.innerHTML = this.text;
		
		container.appendChild(contentContainer);		
		// end user content
		
		parentContainer.appendChild(container);
		
		// start sub-branch
		if ( this.nodes.length > 0 )
		{
			var branchContainer = document.createElement('div');
			branchContainer.id = this.id+'_branch';
			branchContainer.className = (this.expanded ? 'mtvTreeBranchVisible' : 'mtvTreeBranchHidden');
			
			var branchInnerContainer = document.createElement('div');

			for ( var i = 0; i < this.nodes.length; i++ )
			{
				this.nodes[i].Render(treeView, branchContainer);
			}

			branchContainer.appendChild(branchInnerContainer);
			parentContainer.appendChild(branchContainer);
		}
		// end sub-branch
	}
}

MediasiteTreeView = function()
{
	this.id;
	this.elementId;
	this.selectedNodeId;
	this.nodeCssClass;
	this.selectedNodeCssClass;
	this.nodeHoverCssClass;
	this.selectedNodeHoverCssClass;
	this.onClickMethod;
	this.onDropMethod;
	this.imageBasePath;
	this.collapsedImage;
	this.expandedImage;
	this.showLines;
	this.autoPostBack;
	this.nodes = new Array();
	this.selectedValueInputId;
	
	this.Initialize = function(id, elementId, nodeCssClass, selectedNodeCssClass, nodeHoverCssClss, selectedNodeHoverCssClass, imageBasePath, expandedImage, collapsedImage, showLines, autoPostBack, selectedValueInputId)
	{
		this.id = id;
		this.elementId = elementId;
		this.nodeCssClass = nodeCssClass;
		this.selectedNodeCssClass = selectedNodeCssClass;
		this.nodeHoverCssClss = nodeHoverCssClss;
		this.selectedNodeHoverCssClass = selectedNodeHoverCssClass;
		this.imageBasePath = imageBasePath;
		this.expandedImage = expandedImage;
		this.collapsedImage = collapsedImage;
		this.showLines = showLines;
		this.autoPostBack = autoPostBack;
		this.selectedValueInputId = selectedValueInputId;
	}
	
	this.GetSelectedValue = function() 
	{
		if ( this.selectedNodeId == null ) 
		{
			return '';
		}
		
		var node = $(this.selectedNodeId);
		return node.getAttribute('value');
	}

	this.GetSelectedText = function() 
	{
		if ( this.selectedNodeId == null ) 
		{
			return '';
		}

		var node = $(this.selectedNodeId);
		return node.innerHTML;
	}
	
	this.GetNodeById = function(nodeId, nodes)
	{
		if ( nodes == null )
		{
			return this.GetNodeById(nodeId, this.nodes);
		}
	
		for ( var i = 0; i < nodes.length; i++ )
		{
			if ( nodes[i].id == nodeId ) 
			{
				return nodes[i];
			}
			
			if ( nodes[i].nodes.length > 0 ) 
			{
				var result = this.GetNodeById(nodeId, nodes[i].nodes);
				
				if ( result != null )
				{
					return result;
				}
			}
		}
		
		return null;
	}
	
	this.ExpandCollapse = function(nodeId, extension) 
	{
		var branch = $(nodeId + "_branch");
		var image = $(nodeId + "_img");
		var userImage = $(nodeId + "_uimg");
		
		if ( branch.className == 'mtvTreeBranchHidden' ) 
		{
			branch.className = 'mtvTreeBranchVisible';
			
			if ( image != null ) 
			{
				image.src = this.imageBasePath + '/mtv_collapse_' + extension + '.gif';
			}
			
			if ( userImage != null )
			{
				userImage.src = this.imageBasePath + '/' + this.expandedImage;
			}
		}
		else 
		{
			branch.className = 'mtvTreeBranchHidden';
			
			if ( image != null ) 
			{
				image.src = this.imageBasePath + '/mtv_expand_' + extension + '.gif';
			}
			
			if ( userImage != null )
			{
				userImage.src = this.imageBasePath + '/' + this.collapsedImage;
			}
		}	
	}
	
	this.OnMouseOver = function(nodeId)
	{
		var node = $(nodeId);
		
		if ( nodeId == this.selectedNodeId ) 
		{
			node.className = this.selectedNodeHoverCssClass;
		}
		else
		{
			node.className = this.nodeHoverCssClss;
		}
	}
	
	this.OnMouseOut = function(nodeId) 
	{
		var node = $(nodeId);
		
		if ( nodeId == this.selectedNodeId ) 
		{
			node.className = this.selectedNodeCssClass;
		}
		else
		{
			node.className = this.nodeCssClass;
		}
	}
	
	this.SetSelectedNode = function(nodeId) 
	{
		if ( this.selectedNodeId != null ) 
		{
			var currentNode = $(this.selectedNodeId);
			currentNode.className = this.nodeCssClass;
		}
		
		this.selectedNodeId = nodeId;
		var selectedNode = $(nodeId);
		selectedNode.className = this.selectedNodeCssClass;
		
//		var hiddenInput = $(this.selectedValueInputId);
		var hiddenInput = document.getElementsByName(this.selectedValueInputId)[0];
		hiddenInput.value = selectedNode.getAttribute('value');
	}	
	
	this.OnClick = function(nodeId)
	{
		this.SetSelectedNode(nodeId);
		
		if ( this.autoPostBack )
		{
			__doPostBack(this.elementId.replace(/_/g, ':'), nodeId);
		}
		else if ( this.onClickMethod != null )
		{
			eval(this.onClickMethod+"()");
		}
	}
	
	this.Render = function()
	{
		var treeContainer = $(this.elementId);
			
		while ( treeContainer.hasChildNodes() )
		{
			treeContainer.removeChild(treeContainer.childNodes[0]);
		}
		
		for ( var i = 0; i < this.nodes.length; i++ )
		{
			this.nodes[i].Render(this, treeContainer);
		}
	}
}