
var TreeParents		= new Object();
var TreeNames		= new Object();
var TreeExpand		= new Object();
var TreeID			= new Object();
var TreeNode        = new Object();
var TreeClickable	= new Object();
var TreeChecked		= new Object();
var TreeDynamic		= new Object();
var TreeDrawn		= false;
var TreeTickedDesc	= new Object();
var nocategoriesmessage = '';

function DrawFromNode( field, node, inner, search )
{
	var result			= "";
    var width			= 10;
    var numChildren		= 0;
    
    if( node == -1 ) {
    	width = 0;
    }

	if( !inner ) {
		result += "<table border=0 cellpadding=0 cellspacing=1><td width=" + width + ">&nbsp;</td><td class='treetext' nowrap id='" + field + "_node" + node + "'>";
	}
	
	//loop through all nodes with <node> as the parent
	for( var i = 0, il=TreeParents[field].length; i < il; i++ ) {
        if( TreeParents[field][i] == node ) {

			if( HasTickedDescendants( field, i ) ) { 
            	if( !TreeDrawn ) {
            		TreeExpand[field][i] 	= true; 
            	}
		}

			
            if( TreeExpand[field][i] ) {
				icon = "<img xalign=middle width=11 height=11 hspace=3 src=" + baseurl_short + "gfx/interface/node_ex.gif";
			} else {
				icon = "<img xalign=middle hspace=3 width=11 height=11 src=" + baseurl_short + "gfx/interface/node_unex.gif";
			}
    
    		numChildren = CountChildren( field, i );
    		
            if( numChildren == 0 ) {
            	icon = "<img xalign=top src=" + baseurl_short + "gfx/interface/sp.gif width=11 height=11 hspace=3>";
            } else {
            	icon += " onClick=\"ToggleNode('" + field + "'," + i + "," + search + ");\">";
            }
            
        	result	+= icon;
            checked	= "";
            
            if( TreeChecked[field][i] == 1 ) {
            	checked = "checked";
            }
            
            if( TreeClickable[field][i] ) {
            	result += "<input name='' type=checkbox id=checkbox" + i + " " + checked + " onclick=\"CheckNode('" + field + "'," + i + "," + true + "," + search + ");\">";
            }
            
            result += DePath( TreeNames[field][i] );
            result += "<br>";
            
            if( TreeExpand[field][i] && numChildren > 0 ) {
            	result += DrawFromNode( field, i, false, search );
            }
		}
	}
	
	if( !inner ) {
		result += "</td></tr></table>";
	}
	
	if( node == -1 ) {
    	TreeDrawn = true;
    }

	return( result );
}


function CheckNode( field, node, isuseraction, search )
{
	if( (branch_limit == 1 || branch_limit_field[field] == 1)  && search!=true)	{
	var n = TreeChecked[field][node];
	DeselectAll( field );
	} else {var n = node;}


	if( TreeChecked[field][node] != 1 )  {
		TreeChecked[field][node] = 1;

		if( search != true) {

			//Make sure all parents are ticked unless in search mode

			var p = TreeParents[field][n];

			if( p > -1 ) {
				TreeTickedDesc[field][p] = true;
				if( TreeChecked[field][p] != 1 ) {
					CheckNode( field, p, false, search );
					unode = TreeParents[field][p];
					if( unode == -1 ) {
						DrawTree( field, search );
					} else {
						UpdateNode( field, unode, search );
					}
				}
			}
		}if ((branch_limit==1 || branch_limit_field[field] == 1) && search!=true){
			DrawTree(field,search);
			}
	} else {
		TreeChecked[field][node] = 0;
		ResetChildren( field, node, search );
		UpdateNode( field, node, search );
	}

	UpdateStatusBox( field, search );
	UpdateHiddenField( field , isuseraction);
}
	

function UpdateStatusBox( field, search )
{
	var nodes = "";
	
	for( var i = 0, il = typeof(TreeParents[field]) === 'undefined' ? 0 : TreeParents[field].length; i < il; i++ ) {
		if( TreeChecked[field][i] == 1 ) {
			var c = CountTickedChildren( field, i );
			if( c == 0 ) {
				nodes += DescribeNode( field, i, search ) + "<br/>";
			}	
		}	
	}
	
	if( nodes == "" ) {
		document.getElementById( field + "_statusbox" ).innerHTML = nocategoriesmessage;
	} else {
		document.getElementById( field + "_statusbox" ).innerHTML = nodes;
	}
}
	

function StatusReset( field )
{
	//Set the status box to empty
	document.getElementById( field + "_statusbox" ).innerHTML="";
}


function DescribeNode( field, node, search )
{
	// Returns a string containing the node's full 'path'.
	// In search mode only the node itself is returned.
	var path	= DePath( TreeNames[field][node] );
	if(search!=true) {
		var p		= TreeParents[field][node];
		
		while( p > -1 ) {
			path = DePath( TreeNames[field][p] ) + " / " + path;
			var  p = TreeParents[field][p];
		}
	}
	return( path );
}
	

