/*
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
*/

/**
*     @desc: enable/disable drag-and-drop
*     @type: public
*     @param: mode - enabled/disabled [ can be true/false/temporary_disabled - last value mean that tree can be D-n-D can be switched to true later ]
*     @topic: 0
*/
   dhtmlXGridObject.prototype.enableDragAndDrop=function(mode){
        if  (mode=="temporary_disabled"){
            this.dADTempOff=false;
            mode=true;                  }
        else
            this.dADTempOff=true;

		this.dragAndDropOff=dhx4.s2b(mode);
		this._drag_validate=true;
		if (mode)
			this.objBox.ondragstart = function (e) {
				(e||event).cancelBubble = true;
				return false;
			}
       };

/**
*     @desc: set Drag-And-Drop behavior (child - drop as chils, sibling - drop as sibling
*     @type: public
*     @param: mode - behavior name (child,sibling,complex)
*     @topic: 0
*/
dhtmlXGridObject.prototype.setDragBehavior=function(mode){
        this.dadmodec=this.dadmodefix=0;
      switch (mode) {
         case "child": this.dadmode=0; this._sbmod=false;  break;
         case "sibling": this.dadmode=1; this._sbmod=false;  break;
         case "sibling-next": this.dadmode=1; this._sbmod=true; break;
         case "complex": this.dadmode=2; this._sbmod=false;  break;
         case "complex-next": this.dadmode=2; this._sbmod=true;  break;
      }    };


/**
*     @desc: switch to mode when draged item, droped in target location in same order as they was in source grid
*     @type: public
*     @param: mode - true/false to enable/disable mode
*     @topic: 0
*/
dhtmlXGridObject.prototype.enableDragOrder=function(mode){
        this._dndorder=dhx4.s2b(mode);
};


dhtmlXGridObject.prototype._checkParent=function(row,ids){
	var z=this._h2.get[row.idd].parent;
	if (!z.parent) return;
	for (var i=0; i<ids.length; i++) 
		if (ids[i]==z.id) return true;
		
	return this._checkParent(this.rowsAr[z.id],ids);
}

/**
*     @desc: create html element for dragging
*     @type: private
*     @param: htmlObject - html node object
*     @topic: 1
*/
dhtmlXGridObject.prototype._createDragNode=function(htmlObject,e){
	  this.editStop();
	  if (window.dhtmlDragAndDrop.dragNode) return null;
      if (!this.dADTempOff) return null;
      htmlObject.parentObject=new Object();
      htmlObject.parentObject.treeNod=this;

	var text=this.callEvent("onBeforeDrag",[htmlObject.parentNode.idd,htmlObject._cellIndex, e]);
	if (!text) return null;

      var z=new Array();
//#__pro_feature:21092006{
      z=this.getSelectedId();
	  z=(((z)&&(z!=""))?z.split(this.delim):[]);
      var exst=false;
      for (var i=0; i<z.length; i++)
        if (z[i]==htmlObject.parentNode.idd)  exst=true;
      if (!exst){
      	this.selectRow(this.rowsAr[htmlObject.parentNode.idd],false,e.ctrlKey,false);
      	if (!e.ctrlKey) {
      		z=[];
  		}
//#}
          z[this.selMultiRows?z.length:0]=htmlObject.parentNode.idd;
//#__pro_feature:21092006{
    }
//#}

	//remove child in case of treeGrid
	if (this.isTreeGrid()){
		for (var i=z.length-1; i>=0; i--) 
			if (this._checkParent(this.rowsAr[z[i]],z)) z.splice(i,1);
				
	}
	

	var self=this;
	if (z.length && this._dndorder)
		z.sort(function(a,b){ return (self.rowsAr[a].rowIndex>self.rowsAr[b].rowIndex?1:-1); });

     var el = this.getFirstParentOfType(_isIE?e.srcElement:e.target,"TD");
     if (el) this._dndExtra=el._cellIndex;
      this._dragged=new Array();
      for (var i=0; i<z.length; i++)
          if (this.rowsAr[z[i]]){
          this._dragged[this._dragged.length]=this.rowsAr[z[i]];
          this.rowsAr[z[i]].treeNod=this;
          }

      htmlObject.parentObject.parentNode=htmlObject.parentNode;

   var dragSpan=document.createElement('div');
   dragSpan.innerHTML=(text!==true?text:this.rowToDragElement(htmlObject.parentNode.idd));
   dragSpan.style.position="absolute";
   dragSpan.className="dragSpanDiv";
   return dragSpan;
}



