	/* PREFS manager */
	function TREE2_prefs()
	{
		/* atributes */
		this.prefs = new Array();
		
		this.prefs['open_level'] 		= 1;
		this.prefs['hide_levels_css'] 	= false;
		
		//tree elements
		this.prefs['tree_elements'] 	= ['ul', 'li', 'div', 'img', 'a', 'span'];
		
		//class names
		this.prefs['CN_tree'] 			= 'T-t';
		this.prefs['CN_list'] 			= 'T-l'; 
		this.prefs['CN_item_container'] = 'T-ic';
		this.prefs['CN_item'] 			= 'T-i';
		this.prefs['CN_open_subcatgs'] 	= 'T-oc';
		this.prefs['CN_nochild'] 		= 'T-n';
		this.prefs['CN_open_subitems'] 	= 'T-oi'; 
		this.prefs['CN_opened'] 		= 'T-o';
		this.prefs['CN_last'] 			= 'T-last';
		this.prefs['CN_active'] 		= 'T-a';
		
		//images
		this.prefs['plus_img'] 			= '/img/rs/tree/plus.gif';
		this.prefs['minus_img'] 		= '/img/rs/tree/minus.gif';
	};
	
	TREE2_prefs.prototype.setElNames = function () 
	{
		this.prefs['tree_elements'] = setElNames.arguments;
	};
	
	/*
	oClassNames = {
		CN_tree: 'T-t',
		CN_list: 'T-l', 
		CN_item_container: 'T-ic',
		CN_item: 'T-i',
		CN_open_subcatgs: 'T-oc', 
		CN_nochild: 'T-n', 
		CN_open_subitems: 'T-oi', 
		CN_opened: 'T-o', 
		CN_last: 'T-last', 
		CN_active: 'T-a'
	}
	*/
	
	TREE2_prefs.prototype.setClassNames = function (oClassNames)
	{
		for (var key in oClassNames) {
			this.prefs[key] = oClassNames[key];
		};
	};
	
	TREE2_prefs.prototype.setOpenLevel = function (level)
	{
		this.prefs['open_level'] = level;
	};
	
	TREE2_prefs.prototype.setOpenerBgImages = function (plusImg, minusImg)
	{
		this.prefs['plus_img'] = plusImg;
		this.prefs['minus_img'] = minusImg;
	};
	
	/* vypise do stranky CSS skryvajici levely */
	TREE2_prefs.prototype.hideLevelsCSS = function ()
	{
		var x = 0;
		var CSS_list = '';
		var CSS_plusminus = '';
		var CODE = '';
		while(x <= this.prefs['open_level']) {
			CSS_list += '.'+this.prefs['CN_list']+' ';
			if (x < this.prefs['open_level']) {
				CSS_plusminus += '.'+this.prefs['CN_list']+' ';
			};
			x++;
		};
		
		CODE = CSS_list + '{ display : none; } ' + CSS_plusminus + ' .'+this.prefs['CN_open_subcatgs']+' { background-image : url('+this.prefs['plus_img']+'); } ';
		CODE = '<style type="text/css">' + CODE + '</style>';
		document.write(CODE);
		
		this.prefs['hide_levels_css'] = true;
	};
	
	
