/**
* 
* Copyright 2005, addObject.com. All Rights Reserved
* Author Jack Hermanto, www.addobject.com
*/
var nlsTree = new Object();

function NlsTree(tId, xNLSWidth) {
    this.tId = tId;
    this.opt = new StdOpt();
    this.ico = new StdIco("scripts/nlstree/img/");
    this.nLst = new Object();
    this.ctxMenu = null;
    this.nCtxMenu = new Object();
    this.tRef = "";
    this.rt = null;
    this.selNd = null;
    this.tmId = null;
    this.nCnt = 0;
    this.lgth = xNLSWidth;
    
    if (nlsTree[this.tId]!=null) {
        alert("The tree with id " + this.tId + " already exists, please change the tree id.");
    } else {
        nlsTree[this.tId] = this;
    }
    this.xmlOpn=function() { return "<tree id='"+this.tId+"' path='"+this.tRef+"'>\n";}
    this.xmlCls=function() { return "</tree>";}
    
    return this;
}

function StdIco(path) {
    this.pnb = path+"plusnb.gif";
    this.pb  = path+"plusb.gif";
    this.mnb = path+"minusnb.gif";
    this.mb  = path+"minusb.gif";
    this.opf = path+"folderopen2.gif";
    this.clf = path+"folder.gif";
    this.chd = path+"leaf.gif";
    this.rot = path+"root.gif";
    this.lnb = path+"lineang.gif";
    this.lb  = path+"lineints.gif";
    this.lin = path+"line.gif";
    this.bln = path+"blank.gif";
    this.xmlOpn = function() { 
        return "<icon>\n<plus>"+this.pnb+":"+this.pb+"</plus>\n"+
                 "<minus>"+this.mnb+":"+this.mb+"</minus>\n"+
                 "<ico>"+this.opf+":"+this.clf+"</ico>\n"+
                 "<chd>"+this.chd+"</chd>\n"+
                 "<root>"+this.rot+"</root>\n"+
                 "<line>"+this.lnb+":"+this.lb+":"+this.lin+"</line>\n"+
                 "<blank>"+this.bln+"</blank>\n"+
               "</icon>\n"; 
    }
    this.toString = function() { return "Standard Icons"}    
    return this;
}

function StdOpt() {
    this.trg = "_self";
    this.stlprf = "";
    this.sort = "asc"; //desc, no, asc
    this.icon = true;
    this.check = false;
    this.editable = false;
    this.selRow = true;
    this.editKey = 113;
    this.xmlOpn = function () { return "<option>\n<target>"+this.trg+"</target>\n<sort>"+this.sort+"</sort>\n<icon>"+this.icon+"</icon>\n<check>"+this.check+"</check>\n<editable>"+this.editable+"</editable>\n<editkey>"+this.editKey+"</editkey>\n<selrow>"+this.selRow+"</selrow>\n</option>\n";}
    return this;
}

function NlsNode(orgId, capt, url, ic, exp, chk, xtra, lgth) {
    this.orgId = orgId;
    this.id = "";
    this.alt = capt;
	this.lgth = lgth;
//<--- modded by csasp 
	if (this.lgth>0)
	{
		if (capt.length > lgth) 
			{
				capt = capt.substring(-1,lgth-3) + "...";
			}
	}
// --->
    this.capt = capt;
    this.url = (url==null || url=="") ? "javascript:void(0)" : url;
    this.ic = (ic==null || ic=="")?null:ic.split(",");
    this.exp = exp==null ? false : exp;
    this.chk = (chk?chk:false);
    this.xtra = xtra==null ? false : xtra;
    this.ctxMenu = null;

    this.nx = null; 
    this.pv = null; 
    this.fc = null; 
    this.lc = null; 
    this.pr = null;
    this.equals = function (nd) { return (this.id == nd.id); }
    this.xmlOpn = function () { return "<node id='"+this.id+"' alt='"+this.alt+"' caption='"+this.capt+"' url='"+this.url+"' ic='"+this.ic+"' exp='"+this.exp+"' chk='"+this.chk+"'>\n"; }
    this.xmlCls = function () { return "</node>\n"; }
    return this;
}

NlsTree.prototype.genIntId = function(id) { return this.tId+id; }
NlsTree.prototype.genOrgId = function(intId) { return intId.substr(this.tId.length); }
NlsTree.prototype.compareNode = function(aN, bN) { return (aN.capt >= bN.capt); }

