/*
	HelpSmith Web Help System 1.2
	Copyright (c) 2008 Divcom Software
	http://www.helpsmith.com/
*/

var treeList = [];

/* treeNode object */

function treeNode(treeData, tree, index, absIndex, parent) {	
	this.tree = tree;
	this.index = index;
	this.absIndex = absIndex; 
	this.parent = parent;
	this.level = parent.level + 1;
	this.expanded = tree.isNodeExpanded(absIndex);
	this.nodes = [];
	this.title = treeData[0];
	this.closedIcon = treeData[1];
	if (treeData[2] == '') {
		this.openedIcon = this.closedIcon;
	}
	else {
		this.openedIcon = treeData[2];
	}
	this.link = treeData[3];
	
	this.addNode = addNode;
	this.printNode = printNode;
	this.isLast = function () {
		return this.index == this.parent.nodes.length - 1;
	}
	this.setState = setState;

	// add children
	for (var i = 4; i < treeData.length; i++) {
		var d = treeData[i];
		if (!d) return;
		this.addNode(d, tree, this);
	}	
}

function getLevelIdentImages(node) {
	var ident = [];
	var p = node.parent;
	for (var i = node.level; i > 0; i--) {
		ident[i] = '<img src="' + (p.isLast() ? treeLineImages.EMPTY : treeLineImages.I) + '" border="0" alt="">';
		p = p.parent;
	}
	return ident.join('');
}

function getPlusMinusImgSrc(node) {	
	if (!node.absIndex) {
		// is a first node in the tree
		if (node.parent.nodes.length == 1) {
			// no siblings			
			return node.expanded ? treeLineImages.OMINUS : treeLineImages.OPLUS;
		}
		else {
			// has siblings
			return node.expanded ? treeLineImages.RMINUS : treeLineImages.RPLUS;
		}		
	}
	else {
		if (node.isLast()) {
			return node.expanded ? treeLineImages.LMINUS : treeLineImages.LPLUS;
		}
		else {
			return node.expanded ? treeLineImages.TMINUS : treeLineImages.TPLUS;
		}
	}	
}

function getLineImgSrc(node) {	 
	if (!node.absIndex) {
		// is a first node in the tree
		return (node.parent.nodes.length == 1) ? treeLineImages.O : treeLineImages.R;
	}
	else {
		return node.isLast() ? treeLineImages.L : treeLineImages.T;		
	}
}

function getNodeIconSrc(node) {
	return node.expanded ? node.openedIcon : node.closedIcon;
}

function printNodeBody(node) {
	var outStr = '<img id="ni' + node.absIndex + '" src="' + getNodeIconSrc(node) + '" border="0" alt="">&nbsp;';
	if (node.link != '') {
		outStr += '<a class="link" title="' + node.title + '" href="' + node.link + '"';
		if (node.tree.options.target != '') {
			outStr += ' target="' + node.tree.options.target + '"';
		}
		outStr += '>' + node.title + '</a>';
	}
	else {
		outStr += '<span class="header" title="' + node.title + '">' + node.title + '</span>';
	}
	return outStr;
}

function printNode() {
	var outStr = '<div>' + getLevelIdentImages(this);	
	if (this.nodes.length) {
                // plus/minus image
		outStr += '<a href="javascript: treeList[' + this.tree.index + '].toggleNode(' + this.absIndex + ');">' +
			'<img id="pm' + this.absIndex + '" src="' + getPlusMinusImgSrc(this) + '" border="0" alt=""></a>';
		
		outStr += printNodeBody(this);

		// node children
		outStr += '<div id="ch' + this.absIndex + '" style="display: ' + (this.expanded ? 'block' : 'none') + ';">';
		for (var i = 0; i < this.nodes.length; i++) {
			var n = this.nodes[i];
			outStr += n.printNode();
		}
		outStr += '</div>';
	}
	else {		
		outStr += '<img src="' + getLineImgSrc(this) + '" border="0" alt="">';		
		outStr += printNodeBody(this);
	}       	
	return outStr += '</div>';
}

function setState(expanded) {
	this.expanded = expanded;

	// plus/minus image	
	var pmImg = document.getElementById('pm' + this.absIndex);
	pmImg.src = getPlusMinusImgSrc(this);
	
	// show/hide node children
	var chDiv = document.getElementById('ch' + this.absIndex);
	chDiv.style.display = expanded ? 'block' : 'none';

	// node icon
	var nodeIcon = document.getElementById('ni' + this.absIndex);
	nodeIcon.src = expanded ? this.openedIcon : this.closedIcon;

	this.tree.saveNodeStates();
}

/* Tree object */

function Tree(treeData) {
	this.options = {
		target: ''	
	}
	this.level = -1;
	this.nodes = [];
	this.nodeList = [];	
	this.addNode = addNode;
	this.toString = toString;	
	this.absIndex = -1;                     
	this.toggleNode = toggleNode;
	this.openNode = openNode;
	this.saveNodeStates = saveNodeStates;
	this.isNodeExpanded = isNodeExpanded;
	
	// add self to the global treeList array
	this.index = treeList.length;
	treeList[this.index] = this;

	this.nodeStates = [];
	var s = getCookie('tree' + this.index);
	if (s) this.nodeStates = s.split('*');

	// root-level children
	for (var i = 0; i < treeData.length; i++) { 
		this.addNode(treeData[i], this, this);
	}
}

function toString() {
	var outStr = '<div class="tree">';	
	for (var i = 0; i < this.nodes.length; i++) {
		var n = this.nodes[i];
		outStr += n.printNode();
	}                    
	outStr += '</div>';	
	return outStr;
}

function toggleNode(absNodeIndex) {
	var node = this.nodeList[absNodeIndex];	
	node.setState(!node.expanded);	
}

function openNode(absNodeIndex) {
	if (this.nodeStates.length > 0)	return;
	var node = this.nodeList[absNodeIndex];
	var p = node.parent;
	while (p.parent) {
		p.setState(true);
		p = p.parent;
	}
}

function saveNodeStates() {
	var s = '';
	for (var i = 0; i < this.nodeList.length; i++) {
		var node = this.nodeList[i];
		if (node.expanded) {
			if (s) s += '*'; // index separator
			s += node.absIndex;
		}
	}	
	setCookie('tree' + this.index, s);
}

function isNodeExpanded(absNodeIndex) {
	for (var i = 0; i < this.nodeStates.length; i++) {
		if (absNodeIndex == this.nodeStates[i]) {
			return true;
		}
	}
	return false;
}

/* common methods */

function addNode(treeData, tree, parent) {	
	var idx = this.nodes.length;	
	var node = new treeNode(treeData, tree, idx, ++tree.absIndex, parent);	
	this.nodes[idx] = node;
	tree.nodeList[node.absIndex] = node;
}

