/**
** nlstreeext_v1.js
** NLSTree Professional Extension for Standard Context Menu Operation
** 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
** Note: nlstree.js is required
*/

var nlsClipboard = new NlsClipboard();
function NlsClipboard(act, cnt) {
  this.clAction=act;
  this.clContent=cnt;
  this.consume = function() {
    this.clAction=null;
    this.clContent=null;
  }
  return this;
}

function cut(nd) {
  nlsClipboard.clAction="CUT";
  nlsClipboard.clContent=nd;
}

function copy(nd) {
  nlsClipboard.clAction="COPY";
  var newNd = new NlsNode("", nd.capt, nd.url);
  newNd.ic = nd.ic;
  newNd.xtra = nd.xtra;
  newNd.chk = nd.chk;
  newNd.ctxMenu = nd.CtxMenu;
  nlsClipboard.clContent=newNd;
}

function insertBefore(tree, nd) {
  if (!nlsClipboard || !nlsClipboard.clAction) return;
  switch(nlsClipboard.clAction) {
    case "CUT":
      if (!tree.nLst[nlsClipboard.clContent.id])  { nlsClipboard.consume(); return; }
      var rNd = tree.ctx_moveChild(nlsClipboard.clContent, nd,  2);  
      if (rNd) { tree.selectNode(rNd.id); nlsClipboard.consume(); }
      break;
    case "COPY":
      var newNd = tree.ctx_appendChild(nlsClipboard.clContent, nd, 2);
      if (newNd) tree.selectNode(newNd.id);
      break;
  }
}

function insertAfter(tree, nd) {
  if (!nlsClipboard || !nlsClipboard.clAction) return;
  switch(nlsClipboard.clAction) {
    case "CUT":
      if (!tree.nLst[nlsClipboard.clContent.id])  { nlsClipboard.consume(); return; }
      var rNd = tree.ctx_moveChild(nlsClipboard.clContent, nd,  3);
      if (rNd) { tree.selectNode(rNd.id); nlsClipboard.consume();}
      break;
    case "COPY":
      var newNd = tree.ctx_appendChild(nlsClipboard.clContent, nd, 3);
      if (newNd) tree.selectNode(newNd.id);
      break;
  }
}

function insertAsChild(tree, nd) {
  if (!nlsClipboard || !nlsClipboard.clAction) return;
  switch(nlsClipboard.clAction) {
    case "CUT":
      if (!tree.nLst[nlsClipboard.clContent.id])  { nlsClipboard.consume(); return; }
      var rNd = tree.ctx_moveChild(nlsClipboard.clContent, nd, 1);
      if (rNd) { tree.selectNode(rNd.id); nlsClipboard.consume(); }
      break;
    case "COPY":
      var newNd = tree.ctx_appendChild(nlsClipboard.clContent, nd, 1);
      tree.expandNode(nd.orgId);
      if (newNd) tree.selectNode(newNd.id);
      break;
  }
}

NlsTree.prototype.ctx_liveAdd = function (prId) {
  var selNode=this.nLst[this.genIntId(prId)];
  this.expandNode(selNode.orgId);
    var newNode = this.append(
        "",
        selNode.orgId,
        "New Node",
        "",
        "",
        false
    );
  this.selectNode(newNode.id);
  this.liveNodeEditStart(newNode.id);  
}

NlsTree.prototype.ctx_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; }
  }
}

NlsTree.prototype.ctx_appendChild = function (src, dest, type) {
  if (!src || !dest) return;
  var newNd = null;
  switch(type) {
    case 1:
      newNd = this.append(src.orgId, dest.orgId, src.capt, src.url, (src.ic?src.ic.join(","):""), src.exp, src.chk, src.xtra);
      if (src.ctxMenu) this.setNodeCtxMenu(newNd.orgId, src.ctxMenu);
      break;
    case 2:
      if (dest.equals(this.rt)) return;
      var newNd = new NlsNode("int"+ (++this.nCnt), src.capt, src.url, (src.ic?src.ic.join(","):""), src.exp, src.chk, src.xtra);
      newNd.id = this.genIntId(newNd.orgId);
      this.nLst[newNd.id] = newNd;

      newNd.pr=dest.pr;
      if (dest.pv==null) { dest.pv=newNd; dest.pr.fc=newNd; } else { newNd.pv=dest.pv; dest.pv.nx=newNd; dest.pv=newNd; } newNd.nx=dest;
      this.reloadNode(dest.pr.orgId);
      break;
    case 3:
      if (dest.equals(this.rt)) return;
      var newNd = new NlsNode("int"+ (++this.nCnt), src.capt, src.url, (src.ic?src.ic.join(","):""), src.exp, src.chk, src.xtra);
      newNd.id = this.genIntId(newNd.orgId);
      this.nLst[newNd.id] = newNd;

      newNd.pr=dest.pr;
      if (dest.nx==null) { dest.nx=newNd; dest.pr.lc=newNd; } else { newNd.nx=dest.nx; dest.nx.pv=newNd; dest.nx=newNd; } newNd.pv=dest;
      this.reloadNode(dest.pr.orgId);
      break;
  }
  return newNd;
}

//type: 1 append child 2: insert before, 3: insert after
NlsTree.prototype.ctx_moveChild = function (src, dest, type) {
  //validation
  if (!src || !dest) return;
  if (src.equals(dest)) return;
  
  switch (type) {
    case 1:
      if (src.equals(this.rt)) return;
      if (src.pr.equals(dest)) return
      var tmp=dest;
      while(tmp.pr) { if (tmp.equals(src)) return; tmp=tmp.pr; }
      //unreference source node
      var srcPr=src.pr;      
      this.ctx_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.ctx_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.ctx_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;
  }
  return src;
}