NlsTree.prototype.add = function(id, prn, capt, url, ic, exp, chk, xtra, lgth) {	// lgth: added by csasp : max string length displayed (+ "...") for the 'capt' parameter
//    alert(lgth);
    var nNd = new NlsNode(((id==null||id=="")?("int"+ (++this.nCnt)):id), capt, url, ic, exp, chk, xtra, lgth);
    nNd.id = this.genIntId(nNd.orgId);
    if (this.nLst[nNd.id]!=null) { alert("Item with id " + id + " already exist"); return; }
	nNd.lgth = lgth;
//    alert("coucou "+nNd.lgth);
    this.nLst[nNd.id] = nNd;
    if (this.rt==null) { this.rt = nNd; } else {
        var pnd = this.nLst[this.genIntId(prn)];
        if (pnd==null ) { alert("Parent node " + prn + " not found!! (id: " + id + "; Node: " + capt +")"); return; }
        nNd.pr = pnd;
        if (pnd.lc==null) {
            pnd.fc = nNd; pnd.lc = nNd; 
        } else {
            var t=pnd.fc;
            if (this.opt.sort!="no") { 
                do {
                    if (this.opt.sort=="asc" ? this.compareNode(t, nNd) : this.compareNode(nNd, t)) break;
                    t = t.nx;
                } while (t!=null);
                if (t!=null) {
                    if (t.pv==null) { t.pv=nNd; pnd.fc=nNd; } else { nNd.pv=t.pv; t.pv.nx=nNd; t.pv=nNd; }
                    nNd.nx=t;
                }
            }
            if (this.opt.sort=="no" || t==null) { nNd.pv = pnd.lc; pnd.lc.nx = nNd; pnd.lc = nNd; }
        }
    }
    return nNd;
}

NlsTree.prototype.append = function(id, prn, capt, url, ic, exp, chk, xtra, lgth) {
    var nd = this.add(id, prn, capt, url, ic, exp, chk, xtra, lgth);
    this.reloadNode(prn);
    return nd;
}

NlsTree.prototype.remove = function(id) {
    var rNd = (id!=null ? this.nLst[this.genIntId(id)] : this.selNd);
    if (rNd!=null) {
        if (this.rt.equals(rNd)) { this.rt=null; this.nLst=new Object(); this.selNd=null; return rNd};
        if (rNd.equals(this.selNd)) this.selNd = null;
        var pr = rNd.pr;
        if (pr.lc.equals(rNd)) pr.lc=rNd.pv; 
        if (pr.fc.equals(rNd)) pr.fc=rNd.nx;
        if (rNd.pv!=null) rNd.pv.nx=rNd.nx; 
        if (rNd.nx!=null) rNd.nx.pv=rNd.pv;
        rNd.next=null;rNd.pv=null;rNd.pr=null;
        this.loopTree(rNd, "this.nLst[sNd.id]=null");
        this.reloadNode(this.genOrgId(pr.id));
    }
    return rNd;
}

NlsTree.prototype.getSelNode = function() {
    return this.selNd;
}