/**
*   @desc:  create a drag visual marker
*   @type:  private
*/
dhtmlXGridObject.prototype._createSdrgc=function(){
    this._sdrgc=document.createElement("DIV");
    this._sdrgc.innerHTML="&nbsp;";
    this._sdrgc.className="gridDragLine";
    this.objBox.appendChild(this._sdrgc);
}











/**
*   @desc:  create a drag context object
*   @type:  private
*/
function dragContext(a,b,c,d,e,f,j,h,k,l,m){
    this.source=a||"grid";
    this.target=b||"grid";
    this.mode=c||"move";
    this.dropmode=d||"child";
    this.sid=e||0;
    this.tid=f;
    this.sobj=j||null;
    this.tobj=h||null;
   this.sExtra=k||null;
   this.tExtra=l||null;
   this.before=m||false;
    return this;
}
/**
*   @desc:  check is operation possible
*   @type:  private
*/
dragContext.prototype.valid=function(){
   if (this.sobj!=this.tobj) return true;
   if (this.sid==this.tid) return false;
   if (this.target=="treeGrid"){
      var z=this.tid
      while (z = this.tobj.getParentId(z) ){
         if (this.sid==z) return false;
         }
   }
   return true;
}
/**
*   @desc:  close context
*   @type:  private
*/
dragContext.prototype.close=function(){
    this.sobj=null;
    this.tobj=null;
}
/**
*   @desc:  return copy of context
*   @type:  private
*/
dragContext.prototype.copy=function(){
    return new dragContext(this.source,this.target,this.mode,this.dropmode,this.sid,this.tid,this.sobj,this.tobj,this.sExtra,this.tExtra,this.before);
}
/**
*   @desc:  set a lue of context attribute
*   @type:  private
*/
dragContext.prototype.set=function(a,b){
    this[a]=b;
    return this;
}
/**
*   @desc:  generate an Id for new node
*   @type:  private
*/
dragContext.prototype.uid=function(a,b){
    this.nid=this.sid;
    while (this.tobj.rowsAr[this.nid])
        this.nid=this.nid+((new Date()).valueOf());

    return this;
}
/**
*   @desc:  get data array for grid row
*   @type:  private
*/
dragContext.prototype.data=function(){
    if (this.sobj==this.tobj)
        return this.sobj._getRowArray(this.sobj.rowsAr[this.sid]);
    if (this.source=="tree")
        return this.tobj.treeToGridElement(this.sobj,this.sid,this.tid);
    else
        return this.tobj.gridToGrid(this.sid,this.sobj,this.tobj);
}
dragContext.prototype.attrs=function(){
    if (this.source=="tree")
        return {};
    else
        return this.sobj.rowsAr[this.sid]._attrs;
}
dragContext.prototype.childs=function(){
    if (this.source=="treeGrid")
		return this.sobj._h2.get[this.sid]._xml_await?this.sobj._h2.get[this.sid].has_kids:null;
	return null;
}

/**
*   @desc:  return parent id for row in context
*   @type:  private
*/
dragContext.prototype.pid=function(){
    if (!this.tid) return 0;
	if (!this.tobj._h2) return 0;
    if (this.target=="treeGrid")
        if (this.dropmode=="child")
            return this.tid;
        else{
			var z=this.tobj.rowsAr[this.tid];
			var apid=this.tobj._h2.get[z.idd].parent.id;
			if ((this.alfa)&&(this.tobj._sbmod)&&(z.nextSibling)){
				var zpid=this.tobj._h2.get[z.nextSibling.idd].parent.id;
				if (zpid==this.tid)
            		return this.tid;
				if (zpid!=apid)
            		return zpid;
			}
	        return apid;
	   }
}
/**
*   @desc:  get index of target position
*   @type:  private
*/
dragContext.prototype.ind=function(){ 
    if (this.tid==window.unknown) return this.tobj.rowsBuffer.length;
    if (this.target=="treeGrid"){
      if (this.dropmode=="child")
            this.tobj.openItem(this.tid);
      else
         this.tobj.openItem(this.tobj.getParentId(this.tid));
   }
    var ind=this.tobj.rowsBuffer._dhx_find(this.tobj.rowsAr[this.tid]);
	if ((this.alfa)&&(this.tobj._sbmod)&&(this.dropmode=="sibling")){
		var z=this.tobj.rowsAr[this.tid];
		if ((z.nextSibling)&&(this._h2.get[z.nextSibling.idd].parent.id==this.tid))
			return ind+1;
	}

    return (ind+1+((this.target=="treeGrid" && ind>=0 && this.tobj._h2.get[this.tobj.rowsBuffer[ind].idd].state=="minus")?this.tobj._getOpenLenght(this.tobj.rowsBuffer[ind].idd,0):0));
}

