/**
* nlstreeext_dd.js v.1.0.1
* NlsTree Extension : Drap-drop operations
* This file is property of AddObject.com
* You are not allowed to use this script or 
* part of this script indepently without any interaction 
* with NLSTree Professional.
* Copyright 2005, addObject.com. All Rights Reserved
* Author Jack Hermanto, www.addobject.com
*/

//global NlsDDSession object
var nlsddSession=null;

function NlsDDAction() {}
NlsDDAction.DD_INSERT="I";
NlsDDAction.DD_APPEND="A";

function NlsDDSession(sObj, sDt) {
  this.srcObj=sObj;
  this.srcData=sDt;
  this.destObj=null;
  this.destData=null;
  this.action=null;
  this.consume = function () {
    this.srcObj=null; this.srcData=null;this.destObj=null;this.destData=null;this.action=null;
  }
}

function NlsTreeDD(treeId) {
  this.tId = treeId;
  this.tree = nlsTree[treeId];
  this.tree.treeOnMouseUp = ddMouseUp;
  this.tree.treeOnMouseDown = ddMouseDown;
  this.tree.ddHandler=this;
  
  this.startDrag=startDrag;
  this.endDrag=endDrag;
  
  //public events
  this.onNodeDrag=onNodeDrag;
  this.onNodeDrop=onNodeDrop;
  
  //if (!NlsGetElementById("ddGesture")) {
  //  var el = document.createElement("div");
  //  el.setAttribute("id", "ddGesture");
  //  el.style.position="absolute";
  //  el.style.display="none";
  //  el.style.border="#f0f0f0 1px solid";
  //  document.body.appendChild(el);
  //}
  return this;
}

//======================================
//Public, put your drag drop code here
//======================================
function onNodeDrag(e) {
  if (e.shiftKey) {
    nlsddSession.action=NlsDDAction.DD_INSERT;
  } else {
    nlsddSession.action=NlsDDAction.DD_APPEND;
  }
}

//custom drop function
//you can override this function to perform your custom operation
function onNodeDrop(e) {
  //process
  if (!nlsddSession) return;
  if(!nlsddSession.action) return;

  if (nlsddSession.srcObj.tId==nlsddSession.destObj.tId) { //drag drop in a tree
    switch (nlsddSession.action) {
      case NlsDDAction.DD_INSERT:
        this.tree.moveChild(nlsddSession.srcData, nlsddSession.destData, 2);
        break;
      case NlsDDAction.DD_APPEND: 
        this.tree.moveChild(nlsddSession.srcData, nlsddSession.destData, 1);
        break;
    }
  } else { // drag drop between tree
    switch (nlsddSession.action) {
      case NlsDDAction.DD_INSERT:
        with (nlsddSession.srcData) { 
          nlsddSession.destObj.addBefore(null, nlsddSession.destData.orgId, capt, url, (ic?ic.join(","):ic), exp, chk, xtra); 
        } 
        nlsddSession.destObj.reloadNode(nlsddSession.destData.pr.orgId);
        break;
      case NlsDDAction.DD_APPEND: 
        with (nlsddSession.srcData) { 
          nlsddSession.destObj.append(null, nlsddSession.destData.orgId, capt, url, (ic?ic.join(","):ic), exp, chk, xtra); 
          nlsddSession.destObj.expandNode(nlsddSession.destData.orgId);
        } 
        break;
    }
  }
  
}

//========================================
//private, drag and drop events
//========================================
function startDrag(e) {
  var g=NlsGetElementById("ddGesture");
  var scrOffX = window.scrollX?window.scrollX:document.body.scrollLeft; //scrollLeft:IE, scrollX:MOZ
  var scrOffY = window.scrollY?window.scrollY:document.body.scrollTop; //scrollLeft:IE, scrollX:MOZ
  g.style.left=e.clientX+scrOffX+5+"px";
  g.style.top=e.clientY+scrOffY+5+"px";
  g.style.zIndex=1;
  if (g.style.display=="none") {
    var imgEl=NlsGetElementById("ic_"+nlsddSession.srcData.id);
    g.innerHTML="<table cellpadding=0 cellspacing=0><td><img src=\""+imgEl.src+"\"></td><td><a class=\""+this.tree.opt.stlprf+"node\">"+nlsddSession.srcData.capt+"</a></td></table>";
    g.style.display="";  
  }

  this.onNodeDrag(e);
}