NlsTree.prototype.genANode = function(sNd) {
    var ev=""; var st=""; var cm=""; var treeName=this.tRef + "nlsTree." + this.tId;
    var ip = (sNd.nx!=null? this.ico.lb: this.ico.lnb);
    var sv = treeName + ".selectNode(\"" + sNd.id + "\");";
    var cm = treeName + ".contextMenu(\"" + sNd.id + "\");";
    var cn = treeName + ".checkNode(\"" + sNd.id + "\");";
    if (sNd.fc) {
        ev = treeName + ".toggleNode(\"" + sNd.id + "\");";
        st = treeName + ".selNToggle(\"" + sNd.id + "\");";
        ip = (sNd.nx!=null? (sNd.exp?this.ico.mb:this.ico.pb): (sNd.exp?this.ico.mnb:this.ico.pnb));
    } else sNd.exp=false;
    
    	
	if (sNd.lgth<0)
		{
		    var s = (sNd.pr==null ? "": "<img id=ip_" + sNd.id + " style='vertical-align:bottom' src='" + ip + "' " + (sNd.fc==null ? "" : "onclick='"+ ev +"'") + ">") +
		        (this.opt.icon || sNd.equals(this.rt) ? "<img id=ic_" + sNd.id + " style='vertical-align:bottom' src='" + (sNd.ic!=null? sNd.ic[0]:(sNd.fc!=null)?this.ico.clf:this.ico.chd)  + "' onclick='"+ sv + treeName + ".treeOnClick();' ondblclick='" + st + treeName + ".treeOnDblClick()' onmouseover='" + treeName + ".treeOnMouseOver()' onmousemove='"+ treeName +".treeOnMouseMove()' onmouseout='"+ treeName +".treeOnMouseOut()' >" : "") +
		        (this.opt.check ? "<input type='checkbox' id=cb_" + sNd.id + " " + (sNd.chk?"checked":"") + " onclick='" + cn + treeName + ".treeOnCheck()'>" : "") +
		        "</td>\n<td valign=middle >\n<a target=\"" + this.opt.trg + "\" href=\"" + sNd.url + "\" id=ac_" + sNd.id + " class='"+this.opt.stlprf+"node' unselectable='on' onclick='" + sv + treeName + ".treeOnClick();' oncontextmenu='return "+ cm +"' ondblclick='" + st + treeName + ".treeOnDblClick()' onmouseover='" + treeName + ".treeOnMouseOver()' onmousemove='"+ treeName +".treeOnMouseMove()' onmouseout='"+ treeName +".treeOnMouseOut()' onkeyup='"+treeName+".liveNodePress(event)'>\n" + sNd.capt + "\n</a>\n</td>\n"
		}
	else
		{
		    var s = (sNd.pr==null ? "": "<img id=ip_" + sNd.id + " style='vertical-align:bottom' src='" + ip + "' " + (sNd.fc==null ? "" : "onclick='"+ ev +"'") + ">") +
		        (this.opt.icon || sNd.equals(this.rt) ? "<img id=ic_" + sNd.id + " style='vertical-align:bottom' src='" + (sNd.ic!=null? sNd.ic[0]:(sNd.fc!=null)?this.ico.clf:this.ico.chd)  + "' onclick='"+ sv + treeName + ".treeOnClick();' ondblclick='" + st + treeName + ".treeOnDblClick()' onmouseover='" + treeName + ".treeOnMouseOver()' onmousemove='"+ treeName +".treeOnMouseMove()' onmouseout='"+ treeName +".treeOnMouseOut()' >" : "") +
		        (this.opt.check ? "<input type='checkbox' id=cb_" + sNd.id + " " + (sNd.chk?"checked":"") + " onclick='" + cn + treeName + ".treeOnCheck()'>" : "") +
		        "</td>\n<td valign=middle nowrap>\n<a target=\"" + this.opt.trg + "\" href=\"" + sNd.url + "\" id=ac_" + sNd.id + " class='"+this.opt.stlprf+"node' unselectable='on' onclick='" + sv + treeName + ".treeOnClick();' oncontextmenu='return "+ cm +"' ondblclick='" + st + treeName + ".treeOnDblClick()' onmouseover='" + treeName + ".treeOnMouseOver()' onmousemove='"+ treeName +".treeOnMouseMove()' onmouseout='"+ treeName +".treeOnMouseOut()' onkeyup='"+treeName+".liveNodePress(event)'>\n" + sNd.capt + "\n</a>\n</td>\n"
		}
    var n=sNd.pr;
    while (n != null && !n.equals(this.rt)) {
        s = "<img style='vertical-align:bottom' src='"+(n.nx!=null ? this.ico.lin : this.ico.bln)+"'>\n" + s;
        n=n.pr;
    }
    s="<td nowrap align=left>\n"+s;
    s="<table cellpadding='0' cellspacing='0' border='0'>\n<tr>\n" + s + "\n</tr>\n</table>\n";
    if (sNd.ctxMenu && sNd.ctxMenu.mId) s += sNd.ctxMenu.genMenu();
    return s;
}

NlsTree.prototype.genNodes = function(sNd, incpar) {
    var s = incpar ? ("<div id='"+sNd.id+"' class='"+this.opt.stlprf+"row'>\n" + this.genANode(sNd) +
            "\n</div>\n<div style='display:" + (sNd.fc && sNd.exp?"block":"none") + "' id='ch_" + sNd.id + "'>\n") : "";
    if (sNd.fc !=null) {
        var chNode = sNd.fc;
        do {
            s=s+this.genNodes(chNode, true);
            chNode = chNode.nx;
        } while (chNode != null)
    }
    s= incpar ? (s+"</div>") : s;
    return s;
}

NlsTree.prototype.showTree = function() {
    return this.genNodes(this.rt, true) + 
        "<input id='ndedt"+this.tId+"' type='text' class='"+this.opt.stlprf+"nodeedit' style='display:none' value='' onblur='nlsTree."+this.tId+".liveNodeWrite()' onkeypress='nlsTree."+this.tId+".liveNodePress(event)'>\n" +
        (this.ctxMenu ? this.ctxMenu.genMenu() : "");
}