/**
*   @desc:  get row related image
*   @type:  private
*/
dragContext.prototype.img=function(){
    if ((this.target!="grid")&&(this.sobj._h2))
      return this.sobj.getItemImage(this.sid);
   else return null;
}

/**
*   @desc:  return list of rows in context
*   @type:  private
*/
dragContext.prototype.slist=function(){
    var res=new Array();
    for (var i=0; i<this.sid.length; i++)
        res[res.length]=this.sid[i][(this.source=="tree")?"id":"idd"];

    return res.join(",");
}


/**
*   @desc:  drag entry point
*   @type:  private
*/
dhtmlXGridObject.prototype._drag=function(sourceHtmlObject,dhtmlObject,targetHtmlObject,lastLanding){
   if (this._realfake) return this._fake._drag();

   var z=(this.lastLanding)
    //close unfinished tasks
    if  (this._autoOpenTimer) window.clearTimeout(this._autoOpenTimer);

    //detect details
    var r1=targetHtmlObject.parentNode;
    var r2=sourceHtmlObject.parentObject;
    //drop on header
    if (!r1.idd) { r1.grid=this;    this.dadmodefix=0; }

    var c=new dragContext(0,0,0,((r1.grid.dadmode==1 || r1.grid.dadmodec)?"sibling":"child"));


    if (r2 && r2.childNodes)
        c.set("source","tree").set("sobj",r2.treeNod).set("sid",c.sobj._dragged);
    else{
    	if (!r2) return true;
        if (r2.treeNod.isTreeGrid && r2.treeNod.isTreeGrid())
        	c.set("source","treeGrid");
        c.set("sobj",r2.treeNod).set("sid",c.sobj._dragged);
        }

    if (r1.grid.isTreeGrid())
        c.set("target","treeGrid");
	else
		c.set("dropmode","sibling");
    c.set("tobj",r1.grid).set("tid",r1.idd);

//#__pro_feature:21092006{
    //complex drag mode - adjust tartget element
    if (((c.tobj.dadmode==2)&&(c.tobj.dadmodec==1))&&(c.tobj.dadmodefix<0))
       if (c.tobj.obj.rows[1].idd!=c.tid) c.tid=r1.previousSibling.idd;
       else {
         if (this._h2 && c.tid)
           c.before = true;
         else c.tid=0;
       }
//#}

   var el = this.getFirstParentOfType(lastLanding,"TD")
   if (el) c.set("tExtra",el._cellIndex);
   if (el) c.set("sExtra",c.sobj._dndExtra);

    if (c.sobj.dpcpy) c.set("mode","copy");
    
    if (c.tobj._realfake) c.tobj=c.tobj._fake;
    if (c.sobj._realfake) c.sobj=c.sobj._fake;
    
    c.tobj._clearMove();
    
	if (r2 && r2.treeNod && r2.treeNod._nonTrivialRow)
		r2.treeNod._nonTrivialRow(this,c.tid,c.dropmode,r2);
	else {
		c.tobj.dragContext=c;
	    if (!c.tobj.callEvent("onDrag",[c.slist(),c.tid,c.sobj,c.tobj,c.sExtra,c.tExtra]))  return  c.tobj.dragContext=null;
	
	   //all ready, start mantras
	   var result=new Array();
	   if (typeof(c.sid)=="object"){
	        var nc=c.copy();
	        for (var i=0; i<c.sid.length; i++){
	         if (!nc.set("alfa",(!i)).set("sid",c.sid[i][(c.source=="tree"?"id":"idd")]).valid()) continue;
	            nc.tobj._dragRoutine(nc);
	            if (nc.target=="treeGrid" && nc.dropmode == "child") nc.tobj.openItem(nc.tid);
	            result[result.length]=nc.nid;
	         nc.set("dropmode","sibling").set("tid",nc.nid);
	            }
	        nc.close();
	        }
	    else
	       c.tobj._dragRoutine(c);		

	   //finish math if any awaiting
	   if (c.tobj.laterLink) c.tobj.laterLink();
	   //destroy context
		c.tobj.callEvent("onDrop",[c.slist(),c.tid,result.join(","),c.sobj,c.tobj,c.sExtra,c.tExtra]);
	}

   c.tobj.dragContext=null;
   c.close();
}