function endDrag(e) {  
  //hide gesture  
  var g=NlsGetElementById("ddGesture");
  g.innerHTML="";
  g.style.display="none";
  
  //disable all DD related events
  document.onmousemove=null;
  document.onmouseup=null;
  document.onmousedown=function() { return true;}
  document.onselectstart=function() { return true;}
  document.onselectstart=function() { return true;}
  
  this.onNodeDrop(e);
}

//=========================================
//private, drag drop to nlstree integration
//=========================================
//end drag on tree node
//this refer to tree

//nlstree drap drop extension
NlsTree.prototype.ddHandler=null;

NlsTree.prototype.unloadChild = function(src) {
  var pr = src.pr;
  if (pr.lc.equals(src)) pr.lc=src.pv; 
  if (pr.fc.equals(src)) pr.fc=src.nx;
  if (src.pv!=null) src.pv.nx=src.nx; 
  if (src.nx!=null) src.nx.pv=src.pv;
  src.nx=null;src.pv=null;src.pr=null;
  if (this.selNd) {
    var tmp=this.selNd; while(tmp) { if (tmp.equals(src)) {this.selNd=null; return;} tmp=tmp.pr; }
  }
}

//move a node
//type: 1 append child 2: insert before, 3: insert after
NlsTree.prototype.moveChild = function (src, dest, type) {
  //validation
  if (!src || !dest) return;
  if (src.equals(dest)) return;
  var tmp=dest;
  while(tmp.pr) { if (tmp.equals(src)) return; tmp=tmp.pr; }
  
  switch (type) {
    case 1:
      if (src.equals(this.rt)) return;
      if (src.pr.equals(dest)) return
      //unreference source node
      var srcPr=src.pr;      
      this.unloadChild(src);
      this.reloadNode(srcPr.orgId);

      //add to new parent   
      src.pr=dest;
      if (dest.lc==null) {dest.fc=src;dest.lc=src;} else {
        var t=dest.fc;
        if (this.opt.sort!="no") { 
          do { if (this.opt.sort=="asc" ? this.compareNode(t, src) : this.compareNode(src, t)) break; t = t.nx;
          } while (t!=null);
          if (t!=null) { if (t.pv==null) { t.pv=src; dest.fc=src; } else { src.pv=t.pv; t.pv.nx=src; t.pv=src; } src.nx=t; }
        }
        if (this.opt.sort=="no" || t==null) { src.pv = dest.lc; dest.lc.nx = src; dest.lc = src; }
      }
      this.reloadNode(dest.orgId);
      this.expandNode(dest.orgId);
      break;
    case 2: //before
      if (dest.equals(this.rt)) return;
      if (src.nx && dest.equals(src.nx)) return;

      //unreference source node
      var srcPr=src.pr;
      this.unloadChild(src);
      this.reloadNode(srcPr.orgId);

      src.pr=dest.pr;
      if (dest.pv==null) { dest.pv=src; dest.pr.fc=src; } else { src.pv=dest.pv; dest.pv.nx=src; dest.pv=src; } src.nx=dest;
      this.reloadNode(dest.pr.orgId);
      break;
    case 3: //after
      if (dest.equals(this.rt)) return;
      if (src.pv && dest.equals(src.pv)) return;

      var srcPr=src.pr;
      this.unloadChild(src);
      this.reloadNode(srcPr.orgId);

      src.pr=dest.pr;
      if (dest.nx==null) { dest.nx=src; dest.pr.lc=src; } else { src.nx=dest.nx; dest.nx.pv=src; dest.nx=src; } src.pv=dest;
      this.reloadNode(dest.pr.orgId);
      break;
  }
}

function ddMouseUp(e) {
  var ndId=(e.srcElement?e.srcElement.id:e.target.id).split("_")[1];
  var nd = this.nLst[ndId];
  if (!nlsddSession) return false;
  nlsddSession.destObj=this;
  nlsddSession.destData=nd;
  this.ddHandler.endDrag(e);
  nlsddSession=null;
}

function ddMouseDown(e) {
  //initiate drag  
  var ddHd = this.ddHandler;
  var ndId=(e.srcElement?e.srcElement.id:e.target.id).split("_")[1];
  var nd = this.nLst[ndId];
  nlsddSession=new NlsDDSession(this, nd);
  
  document.onmousemove=function(ev) {ddHd.startDrag((ev?ev:event));}
  document.onmouseup=function(ev) {nlsddSession.action=null;ddHd.endDrag((ev?ev:event));}
  document.onselectstart=function() { return false;}
  document.onmousedown=function() { return false;}
  document.ondragstart=function() { return false;}
}
