// ListMagic 3.4m ecenter edition
// written by fczbkk
// revised by RSe 21.11.2005
//
// requires functions 1.8, dom 3.7
//
// 	3.4m	bugfix - when cloning node, MSIE incorrectly handles selected item in select
// 	3.2m	taber.getTab modified to work with dom 2.5

var listMagic = {
	
	assignItems : function(list, liClassArray) {
		if (typeof list == "undefined") return false;
		if (typeof liClassArray == "undefined") return false;
		var i; // int iterator
		var li = null; // HTMLelement collection
		var counter = 0; // int line counter
		li = list.getElementsByTagName("li");
		for (i = 0; i < li.length; i++) {
			if (li[i].parentNode == list) {
				cls.add(li[i], liClassArray[counter]);
				counter = (++counter == liClassArray.length) ? 0 : counter;
			}
		}
		return true;
	},
	
	addCursor : function(list, cursorClass) {
		if (typeof list == "undefined") return false;
		if (typeof cursorClass == "undefined") return false;
		var i; // iterator
		var li = list.getElementsByTagName("li"); // HTMLcollection of list items
		var getTargetItem = function(e) {
			var obj;
				obj = evt.getTrigger(e);
				while (obj.parentNode != list)
					obj = obj.parentNode;

			return obj;
		}
		var showCursor = function(e) {
			var obj = getTargetItem(e);
			cls.add(obj, cursorClass);
		}
		var hideCursor = function(e) {
			var obj = getTargetItem(e);
			cls.remove(obj, cursorClass);
		}
		for (i = 0; i < li.length; i++) {
			if (li[i].parentNode == list) {
				evt.add(li[i], "mouseover", showCursor);
				evt.add(li[i], "mouseout", hideCursor);
			}
		}
		return true;
	},
	
	makeFolding : function(list, openClass) {
		if (typeof list == "undefined") return false;
		if (typeof openClass == "undefined") return false;
		var i; // iterator
		var li = list.getElementsByTagName("li");
		var getTargetItem = function(e) {
			var obj;
			e = evt.fix(e);
			if (e.currentTarget) obj = e.currentTarget;
			else {
				obj = e.target;
				while (obj.parentNode != list)
					obj = obj.parentNode;
				}
			return obj;
		}
		var switchItem = function(e){
			var obj = getTargetItem(e);
			if(cls.has(obj, openClass)) cls.remove(obj, openClass);
			else cls.add(obj, openClass);
		}
		for (i = 0; i < li.length; i++) {
			if (li[i].parentNode == list) {
				evt.add(li[i], "click", switchItem);
			}
		}
	return true;
	}
}