/**
*   @desc:  context drag routine
*   @type:  private
*/
dhtmlXGridObject.prototype._dragRoutine=function(c){
      if ((c.sobj==c.tobj)&&(c.source=="grid")&&(c.mode=="move")&&!this._fake){
         //special case for moving rows in same grid
         if (c.sobj._dndProblematic) return;
         var fr=c.sobj.rowsAr[c.sid];
         var bind=c.sobj.rowsCol._dhx_find(fr);
         c.sobj.rowsCol._dhx_removeAt(c.sobj.rowsCol._dhx_find(fr));
         c.sobj.rowsBuffer._dhx_removeAt(c.sobj.rowsBuffer._dhx_find(fr));
         c.sobj.rowsBuffer._dhx_insertAt(c.ind(),fr);
         if (c.tobj._fake){
         	c.tobj._fake.rowsCol._dhx_removeAt(bind);
         	var tr=c.tobj._fake.rowsAr[c.sid];
         	tr.parentNode.removeChild(tr);
     	 }         
         c.sobj._insertRowAt(fr,c.ind()-(this.pagingOn?((this.currentPage-1)*this.rowsBufferOutSize):0));

         c.nid=c.sid;
         c.sobj.callEvent("onGridReconstructed",[]);
         return;
      }
      var new_row;
		if (this._h2 && typeof c.tid !="undefined" && c.dropmode=="sibling" && (this._sbmod || c.tid)){
      if (c.before)
        new_row=c.uid().tobj.addRowBefore(c.nid,c.data(),c.tid,c.img(),c.childs());
			else if (c.alfa && this._sbmod && this._h2.get[c.tid].childs.length){
				this.openItem(c.tid)
				new_row=c.uid().tobj.addRowBefore(c.nid,c.data(),this._h2.get[c.tid].childs[0].id,c.img(),c.childs());
			}
			else
		  	new_row=c.uid().tobj.addRowAfter(c.nid,c.data(),c.tid,c.img(),c.childs());
		}
		else
        	new_row=c.uid().tobj.addRow(c.nid,c.data(),c.ind(),c.pid(),c.img(),c.childs());

          new_row._attrs = c.attrs();
		
		
        if (c.source=="tree"){
        	this.callEvent("onRowAdded",[c.nid]);            
            var sn=c.sobj._globalIdStorageFind(c.sid);
            if (sn.childsCount){
                var nc=c.copy().set("tid",c.nid).set("dropmode",c.target=="grid"?"sibling":"child");
              for(var j=0;j<sn.childsCount;j++){
                    c.tobj._dragRoutine(nc.set("sid",sn.childNodes[j].id));
                    if (c.mode=="move") j--;
                    }
                nc.close();
                }
        }
        else{
            c.tobj._copyUserData(c);
			this.callEvent("onRowAdded",[c.nid]);            
			
            if ((c.source=="treeGrid")){
            	
            	if (c.sobj==c.tobj) new_row._xml=c.sobj.rowsAr[c.sid]._xml;
                var snc=c.sobj._h2.get[c.sid];
                if ((snc)&&(snc.childs.length)){
                    var nc=c.copy().set("tid",c.nid);
                    if(c.target=="grid")
                        nc.set("dropmode","sibling");
                    else {
                        if (!nc.tobj.kidsXmlFile)
                    	   nc.tobj.openItem(c.tid);
                        nc.set("dropmode","child");
                        }
					var l=snc.childs.length;
                    if (!nc.tobj.kidsXmlFile)
                    for(var j=0;j<l;j++){
                    	c.sobj.render_row_tree(null,snc.childs[j].id);
                        c.tobj._dragRoutine(nc.set("sid",snc.childs[j].id));
                        if (l!=snc.childs.length) {  j--; l=snc.childs.length; }
                        }
                    nc.close();
                    }
            }
        }

        if (c.mode=="move"){
           c.sobj[(c.source=="tree")?"deleteItem":"deleteRow"](c.sid);
           if ((c.sobj==c.tobj)&&(!c.tobj.rowsAr[c.sid])) {
               c.tobj.changeRowId(c.nid,c.sid);
            c.nid=c.sid;
         }
      }
}