/* ======================================================== */
	
	var TREE2_object;
	function TREE2 () 
	{
		TREE2_object = this;
	};
	
	/* inicializace */
	TREE2.prototype.init = function (oPrefs)
	{
		//pokud nedostanu objekt tridy TREE2_prefs, vytvorim ho sam
		this.PREFS = typeof(oPrefs)=='object' ? oPrefs : new TREE2_prefs();
		
		var i, j;
		var opened_elements = new Array();
		var elements;
		
		/* prolezeni stromu a registrace udalosti/ostatni akce */
		for (i=0; i<this.PREFS.prefs['tree_elements'].length; i++) {
			elements = document.getElementsByTagName(this.PREFS.prefs['tree_elements'][i]);
			for (j=0; j<elements.length; j++) {
				if (this.containsClass(elements[j], this.PREFS.prefs['CN_open_subcatgs'])) {
					/* na openery subkategorii (vetsinou obr. s +/-) zaregistruje akce */
					elements[j].onclick = this.constructor.prototype.openCloseSubtree;
				};
				if (this.containsClass(elements[j], this.PREFS.prefs['CN_list'])) {
					/* list elementy se zkontroluji, jestli maji byt zobrazeny, nebo ne */
					this.checkListDisplay(elements[j]);
				};
				if (this.containsClass(elements[j], this.PREFS.prefs['CN_opened']) || this.containsClass(elements[j], this.PREFS.prefs['CN_active'])) {
					/* pokud se najde nejaky otevreny folder  u element typu TR-open-subitems (TR-opened), nebo aktivni folder (TR-active),  zaznamena se */
					opened_elements[opened_elements.length] = elements[j];
				};
			};
		};
		
		/* zpracovani opened_elements - otevreni vsech vetvi s opened foldery */
		for (i=0; i<opened_elements.length; i++) {
			el = opened_elements[i].parentNode;
			while (!this.containsClass(el, this.PREFS.prefs['CN_tree'])) {
				if (this.containsClass(el, this.PREFS.prefs['CN_list'])) {
					this.checkListDisplay(el, true);
				};
				el = el.parentNode;
			};
		};
	};
	
	TREE2.prototype.openCloseSubtree = function (e)
	{
		SELF = TREE2_object;
		
		if (window.event) {
			var OpenEl = window.event.srcElement;
		} else {
			var OpenEl = e.currentTarget;
		};
		var Item = OpenEl.parentNode;
		var List = SELF.getNextList(Item);
		if (List) {
			if (List.offsetHeight > 0) {//zavreni submenu
				List.style.display = 'none';
				OpenEl.style.backgroundImage = 'url('+SELF.PREFS.prefs['plus_img']+')';
			} else {//otevreni submenu
				List.style.display = 'block';
				OpenEl.style.backgroundImage = 'url('+SELF.PREFS.prefs['minus_img']+')';
			};
		};
		return false;
	};
	
	TREE2.prototype.checkListDisplay = function (List, open)//open - true/false; muze byt vynechano a pak se to ridi podle nastaveneho levelu
	{
		if (open==null) {
			if (this.PREFS.prefs['hide_levels_css']) return false;//pokud jsou levely skryty pres CSS, nemusim je skryvat skriptem
			
			var level = this.getListLevel(List);
			if (level>this.PREFS.prefs['open_level']) {
				open = false;
			} else {
				open = true;
			};
		};
		
		if (open) {
			List.style.display = 'block';
		} else {
			List.style.display = 'none';
		};
		
		var Item = this.getPreviousItem(List);
		
		if (Item) {
			var OpenEl = this.getItemOpenEl(Item);
			if (OpenEl) {
				if (open) {
					OpenEl.style.backgroundImage = 'url('+this.PREFS.prefs['minus_img']+')';
				} else {
					OpenEl.style.backgroundImage = 'url('+this.PREFS.prefs['plus_img']+')';
				};
			};
		};
	};
	
	/* vraci level zadaneho elementu typu TR-listu */
	TREE2.prototype.getListLevel = function (List)
	{
		var level = 0;
		var el = List;
		
		while (!this.containsClass(el, this.PREFS.prefs['CN_tree']) && el!=document.body) {
			if (this.containsClass(el, this.PREFS.prefs['CN_list'])) level++;
			el = el.parentNode;
		};
		
		if (this.containsClass(el, this.PREFS.prefs['CN_tree'])) level++;
		return level;
	};
	
	/* vraci 1. element typu TR-list mezi nasledujicimi siblingy (nebo null) */
	TREE2.prototype.getNextList = function (Item)
	{
		var el = Item.nextSibling;
		while (el!=null) {
			if (el.nodeType==1) {
				if (this.containsClass(el, this.PREFS.prefs['CN_list'])) {
					return el;
				};
			};
			el = el.nextSibling;
		};
		return null;
	};
	
	/* vraci 1.  element typu TR-item mezi predchozimi siblingy (nebo null) */
	TREE2.prototype.getPreviousItem = function (List)
	{
		var el = List.previousSibling;
		while (el!=null) {
			if (el.nodeType==1) {
				if (this.containsClass(el, this.PREFS.prefs['CN_item'])) {
					return el;
				};
			};
			el = el.previousSibling;
		};
		return null;
	};
	
	/* vraci 1.child element typu TR-item, ktery je typu TR-open-subcatgs (nebo null) */
	TREE2.prototype.getItemOpenEl = function (Item)
	{
		var el = Item.firstChild;
		while(el!=null) {
			if (el.nodeType==1) {
				if (this.containsClass(el, this.PREFS.prefs['CN_open_subcatgs'])) {
					return el;
				};
			};
			el = el.nextSibling;
		};
		return null;
	};
	
	/* vraci true, pokud string className obsahuje prislusne jmeno tridy (pokud je jich vice) */
	TREE2.prototype.containsClass = function (el, className) 
	{
		if(!el) return false;
		if(!el.className) return false;
		var subNames = el.className.split(' ');
		for(i=0; i<subNames.length; i++) {
			if(subNames[i]==className) return true;
		};
		return false;
	};