NlsTree.prototype.reloadNode = function(id) {
    var intId = this.genIntId(id);
    var s = this.genNodes(this.nLst[intId], false);
    var dvN = NlsGetElementById("ch_"+intId);
    dvN.innerHTML = s;
    if (dvN.innerHTML=="") dvN.style.display="none";
    s = this.genANode(this.nLst[intId]);
    dvN = NlsGetElementById(intId);
    dvN.innerHTML = s;
    if (this.selNd!=null) {var sId=this.selNd.id; this.selNd=null; this.selectNode(sId); }
}

NlsTree.prototype.selNToggle = function(id) {
    this.toggleNode(id); //this.selectNode(id);
    if (this.tmId!=null) { clearTimeout(this.tmId); this.tmId=null; }
}

NlsTree.prototype.selectNode = function (id) {
    if (this.opt.editable) {
        if (this.selNd!=null && this.selNd.id==id) { this.tmId=setTimeout("nlsTree."+this.tId+".liveNodeEdit('"+id+"')", 1000); }
        if (NlsGetElementById("ndedt"+this.tId).style.display=="") NlsGetElementById("ndedt"+this.tId).style.display="none";
    }
    var ac=null;var ic=null;var sNd=null;
    sNd = this.selNd;
    if (sNd!=null) {
        if (this.opt.selRow) NlsGetElementById(sNd.id).className = this.opt.stlprf+"row";
        ac = NlsGetElementById("ac_" + sNd.id);
        if (this.opt.icon) { ic = NlsGetElementById("ic_" + sNd.id); ic.src = sNd.ic!=null ? sNd.ic[0] :(sNd.fc!=null?this.ico.clf:this.ico.chd); }    
        ac.className = this.opt.stlprf+"node";
    }
    sNd = this.nLst[id];
    this.selNd = sNd;
    if (this.opt.selRow) NlsGetElementById(id).className = this.opt.stlprf+"selrow"; 
    ac = NlsGetElementById("ac_" + id);
    if (this.opt.icon) 
    	{ 
//    		alert("ic_" + id); 
    		ic = NlsGetElementById("ic_" + id); 
//    		ic.src = sNd.ic!=null ? (sNd.ic[1]!=null?sNd.ic[1]:sNd.ic[0]) : (sNd.fc!=null?this.ico.opf:this.ico.chd); 
    		 
    		if (sNd.ic!=null)
    		{
    			if (sNd.ic[1]!=null)
	    			{
	    			 	ic.src = sNd.ic[1];
	    			}
    			else
    				{
    					ic.src = sNd.ic[0];
    				}
    		}
    		else 
    		{
    			if (sNd.fc!=null)
    			{
    				ic.src = this.ico.opf;
    			}
    			else
    			{
    				ic.src = this.ico.chd;
    			}
    		} 
    	}
    ac.className = this.opt.stlprf+"selnode";
    ac.focus();
}

NlsTree.prototype.toggleNode = function(id) {;
    var nd = NlsGetElementById("ch_" + id);
    var ip = NlsGetElementById("ip_" + id);
    var sNd = this.nLst[id];
    if (sNd.exp) {
        sNd.exp = false;
        nd.style.display="none";
        if (ip!=null && sNd.fc!=null) ip.src=sNd.nx ? this.ico.pb : this.ico.pnb;
    } else {
        sNd.exp = true;
        nd.style.display="block";
        if (ip!=null && sNd.fc!=null) ip.src=sNd.nx ? this.ico.mb : this.ico.mnb;
    }
}

NlsTree.prototype.checkNode = function(id) {
    var nd = NlsGetElementById("cb_" + id);
    var sNd = this.nLst[id];
    sNd.chk = nd.checked;
}

NlsTree.prototype.setNodeCaption = function(id, capt) {
    var intId = this.genIntId(id);
    var nd = NlsGetElementById("ac_" + intId);
    var sNd = this.nLst[intId];
    nd.innerHTML = capt;
    sNd.capt = capt;
}

NlsTree.prototype.getNodeById = function(id) {
  return this.nLst[this.genIntId(id)]
}

NlsTree.prototype.setGlobalCtxMenu = function(ctx) {
  this.ctxMenu = ctx;
  ctx.container=this;
}

NlsTree.prototype.setNodeCtxMenu = function(id, ctx) {
  var nd = this.nLst[this.genIntId(id)];
  nd.ctxMenu = ctx;
  if (ctx.mId) ctx.container=this;
}