var taber = {
	cls:          "taber",        // taber class
	clsTab:       "tab",          // tab
	clsActive:    "tabActive",    // activated tab
	clsInactive:  "tabInactive",  // deactivated tab
	clsDefault:   "tabDefault",   // default activated tab
	clsLinked:    "tabLink",      // linked tab (no content, only link)
	
	init: function(dl) {
		
		dl = elm.get(dl);
		if (dl == null) return false; // not found
		
		var i, j; // int iterators
		var currentNode; // DOM node - iterator
		var dt = null; // HTMLelement dt
		var dd = null; // HTMLelement dd
		var ddCache = new Array(); // cache for dd nodes
		var toRemove = new Array(); // dd nodes to remove
		var ddHeight = 0; // int, height of largest dd
		
		if (dl && dl.tagName && dl.tagName.toLowerCase() == "dl") { // dl is valid definition list
			
			dl.taber_activeTab = null;
			dl.taber_firstTab = null;
			dl.taber_lastTab = null;
			
			currentNode = dl.firstChild;
			do {
				if (currentNode.tagName) { // Node is tag, go on
					if (currentNode.tagName.toLowerCase() == "dt") {
						// definition term found, process it
						dt = currentNode;
						if (dl.taber_firstTab == null) dl.taber_firstTab = dt;
						dl.taber_lastTab = dt;
						dt.taber_tabReference = new Array();
						cls.add(dt, taber.clsTab);
						if (cls.has(dt, taber.clsActive))
							dl.taber_activeTab = dt;
						cls.add(dt, taber.clsInactive);
						evt.add(dt, "click", taber.clickAction);
					} else if (currentNode.tagName.toLowerCase() == "dd") {
						// definition data found
						if (dt == null) return false; // dd found before first dt - bad dl structure, initialization fails
						dd = currentNode;
						ddCache[ddCache.length] = dd;
						dt.taber_tabReference[dt.taber_tabReference.length] = dd;
						dd.taber_tabReference = dt;
						cls.add(dd, taber.clsTab);
						toRemove[toRemove.length] = currentNode;
					}
				}
				currentNode = currentNode.nextSibling;
			} while (currentNode);
			
			// insert new definition data now
			for (i = 0; i < ddCache.length; i++) {
				ddCache[i].style.display = "none";
				dl.appendChild(ddCache[i]);
			}
			
			// set active node
			if (dl.taber_activeTab)
				taber.activateTab(dl.taber_activeTab);
			else
				taber.activateTab(dl.taber_firstTab);
		}
		return true;
	},
	
	getTab: function(obj) {
		if (typeof obj.tagName == "undefined") {
			obj = evt.fix(obj);
			obj = evt.getTarget(obj);
		}
		obj = elm.get(obj); // search for the right object
		while (obj.tagName.toLowerCase() != "dt") obj = obj.parentNode;
		return obj;
	},

	activateTab: function(tab) {
		if (typeof tab == "undefined") return false;
		var i; // int iterator
		var tabSet; // HTMLelement
		if (tab && (tab.tagName) && (tab.tagName.toLowerCase() == "dt")) {
			tabSet = tab.parentNode;
			// check if given dl is really tabber
			if (tabSet.taber_activeTab == null) tabSet.taber_activeTab = tab;
			else if(tabSet.taber_activeTab) { // this could be really tabber
				if(tab != tabSet.taber_activeTab) { // if tab is not already active
					// set active tab inactive
					cls.replace(tabSet.taber_activeTab, taber.clsActive, taber.clsInactive);
					for(i = 0; i < tabSet.taber_activeTab.taber_tabReference.length; i++) {
						cls.replace(tabSet.taber_activeTab.taber_tabReference[i], taber.clsActive, taber.clsInactive);
						tabSet.taber_activeTab.taber_tabReference[i].style.display ="none";
					}
					tabSet.taber_activeTab = tab;
				}
			}
			// set new tab active
			cls.remove(tabSet.taber_activeTab, taber.clsInactive);
			cls.add(tabSet.taber_activeTab, taber.clsActive);
			for (i = 0; i < tab.taber_tabReference.length; i++) {
				cls.remove(tab.taber_tabReference[i], taber.clsInactive);
				cls.add(tab.taber_tabReference[i], taber.clsActive);
				tabSet.taber_activeTab.taber_tabReference[i].style.display = "";
			}
			return true;
		}
		return false;
	},
	
	activateNextTab: function(obj) {
		obj = elm.get(obj);
		if (obj == null) return false; // fail - list not found
		if (obj.tagName.toLowerCase() != "dl") {
			obj = elm.getAncestorByTag(obj, "dl");
		}
		if (typeof obj.taber_activeTab == "undefined") return false; // fail - list not initialized?
		var actualNode = obj.taber_activeTab;
		var endSearch = false;
		do {
			if (obj.taber_activeTab.nextSibling == null) {
				taber.activateTab(taber.firstTab);
				return true;
			} else {
				actualNode = actualNode.nextSibling;
			}
			if (actualNode.tagName && (actualNode.tagName.toLowerCase() != "dl"))
				endSearch = true;
		} while (!endSearch);
		taber.activateTab(actualNode);
		return true;
	},
	
	activatePrevTab: function(obj) {
		obj = elm.get(obj);
		if (obj == null) return false; // fail - list not found
		if (obj.tagName.toLowerCase() != "dl") {
			obj = elm.getAncestorByTag(obj, "dl");
		}
		if (typeof obj.taber_activeTab == "undefined") return false; // fail - list not initialized?
		var actualNode = obj.taber_activeTab;
		var endSearch = false;
		do {
			if (obj.taber_activeTab.previousSibling == null) {
				taber.activateTab(taber.lastTab);
				return true;
			} else {
				actualNode = actualNode.previousSibling;
			}
			if (actualNode.tagName && (actualNode.tagName.toLowerCase() != "dl"))
				endSearch = true;
		} while (!endSearch);
		
		taber.activateTab(actualNode);
		return true;
	},
	
	clickAction: function(e) {
		var tabLinks; // HTMLcollection
		var tab = taber.getTab(e);
		if (tab == null) return false;
		tabLinks = tab.getElementsByTagName("a");
		if (tabLinks[0]) window.location = tabLinks[0].href;
		taber.activateTab(tab);
		return true;
	}
}