/**
*   @desc: redefine this method in your code to define how grid row values should be used in another grid
*   @param: rowId - id of draged row
*   @param: sgrid - source grid object
*   @param: tgrid - target grid object
*   @returns: array of values for cells in target grid row
*   @type: public
*   @topic: 7
*/
dhtmlXGridObject.prototype.gridToGrid = function(rowId,sgrid,tgrid){
    var z=new Array();
    for (var i=0; i<sgrid.hdr.rows[0].cells.length; i++)
        z[i]=sgrid.cells(rowId,i).getValue();
   return z;
}

/**
*   @desc:  check if d-n-d is in allowed rules
*   @type:  private
*/
dhtmlXGridObject.prototype.checkParentLine=function(node,id){
    if ((!this._h2)||(!id)||(!node)) return false;
    if (node.id==id) return true;
    else return this.checkParentLine(node.parent,id);
}

/**
*   @desc:  called when drag moved over landing
*   @type:  private
*/
dhtmlXGridObject.prototype._dragIn=function(htmlObject,shtmlObject,x,y){
                    if (!this.dADTempOff) return 0;
                    var tree=this.isTreeGrid();
                    var obj=shtmlObject.parentNode.idd?shtmlObject.parentNode:shtmlObject.parentObject;
                    
					if (this._drag_validate){
                    	if(htmlObject.parentNode==shtmlObject.parentNode)
                        	return 0;
                        	
	                    if ((tree)&&(this==obj.grid)&&((this.checkParentLine(this._h2.get[htmlObject.parentNode.idd],shtmlObject.parentNode.idd))))
    	                    return 0;
    	            }
                    if (!this.callEvent("onDragIn",[obj.idd||obj.id,htmlObject.parentNode.idd,obj.grid||obj.treeNod,(htmlObject.grid||htmlObject.parentNode.grid)]))
                        return this._setMove(htmlObject,x,y,true);

                    this._setMove(htmlObject,x,y);

                  if ((tree)&&(htmlObject.parentNode.expand!="")){
                    var self = this;
                    this._autoOpenTimer=window.setTimeout(function(){
                      self._autoOpenItem(null, self);
                      self = null;
                    },1000);
                    this._autoOpenId=htmlObject.parentNode.idd;
                  }
                  else
                    if  (this._autoOpenTimer) window.clearTimeout(this._autoOpenTimer);

                    return htmlObject;
}
/**
*   @desc:  open item on timeout
*   @type:  private
*/
dhtmlXGridObject.prototype._autoOpenItem=function(e,gridObject){
	   gridObject.openItem(gridObject._autoOpenId);
}