NlsTree.prototype.contextMenu = function(id) {
    var sNd=this.nLst[id]; var ctx=null;
    if (sNd.ctxMenu && sNd.ctxMenu.mId) ctx=sNd.ctxMenu; else 
    if (sNd.ctxMenu=="DEFAULT") ctx=null; else
    if (sNd.ctxMenu=="NONE") return false; else ctx=this.ctxMenu;
    if (!ctx) return true;
    this.selectNode(id);
    if (this.tmId) clearTimeout(this.tmId);
    var ac = NlsGetElementById("ac_" + id);
    var x=0,y=0,elm=ac;
    while(elm.nodeName!="BODY") { x += elm.offsetLeft; y+=elm.offsetTop; elm=elm.offsetParent; }
    ctx.showMenu(x, y+ac.offsetHeight);
    return false;
}

NlsTree.prototype.loopTree = function(sNd, act) {
    eval(act);
    if (sNd.fc !=null) {
        var chNode = sNd.fc;
        do {
            this.loopTree(chNode, act);
            chNode = chNode.nx;
        } while (chNode != null)
    }
}

NlsTree.prototype.nodeXML = function(sNd) {
    sNd=(sNd==null?this.rt:sNd);
    var n=sNd; var spc="";
    while (n != null && !n.equals(this.rt)) { spc+="  "; n=n.pr;}    
    var s=(spc+sNd.xmlOpn()+"\n");
    if (sNd.fc !=null) {
        var chNode = sNd.fc;
        do {
            s+=this.nodeXML(chNode);
            chNode = chNode.nx;
        } while (chNode != null)
    }
    s+=(spc+sNd.xmlCls()+"\n");
    return s;
}

NlsTree.prototype.toXML = function() {
    return this.xmlOpn() + this.opt.xmlOpn() + this.ico.xmlOpn() + this.nodeXML(this.rt) + this.xmlCls();
}

NlsTree.prototype.liveNodeEditStart = function(id) {
  this.tmId = setTimeout("nlsTree."+this.tId+".liveNodeEdit('"+id+"')", 0)
}

NlsTree.prototype.liveNodeEdit = function(id) {
    if (this.tmId!=null) {
        var edt = NlsGetElementById("ndedt"+this.tId);
        var ac = NlsGetElementById("ac_" + id);
        var x=0,y=0,elm=ac;
        while(elm.nodeName!="BODY") { x += elm.offsetLeft; y+=elm.offsetTop; elm=elm.offsetParent; }
        edt.style.top=y;
        edt.style.left=x;
        edt.style.display="";
        edt.focus();
        edt.value = ac.innerHTML;
        this.tmId = null;
    }
}

NlsTree.prototype.liveNodeWrite = function() {
    var edt = NlsGetElementById("ndedt"+this.tId);
    if (edt.style.display=="none") return;
    var ac = NlsGetElementById("ac_" + this.selNd.id);
    if (edt.value != "") ac.innerHTML=edt.value;
    edt.style.display="none";
}

NlsTree.prototype.liveNodePress = function(e) {
    if (!this.opt.editable) return;
    if (e.keyCode==13) {
        NlsGetElementById("ndedt"+this.tId).blur(); 
        NlsGetElementById("ac_" + this.selNd.id).focus();
    } else if(e.keyCode==27) {
        NlsGetElementById("ndedt"+this.tId).style.display="none";
        NlsGetElementById("ac_" + this.selNd.id).focus();
    } else if(e.keyCode==this.opt.editKey) {//f2
        this.tmId = setTimeout("nlsTree."+this.tId+".liveNodeEdit('"+this.selNd.id+"')", 10);
    }
}

NlsTree.prototype.treeOnClick = function() { /*PUT YOUR CODE HERE OR ASSIGN NEW EVENT HANDLER*/ }
NlsTree.prototype.treeOnDblClick = function() { /*PUT YOUR CODE HERE OR ASSIGN NEW EVENT HANDLER*/ }
NlsTree.prototype.treeOnMouseOver = function () { /*PUT YOUR CODE HERE OR ASSIGN NEW EVENT HANDLER*/ }
NlsTree.prototype.treeOnMouseMove = function () { /*PUT YOUR CODE HERE OR ASSIGN NEW EVENT HANDLER*/ }
NlsTree.prototype.treeOnMouseOut = function () { /*PUT YOUR CODE HERE OR ASSIGN NEW EVENT HANDLER*/ }
NlsTree.prototype.treeOnCheck = function () { /*PUT YOUR CODE HERE OR ASSIGN NEW EVENT HANDLER*/ }


/**Cross browser related methods*/
function NlsGetElementById(id) {
    if (document.all) {
        return document.all(id);
    } else
    if (document.getElementById) {
        return document.getElementById(id);
    }
}