
function joTreeNodeClass (parent_obj, node_name)
{
	this.parent								= parent_obj;
	this.name								= node_name;
	this.data								= "";
	this.attributes						= new Array();
	this.childNodes						= new joChainedListClass (this);
	
	this.FindNode							= _joXMLElem_FindNode;
	this.FindNodeByAttribute			= _joXMLElem_FindNodeByAttribute;
	this.RemoveNode						= _joXMLElem_RemoveNode;
	this.AppendNode						= _joXMLElem_AppendNode;
	this.CopyNode							= _joXMLElem_CopyNode;

	this.SetData							= function (data) { this.data = data; };

	this.SetAttribute						= _joXMLElem_SetAttribute;
	this.GetAttributeNode				= _joXMLElem_GetAttributeNode;
	this.GetAttribute						= _joXMLElem_GetAttribute;
	this.HasAttribWithValue 			= _joXMLElem_HasAttribWithValue; 
}

/* ********************************************************************************************************** */

function _joXMLElem_AppendNode (data_name, append_after_node)
{
	var result					= false;
	var new_node				= new joTreeNodeClass (this.childNodes, data_name);
	return this.childNodes.AppendElement (new_node, append_after_node);
}

/* ********************************************************************************************************** */

function _joXMLElem_RemoveNode (data_name, attrib_name, attrib_value)
{
	var result					= false;
	var del_node				= this.FindNodeByAttribute (data_name, attrib_name, attrib_value);
	if (del_node) result 	= del_node.parent.RemoveElement (del_node);
	return result;
}

/* ********************************************************************************************************** */

function _joXMLElem_CopyNode (new_parent)
{
	var new_node = new joTreeNodeClass (new_parent, this.name);
	new_node.data			= this.data;
	
	for (var i = 0; i < this.attributes.length; i++)
	{
		new_node.SetAttribute (this.attributes [i][0], this.attributes [i][1]);
	}
	new_node.childNodes.CopyElements (this.childNodes);
	return new_node;
}

/* ********************************************************************************************************** */

function _joXMLElem_SetAttribute (attrib_name, attrib_value)
{
	var attrib_pair;
	var myattrib = this.GetAttributeNode (attrib_name);
	if (myattrib)
	{
		myattrib[1] = attrib_value;
	}
	else
	{
		attrib_pair = new Array (attrib_name, attrib_value);
		this.attributes.push (attrib_pair);
	}
}

/* ********************************************************************************************************** */

function _joXMLElem_HasAttribWithValue (attrib_name, attrib_value)
{
	var result = false;
	
	var attrib = this.GetAttributeNode (attrib_name);
	if (attrib && attrib[1] == attrib_value) result = true;
	
	return result;
}

/* ********************************************************************************************************** */

function _joXMLElem_GetAttribute (attrib_name, default_value)
{
	var result = null;
	for (var i = 0; !result && i < this.attributes.length; i++)
	{
		if (this.attributes[i][0] == attrib_name)
			result = this.attributes[i][1];
	}
	if (!result)
	{
		if (default_value) 
				result = default_value;
		else	result = "";
	}
	return result;
}

/* ********************************************************************************************************** */

function _joXMLElem_GetAttributeNode (attrib_name)
{
	var result = null;
	for (var i = 0; !result && i < this.attributes.length; i++)
	{
		if (this.attributes[i][0] == attrib_name)
			result = this.attributes[i];
	}
	return result;
}

/* ********************************************************************************************************** */

function _joXMLElem_FindNode (node_name, create_if_not_exists)
{
	var result = this.FindNodeByAttribute (node_name, "", "");
	
	if (!result && create_if_not_exists)
	{
		result = this.AppendNode (node_name);
	}
	
	return result;
}

/* ********************************************************************************************************** */

function _joXMLElem_FindNodeByAttribute (node_name, attrib_name, attrib_value, with_following_siblings)
{
	var result = null;
	
	if ((node_name == "" || this.name == node_name) && (attrib_name == "" || this.HasAttribWithValue (attrib_name, attrib_value))) 
	{
		result = this;
	}
	else
	{
		if (!result && this.childNodes.element_first)
		{
			result = this.childNodes.element_first.FindNodeByAttribute (node_name, attrib_name, attrib_value, true);
		}
		if (!result && with_following_siblings && this.element_next) 
		{
			result = this.element_next.FindNodeByAttribute (node_name, attrib_name, attrib_value, true); 
		}
	}
	
	
	return result;
}