var catList = {
	
	cls:                "categoryListEdit",
	
	editModeCls:        "categoryList_editMode",
	viewModeCls:        "categoryList_viewMode",
	
	dataInput: {
		dataNodeName:     "categoryList_inputData",
		dataNode:         null, // HTML element containing data
		treeNodeCls:      "categoryList_tree",
		treeNode:         null, // block containing input tree
		treeItems:        {},   // here are stored all tree nodes indexed by their ID
		data:             {},   // all structural data needed to create tree
		treeCreated:      false // will be set to true after the tree is physicaly built in HTML
	},
	
	dataOutput: {
		dataNodeName:      "categoryList_submitData",
		dataNode:          null,
		previewSeparator:  "&nbsp;,&nbsp; ",
		previewConnector:  " > ",
		previewNodeCls:    "categoryList_submitPreview",
		previewNode:       null,
		data:              {} // all output data
	},
	
	btnArea: {
		btnAreaCls:        "categoryList_btnArea",
		btnAreaNode:       null, // all buttons are located in this area
		btn: {
			view: {
				label:     "View",
				type:      "button",
				name:      "chkBoxViewBtn",
				cls:       "btnView"
			},
			edit: {
				label:     "Edit",
				type:      "button",
				name:      "chkBoxEditBtn",
				cls:       "btnEdit"
			},
			checkAllBtn: {},
			uncheckAllBtn: {}
		}
	},
	
	boxStates: {
		checked: {
			name:   "checked",
			cls:    "chkBoxChecked",
			title:  "",
			alt:  "",
			imgSrc: "",
			clickHandler: null
		},
		unchecked: {
			name:   "unchecked",
			cls:    "chkBoxUnchecked",
			title:  "",
			alt:  "",
			imgSrc: "",
			clickHandler: null
		},
		indeterminate: {
			name:   "indeterminate",
			cls:    "chkBoxIndeterminate",
			title:  "",
			alt:  "",
			imgSrc: "",
			clickHandler: null
		}
	},
	
	init: function(listNode) {
		listNode     = elm.get(listNode);
		cls.add(listNode, catList.cls); // assign the block as category tree if it is not assigned yet
		
		// TODO - this should be tested with more controls at one page - maybe arrays must be cloned
		listNode.catListInput = catList.dataInput;
		listNode.catListInput.treeItems = {}; // associative array of all items in category tree. Indexes equal ID numbers		
		listNode.catListOutput = catList.dataOutput;
		listNode.catListInput.dataNode = elm.get(catList.dataInput.dataNodeName);
		listNode.catListOutput.dataNode = elm.get(catList.dataOutput.dataNodeName);
			
		// set behavior of checkboxes
		catList.boxStates.unchecked.clickHandler     = catList.check;
		catList.boxStates.indeterminate.clickHandler = catList.uncheck;
		catList.boxStates.checked.clickHandler       = catList.uncheck;
		
		// create connections to DOM
		catList.initBlocks(listNode);
		catList.initInputs(listNode);
		catList.initButtons(listNode);
		
		// get data from DOM
		catList.readInputDataJSON(listNode);
		catList.getOutputData(listNode);
		
		listNode.catListOutput.previewNode.innerHTML = catList.getOutputPreview(listNode);
		
		// all should be ready in view mode now
		return true;
	},
	
	initBlocks: function(listNode) {
		listNode = elm.get(listNode);
		var blocks = elm.getByTag("div", listNode);
		var i;
		for (i = 0; i < blocks.length; i++) {
			// find blocks
			if (cls.has(blocks[i], catList.dataInput.treeNodeCls))
				listNode.catListInput.treeNode = blocks[i];
			if (cls.has(blocks[i], catList.btnAreaCls))
				listNode.catListInput.btnAreaNode = blocks[i];
			if (cls.has(blocks[i], catList.dataOutput.previewNodeCls))
				listNode.catListOutput.previewNode = blocks[i];
		}
		// if required block were not found, create them
		if (listNode.catListInput.treeNode == null) {
			listNode.catListInput.treeNode = elm.createDiv({className: catList.dataInput.treeNodeCls}, listNode);
		}
		if (listNode.catListInput.btnAreaNode == null) {
			listNode.catListInput.btnAreaNode = elm.createDiv({className: catList.btnAreaCls}, listNode);
		}
		return true;
	},
	
	initInputs: function(listNode) {
		listNode = elm.get(listNode);
		var inputs = elm.getByTag("input", listNode);
		var i;
//		for (i = 0; i < inputs.length; i++) {
//		}
		return true;
	},
	
	initButtons: function(listNode) {
		listNode = elm.get(listNode);
		
		// set handlers first
		listNode.catListInput.editBtn = elm.button.create(catList.btnArea.btn.edit);
		listNode.catListInput.btnAreaNode.appendChild(listNode.catListInput.editBtn);
		
		evt.add(listNode.catListInput.editBtn, "click", catList.setEditMode);
		
		return true;
	},
	
	getOutputData: function(listNode) {
		// read Id numbers from output field
		listNode = elm.get(listNode);
//		var data = {};
//		var dataArray = elm.getValue(listNode.catListOutput.dataNode).split(listNode.catListOutput.dataSeparator);
		dataArray = variable.parseJsonString(elm.getValue(listNode.catListOutput.dataNode));
		var dataArraySorted = {};
		var i, j, k;
		// create associative array of all id numbers
		for (i = 0; i < dataArray.length; i++) {
			dataArraySorted[dataArray[i]] = dataArray[i];
		}
		
		// create output data structure (merge sorted id numbers with existing tree nodes)
		
		for (i in listNode.catListInput.data) {
			if (dataArraySorted[listNode.catListInput.data[i][0]] == listNode.catListInput.data[i][0]) {
				listNode.catListOutput.data[listNode.catListInput.data[i][0]] = listNode.catListInput.data[i];
			}
		}
		return listNode.catListOutput.data;
	},
	
	getOutputPreview: function(listNode) {
		// generate output data string
		
		listNode = elm.get(listNode);
		var otputDataSet;
		var outputText = "";
		var nodeText = "";
		var i, j, k;
		for (i in listNode.catListOutput.data) { // in each branch
			nodeText = listNode.catListInput.data[i][2];
			j = listNode.catListInput.data[i][1]; // parent
			getUpTheTree: {
				while (j != null) {
					if (listNode.catListOutput.data[j] == null)
						nodeText = listNode.catListInput.data[j][2] + listNode.catListOutput.previewConnector + nodeText;
					else {
						nodeText = "";
						break getUpTheTree;
					}
					j = listNode.catListInput.data[j][1]; // parent
				}
			}
			if (nodeText != "")
				outputText = outputText + listNode.catListOutput.previewSeparator + nodeText;
		}
		if (outputText.length > 0) {
			outputText = outputText.substr(listNode.catListOutput.previewSeparator.length, outputText.length - listNode.catListOutput.previewSeparator.length);
		}
		return outputText;
	},
	
	setOutput: function(listNode) {
		// fills output fields
		listNode = elm.get(listNode);
		var k;
		var actualNode = null;
		var outputArray = new Array();
//		var outputValue = "";
		var itemValue;
		for (k in listNode.catListOutput.data) { // walks through all id numbers at output
			if (listNode.catListOutput.data[k] && listNode.catListInput.treeItems[k]) { // if id number has really item attached
				actualNode = listNode.catListInput.treeItems[k];
				itemValue = actualNode.catListItemData[0]; // same as k
				
				goUpTheTree:
				while (actualNode.catListItemParent != null) {
					actualNode = actualNode.catListItemParent;
					if (actualNode.catListItemBoxStatus != catList.boxStates.indeterminate.name) {
						// parent is in list, so current node will not be there
						itemValue = null;
						break goUpTheTree;	
					}
				}
				if (itemValue != null) {
					outputArray[outputArray.length] = itemValue;
//					outputValue += itemValue + listNode.catListOutput.dataSeparator;
				}
			}
		}
//		listNode.catListOutput.dataNode.value = outputValue;
		listNode.catListOutput.dataNode.value = variable.getJsonString(outputArray);
		if (listNode.catListOutput.previewNode)
			listNode.catListOutput.previewNode.innerHTML = catList.getOutputPreview(listNode);
		
		return true;
	},
	
	readInputDataJSON: function(listNode) {
		listNode = elm.get(listNode);
		var data = eval(elm.getValue(listNode.catListInput.dataNode)); // eval creates and returns new local variable "data"
		// TODO - here we can test correct data format and stuff
		var i;
		listNode.catListInput.data = {};
		for (i in data) {
			listNode.catListInput.data[data[i][0]] = data[i];
		}
		return listNode.catListInput.data;
	},
	
	// methods for category tree management. May be used only after the tree has been built
	
	check: function(treeItem) {
		// checks specified treeItem.
		treeItem = elm.get(treeItem);
		while (treeItem.tagName.toLowerCase() != "li") {
			treeItem = treeItem.parentNode;
		}
		return catList.setTreeItemBoxState(treeItem, catList.boxStates.checked.name, true);
	},
	
	uncheck: function(treeItem) {
		treeItem = elm.get(treeItem);
		while (treeItem.tagName.toLowerCase() != "li") {
			treeItem = treeItem.parentNode;
		}
		return catList.setTreeItemBoxState(treeItem, catList.boxStates.unchecked.name, true);
	},
	
	setTreeItemBoxState: function(treeItem, actionType, affectParent) {
		// performs check or uncheck action upon treeItem (determined by actionType)
		// You can select if this operation should affect also value of parent node or not.
		treeItem = elm.get(treeItem);
		
		if (typeof affectParent == "undefined")
			affectParent = true;
		
		var tree = treeItem.catListItemParentTree;
		
		// set checkBoxIcons etc.
		catList._setBoxStatus(treeItem, actionType);
		
		// set all children
		for (k in treeItem.catListItemChildren) {
			catList.setTreeItemBoxState(treeItem.catListItemChildren[k], actionType, false);
		}
		
		// set status of all parent items
		if (affectParent)
			catList._setParentBoxStatus(treeItem, actionType);
		
		return true;
	},
	
	addTreeItem: function(tree, parentItem, newItemData) {
		tree       = elm.get(tree);
		parentItem = elm.get(parentItem);
		
		var treeItem = document.createElement("li");
		
		// set tree item custom attributes
		treeItem.catListItemData        = newItemData;
		treeItem.catListItemParentTree  = tree;
		treeItem.catListItemChildren    = {};
		treeItem.catListItemParent      = parentItem;
		treeItem.catListItemBoxStatus   = catList.boxStates.unchecked.name;
		
		// find a tree to insert item into
		var ulNode;
		if (parentItem.tagName.toLowerCase() == "li") {
			var uls = parentItem.getElementsByTagName("ul");
			if (uls.length == 0) {
				ulNode = document.createElement("ul");
				parentItem.appendChild(ulNode);
			} else ulNode = uls[0];
		} else {
			ulNode = parentItem;
			treeItem.catListItemParent = null;
		}
		
		// TODO - this will not be so simple, branch expand icons have to be added
		
		// insert checkBox icons
		var k;
		treeItem.catListItemCheckBoxes = {};
		for (k in catList.boxStates) {
			treeItem.catListItemCheckBoxes[k] = catList._createCheckBox(catList.boxStates[k]);
			treeItem.appendChild(treeItem.catListItemCheckBoxes[k]);
		}
		catList._setBoxStatus(treeItem, catList.boxStates.unchecked.name);
		
		// create text label
		treeItem.appendChild(document.createTextNode(nbsp));
		treeItem.appendChild(document.createTextNode(newItemData[2]));
		
		// add item to tree
		ulNode.appendChild(treeItem);
		if (parentItem.catListItemChildren) { // if it is not first-level node
			parentItem.catListItemChildren[newItemData[0]] = treeItem;
		}
		tree.catListInput.treeItems[newItemData[0]] = treeItem;
		
		return true;
	},
	
	createTree: function(tree) {
		tree = elm.get(tree);
		
		// save info about aqctive nodes as it will be destroyed during tree creation
		
		var outputDataCache = variable.clone(tree.catListOutput.data);
		
		// create first level
		var inputList = document.createElement("ul");
		tree.catListInput.treeNode.appendChild(inputList);
		var dataArray = tree.catListInput.data;
		var i, j, k;
		var li;
		var dataLeft = new Array();
		
		for (i in dataArray) {
			if ((dataArray[i][1] == null) || (dataArray[i][1] < 0)) {
				catList.addTreeItem(tree, inputList, dataArray[i]);
			} else {
				dataLeft[dataLeft.length] = dataArray[i];
			}
		}
		
		// create all other levels
		do {
			var changed = false; // changed is set to true when some any is processed during for cycle
			for (i in dataLeft) {
				if (typeof tree.catListInput.treeItems[dataLeft[i][1]] != "undefined") {
					catList.addTreeItem(tree, tree.catListInput.treeItems[dataLeft[i][1]], dataLeft[i]);
					tree.catListInput.treeItems[dataLeft[i][0]].catListParentItem = tree.catListInput.treeItems[dataLeft[i][1]];
					delete(dataLeft[i]);
					changed = true;
				}
			}
		} while (changed); // if there was no change during last cycle, there is nothing to process anymore
		
		// reconstruct data destroyed during tree creation
		tree.catListOutput.data = outputDataCache;
		
		// set checkBoxes for all list items
		for (i in tree.catListInput.data) {
			k = tree.catListInput.data[i][0];
			if (tree.catListOutput.data[k] == tree.catListInput.data[i]) {
				catList.check(tree.catListInput.treeItems[k]);
			}
		}
		
		tree.catListInput.treeCreated = true;
		return true;
	},
	
	setEditMode: function(tree) {
		// transforms control to editable mode (folding tree)
		tree = elm.get(tree);
		while (!cls.has(tree, catList.cls)) {
			tree = tree.parentNode;
		}
		cls.remove(tree, catList.viewModeCls);
		cls.add(tree, catList.editModeCls);
		
		// hide edit button, show view button
		if (tree.catListInput.viewBtn == null) {
			// view button not available, create it
			tree.catListInput.viewBtn = elm.button.create(catList.btnArea.btn.view);
			tree.catListInput.btnAreaNode.appendChild(tree.catListInput.viewBtn);
			evt.add(tree.catListInput.viewBtn, "click", catList.setViewMode);
		}
		tree.catListInput.editBtn.style.display = "none";
		tree.catListInput.viewBtn.style.display = "";
		
		// show tree
		if (!tree.catListInput.treeCreated) {

			catList.createTree(tree);
		}
		tree.catListInput.treeNode.style.display = "";
		
		return true;
	},
	
	setViewMode: function(tree) {
		// transforms control to view mode (categories written as text)
		tree = elm.get(tree);
		while (!cls.has(tree, catList.cls)) {
			tree = tree.parentNode;
		}
		cls.remove(tree, catList.editModeCls);
		cls.add(tree, catList.viewModeCls);
		
		if (tree.catListInput.editBtn == null) {
			// view button not available, create it
			tree.catListInput.editBtn = elm.createButton(catList.btn.edit, tree.catListInput.btnAreaNode);
			evt.add(tree.catListInput.editBtn, "click", catList.setEditMode);
		}
		tree.catListInput.viewBtn.style.display = "none";
		tree.catListInput.editBtn.style.display = "";
		
		tree.catListInput.treeNode.style.display = "none";
		
		return true;
	},
	
	_createCheckBox: function(chkBoxData) {
		// create 3 state checkboxes
		var box = document.createElement("img");
		box.src = chkBoxData.imgSrc;
		box.title = chkBoxData.title;
		box.alt = chkBoxData.alt;
		evt.add(box, "click", chkBoxData.clickHandler);
		return box;
	},
	
	_setBoxStatus: function(treeItem, newStatus) {
		// sets boxStatus of the tree item
		// it cannot be used to check or uncheck item, as it does NOT modify output fields
		treeItem = elm.get(treeItem);
		
		var tree = treeItem.catListItemParentTree;
		if (typeof tree == "undefined") return false;
		
		var k;
		for (k in treeItem.catListItemCheckBoxes) {
			if (newStatus == k) {
				treeItem.catListItemCheckBoxes[k].style.display = "";
				cls.add(treeItem, catList.boxStates[k].cls);
				treeItem.catListItemBoxStatus = k;
			} else {
				treeItem.catListItemCheckBoxes[k].style.display = "none";
				cls.remove(treeItem, catList.boxStates[k].cls);
			}
		}
		
		// update output data field
		if (newStatus == catList.boxStates.checked.name) {
			tree.catListOutput.data[treeItem.catListItemData[0]] = treeItem.catListItemData;
		} else {
			delete (tree.catListOutput.data[treeItem.catListItemData[0]]);
		}
		catList.setOutput(tree);
		return true;
	},
	
	_setParentBoxStatus: function(treeItem, treeItemBoxStatus) {
		// sets status of parent nodes
		treeItem = elm.get(treeItem);
		
		if (treeItem.catListItemParent != null) {
			var allChildrenSet = true;
			for (k in treeItem.catListItemParent.catListItemChildren) {
				if (treeItem.catListItemParent.catListItemChildren[k].catListItemBoxStatus != treeItemBoxStatus) {
					allChildrenSet = false;
				}
			}
			if (allChildrenSet) {
				catList._setBoxStatus(treeItem.catListItemParent, treeItemBoxStatus);
			} else {
				catList._setBoxStatus(treeItem.catListItemParent, catList.boxStates.indeterminate.name);
			}
			catList._setParentBoxStatus(treeItem.catListItemParent, treeItemBoxStatus);
		}
		return true;
	}
	
}




var tree = {
	// explorer like folding tree
	branchStates: {
		expanded: {
			cls:    "chkBoxExpanded",
			title:  "",
			imgSrc: ""
		},
		contracted: {
			cls:    "chkBoxContracted",
			title:  "",
			imgSrc: ""
		}
	},
	buttons: {
		expandAllBtn: {},
		contractAllBtn: {}
	},	
	expandBranch: function(tree, branch) {
	
	},
	
	contractBranch: function(tree, branch) {
	
	}
}
