var JSDC_DAO_TREE_EXISTS = true;


// treetableoptions() - Settingsobject for data_aware_object.
function treeoptions(dest,parentcol_idx,top_parentid)
{
	this.dest = dest;
	this.nodes = new Array();
	this.stateClass = null;
	this.captionClass = null;
	this.parentcol_idx = parentcol_idx;
	this.top_parentid = top_parentid;
	this.selectednode = null;
	this.selectedelement = null;
	this.selectedcolor = "#FFFFFF";
	this.selectedbgclr = "#000070";
	
  this.DoOnStateClick = function DoOnStateClick(e) 
	{ 
		var target = window.event ? event.srcElement : e.target;
		if (target.nodeName == 'SPAN')
		{	
			var ref_node = target.parentNode.childNodes[0];
			
			// The row has a hidden input field with the row index.
			if (ref_node.id == "node_ref")
			{
				
			  var currnode = dest.options.nodes[ref_node.value];
			  
			  if (currnode.state == 1) 
			  {
					collapse_treenode(currnode);
				}
				else
				if (currnode.state == 0) 
				{
					expand_treenode(dest, currnode, 1);
				}
			}
			else
			{
				throw ('Internal JSDC error, row_ref object expected in DoOnStateClick.');
			}
		}
	};
	
  this.DoOnSingleClick = function DoOnSingleClick(e) 
	{ 
		var target = window.event ? event.srcElement : e.target; 
		// The row has a hidden input field with the row index.
		
		var ref_node = target.parentNode.childNodes[0].childNodes[0];
		if (ref_node.id == "node_ref")
		{
			if (dest.onChange) // Add general result handling like cancel or similar?
			{
		    	dest.onChange(dest.dataview);
		    }
			var currnode = dest.options.nodes[ref_node.value];
	
			dest.dataview.gotoRecord(Number(currnode.row_idx));
			if (dest.options.selectednode)
			{
				dest.options.selectedelement.style.backgroundColor = "transparent";
				dest.options.selectedelement.style.color = "#000000";
			}

			target.style.backgroundColor = dest.options.selectedbgclr;
		
			target.style.color = dest.options.selectedcolor;
			
			dest.options.selectednode = currnode;
			dest.options.selectedelement = target;

		}
		else
		{
			throw ('Internal JSDC error, row_ref object expected in DoOnSingleClick.');
		}
	};
}

function collapse_treenode(node)
{
	if (node.state == 1)
	{
		node.childelement.parentNode.removeChild(node.childelement);
		node.element.childNodes[0].childNodes[0].innerHTML = '<input type="hidden" id="node_ref" value="' + node.node_ref + '">' + MakeSpanned('[+]', "tree_state");//'<img src="'+  + '">'
		node.state = 0;
	}
}

