/* ---------------------------------------------- Base functions --- */
var ie = (document.all)? true : false;
function putElem(elemId,displayValue) {
	if (displayValue) document.getElementById(elemId).style.display = (ie5)? "block" : displayValue;
		else document.getElementById(elemId).style.display = "block";
}

function removeElem(elemId) {
	document.getElementById(elemId).style.display = "none";
}

/* ---------------------------------------------- End of base functions --- */

/* ---------------------------------------------- Tree functions --- */

// All the treeItems arrays is collected in this one:
var trees = new Array();
// And the visible - here:
var visible = new Array();

// The constructor of tree items
function treeItem(tree, id, parent, isOpen, captionPointer) {
	this.tree = tree;
	this.id = id;
	this.caption = captionPointer;
	this.parent = parent;
	this.children = new Array();
	if (parent != '') {
		trees[tree][parent].children[trees[tree][parent].children.length] = id;
		this.level = trees[tree][parent].level + 1;
	} else this.level = 0;
	this.isOpen = isOpen;
	return this;
}

function visibleAdd(main, where, sub) {
	var resArr = new Array();
	for (i in main) {
		resArr[resArr.length] = main[i];
		if (main[i] == where) for (j in sub) resArr[resArr.length] = sub[j];
	}
	return resArr;
}

function visibleRemove(main, sub) {
	for (i in main) for (j in sub) if (main[i] == sub[j]) delete main[i];
	return main;
}

function isItemVisible(treeId, leafId) {
	for (var v in visible[treeId]) {
		if (visible[treeId][v] == leafId) return true;
	}
	return false;
}

function visibleChildren(treeId, leafId) {
	var vChildren = new Array();
	if (trees[treeId][leafId].children.length > 0) {
		var j = 0;
		for (j in trees[treeId][leafId].children) {
			vChildren[vChildren.length] = trees[treeId][leafId].children[j];
			if (trees[treeId][trees[treeId][leafId].children[j]].children.length > 0 &&
				trees[treeId][trees[treeId][leafId].children[j]].isOpen) {
					vChildren = vChildren.concat(visibleChildren(treeId, trees[treeId][leafId].children[j]));
			}
		}
	}
	return vChildren;
}

function changeTree(treeId, leafId) {
	var changingElems = visibleChildren(treeId, leafId);
	if (trees[treeId][leafId].isOpen) {
		visible[treeId] = visibleRemove(visible[treeId], changingElems);
		for (i in changingElems) removeElem(changingElems[i]);
		trees[treeId][leafId].isOpen = false;
	} else {
		visible = visibleAdd(visible[treeId], leafId, changingElems);
		for (i in changingElems) putElem(changingElems[i]);
		trees[treeId][leafId].isOpen = true;
	}
}

function changeTreeState(e) {
	var imgClicked = this.firstChild;
	while(imgClicked.tagName != "IMG")
		imgClicked = imgClicked.nextSibling;
	if (imgClicked) {
		var leafId = imgClicked.getAttribute('leafId');
		var treeId = imgClicked.getAttribute('treeId');
		imgClicked.src = (trees[treeId][leafId].isOpen)? leafClosedImg.src : leafOpenImg.src;
		imgClicked.parentNode.style.backgroundColor = (trees[treeId][leafId].isOpen)? "#BBCDDB" : "#DFE6EB";
		changeTree(treeId, leafId);
	}
}

function changeTheLookAndFeelOfTreeItem(itemPointer) {
	if(!ie)
	 itemPointer.caption.style.paddingLeft = (itemPointer.level * leafImgWidth) + leafCaptionDefPadding;

	// removing from page if is not visible, or putting if is
	if (isItemVisible(itemPointer.tree, itemPointer.id)) putElem(itemPointer.id);
		else removeElem(itemPointer.id);

	if (itemPointer.children.length > 0) {

		// getting item image pointer
		var itemImage = itemPointer.caption.getElementsByTagName('img').item(0);
		
		// setting the right src
		itemImage.src = (itemPointer.isOpen)? leafOpenImg.src : leafClosedImg.src;

		// Handling onlick event

		// Setting the treeId and leafId attributes to the image
		itemImage.setAttribute('treeId',itemPointer.tree);
		itemImage.setAttribute('leafId',itemPointer.id);
		
		// Adding handler
		if (ie5) {
			itemImage.parentNode.onclick = changeTreeState;
		} else if (dom) {
			itemImage.parentNode.addEventListener("click", changeTreeState, false);
		}
	}
}

function initTreeBranch(treeId, branchId) {
	var currentBranch = document.getElementById(branchId);
	
	// Puting the treeItems into trees array
	for (var i = 0; i < currentBranch.childNodes.length; i++) {

		// Ignoring textNodes between elements:
		if (currentBranch.childNodes[i].tagName == 'DIV') {

			// Checking is this a caprion of the item
			if (currentBranch.childNodes[i].className == 'treeItemCaption') {

				// Checking to see is the current item the top-level-item
				parentId = (treeId == currentBranch.parentNode.id)? '' : currentBranch.parentNode.id;

				// Creating the new treeItem array element
				trees[treeId][branchId] = new treeItem(
					treeId,
					branchId,
					parentId,
					isTreeOpen,
					currentBranch.childNodes[i]
				);

			}

			// Checking is this a sub-item
			if (currentBranch.childNodes[i].className == 'treeItem') {
			
				// If so - initializing it!
				initTreeBranch(treeId, currentBranch.childNodes[i].id);

			}

		}

	}

}

function initTree(treeContainerId) {
	// Checking is browser supporting DOM-methods
	if (ie5 || dom) {

		// Creating treeItems array for this tree:
		trees[treeContainerId] = new Array();

		// Initializing tree branches - starting at 0 level...
		// i.e. -1 of starting with the tree container ;-)
		initTreeBranch(treeContainerId, treeContainerId);

		// Creating visible items array for this tree and fill it
		visible[treeContainerId] = new Array();
		for (var i in trees[treeContainerId]) {
			if (trees[treeContainerId][i].level == 0) {
				visible[treeContainerId][visible[treeContainerId].length] = trees[treeContainerId][i].id;
				if(!ie) {
				 if (trees[treeContainerId][i].isOpen)
					visible[treeContainerId] =
						visible[treeContainerId].concat(visibleChildren(treeContainerId, trees[treeContainerId][i].id));
				}
			}
		}

		// initializing events and changing the view of the treeItems...
		for (var i in trees[treeContainerId]) {
			changeTheLookAndFeelOfTreeItem(trees[treeContainerId][i]);
		}

	}
}

/* ---------------------------------------------- End of tree functions --- */