function ResetChildren( field, node, search )
{
	if( search!=true) {
		for( var p = 0; p < TreeParents[field].length; p++ ) {
			if( TreeParents[field][p] == node ) {
				TreeChecked[field][p] = 0;
				TreeTickedDesc[field][p] = false;
				ResetChildren( field, p, search );
				UpdateNode( field, p, search );
			}
		}
	}
}


function ToggleNode( field, node, search )
{ 
	TreeExpand[field][node] =! TreeExpand[field][node];
	UpdateNode( field, TreeParents[field][node], search );
}


function UpdateNode( field, node, search )
{
    if( document.getElementById( field + "_node" + node ) ) {
        document.getElementById( field + "_node" + node ).innerHTML = DrawFromNode( field, node, true, search );
    }
}

    
function CountChildren( field, node )
{
	var count	=	0;
	
	for( var i = 0, il = TreeParents[field].length; i < il; i++ ) {
		if( TreeParents[field][i] == node ) {
			count++;
		}	
	}
	
	return( count );
}


function CountTickedChildren( field, node )
{
	var count	= 0;
	
	for( var i = 0, il = TreeParents[field].length; i < il; i++ ) {
		if( ( TreeParents[field][i] == node ) && ( TreeChecked[field][i] == 1 ) ) {
			count++;
		}	
	}
	
	return( count );
}


function HasTickedDescendants( field, node )
{
		var hasTickedDescendants = false;

		if (typeof TreeTickedDesc[field][node] != 'undefined') {
    		return TreeTickedDesc[field][node];
		}

		for( var i = 0, il = TreeParents[field].length; i < il; i++ ) {
			if( ( TreeParents[field][i] == node ) && ( TreeChecked[field][i] == 1 ) ) {
				hasTickedDescendants = true;
				break;	
			} else {
				if( TreeParents[field][i] == node ) {
					hasTickedDescendants = HasTickedDescendants( field, i );
					 if( hasTickedDescendants ) { 
						break; 
					 } 
				}
			}
		}

	TreeTickedDesc[field][node] = hasTickedDescendants;
	return( hasTickedDescendants );
}


function CountCheckedRootLevels( field )
{
	var count	= 0;
	
	for( var i = 0, il = TreeParents[field].length; i < il; i++ ) {
		if( ( TreeParents[field][i] == -1 ) && ( TreeChecked[field][i] == 1 ) ) {
		count++;
		}	
	}
	
	return( count );
}


function DeselectAll( field, search )
{
	TreeChecked[field] = new Array();
	DrawTree( field, search );
	UpdateStatusBox( field, search );
	UpdateHiddenField( field , true);
}


function DrawTree( field, search )
{
	document.getElementById( field + "_tree" ).innerHTML = DrawFromNode( field, -1, false, search );
}


function AddNode( field, nodeparent, nodeid, nodename, nodeclickable, nodechecked, nodeexpand )
	{
    //try to find an empty space first

    var found	= false;
/*    
	for( var c = 0, cl = TreeParents[field].length; c < cl; c++ ) {
		if( TreeParents[field][c] == -100 ) {
			found = true;
			break;
		}	
	}
*/	
    if( found == false ) {
    	c = TreeParents[field].length;
    }
    
	TreeParents[field][c]		= nodeparent;    
    TreeID[field][c]			= nodeid;
    TreeNode[field][nodeid]		= c;
	TreeNames[field][c]			= nodename;
	TreeExpand[field][c]		= false;
    TreeClickable[field][c]		= nodeclickable;
    TreeChecked[field][c]		= nodechecked;
    TreeExpand[field][c]		= false;
    TreeTickedDesc[field][c]	= false;
}


function ResolveParents( field )
{
	for( var c = 0, cl = TreeParents[field].length; c < cl; c++ ) {
    	//resolve nodeparent to internal node id
	    found  = false;
	    
	    if (typeof TreeNode[field][TreeParents[field][c]] != 'undefined') {
			p = TreeNode[field][TreeParents[field][c]]
			found = true;
		}
		
	    if( found ) {
	    	TreeParents[field][c] = p;
			if (TreeChecked[field][c] == 1) {
				TreeTickedDesc[field][p] = true;
			}
	    }
	    
	    if( TreeParents[field][c] == -1 ) {
	    	TreeParents[field][c] = -1;
	    }
	}
}


function UpdateHiddenField( field , user_action)
{
	var f = "";
	
	for( var p = 0, pl = TreeID[field].length; p < pl; p++ ) {
		if ( TreeChecked[field][p] == 1 ) {
			f += "|" + TreeNames[field][p];
		}	
	}
	
	document.getElementById( field + "_category" ).value = f;
	
	// Update the result counter, if the function is available (e.g. on Advanced Search).
	if( typeof( UpdateResultCount ) == 'function' ) {
		UpdateResultCount();
	}
	
	// Update auto save status
	if (user_action)
		{
		var AutoSaveField=field.replace('field_','');
		if (document.getElementById('AutoSaveStatus'+AutoSaveField))
			{
			AutoSave(AutoSaveField);
			}
		}	
}
	
function DePath( path )
{
	// Returns the last element in a tilda-separated path as produced by StaticSync for the various tree levels.
	pathsplit=path.split( '~' )
	return( pathsplit[pathsplit.length-1] );
}
