function Bs_TreeElement()
{
	this.id;
	this.parent;
	this._tree;
	this.caption;
	this.value;//Added by dubf on 2004/04/21
	this.param;//Added by dubf on 2004/04/21
	this.url;
	this.target;
	this.linkStyle;
	this.divStyle;
	this.onClick;
	this.isOpen = false;
	this.visible = true;
	this.isChecked = 0;
	this.checkboxName;
	this.checkboxValue;//Added by dubf on 2004/04/19
	this.radioButtonSelected;
	this._checkboxObject;
	this._level = 0;
	this._children = new Array;
	this._undoneChildren;
	this.imageDir;
	this.imageHeight;
	this.icon;
	this.beforeIconSpan;
	this.beforeCaptionSpan;
	this.afterCaptionSpan;
	this.dataContainer;
	this._attachedEvents;
	this._isOutrendered = false;
	this._errorArray;
	this.getThis = function()
	{
		return this;
	}
	this.addChild = function(treeElement)
	{
		treeElement.parent = this;
		if (typeof(this._children) != 'object')
			this._children = new Array;
		if (this._children.push)
		{
			this._children.push(treeElement);
		} else {
			this._children[this._children.length] = treeElement;
		}

		treeElement._level = this._level +1;
		this._updateLevelAndParent(treeElement);
		this._tree._clearingHouse[treeElement.id] = treeElement;
		if (this._isOutrendered)
		{
			this.render(true, true);
		}
	}

	this.addChildByArray = function(elementData)
	{
		var treeElement = this._tree._createTreeElement(elementData);
		this.addChild(treeElement);
		return treeElement;
	}

	this.isChild = function(elementId, bubble)
	{
		for (var i=0; i<this._children.length; i++)
		{
			if (this._children[i].id == elementId) return true;
			if (bubble)
			{
				if (this._children[i].isChild(elementId, true))
					return true;
			}
		}
		return false;
	}

	this.setCaption = function(caption)
	{
		this.caption = caption;
		if (this._isOutrendered)
		{
			var span = document.getElementById(this._tree._objectId + '_e_' + this.id + '_caption2');
			if (span) span.innerHTML = caption;
		}
	}

	this.render = function(omitDivTags, putIntoPage, lookAhead)
	{
		if (typeof(this._tree.stopWatch) == 'object')
			this._tree.stopWatch.takeTime('Bs_TreeElement.render() for id: ' + this.id + ' in level: ' + this._level);
		if (typeof(lookAhead) == 'undefined')
		{
			lookAhead = this._tree.lookAhead;
		}

		if ((this._tree._pseudoElement == this) && !this._tree.showPseudoElement && (lookAhead != -1))
		{
			lookAhead++;
		}

		var imageDir    = this._getVar('imageDir');
		var imageHeight = this._getVar('imageHeight');
		var out      = new Array();
		var outI     = 0;
		var evalStr  = '';
		if (!omitDivTags)
		{
			out[outI++] = '<span id="' + this._tree._objectId + '_e_' + this.id + '"';
			out[outI++] = ' style="';
			if (!this.visible)
			{
				out[outI++] = 'display:none;';
			}
			out[outI++] = '">';
		}
		if ((this._level) > 0 || (this._tree.showPseudoElement))
		{
			out[outI++] = '<nobr>';
			out[outI++] = '<div style="float:none;"';
			out[outI++] = ' id="' + this._tree._objectId + '_e_' + this.id + '_drag"';
			if (this._tree.draggable)
			{
				out[outI++] = ' onDragStart="Bs_Objects['+this._tree._id+'].executeOnElement(\'' + this.id + '\', \'fireEvent\', Array(\'onDragStart\'));"';
				out[outI++] = ' onDragEnter="Bs_Objects['+this._tree._id+'].executeOnElement(\'' + this.id + '\', \'fireEvent\', Array(\'onDragEnter\'));"';
				out[outI++] = ' onDragOver="Bs_Objects['+this._tree._id+'].executeOnElement(\'' + this.id + '\', \'fireEvent\', Array(\'onDragOver\'));"';
				out[outI++] = ' onDrop="Bs_Objects['+this._tree._id+'].executeOnElement(\'' + this.id + '\', \'fireEvent\', Array(\'onDrop\'));"';
			}

			out[outI++] = '>';
			out[outI++] = '<div style="overflow:visible; height:' + imageHeight + '; ' + this._getVar('divStyle') + '">';
			var level = this._level;
			if (!this._tree.showPseudoElement) --level;
			var obj = null;
			var outTemp = '';
			for (var i=0; i<level; i++)
			{
				if (!obj)
				{
					obj = this.parent;
				} else {
					obj = obj.parent;
				}

				if (obj.hasSiblingsDown())
				{
					var img = 'line1';
				} else {
					var img = 'empty';
				}

				outTemp = '<img src="' + imageDir + img + '.gif" height="' + imageHeight + '" border="0" align="top">' + outTemp;
		   }

			out[outI++] = outTemp;
			if (this.hasSiblingsDown())
			{
				var imgNumber = 3;
			} else {
				var imgNumber = 2;
			}

			if (this.hasVisibleChildren())
			{
				if ((this._level == 0) || (!this._tree.showPseudoElement && (this._level == 1) && ((this._tree.useAutoSequence && (this.id == 1)) || (!this._tree.useAutoSequence && true))))
				{
					if (this.hasSiblingsDown())
					{
						imgNumber++;
					} else {
						imgNumber--;
					}
				}

				if (this.isOpen)
				{
					var plusImg = 'minus' + imgNumber;
					var onClick = 'Close';
				} else {

					var plusImg = 'plus' + imgNumber;
					var onClick = 'Open';
				}

			} else {
				var plusImg = 'line' + imgNumber;
				var onClick = false;
			}

			if (onClick) 
			{
				var onClickStr = 'onClick="Bs_Objects['+this._tree._id+'].elementToggleOpenClose(\'' + this.id + '\');"';
			} else {
				var onClickStr = '';
			}

			if (this.onClick)
			{
				var onClick = this.onClick;
				onClick = onClick.replace(/__this\.id__/g, this.id);
				//replace the string __this.id__ with the actual id (int).
				out[outI++] = '<span style="cursor:pointer; cursor:hand;" onClick="' + onClick + '">';
			}

			out[outI++] = '<img id="' + this._tree._objectId + '_e_' + this.id + '_openClose" src="' + imageDir + plusImg + '.gif" height="' + imageHeight + '" border="0" ' + onClickStr + ' align="middle"';
			out[outI++] = ' style="vertical-align:' + ((imageHeight > 16) ? 'middle' : 'top') + '">';
			
			if (this.beforeIconSpan)
			{
				out[outI++] = "<span>" + this.beforeIconSpan + "</span>";
			}

			if (this.url)
			{
				var hRef = '<a href="' + this.url + '"';
				if (this.target)
				{
					hRef += ' target="' + this.target + '"';
					hRef += ' style="'  + this._getLinkStyle() + '"';
				}
				hRef += '>';
			}

			var folderIconId = this._tree._objectId + '_e_' + this.id + '_folder';
			if (this._getVar('useFolderIcon'))
			{
				if (hRef) out[outI++] = hRef;
				switch (typeof(this.icon))
				{
					case 'undefined':
						if (this._tree.useLeaf && !this.hasChildren())
						{
							var folderImg = 'leaf';
						} else {
							var folderImg = 'folder';
							folderImg += (this.isOpen) ? 'Open' : 'Closed';
						}

						out[outI++] = '<img id="' + folderIconId + '" src="' + imageDir + folderImg + '.gif" height="' + imageHeight + '" border="0" align="top">';
						break;
					case 'bool':
					case 'boolean':
						break;
					case 'string':
						if (this.icon != 'false')
						{
							out[outI++] = '<img id="' + folderIconId + '" src="';
							if (!this._iconHasPath(this.icon)) out[outI++] = imageDir;
							out[outI++] = this.icon;
							if (!this._iconHasExtension(this.icon))
								out[outI++] = '.gif';
							out[outI++] = '" height="' + imageHeight + '" border="0" align="top">';
						}
				}

				if (hRef) out[outI++] = '</a>';
			}

			if (this.beforeCaptionSpan)
			{
				out[outI++] = "<span>" + this.beforeCaptionSpan + "</span>";
			}

			if (this._tree.useRadioButton)
			{

				out[outI++] = '<input type="radio"';
				if (this._tree.radioButtonName)
				{
					out[outI++] = ' name="' + this._tree.radioButtonName + '"';
				} else {
					out[outI++] = ' name="' + 'bsTreeRad_' + this._tree._objectId + '"';
				}

				if (true)
				{
					out[outI++] = ' style="height:16px;"';
				}

				if (this.radioButtonSelected)
				{
					out[outI++] = ' checked';
				}

				out[outI++] = '>';
			}
            //下面this != this._tree._pseudoElement是由杜保发于2004/4/23加上，即根结点不内嵌checkbox,否则会报错
			if (this._tree.useCheckboxSystem && this != this._tree._pseudoElement)
			{

				var checkboxSpan = this.checkboxName + 'Span';
				var checkboxObj  = this.checkboxName + 'Obj';
				out[outI++] = '&nbsp;<span id="' + checkboxSpan + '">';
				var t = new Bs_Checkbox();
				t.objectName = checkboxObj;
				t.checkboxName = this.checkboxName;
				t.checkboxValue = this.checkboxValue;//Added by dubf on 2004/04/19
				t.value = this.isChecked;
				if (this._getVar('checkboxSystemGuiNochange')) 
				{
					t.guiNochange = true;
				}

				var chkImagDir = this._getVar('checkboxSystemImgDir');
				if (chkImagDir)
				{
					t.imgDir = chkImagDir;
				} else {
					t.imgDir     = "";//'../image/checkbox/win2k/';
				}

				//t.imgWidth   = 11;
				//t.imgHeight  = 11;
				if (this._tree.checkboxSystemWalkTree)
				{
					t.attachOnClick('Bs_Objects['+this._tree._id+'].elementCheckboxEvent(\'' + this.id + '\', ' + checkboxObj + '.value);');
				}

				eval(checkboxObj + ' = t;');
				this._checkboxObject = t;
				evalStr += checkboxObj + ".draw('" + checkboxSpan + "');";
				out[outI++] = '</span>';
			}

			out[outI++] = '&nbsp;';
			out[outI++] = '<span id="' + this._tree._objectId + '_e_' + this.id + '_caption"';
			if (this.onClick || this.hasEventAttached('onClickCaption'))
			{
				out[outI++] = ' style="cursor:pointer; cursor:hand;"';
			} else {
				out[outI++] = ' style="cursor:default;"';
			}
			out[outI++] = ' onClick="Bs_Objects['+this._tree._id+'].executeOnElement(\'' + this.id + '\', \'fireEvent\', Array(\'onClickCaption\'));">';
			if (hRef) out[outI++] = hRef;
			out[outI++] = '<span id="' + this._tree._objectId + '_e_' + this.id + '_caption2"  value="'+this.value+'" param="'+this.param+'">' + this.caption + '</span>';
			if (hRef) out[outI++] = '</a>';
			out[outI++] = '</span>';
			if (this.onClick)
			{
				out[outI++] = '</span>';
			}
			out[outI++] = '</div>';
			if (this.afterCaptionSpan)
			{
				out[outI++] = '<div style="overflow:visible;">' + this.afterCaptionSpan + '</div>';
			} else {

			}
			out[outI++] = '</div>';
			out[outI++] = '</nobr>';
		}

		out[outI++] = '<span id="' + this._tree._objectId + '_e_' + this.id + '_children"';
		if (!this.isOpen)
		{
			out[outI++] = ' style="display:none;"';
		}
		out[outI++] = '>';
		if (this.isOpen || (lookAhead > 0) || (lookAhead == -1))
		{
			for (var i=0; i<this._children.length; i++)
			{
				if (lookAhead == -1)
				{
					var newLookAhead = -1;
				} else {
					if (this.isOpen)
					{
						var newLookAhead = lookAhead;
					} else {
						var newLookAhead = lookAhead -1;
					}
				}
				var t = this._children[i].render(false, false, newLookAhead);
				out[outI++] = t[0];
				evalStr    += t[1];
			}
		}
		out[outI++] = '</span>';
		if (!omitDivTags)
		{
			out[outI++] = '</span>';
		}

		out[outI++] = "\n";
		this._isOutrendered = true;
		var content = new Array(out.join(''), evalStr);
		if (putIntoPage)
		{
			var doc = document.getElementById(this._tree._objectId + '_e_' + this.id);
			if (doc != null)
			{
				doc.innerHTML = content[0];
				if (content[1] != '')
				{
					eval(content[1]);
				}
				return true;
			} else {
				return false;
			}
		} else {
			return content;
		}
	}

	this.reset = function()
	{
			this.caption= null;
			this.value=null; //Added by dubf on 2004/04/21
			this.param=null;//Added by dubf on 2004/04/19
			this.url= null;
			this.target= null;
			this.onClick= null;
			this.isOpen= false;
			this.isChecked= 0;
			this.checkboxName= null;
			this.checkboxValue=null;//Added by dubf on 2004/04/19
			this.beforeIconSpan = null;
			this.beforeCaptionSpan = null;
			this.afterCaptionSpan  = null;
	}

	this.initByArray = function(a, tree, level)
	{
		this._tree= tree;
		this._level= level;
		if (typeof(this._tree.stopWatch) == 'object')
			this._tree.stopWatch.takeTime('Bs_TreeElement.initByArray()');
		if (this._tree.useAutoSequence && (level > 0))
		{
			this.id= ++this._tree._elementSequence;
		} else {
			if (typeof(a['id']) == 'undefined')
			{
				this._addError('无法生成树结点id\n: 自动生成id属性useAutoSequence被设置为false, 但是树结点元素没有指定id.');
				return false;
			}
			this.id = a['id'];
		}
 		if (typeof(a['value'])!= 'undefined')
			this.value= a['value'];
		if (typeof(a['caption'])!= 'undefined')
			this.caption= a['caption'];
		if (typeof(a['url'])!= 'undefined')
			this.url= a['url'];
 		if (typeof(a['param'])!= 'undefined')
			this.param= a['param'];
		if (typeof(a['target'])!= 'undefined')
			this.target= a['target'];
		if (typeof(a['onClick'])!= 'undefined')
			this.onClick= a['onClick'];
		if (typeof(a['isOpen'])!= 'undefined')
			this.isOpen= a['isOpen'];
		if (typeof(a['isChecked'])!= 'undefined')
			this.isChecked= parseInt(a['isChecked']);
		if (typeof(a['visible'])!= 'undefined')
			this.visible = a['visible'];
		if (typeof(a['icon'])!= 'undefined')
			this.icon= a['icon'];
		if (typeof(a['imageDir'])!= 'undefined')
			this.imageDir= a['imageDir'];
		if (typeof(a['beforeIconSpan'])!= 'undefined')
			this.beforeIconSpan= a['beforeIconSpan'];
		if (typeof(a['beforeCaptionSpan'])!= 'undefined')
			this.beforeCaptionSpan = a['beforeCaptionSpan'];
		if (typeof(a['afterCaptionSpan'])!= 'undefined')
			this.afterCaptionSpan= a['afterCaptionSpan'];
		if (typeof(a['radioButtonSelected']) != 'undefined')
			this.radioButtonSelected = a['radioButtonSelected'];
		if (typeof(a['dataContainer'])!= 'undefined')
			this.dataContainer= a['dataContainer'];
	
		if (typeof(a['checkboxValue']) != 'undefined') 
			this.checkboxValue = a['checkboxValue']; //Added by dubf on 2004/04/19
		if (typeof(a['checkboxName']) != 'undefined')
		{
			this.checkboxName  = a['checkboxName'];
		} else {
			if (this._tree.useCheckboxSystem)
			{
				this.checkboxName = 'bsTreeChk_' + this._tree._objectId + '_' + this.id;
			}
		}
		if (typeof(a['onClickCaption'])    != 'undefined')
		{
			this.attachEvent('onClickCaption', a['onClickCaption']);
		}

		if (typeof(a['onChangeCheckbox'])    != 'undefined')
		{
			this.attachEvent('onChangeCheckbox', a['onChangeCheckbox']);
		}

		if (typeof(a['events']) != 'undefined')
		{
			for (ev in a['events'])
			{
				this.attachEvent(ev, a['events'][ev]);
			}
		}

		return true;
	}

	this.exportAsArray = function(withChildren)
	{
		var ret = new Array();
		if (typeof(this.id)!= 'undefined')
			ret['id']= this.id;
		if (typeof(this.value)!= 'undefined')
			ret['value'] = this.value;
		if (typeof(this.caption)!= 'undefined')
			ret['caption'] = this.caption;
		if (typeof(this.url)!= 'undefined')
			ret['url']= this.url;
		if (typeof(this.param)!= 'undefined')
			ret['param']= this.param;
		if (typeof(this.target) != 'undefined')
			ret['target']= this.target;
		if (typeof(this.onClick)!= 'undefined')
			ret['onClick']= this.onClick;
		if (typeof(this.isOpen)!= 'undefined')
			ret['isOpen'] = this.isOpen;
		if (typeof(this.isChecked)!= 'undefined')
			ret['isChecked'] = this.isChecked;
		if (typeof(this.visible)!= 'undefined')
			ret['visible'] = this.visible;
		if (typeof(this.icon)!= 'undefined') 
			ret['icon']= this.icon;
		if (typeof(this.imageDir)!= 'undefined')
			ret['imageDir'] = this.imageDir;
		if (typeof(this.beforeIconSpan)!= 'undefined')
			ret['beforeIconSpan'] = this.beforeIconSpan;
		if (typeof(this.afterCaptionSpan)!= 'undefined')
			ret['afterCaptionSpan'] = this.afterCaptionSpan;
		if (typeof(this.radioButtonSelected)!= 'undefined')
			ret['radioButtonSelected']= this.radioButtonSelected;
		if (typeof(this.dataContainer)!= 'undefined')
			ret['dataContainer']= this.dataContainer;
		if (typeof(this.checkboxName)!= 'undefined')
			ret['checkboxName'] = this.checkboxName;
		if (typeof(this.checkboxValue)!= 'undefined')
			ret['checkboxValue'] = this.checkboxValue;//Added by dubf on 2004/04/19
		if (typeof(this.beforeCaptionSpan)!= 'undefined')
			ret['beforeCaptionSpan'] = this.beforeCaptionSpan;
		if (withChildren)
		{
			ret['children'] = new Array();
			for (var i=0; i<this._children.length; i++)
			{
				ret['children'][ret['children'].length] = this._children[i].exportAsArray(true);
			}
		}
		return ret;
	}

	this.updateObjectByArray = function(a)
	{
		this.reset();
		if (a['value'])
			this.value = a['value'];
		if (a['caption'])
			this.caption = a['caption'];
		if (a['url'])
			this.url = a['url'];
		if (a['param'])
			this.param = a['param'];
		if (a['target'])
			this.target = a['target'];
		if (a['onClick'])
			this.onClick = a['onClick'];
		if (a['isOpen'])
			this.isOpen = a['isOpen'];
		if (a['isChecked'])          
			this.isChecked = a['isChecked'];
		if (a['imageDir'])
			this.imageDir= a['imageDir'];
		if (a['checkboxValue'])
			this.checkboxValue= a['checkboxValue'];//Added by dubf on 2004/04/19
		if (a['checkboxName'])
		{
			this.checkboxName  = a['checkboxName'];
		} else {
			if (this._tree.useCheckboxSystem)
			{
				this.checkboxName = 'bsTreeCheckbox' + this.id;
			}
		}

		if (a['beforeIconSpan'])
			this.beforeIconSpan  = a['beforeIconSpan'];
		if (a['beforeCaptionSpan'])
			this.beforeCaptionSpan  = a['beforeCaptionSpan'];
		if (a['afterCaptionSpan'])
			this.afterCaptionSpan   = a['afterCaptionSpan'];
	}

	this.getJavascriptCode = function(varName, recursive)
	{
		var ret = "";
		if ((this._tree.useAutoSequence && (this.id > 1))
			|| (!this._tree.useAutoSequence && !this.parent))
		{
		} else {
			ret += varName + " = new Array();\n";
			if (!this._tree.useAutoSequence)
			{
				ret += varName + "['id'] = \"" + this.id + "\";\n";
			}
			if (this.value)
				ret += varName + "['value'] = \"" + this.value + "\";\n";
			if (this.caption)
				ret += varName + "['caption'] = \"" + this.caption + "\";\n";
			if (this.url)
				ret += varName + "['url']= \"" + this.url + "\";\n";
			if (this.param)
				ret += varName + "['param'] = \"" + this.param + "\";\n";
			if (this.target)
				ret += varName + "['target']= \"" + this.target+ "\";\n";
			if (this.onClick)
			{
				//var onClick = this.onClick.replace(/'/g,  "\'");
				var onClick = this.onClick.replace(/"/g,  '\"');
				ret += varName + "['onClick']= \"" + onClick+ "\";\n";
			}

			if (this.imageDir)
				ret += varName + "['imageDir']= \"" + this.imageDir+ "\";\n";
			if (this.isOpen)
				ret += varName + "['isOpen'] = '" + this.isOpen + "';\n";
			if (this.isChecked)
				ret += varName + "['isChecked']  = '" + this.isChecked + "';\n";
			if (this.checkboxValue)
				ret += varName + "['checkboxValue'] = '" + this.checkboxValue+ "';\n";//Added by dubf on 2004/04/19
			if (this.checkboxName)
				ret += varName + "['checkboxName'] = '" + this.checkboxName+ "';\n";
			if (this.icon)
				ret += varName + "['icon']   = \"" + this.icon  + "\";\n";
			if (this.beforeIconSpan)
				ret += varName + "['beforeIconSpan']     = \"" + this.beforeIconSpan     + "\";\n";
			if (this.beforeCaptionSpan) 
				ret += varName + "['beforeCaptionSpan']  = \"" + this.beforeCaptionSpan  + "\";\n";
			if (this.afterCaptionSpan) 
				ret += varName + "['afterCaptionSpan']   = \"" + this.afterCaptionSpan   + "\";\n";
	
			varName += "['children']";
		}

		if (recursive)
		{
			if (this._children.length > 0)
			{
				ret += varName + " = new Array();\n";
				for (var i=0; i<this._children.length; i++)
				{
					ret += this._children[i].getJavascriptCode(varName + "[" + i + "]", recursive);
				}
			}
		}
		return ret;
	}

	this.setActive = function()
	{
		var activeElement = this._tree.getActiveElement();
		if (activeElement != false)
		{
			activeElement.unsetActive();
		}

		this._tree.setActiveElement(this);
		this._highlight();
	}

	this._highlight = function()
	{
		var elmSetActive = document.getElementById(this._tree._objectId + '_e_' + this.id + '_caption');
		if (elmSetActive != null)
		{
			elmSetActive.style.backgroundColor = this._getVar('captionBgColor');
		} else {
			setTimeout("Bs_Objects["+this._tree._id+"].executeOnElement('" + this.id + "', '_highlight');", 800);
		}
	}

	this.unsetActive = function()
	{
		var e = document.getElementById(this._tree._objectId + '_e_' + this.id + '_caption');
		if (e != null) e.style.backgroundColor = 'transparent';
	}

	this.toggleOpenClose = function()
	{
		if (this.isOpen)
		{
			if (this.hasEventAttached('onBeforeClose')) 
			{
				var status = this.fireEvent('onBeforeClose');
				if (status != true) return;
			}
			this.close();
			if (this.hasEventAttached('onAfterClose'))
				this.fireEvent('onAfterClose');
		} else {
			if (this.hasEventAttached('onBeforeOpen'))
			{
				var status = this.fireEvent('onBeforeOpen');
				if (status != true) return;
			}
			this.open();
			if (this.hasEventAttached('onAfterOpen'))
				this.fireEvent('onAfterOpen');
		}
	}

	this.open = function(checkParents)
	{
		if (this.isOpen) return;
		this.isOpen = true;
		if (true || !doRender)
		{
			if (this._isOutrendered)
			{
				var d = document.getElementById(this._tree._objectId + '_e_' + this.id + '_children');
				d.style.display = 'block';
				this._switchIconsOnToggleOpenClose();
			} else {
				if (checkParents) 
				{
					this._renderParentsUp();
				}
				this.render(true, true);
			}
		}
		if (this._tree.autoCollapse)
		{
			var sib = this.getSiblings();
			for (var i=0; i<sib.length; i++)
			{
				if (sib[i].id != this.id)
				{
					sib[i].close();
				}
			}
		}

		if (this.hasVisibleChildren())
		{
			var lookAhead = this._tree.lookAhead;
			var treeElm = this;
			for (var j=0; j<treeElm._children.length; j++)
			{
				if (typeof(treeElm._children[j]._undoneChildren) == 'object')
				{
					for (var k=0; k<treeElm._children[j]._undoneChildren.length; k++)
					{
						var newE = this._tree._createTreeElement(treeElm._children[j]._undoneChildren[k], treeElm._children[j]._level +1);
						treeElm._children[j].addChild(newE);
					}
					treeElm._children[j]._undoneChildren = false;
				}
				if (treeElm._children[j].hasVisibleChildren())
				{
					var doRender = false;
					for (var k=0; k<treeElm._children[j]._children.length; k++)
					{
						if (!treeElm._children[j]._children[k]._isOutrendered) 
						{
							var doRender = true;break;
						}
					}

					if (doRender)
					{
						treeElm._children[j].render(true, true, lookAhead);
					}
				}
			}
		}
	}

	this._renderParentsUp = function()
	{
			if (typeof(this.parent) == 'undefined')
				this.parent._renderParentsUp();
			if (this._isOutrendered) return;
			this.render(true, true);
	}

	this.close = function()
	{
		if (!this.isOpen) return;
		this.isOpen = false;
		if (this._isOutrendered)
		{
			var d = document.getElementById(this._tree._objectId + '_e_' + this.id + '_children');
			d.style.display = 'none';
			this._switchIconsOnToggleOpenClose();
		} else {				
			this.render(true, true);
		}
	}

	this._switchIconsOnToggleOpenClose = function()
	{
		var openClose = document.getElementById(this._tree._objectId + '_e_' + this.id + '_openClose');
		openClose.src = this._getSourceOpenCloseIcon();
		if (this._getVar('useFolderIcon'))
		{
			var folderIconId = this._tree._objectId + '_e_' + this.id + '_folder';
			var fIcon = document.getElementById(folderIconId);
			if (fIcon)
			{
				fIcon.src = this._getSourceFolderIcon();
			}
		}
	}

	this._getSourceOpenCloseIcon = function()
	{
		if (this.hasSiblingsDown())
		{
			var imgNumber = 3;
		} else {
			var imgNumber = 2;
		}

		if (this.hasVisibleChildren())
		{
			if ((this._level == 0)
				|| (!this._tree.showPseudoElement
					&& (this._level == 1)
					&& ((this._tree.useAutoSequence
						&& (this.id == 1))
				|| (!this._tree.useAutoSequence && true))))
			{
				if (this.hasSiblingsDown())
				{
					imgNumber++;
				} else {
					imgNumber--;
				}
			}

			if (this.isOpen)
			{
				var plusImg = 'minus' + imgNumber;
				var onClick = 'Close';
			} else {
				var plusImg = 'plus' + imgNumber;
				var onClick = 'Open';
			}

		} else {

			var plusImg = 'line' + imgNumber;
		}
		var imageDir = this._getVar('imageDir');
		return imageDir + plusImg + '.gif';		
	}

	this._getSourceFolderIcon = function()
	{
		var imageDir = this._getVar('imageDir');
		switch (typeof(this.icon))
		{
			case 'undefined':
				if (this._tree.useLeaf && !this.hasChildren())
				{
					var folderImg = 'leaf';
				} else {
					var folderImg = 'folder';
					folderImg += (this.isOpen) ? 'Open' : 'Closed';
				}
				return imageDir + folderImg + '.gif';
				break;
			case 'bool':
			case 'boolean':
				break;
			case 'string':
				if (this.icon != 'false')
				{
					var ret = '';
					if (!this._iconHasPath(this.icon))
						ret += imageDir;
					ret += this.icon;
					if (!this._iconHasExtension(this.icon))
						ret += '.gif';return ret;
				}
		}
		return '';
	}

	this.hasChildren = function()
	{
		return (this._children.length > 0);
	}

	this.hasVisibleChildren = function()
	{
		if (!this._children || !(this._children.length > 0)) 
			return false;
		for (var i=0; i<this._children.length; i++)
		{
			if (this._children[i].visible) return true;
		}
		return false;
	}

	this.numChildren = function()
	{
		return this._children.length;
	}

	this.childPos = function(id)
	{
		for (var i=0; i<this._children.length; i++)
		{
			if (this._children[i].id == id) 
			return ++i;
		}
		return false;
	}

	this.hasSiblings = function() {}

	this.hasSiblingsDown = function()
	{
		try
		{
			var tot = this.parent.numChildren();
			var pos = this.parent.childPos(this.id);
			return (pos < tot);
		} catch (e)
		{
			return false;
		}
	}

	this.hasSiblingsAbove = function() {}
	this.getSiblings = function()
	{
		try 
		{
			return this.parent.getChildren();
		} catch(e) {
			return new Array;
		}
	}

	this.getChildren = function()
	{
		return this._children;
	}

	this.getParentId = function()
	{
		try {
			return this.parent.id;
		} catch (e) {
			return false;
		}
	}

	this.hasParent = function()
	{
		return (this.parent);
	}

	this.attachEvent = function(trigger, yourEvent)
	{
		if (typeof(this._attachedEvents) == 'undefined')
		{
			this._attachedEvents = new Array();
		}

		if (typeof(this._attachedEvents[trigger]) == 'undefined')
		{
			this._attachedEvents[trigger] = new Array(yourEvent);
		} else {
			this._attachedEvents[trigger][this._attachedEvents[trigger].length] = yourEvent;
		}
	}

	this.hasEventAttached = function(trigger)
	{
		return ((typeof(this._attachedEvents) != 'undefined') && (typeof(this._attachedEvents[trigger]) != 'undefined'));
	}

	this.fireEvent = function(trigger)
	{
		var ret = true;
		if (trigger == 'onClickCaption')
		{
			this.setActive();
		}
		if ((typeof(this._attachedEvents) != 'undefined') && (typeof(this._attachedEvents[trigger]) != 'undefined'))
		{
			var e = this._attachedEvents[trigger];
			if ((typeof(e) == 'string') || (typeof(e) == 'function'))
			{
				e = new Array(e);
			}
			for (var i=0; i<e.length; i++)
			{
				if (typeof(e[i]) == 'function')
				{
					var status = e[i](this);
					if (status == false) ret = false;
				} else if (typeof(e[i]) == 'string') {
					var ev = e[i].replace(/__this\.id__/g, this.id);
					//replace the string __this.id__ with the actual id.
					//ev = ev.replace(/__this__/g, 'this'); //replace the string __this__ with 'this'.
					eval(ev);
				}
			}
		}
		return ret;
	}

	this._addError = function(str)
	{
		if (typeof(this._errorArray) == 'undefined')
		{
			this._errorArray = new Array(str);
		} else {
			this._errorArray[this._errorArray.length] = str;
		}
	}

	this.getLastError = function()
	{
		if (typeof(this._errorArray) != 'undefined')
		{
			if (this._errorArray.length > 0) 
			{
				return this._errorArray[this._errorArray.length -1];
			}
		}
		return false;
	}

	this._getVar = function(varName)
	{
		if (typeof(this[varName]) != 'undefined')
		{
			return this[varName];
		} else {
			if (this._tree.walkTree && (typeof(this.parent) != 'undefined'))
			{
				return this.parent._getVar(varName);
			} else if (typeof(this._tree[varName]) != 'undefined')
			{
				return this._tree[varName];
			} else {
				return null;
			}
		}
	}

	this.onMouseOver = function()
	{
		var img = document.getElementById(this._spanId + 'icon');
		if (!img.swapOver0)
		{
			img.swapOver0 = new Image();
			img.swapOver0.src = this.imgDir + 'enabled_0_over.gif';
			img.swapOver1 = new Image();
			img.swapOver1.src = this.imgDir + 'enabled_1_over.gif';
			img.swapOver2 = new Image();
			img.swapOver2.src = this.imgDir + 'enabled_2_over.gif';
			img.swapOut0 = new Image();
			img.swapOut0.src = this.imgDir + 'enabled_0.gif';
			img.swapOut1 = new Image();
			img.swapOut1.src = this.imgDir + 'enabled_1.gif';
			img.swapOut2 = new Image();
			img.swapOut2.src = this.imgDir + 'enabled_2.gif';
		}
		img.src = img['swapOver' + this.value].src;
	}

	this.onMouseOut = function()
	{
		var img = document.getElementById(this._spanId + 'icon');
		img.src = img['swapOut' + this.value].src;
	}

	this.setCheckboxValue = function(value, fireEvents, doWalk)
	{
		if (typeof(fireEvents) == 'undefined') 
			fireEvents = true;
		if (typeof(doWalk)     == 'undefined')
			doWalk = true;
		if (!this.hasChildren())
		{
			value = (value) ? 2 : 0;
		} else {
			if (this.isChecked == 0)
			{
				if (this._tree.checkboxSystemWalkTree 
					&& (this._tree.checkboxSystemWalkTree != 2)
					&& (this._tree.checkboxSystemWalkTree != 3) 
					&& this.hasChildren())
				{
					value = 1;
				}
			}
		}

		this.isChecked = value;
		this._checkboxObject.setTo(value, true);
		if (fireEvents)
		{
			if (this.hasEventAttached('onChangeCheckbox'))
				this.fireEvent('onChangeCheckbox');
		}

		if (doWalk)
		{
			if ((this._tree.checkboxSystemWalkTree == 3)
				|| (this._tree.checkboxSystemWalkTree == 1)
				|| (this._tree.checkboxSystemWalkTree == 4))
			{
				this.parent.updateCheckboxFromChild();
			}

			if ((this._tree.checkboxSystemWalkTree == 3)
				|| (this._tree.checkboxSystemWalkTree == 2)
				|| ((this._tree.checkboxSystemWalkTree == 4)
					&& (value == 0)))
			{
				this.checkboxUpdateDown(value);
			}
		}
	}

	this.checkboxEvent = function(value)
	{
		if (!this.hasChildren())
		{
			value = (value) ? 2 : 0;
		} else {
			if (this.isChecked == 1) {
				if ((!this._tree.checkboxSystemIfPartlyThenFull)
					|| ((this._tree.checkboxSystemWalkTree)
						&& (this._tree.checkboxSystemWalkTree != 2) 
						&& (this._tree.checkboxSystemWalkTree != 3)))
				{
					value = 0;
				} else {
					value = 2;
				}
			} else if (this.isChecked == 0)
			{
				if (this._tree.checkboxSystemWalkTree 
					&& (this._tree.checkboxSystemWalkTree != 2) 
					&& (this._tree.checkboxSystemWalkTree != 3) 
						&& this.hasChildren()) 
				{
					value = 1;
				}
			}
		}

		this.isChecked = value;
		this._checkboxObject.setTo(value, true);
		if (this.hasEventAttached('onChangeCheckbox'))
			this.fireEvent('onChangeCheckbox');
		if ((this._tree.checkboxSystemWalkTree == 3) 
			|| (this._tree.checkboxSystemWalkTree == 1)
			|| (this._tree.checkboxSystemWalkTree == 4))
		{
			this.parent.updateCheckboxFromChild();
		}

		if ((this._tree.checkboxSystemWalkTree == 3) 
			|| (this._tree.checkboxSystemWalkTree == 2) 
			|| ((this._tree.checkboxSystemWalkTree == 4)
				&& (value == 0)))
		{
			this.checkboxUpdateDown(value);
		}
	}

	this.checkboxUpdateDown = function(value)
	{
		for (var i=0; i<this._children.length; i++) 
		{
			this._children[i]._updateCheckboxFromParent(value, true);
		}
	}

	this.updateCheckboxVisually = function()
	{
		if (typeof(this._checkboxObject) == 'object')
		{
			try
			{
				this._checkboxObject.setTo(this.isChecked);
			} catch (e) {
			}
		}
	}

	this._updateCheckboxFromParent = function(newValue, recursiveDown)
	{
		var backupValue = this.isChecked;
		this.isChecked = (newValue) ? 2 : 0;
		var hasChanged = (this.isChecked != backupValue);
		if (hasChanged)
		{
			this.updateCheckboxVisually();
			if (this.hasEventAttached('onChangeCheckbox'))
				this.fireEvent('onChangeCheckbox');
		}

		if (recursiveDown)
			this.checkboxUpdateDown(newValue, true);
	}

	this.updateCheckboxFromChild = function()
	{
		var backupIsChecked = this.isChecked;
		var numYes   = 0;
		var numNo    = 0;
		var isPartly = false;
		for (var i=0; i<this._children.length; i++)
		{
			if (this._children[i].isChecked == 1)
			{
				isPartly = true;
				this.isChecked = 1;
				break;
			} else if (this._children[i].isChecked)
			{
				numYes++;
			} else {
				numNo++;
			}

			if ((numYes > 0) && (numNo > 0))
			{
				break;
			}
		}

		if (!isPartly)
		{
			if ((numYes > 0) && (numNo > 0))
			{
				this.isChecked = 1;
			} else if (numYes > 0) {
				this.isChecked = 2;
			} else {
				this.isChecked = 0;
			}
		}

		if (backupIsChecked != this.isChecked)
		{
			this.updateCheckboxVisually();
			if (this.hasEventAttached('onChangeCheckbox')) 
				this.fireEvent('onChangeCheckbox');
		}

		if (typeof(this.parent) == 'object')
		{
			this.parent.updateCheckboxFromChild();
		}
	}

	this._updateLevelAndParent = function(treeElement)
	{
		if ((typeof(treeElement._children) == 'object')
			&& (treeElement._children.length > 0))
		{
			for (var i=0; i<treeElement._children.length; i++)
			{
				treeElement._children[i].parent = treeElement;
				treeElement._children[i]._level = treeElement._level +1;
				this._updateLevelAndParent(treeElement._children[i]);
			}
		}
	}

	this._getLinkStyle = function()
	{
		if (typeof(this.linkStyle)!= 'undefined')
			return this.linkStyle;
		if (typeof(this._tree.linkStyle) != 'undefined')
			return this._tree.linkStyle;
		return '';
	}

	this._iconHasExtension = function(iconStr)
	{
		var iconLower = iconStr.toLowerCase();
		var iconPos   = iconLower.lastIndexOf('.');
		if (iconPos > -1)
		{
			var iconExt = iconLower.substr(iconPos +1);
			if ((iconExt != 'gif') && (iconExt != 'png') && (iconExt != 'jpg') && (iconExt != 'jpeg'))
			{
				return false;
			}
		} else {
			return false;
		}
		return true;
	}

	this._iconHasPath = function(iconStr)
	{
		if (iconStr.indexOf('://') > -1) return true;
		if (iconStr.substr(0, 1) == '/') return true;
		return false;
	}
}