/**
*   @desc:  called on onmouseout event , when drag out landing zone
*   @type:  private
*/
dhtmlXGridObject.prototype._dragOut=function(htmlObject){
                    this._clearMove();
                    var obj=htmlObject.parentNode.parentObject?htmlObject.parentObject.id:htmlObject.parentNode.idd;
                    this.callEvent("onDragOut",[obj]);
                    if  (this._autoOpenTimer) window.clearTimeout(this._autoOpenTimer);
}
/**
*   @desc:  set visual effect for moving row over landing
*   @type:  private
*/
dhtmlXGridObject.prototype._setMove=function(htmlObject,x,y,skip){
   if (!htmlObject.parentNode.idd) return;
   var a1=dhx4.absTop(htmlObject);
   var a2=dhx4.absTop(this.objBox);
   

   //scroll down
   if ( (a1-a2)>(parseInt(this.objBox.offsetHeight)-50) )
      this.objBox.scrollTop=parseInt(this.objBox.scrollTop)+20;
   //scroll top
   if ( (a1-a2+parseInt(this.objBox.scrollTop))<(parseInt(this.objBox.scrollTop)+30) )
      this.objBox.scrollTop=parseInt(this.objBox.scrollTop)-20;
      
   if (skip) return 0;
   
    if (this.dadmode==2)
    {

        var z=y-a1+(document.body.scrollTop||document.documentElement.scrollTop)-2-htmlObject.offsetHeight/2;
        if ((Math.abs(z)-htmlObject.offsetHeight/6)>0)
        {
        this.dadmodec=1;
      //sibbling zone
        if (z<0)  this.dadmodefix=-1; else   this.dadmodefix=1;
        }
        else this.dadmodec=0;
    }
    else
        this.dadmodec=this.dadmode;




    if (this.dadmodec){
      if (!this._sdrgc) this._createSdrgc();
      this._sdrgc.style.display="block";
      this._sdrgc.style.top=a1-a2+parseInt(this.objBox.scrollTop)+((this.dadmodefix>=0)?htmlObject.offsetHeight:0)+"px";
    }
    else{
      this._llSelD=htmlObject;
      if (htmlObject.parentNode.tagName=="TR")
      for (var i=0; i<htmlObject.parentNode.childNodes.length; i++)
      {
      var z= htmlObject.parentNode.childNodes[i];
	    z.className += " dhx_row_drag_active";
      }
    }
}
/**
*   @desc:  remove all visual effects
*   @type:  private
*/
dhtmlXGridObject.prototype._clearMove=function(){
    if (this._sdrgc) this._sdrgc.style.display="none";
    if ((this._llSelD)&&(this._llSelD.parentNode.tagName=="TR")){
    	var coll = this._llSelD.parentNode.childNodes;
        for (var i=0; i<coll.length; i++)
           coll[i].className = (coll[i].className || "").replace(" dhx_row_drag_active", "");
	}       

    this._llSelD=null;
}


/**
*   @desc: redefine this method in your code to define how grid row values should be displaied while draging
*   @param: gridRowId - id of grid row
*   @returns: html string representing dragging row 
*   @type: public
*   @topic: 7
*/
dhtmlXGridObject.prototype.rowToDragElement=function(gridRowId){
    var out=this.cells(gridRowId,0).getValue();
    return out;
}








/**
*   @desc:  copy user data for row
*   @type:  private
*/
dhtmlXGridObject.prototype._copyUserData = function(c){
			if(!c.tobj.UserData[c.nid] || c.tobj!=c.sobj)
            	c.tobj.UserData[c.nid] = new Hashtable();
            else return;

            var z1 = c.sobj.UserData[c.sid];
            var z2 = c.tobj.UserData[c.nid];
            if (z1) {
                z2.keys = z2.keys.concat(z1.keys);
                z2.values = z2.values.concat(z1.values);
            }
    }



/**
*     @desc: move row
*     @type:  public
*     @param: rowId - source row Id
*     @param: mode - moving mode (up,down,row_sibling)
*     @param: targetId - target row  in row_sibling mode
*     @param: targetGrid - used for moving between grids (optional)
*     @edition: Professional
*     @topic: 2
*/
dhtmlXGridObject.prototype.moveRow=function(rowId,mode,targetId,targetGrid){
      switch(mode){
      case "row_sibling":
                    this.moveRowTo(rowId,targetId,"move","sibling",this,targetGrid);
         break;
      case "up":
               this.moveRowUp(rowId);
         break;
      case "down":
               this.moveRowDown(rowId);
          break;
      }
}





//#__pro_feature:21092006{

