
function structure_class_item(name, value) {
	this.next = null;
	this.last = null;
	this.parent = null;
	this.child = null;
	
	this.name = name;
	this.value = value;
	
	this.append_child = function(ref) {
		if (this.child == null) {
			this.child = ref;
			ref.parent = this;
		
		} else {
			var loop = this.child;
			
			while (loop.next != null) loop = loop.next;
			
			loop.next = ref;
			ref.last = loop;
			ref.parent = this;
		}
		
		return ref;
	}
	
	this.add_child = function(name, value) {
		return this.append_child(new structure_class_item(name, value));
	}
	
	this.get_child = function(name) {
		var founded = false;
		var loop = this.child;
		
		while (!founded && loop != null) {
			if (loop.name == name) founded = true;
			else loop = loop.next;
		}
		
		return founded ? loop : null;
	}
	
	this.destroy = function() {
		var stack = context.object_create(new Array());
		var current = null;
		var loop = null;
		stack[stack.length] = this;
		
		while (stack.length > 0) {
			current = stack.pop();
			
			loop = current.child;
			while (loop != null) {
				stack[stack.length] = loop;
				loop = loop.next;
			}
			
			context.object_destroy(current);
			current = null;
		}
	}
}

function structure_class() {
	this.root = null;

	this.construct = function() {
		this.flush();
	}
	
	this.flush = function() {
		if (this.root != null) {
			this.root.destroy();
			this.root = null;
		}
		this.root = context.object_create(new structure_class_item());
	}
	
	this.path_parts = function(path) {
		var path_parts = context.object_create(new Array());
		var point = 0;
		
		var cur_char = "";
		var cur_str = "";
		
		for (point = 0; point <= path.length; point++) {
			cur_char = point == path.length ? "/" : path.substr(point, 1);
			
			switch (cur_char) {
				case "/" :
					path_parts[path_parts.length] = cur_str;
					cur_str = "";
					break;
					
				default :
					cur_str += cur_char;
					break;
			}
		} // for
		
		return path_parts
	}
	
	this.map = function(path, value) {
		var path_parts = this.path_parts(path);
		
		if (path_parts.length > 0) {
			var current = this.root;
			var child;
			var f;
			
			for (f = 0; f < path_parts.length; f++) {
				child = current.get_child(path_parts[f]);
				if (child == null) {
					child = context.object_create(new structure_class_item(path_parts[f], f + 1 == path_parts.length ? value : null));
					current.append_child(child);
				} else {
					if (f + 1 == path_parts.length) child.value = value;
				}
				
				current = child;
			}
			
			return current;
		}
		
		return null;
	}
	
	this.get = function(path) {
		var path_parts = this.path_parts(path);
		var founded = null;
		
		if (path_parts.length > 0) {
			var f;
			var founded = this.root;
			
			for (f = 0; f < path_parts.length && founded != null; f++)
				founded = founded.get_child(path_parts[f]);
		}
		
		return founded != null ? founded.value : null;
	}
	
	this.compose = function(container_element) {
		var output = "<" + "?xml version=\"1.0\" encoding=\"iso-8859-2\"?" + "><" + container_element + ">";
		var stack = context.object_create(new Array());
		var opened = context.object_create(new Array());
		var current, add, loop;
		stack[stack.length] = this.root;
		
		while (stack.length > 0) {
			current = stack.pop();
			
			if (current != this.root) {
				
				// uzavreni
				var brk = false;
				var pos = opened.length - 1;
				
				while (!brk && pos >= 0) {
					if (opened[pos] == current.parent) brk = true;
					else pos--;
				}
				
				if (brk) {
					var max;
					for (max = opened.length - 1; max > pos; max--) {
						output += "</" + opened[max].name + ">";
						opened.pop();
					}
				} else {
					var f;
					for (f = opened.length -1; f >= 0; f--) {
						output += "</" + opened[f].name + ">";
					}
					opened = context.object_create(new Array());
				}
					
				if (current.child != null) {
					// otevreni
					output += "<" + current.name + ">";
					opened[opened.length] = current; 
					
				}
				
				if (current.child == null) {
					output += "<" + current.name + ">" + current.value + "</" + current.name + ">";
				}
			}
							
			if ((loop = current.child) != null) {
				add = context.object_create(new Array());
				while (loop != null) {
					add[add.length] = loop;
					loop = loop.next;
				}
				
				var f;
				for (f = add.length - 1; f >= 0; f--)
					stack[stack.length] = add[f];
			}
		}
		
		var f;
		for (f = opened.length - 1; f >= 0; f--) {
			output += "</" + opened[f].name + ">";
		}
		output += "</" + container_element + ">";
		
		return output;
	}
	
	this.construct();
}