function expand_treenode(dest, node)
{

	if (node.state < 1)
	{

		if (node.childelement)  // If this node has been previously expanded, the structures are left in memory.
		{
	  		node.element.appendChild(node.childelement);
			node.element.childNodes[0].childNodes[0].innerHTML = '<input type="hidden" id="node_ref" value="' + node.node_ref + '">' +MakeSpanned('[-]', "tree_state");//'<img src="'+  + '">'

			node.state = 1;
		}
		else
		{
		
			var row_idx, new_table, new_tr, new_td, node_tr, node_td,
			child_tr, child_state_td, child_caption_td, child_table, childholder_tr, childholder_td,
			 	parentnodeid, new_node, parentnodeid, child_id, child_idx, has_child;
			 	
			// loop all nodes where parentnodeid is parentnodeid 
			var idcol = dest.dataview.columns[dest.idcol_idx];
			var valuecol = dest.dataview.columns[dest.valuecol_idx];
			var parentcol = dest.dataview.columns[dest.options.parentcol_idx];

			if  (node.parentnode) // Find parentnodeid.
			{  
				parentnodeid = idcol.getdata(node.row_idx);
			}
			else
			{
				parentnodeid = dest.options.top_parentid; // A topnode has the top_parentid..Usually -1.
			}	
			
			var childholder = document.createDocumentFragment();
			var localselection = dest.dataview.selection;
			var sel_length = localselection.length;

			node.state = -1; // Node is a leaf if no children are found.
			for (row_idx = 0;row_idx<sel_length;row_idx++) 
			{
				if (parentcol.getdata(row_idx) == parentnodeid)
				{
					// Create child tr.
					child_tr = document.createElement("tr");
					child_state_td = document.createElement("td"); 
					child_caption_td = document.createElement("td");
					
					// Create child table.
					child_table = document.createElement("table")
		  		
					if (child_table.tBodies.length == 1)  
					{
					  // Use existing tBody.. For IE 
						var new_tbody = child_table.tBodies[0];
					}
					else
					{
						var new_tbody = document.createElement("tbody");
						child_table.appendChild(new_tbody);
					}

					new_node = new treenode(dest, node, row_idx, new_tbody);
					node.childNodes.push(new_node);
					
					// Check for child nodes. Is this part ugly? Should it recurse instead?
					child_idx = 0;					
					child_id = idcol.getdata(row_idx);
					while ((child_idx < sel_length) && (parentcol.getdata(child_idx) != child_id))
					{
						child_idx++;
					}

					// If applicable, add expander and hidden node reference field.
					
					if (child_idx < sel_length) 
					{

						child_state_td.innerHTML = '<input type="hidden" id="node_ref" value="' + new_node.node_ref + '">'+MakeSpanned('[+]', "tree_state");//'<img src="'+  + '">'
						if (child_state_td.attachEvent) 
						{
							child_state_td.attachEvent("onclick", dest.options.DoOnStateClick);
						}
						else
						{
							child_state_td.addEventListener("click", dest.options.DoOnStateClick, true); // standards compliant; doesn't work in IE
						}
					}
					else
					{
						child_state_td.innerHTML = '<input type="hidden" id="node_ref" value="' + new_node.node_ref + '">';//'<img src="'+  + '">'
					}
					child_tr.appendChild(child_state_td);
					child_state_td.className = dest.options.stateClass;

					// Add node caption
					child_caption_td.innerHTML = valuecol.getdata(row_idx);
					child_caption_td.className = dest.options.captionClass;
					
					// Add selector.
					if (child_caption_td.attachEvent) 
					{
						child_caption_td.attachEvent("onclick", dest.options.DoOnSingleClick);
					}
					else
					{
						child_caption_td.addEventListener("click", dest.options.DoOnSingleClick, true); // standards compliant; doesn't work in IE
					}
				  
					child_tr.appendChild(child_caption_td);
					
					add_tr_to_table(child_table, child_tr);
					
					new_tr = document.createElement("tr");
					new_td = document.createElement("td");
					new_td.appendChild(child_table);
					
					new_tr.appendChild(new_td);
					childholder.appendChild(new_tr);
				
				}
			}
			
			if  (node.parentnode) // Check so it's not a topnode.
			{  
				
				// Create structure to hold children
				childholder_tr = document.createElement("tr");
				childholder_td = document.createElement("td");		
				childholder_tr.appendChild(childholder_td);
				childholder_td.colSpan = 2;
				var childholder_table = document.createElement("table");
				childholder_td.appendChild(childholder_table);

				// Add children
				add_tr_to_table(childholder_table, childholder);
				// Add them to node
				node.element.appendChild(childholder_tr);
				
				node.childelement = childholder_tr;
				
				if (node.childNodes.length > 0)
				{
					// The node has children.
					node.element.childNodes[0].childNodes[0].innerHTML = '<input type="hidden" id="node_ref" value="' + node.node_ref + '">'+MakeSpanned('[-]', "tree_state");//'<img src="'+  + '">'
					node.state = 1;
				}
				else
				{
					// The node is a leaf
					node.element.childNodes[0].childNodes[0].innerHTML = '<input type="hidden" id="node_ref" value="' + node.node_ref + '">';//'<img src="'+  + '">'
				}

	    }
	    else
	    {
				parentnodeid = dest.options.top_parentid;
				add_tr_to_table(dest.daobj, childholder);
	    }
	  }
	}

}		
function tree_change(dest, action, row_idx, col_idx)
{
	if (dest.daobj)
	{
		switch (action)
		{
			case "refresh":
		  	if (!dest.options.topnode)
			{
				dest.options.topnode = new treenode(dest);
			}
			expand_treenode(dest, dest.options.topnode, 1);	  
			break;
			case "remove":
			break;
			case "insert":
			break;
			case "update": // not functional.Move? Change?
			break;
		}
	}
	else
	{ 
		alert("daobj not assigned"); 
	}
   
}

// treenode() - Represents a node in a tree.
function treenode(dest, parentnode, row_idx, element)
{
	this.dataview = dest.dataview;
	this.parentnode = parentnode;
	this.element		= element;
	this.childelement	= null;
	this.childNodes 	= new Array();
	this.cached			= false;
	this.row_idx 		= row_idx;
	this.node_ref 		= dest.options.nodes.push(this) - 1;
	this.state 			= 0;
	this.selected = null;

}