/**
*   @desc: move rows from grid to tree
*   @param: tree - object of tree
*   @param: targetObject - target node of tree
*   @param: beforeNode - anchor node of tree
*   @param: itemObject - dragged node
*   @param: z2 - flag of recursion
*   @type:  private
*   @edition: Professional
*   @topic: 7
*/
dhtmlXGridObject.prototype._nonTrivialNode=function(tree,targetObject,beforeNode,itemObject,z2)
{
    if ((tree.callEvent)&&(!z2))
          if (!tree.callEvent("onDrag",[itemObject.idd,targetObject.id,(beforeNode?beforeNode.id:null),this,tree])) return false;

    var gridRowId = itemObject.idd;
    var treeNodeId = gridRowId;
    while (tree._idpull[treeNodeId]) treeNodeId+=(new Date()).getMilliseconds().toString();

   var img=(this.isTreeGrid()?this.getItemImage(gridRowId):"")
	if (beforeNode){
		for (i=0; i<targetObject.childsCount; i++)
		    if (targetObject.childNodes[i]==beforeNode) break;
		
		if (i!=0)
		    beforeNode=targetObject.childNodes[i-1];
		else{
		    st="TOP";
		    beforeNode="";
		    }
	}   
   var newone=tree._attachChildNode(targetObject,treeNodeId,this.gridToTreeElement(tree,treeNodeId,gridRowId),"",img,img,img,"","",beforeNode);
    if (this._h2){
      var akids=this._h2.get[gridRowId];
      if (akids.childs.length)
      for (var i=0; i<akids.childs.length; i++){
          this._nonTrivialNode(tree,newone,0,this.rowsAr[akids.childs[i].id],1);
          if (!this.dpcpy) i--;
      }
    }

    if (!this.dpcpy) this.deleteRow(gridRowId);

    if ((tree.callEvent)&&(!z2))
       tree.callEvent("onDrop",[treeNodeId,targetObject.id,(beforeNode?beforeNode.id:null),this,tree]);
}

/**
*   @desc: redefine this method in your code to define how grid row values should be used in tree (using input parameters you can change id of new tree node, set label, set userdata blocks etc.).
*   @param: treeObj - object of tree
*   @param: treeNodeId - id of node created in tree
*   @param: gridRowId - id of grid row
*   @returns: if true, then grid row will be moved to tree, else - copied
*   @type: public
*   @edition: Professional
*   @topic: 7
*/
dhtmlXGridObject.prototype.gridToTreeElement = function(treeObj,treeNodeId,gridRowId){
   return this.cells(gridRowId,0).getValue();
}

/**
*   @desc: redefine this method in your code to define how tree node values should be used in grid (using input parameters you can change id of new row, values for cells, userdata blocks etc.).
*   @param: treeObj - object of tree
*   @param: treeNodeId - id of node created in tree
*   @param: gridRowId - id of grid row
*   @returns: if true, then tree node should be moved to grid, else - copied
*   @type: public
*   @edition: Professional
*   @topic: 7
*/
dhtmlXGridObject.prototype.treeToGridElement = function(treeObj,treeNodeId,gridRowId){
    var w=new Array();
    var z=this.cellType._dhx_find("tree");
   if (z==-1) z=0;
   for(var i=0;i<this.getColumnCount();i++)
        w[w.length]=(i!=z)?(treeObj.getUserData(treeNodeId,this.getColumnId(i))||""):treeObj.getItemText(treeNodeId);
   return w;
}

/**
*     @desc: move row
*     @type:  public
*     @param: srowId - source row Id
*     @param: trowId - target row Id
*     @param: mode - move or copy
*     @param: dropmode - sibling or child
*     @param: sourceGrid - target row  in row_sibling mode
*     @param: targetGrid - used for moving between grids (optional)
*     @returns: moved item ID
*     @edition: Professional
*     @topic: 2
*/
dhtmlXGridObject.prototype.moveRowTo=function(srowId,trowId,mode,dropmode,sourceGrid,targetGrid){
    var c=new dragContext((sourceGrid||this).isTreeGrid()?"treeGrid":"grid",(targetGrid||this).isTreeGrid()?"treeGrid":"grid",mode,dropmode||"sibling",srowId,trowId,sourceGrid||this,targetGrid||this);
    c.tobj._dragRoutine(c);
    c.close();
    return c.nid;
}

/**
*     @desc: enable drag without removing (copy instead of move)
*     @beforeInit: 1
*     @param: mode - 1 - on, 0 - off;
*     @type: public
*     @edition:Professional
*     @topic: 0
*/
dhtmlXGridObject.prototype.enableMercyDrag=function(mode){ this.dpcpy=dhx4.s2b(mode); };
//#}
//(c)dhtmlx ltd. www.dhtmlx.com

