/*
Product Name: dhtmlxSuite 
Version: 5.2.0 
Edition: Professional 
License: content of this file is covered by DHTMLX Commercial or Enterprise license. Usage without proper license is prohibited. To obtain it contact sales@dhtmlx.com
Copyright UAB Dinamenta http://www.dhtmlx.com
*/
/*
Purpose: saving state extension for dhtmlxTree
Inner Version: 1.3
Last updated: 05.07.2005
*/
dhtmlXTreeObject.prototype._serEnts=[["&","&"],["<","<"],[">",">"]];
/**
*     @desc: register XML entity for replacement while initialization (default are: ampersand, lessthen and greaterthen symbols)
*     @type: public
*     @edition: Professional
*	  @param: rChar - source char
*	  @param: rEntity - target entity
*     @topic: 2
*/
dhtmlXTreeObject.prototype.registerXMLEntity=function(rChar,rEntity){
    this._serEnts[this._serEnts.length]=[rChar,rEntity,new RegExp(rChar,"g")];
}
/**
*     @desc: configure XML serialization
*     @type: public
*     @edition: Professional
*	  @param: userData - enable/disable user data serialization
*	  @param: fullXML - enable/disable full XML serialization
*	  @param: escapeEntities - convert tag brackets to related html entitites
*	  @param: userDataAsCData - output user data in CDATA sections
*	  @param: DTD - if specified, then set as XML's DTD
*     @topic: 2
*/
dhtmlXTreeObject.prototype.setSerializationLevel=function(userData,fullXML,escapeEntities,userDataAsCData,DTD){
	this._xuserData=dhx4.s2b(userData);
	this._xfullXML=dhx4.s2b(fullXML);
    this._dtd=DTD;
    this._xescapeEntities=dhx4.s2b(escapeEntities);
    if (dhx4.s2b(userDataAsCData)){
        this._apreUC="";
    }
    else{
    }
    for (var i=0; i< this._serEnts.length; i++)
        this._serEnts[i][2]=new RegExp(this._serEnts[i][0],"g");
}
/**
*     @desc: get xml representation (as string) of tree
*     @type: public
*     @edition: Professional
*     @topic: 2
*/
dhtmlXTreeObject.prototype.serializeTree=function(){
    if (this.stopEdit) this.stopEdit();
    this._apreUC=this._apreUC||"";
    this._apstUC=this._apstUC||"";
	var out='';
    if (this._dtd)
        out+="";
    out+='';
		if ((this._xuserData)&&(this._idpull[this.rootId]._userdatalist))
		{
		var names=this._idpull[this.rootId]._userdatalist.split(",");
		for  (var i=0; i"+this._apreUC+this._idpull[this.rootId].userData["t_"+names[i]]+this._apstUC+"";
		}
		for (var i=0; i";
	return out;
};
/**  
*     @desc: return xml description of tree item
*     @type: private
*     @param: itemNode - tree item object
*     @edition: Professional
*     @topic: 2
*/
dhtmlXTreeObject.prototype._serializeItem=function(itemNode){
	if (itemNode.unParsed)
		if (dhx4.isIE){
			return itemNode.unParsed.d.xml;
		}
		else{
  var xmlSerializer = new XMLSerializer();
  return xmlSerializer.serializeToString(itemNode.unParsed.d);
		}
		
	var out="";
	if (this._selected.length)
		var lid=this._selected[0].id;
	else lid="\"";
    var text=itemNode.span.innerHTML;
    if (this._xescapeEntities)
        for (var i=0; i';
	else
		out='- ';
	if ((this._xuserData)&&(itemNode._userdatalist))
		{
		var names=itemNode._userdatalist.split(",");
		for  (var i=0; i"+this._apreUC+itemNode.userData["t_"+names[i]]+this._apstUC+"";
		}
		for (var i=0; i";
	return out;
}
/**  
*     @desc: save selected item to cookie
*     @type: public
*     @param: name - optional, cookie name
*     @param: cookie_param - additional parametrs added to cookie
*     @edition: Professional
*     @topic: 2
*/
dhtmlXTreeObject.prototype.saveSelectedItem=function(name,cookie_param){
	name=name||"";
	this.setCookie("treeStateSelected"+name,this.getSelectedItemId(),cookie_param);
}
/**     @desc: restore selected item from cookie
*     @type: public
*     @param: name - optional, cookie name
*     @edition: Professional
*     @topic: 2
*/
dhtmlXTreeObject.prototype.restoreSelectedItem=function(name){
	name=name||"";
	var z=this.getCookie("treeStateSelected"+name);
	this.selectItem(z,false);
}
/**   @desc: enable/disable autosaving selected node in cookie
*     @type: public
*     @param: mode - true/false
*     @edition: Professional
*     @topic: 2
*/	
dhtmlXTreeObject.prototype.enableAutoSavingSelected=function(mode,cookieName){
 this.assMode=dhx4.s2b(mode);
 if ((this.assMode)&&(!this.oldOnSelect)){
		 this.oldOnSelect=this.onRowSelect;
		 this.onRowSelect=function(e,htmlObject,mode){
 			if (!htmlObject) htmlObject=this;
			htmlObject.parentObject.treeNod.oldOnSelect(e,htmlObject,mode);
			if (htmlObject.parentObject.treeNod.assMode)
				htmlObject.parentObject.treeNod.saveSelectedItem(htmlObject.parentObject.treeNod.assCookieName);
		}
 }
 this.assCookieName=cookieName;
}
/**   @desc: save tree to cookie
*     @type: public
*     @param: name - optional, cookie name
*     @param: cookie_param - additional parametrs added to cookie
*     @edition: Professional
*     @topic: 2
*/
dhtmlXTreeObject.prototype.saveState=function(name,cookie_param){
	var z=this._escape(this.serializeTree());
	var kusok = 4000;
	if (z.length>kusok)
	{
		if(navigator.appName.indexOf("Microsoft")!=-1)
			return false;//IE max cookie length is ~4100
	this.setCookie("treeStatex"+name,Math.ceil(z.length/kusok));
		for (var i=0; i 0) {
		var offset = document.cookie.indexOf(search);
		if (offset != -1) {
			offset += search.length;
			var end = document.cookie.indexOf(";", offset);
			if (end == -1)
				end = document.cookie.length;
			return document.cookie.substring(offset, end);
						}		}
};
/**   @desc: save open nodes to cookie
*     @type: public
*     @edition: Professional
*     @param: name - optional,cookie name
*     @param: cookie_param - additional parametrs added to cookie
*     @topic: 2
*/
dhtmlXTreeObject.prototype.saveOpenStates=function(name,cookie_param){
    var z=[];
    for (var i=0; i0){
			this.onLoadReserve = this.onXLE; //save loading end handler
			this.onXLE=this._loadAndOpen; //set on XML data loading end handler
			this._loadAndOpen(this); //if there are not loaded items -> run load&open routine
		}
	};
	dhtmlXTreeObject.prototype._openAllNodeChilds = function(itemNode)
	{
			//for dynamic loading
    	if ((itemNode.XMLload==0)||(itemNode.unParsed))  this.ClosedElem.push(itemNode);  //if not loaded put in array
		for (var i=0; i open
			if(itemNode.childNodes[i].childsCount>0) this._openAllNodeChilds(itemNode.childNodes[i]); //if has childs -> run same routine for that node
			//for dynamic loading
			if ((itemNode.childNodes[i].XMLload==0)||(itemNode.childNodes[i].unParsed)) this.ClosedElem.push(itemNode.childNodes[i]); //if not loaded put in array
		}
	}
	dhtmlXTreeObject.prototype._loadAndOpen = function(that)
	{
		if(that.G_node) //if there was loaded one node
		{
			that._openItem(that.G_node); //open it
			that._openAllNodeChilds(that.G_node); //run open/find closed nodes for childs of this node
			that.G_node = null; //erase "just loaded node" pointer
		}
		if(that.ClosedElem.length>0) that.G_node = that.ClosedElem.shift(); //get not loaded node if any left in array
		if(that.G_node)
            if (that.G_node.unParsed)
                that.reParse(that.G_node);
            else
                window.setTimeout( function(){  that._loadDynXML(that.G_node.id); },100);
        else
			{
            that.onXLE = that.onLoadReserve; //restore loading end handler if finished opening
            if (that.onXLE) that.onXLE(that);
			that.callEvent("onAllOpenDynamic",[that]);
			}
	}
/**
*     @desc: expand list of nodes in dynamic tree (wait of loading of node before expanding next)
*     @type: public
*     @edition: Professional
*     @param: list - list of nodes which will be expanded
*     @param: flag - true/false - select last node in the list
*     @topic: 4
*/
    dhtmlXTreeObject.prototype.openItemsDynamic=function(list,flag){
    	if (this.onXLE==this._stepOpen) return;
        this._opnItmsDnmcFlg=dhx4.s2b(flag);
        this.onLoadReserve = this.onXLE;
        this.onXLE=this._stepOpen;
        this.ClosedElem=list.split(",").reverse();
        this._stepOpen(this);
        }
	dhtmlXTreeObject.prototype._stepOpen=function(that){
		if(!that.ClosedElem.length){
			that.onXLE = that.onLoadReserve;
			if (that._opnItmsDnmcFlg)
				that.selectItem(that.G_node,true);
			if ((that.onXLE)&&(arguments[1]))
				that.onXLE.apply(that,arguments);
			that.callEvent("onOpenDynamicEnd",[]);
			return;
		}
		that.G_node=that.ClosedElem.pop();
		that.skipLock = true;
		var temp=that._globalIdStorageFind(that.G_node);
		if(temp){
			if (temp.XMLload===0)
				that.openItem(that.G_node);
			else{
				that.openItem(that.G_node);
				that._stepOpen(that);
			}
		}
		that.skipLock = false;
	}
//(c)dhtmlx ltd. www.dhtmlx.com