﻿// JScript File
var eNodeType = {
    link            :  1,   // 0x00000001
    ghostCheck      :  2,   // 0x00000010
    check           :  4    // 0x00000100
}

var eNodeBehavior = {
    none            :  0,   // 0x00000000
    parentUpdate    :  1,   // 0x00000001
    childUpdate     :  2    // 0x00000010
}

var eNodeState = {
    unChecked       :  1,   // 0x00000001
    ghostChecked    :  2,   // 0x00000010
    checked         :  4    // 0x00000100
}    

function JTreeNode(strId, strName, strUrl, strTitle, strTarget, fIsOpen, fIsChecked, nLevel) 
{
    this.m_oType        = eNodeType.link | eNodeType.check;
    this.m_oBehavior    = eNodeBehavior.parentUpdate;

    this.m_strId        = (!_isUndefined(strId))?strId.toString():"root";
    this.m_strName      = (!_isUndefined(strName))?strName.toString():"";
    this.m_strUrl       = (!_isUndefined(strUrl))?strUrl.toString():"";
    this.m_strTitle     = (!_isUndefined(strTitle))?strTitle.toString():"";
    this.m_strTarget    = (!_isUndefined(strTarget))?strTarget.toString():"";
    this.m_strCount     = "";
    this.m_nLevel       = (!_isUndefined(nLevel))?nLevel:0;

    this.m_oParentNode  = null;
    this.m_oChildNodes  = [];

    this.m_oIcon        = {
        base            :   null,
        open            :   null,
        unChecked       :   null,
        ghostChecked    :   null,
        checked         :   null
    };

    this.m_fIsOpen      = fIsOpen || false;
    this.m_fIsChecked   = (fIsChecked || false)?eNodeState.checked:eNodeState.unChecked;

    this.m_fIsSelected      = false;;
    this.m_fIsLastSibling   = true;
    
    this.isRoot         = function() { return (this.m_strId == 'root'); }
    
    this.setId          = function(strId) { this.m_strId = (!_isUndefined(strId))?strId.toString():""; return this; }
    this.getId          = function() { return this.m_strId; }
    this.setName        = function(strName) { this.m_strName = (!_isUndefined(strName))?strName.toString():""; return this; }
    this.setUrl         = function(strUrl) { this.m_strUrl = (!_isUndefined(strUrl))?strUrl.toString():""; return this; }
    this.setTitle       = function(strTitle) { this.m_strTitle = (!_isUndefined(strTitle))?strTitle.toString():""; return this; }
    this.setTarget      = function(strTarget) { this.m_strTarget = (!_isUndefined(strTarget))?strTarget.toString():""; return this; }
    this.setCount       = function(strCount) { this.m_strCount = (!_isUndefined(strCount))?strCount.toString():""; return this; }
    this.setType        = function(oType) { this.m_oType = (!_isUndefined(oType))?oType:eNodeType.link; return this; }
    this.setBehavior    = function(oBehavior) { this.m_oBehavior = (!_isUndefined(oBehavior))?oBehavior:eNodeBehavior.parentUpdate; return this; }
    this.getBehavior    = function() { return this.m_oBehavior; }
    this.setLevel       = function(nLevel) { this.m_nLevel = (!_isUndefined(nLevel))?nLevel:0; return this; }
    this.getLevel       = function() { return this.m_nLevel; }

    this.setParent      = function(oNode) { this.m_oParentNode = (!_isUndefined(oNode))?oNode:null; if(this.m_oParentNode != null) this.setLevel(this.m_oParentNode.getLevel()+1); return this; }
    this.getParent      = function() { return this.m_oParentNode }
    this.addChild       = function(oNode) { if(_isUndefined(oNode)) return; if(this.m_oChildNodes.length > 0) this.m_oChildNodes[this.m_oChildNodes.length-1].lastSibling(false); this.m_oChildNodes.push(oNode); this.m_oChildNodes[this.m_oChildNodes.length-1].setParent(this).lastSibling(true); return this; }
    this.getChildNbr    = function() { return this.m_oChildNodes.length; }
    this.getChild       = function(nIdx) { if(this.m_oChildNodes.length < nIdx || nIdx < 0) return null; return this.m_oChildNodes[nIdx]; }
    
    this.open           = function(fIsOpen) { if(!_isUndefined(fIsOpen)) this.m_fIsOpen = fIsOpen; return this.m_fIsOpen; }
    this.check          = function(fIsChecked) { if(!_isUndefined(fIsChecked)) this.m_fIsChecked = fIsChecked; return this.m_fIsChecked; }
    this.select         = function(fIsSelected) { if(!_isUndefined(fIsSelected)) this.m_fIsSelected = fIsSelected; return this.m_fIsSelected; }
    this.lastSibling    = function(fIsLastSibling) { if(!_isUndefined(fIsLastSibling)) this.m_fIsLastSibling = fIsLastSibling; return this.m_fIsLastSibling; }
    this.haveChild      = function() { return this.m_oChildNodes.length > 0; }
}

JTreeNode.prototype.toString = function(oTree) 
{
    var arrRet = new Array();
    try
    {
        var oConfig = oTree.config;

        if(!oConfig.showRoot && this.isRoot())
        {
            if(this.haveChild())
            {
                arrRet.push('<div id="d' + oTree.getName() + this.getId() + '" class="clip" style="display:' + ((this.isRoot() || this.open()) ? 'block' : 'none') + ';">');
                for(var nIdx = 0, nCnt = this.m_oChildNodes.length; nIdx < nCnt; nIdx++)
                    arrRet.push(this.m_oChildNodes[nIdx].toString(oTree));
                arrRet.push('</div>');
            }
            return arrRet.join('');
        }
        
        if(!this.isRoot() && this.m_oParentNode && oTree.config.useLines)
            oTree.m_arrIndent.push( !this.lastSibling() );
            
        arrRet.push('<div class="' + ((!this.isRoot() || oConfig.showRoot)?'node':'noRoot') + '">');
    
        if(oConfig.showCount)
            arrRet.push('<table cellspacing="0" cellpadding="0" border="0" class="nodeTbl"><tr><td class="nodeTxt" nowrap><div class="nodeTxt">');
            
        arrRet.push(oTree.getIndent(this));

        if(oConfig.useIcons) 
        {
            var oIcons = oTree.defaultIcon;

            if(!this.m_oIcon.base)
                this.m_oIcon.base = (this.isRoot())?oIcons.root: ((this.haveChild())?oIcons.folder:oIcons.node);

            if(!this.m_oIcon.open)
                this.m_oIcon.open = (this.isRoot())?oIcons.root: ((this.haveChild())?oIcons.folderOpen:oIcons.node);

            arrRet.push('<img id="i' + oTree.getName() + this.getId() + '" src="' + ((this.open()) ? this.m_oIcon.open : this.m_oIcon.base) + '" alt="" />');
	       }
    	   
	       if( (oConfig.useCheckboxes || oConfig.useRadios) && (((this.m_oType & eNodeType.check) == eNodeType.check) || ((this.m_oType & eNodeType.ghostCheck) == eNodeType.ghostCheck))) 
        {
            var oIconPool = (oConfig.useRadios)?oTree.defaultIcon.radio:oTree.defaultIcon.checkbox;
        
            if (!this.m_oIcon.unChecked)
            {
                if((this.m_oType & eNodeType.check) == eNodeType.check)
                    this.m_oIcon.unChecked = oIconPool.active.unchecked;
                else if((this.m_oType & eNodeType.ghostCheck) == eNodeType.ghostCheck)
                    this.m_oIcon.unChecked = oIconPool.inactive.unchecked;
            }
            
            if (!this.m_oIcon.ghostChecked)
            {
                if((this.m_oType & eNodeType.check) == eNodeType.check)
                    this.m_oIcon.ghostChecked = oIconPool.active.partial;
                else if((this.m_oType & eNodeType.ghostCheck) == eNodeType.ghostCheck)
                    this.m_oIcon.ghostChecked = oIconPool.inactive.partial;
            }

            if (!this.m_oIcon.checked)
            {
                if((this.m_oType & eNodeType.check) == eNodeType.check)
                    this.m_oIcon.checked = oIconPool.active.checked;
                else if((this.m_oType & eNodeType.ghostCheck) == eNodeType.ghostCheck)
                    this.m_oIcon.checked = oIconPool.inactive.checked;
            }

            if((this.m_oType & eNodeType.check) == eNodeType.check)
                arrRet.push('<a href="javascript: ' + oTree.getName() + '.toggleCheck(\'' + this.getId() + '\'); ' + oTree.getName() + '.onCheck(' + oTree.getName() + '.getNode(\'' + this.getId() + '\'));">');

            arrRet.push('<img id="c' + oTree.getName() + this.getId() + '" src="' + ((this.check() == eNodeState.unChecked)? this.m_oIcon.unChecked : ((this.check() == eNodeState.ghostChecked)? this.m_oIcon.ghostChecked : this.m_oIcon.checked)) + '" alt="" border="0" />');

            if((this.m_oType & eNodeType.check) == eNodeType.check)
                arrRet.push('</a>');
        }

        arrRet.push('<a id="s' + oTree.getName() + this.getId() + '"');
        
        if(this.m_strUrl != "") 
            arrRet.push(' class="' + ((oConfig.useSelection) ? ((this.select() ? 'nodeSel' : 'node')) : 'node') + '" href="' + this.m_strUrl + '"');
        else if( this.haveChild() && !this.isRoot() && (!oConfig.useCheckboxes || ((this.m_oType & eNodeType.check) != eNodeType.check)))
            arrRet.push(' class="' + ((oConfig.useSelection) ? ((this.select() ? 'nodeSel' : 'node')) : 'node') + '" href="javascript: ' + oTree.getName() + '.toggleNode(' + this.getId() + '); ' + oTree.getName() + '.onOpen(' + oTree.getName() + '.getNode(\'' + this.getId() + '\'));"');
        else if(oConfig.useCheckboxes && ((this.m_oType & eNodeType.check) == eNodeType.check))
            arrRet.push(' class="' + ((oConfig.useSelection) ? ((this.select() ? 'nodeSel' : 'node')) : 'node') + '" href="javascript: ' + oTree.getName() + '.toggleCheck(\'' + this.getId() + '\'); ' + oTree.getName() + '.onCheck(' + oTree.getName() + '.getNode(\'' + this.getId() + '\'));"');            
        else
            arrRet.push(' class="' + ((oConfig.useSelection) ? ((this.select() ? 'nodeSel' : 'emptynode')) : 'emptynode') + '" name="' + oTree.getName() + this.getId() + '"');

        if(this.m_strTitle != "") 
            arrRet.push(' title="' + this.m_strTitle + '"');

        if(this.m_strTarget != "") 
            arrRet.push(' target="' + this.m_strTarget + '"');

        if(oConfig.useStatusText)
            arrRet.push(' onmouseover="window.status=\'' + this.m_strName + '\';return true;" onmouseout="window.status=\'\';return true;" ');

        if(oConfig.useSelection && ((this.haveChild() && oConfig.folderLinks) || !this.haveChild()))
            arrRet.push(' onclick="javascript: ' + oTree.getName() + '.highlightNode(' + this.getId() + ');"');

        arrRet.push('>');
            arrRet.push(this.m_strName);
        arrRet.push('</a>');

        if(oConfig.showCount)
        {
            arrRet.push('</div></td>');
            arrRet.push('<td class="nodeVal" nowrap><div class="nodeVal">' + ((this.m_strCount != "")?'(' + this.m_strCount + ')':'') + '</div></td></tr></table>');
        }
        arrRet.push('</div>');

        if(this.haveChild())
        {
            arrRet.push('<div id="d' + oTree.getName() + this.getId() + '" class="clip" style="display:' + ((this.isRoot() || this.open()) ? 'block' : 'none') + ';">');
            for(var nIdx = 0, nCnt = this.m_oChildNodes.length; nIdx < nCnt; nIdx++)
                arrRet.push(this.m_oChildNodes[nIdx].toString(oTree));
            arrRet.push('</div>');
        }
                
        if(!this.isRoot() && this.m_oParentNode && oTree.config.useLines)
            oTree.m_arrIndent.pop();
    }
    catch(e)
    {
        //console.error(e);
    }
    return arrRet.join('');
};



// Tree object
function JTree(strObjName) 
{
    this.config = 
    {
        target					     : null,
		      folderLinks			  : true,
        useSelection		  : false,
        useLines				    : true,
        useIcons				    : true,
        useCheckboxes		 : false,
        useRadios		     : false,
        useStatusText		 : false,
        closeSameLevel	 : false,
        inOrder					    : false,
        showRoot		      : true,
        showCount       : false
    };

    this.defaultIcon = 
    {
        root				                            : 'img/widgets/base.gif',
        folder			                           : 'img/widgets/folder.gif',
        folderOpen	                         : 'img/widgets/folderopen.gif',
        checkbox                            : {
            active                              : {
                unchecked                           : "img/widgets/check-active.gif",
                partial                             : "img/widgets/check-active-partial.gif",
                checked                             : "img/widgets/check-active-checked.gif"
            },
            inactive                            : {
                unchecked                           : "img/widgets/check-inactive.gif",
                partial                             : "img/widgets/check-inactive-partial.gif",
                checked                             : "img/widgets/check-inactive-checked.gif"
            }
        },
        radio                               : {
            active                              : {
                unchecked                           : "img/widgets/radio-active.gif",
                partial                             : "img/widgets/radio-active-partial.gif",
                checked                             : "img/widgets/radio-active-checked.gif"
            },
            inactive                            : {
                unchecked                           : "img/widgets/radio-inactive.gif",
                partial                             : "img/widgets/radio-inactive-partial.gif",
                checked                             : "img/widgets/radio-inactive-checked.gif"
            }
        },
        node				                            : 'img/widgets/page.gif',
        empty				                           : 'img/widgets/empty.gif',
        line				                            : 'img/widgets/line.gif',
        join				                            : 'img/widgets/join.gif',
        joinBottom	                         : 'img/widgets/joinbottom.gif',
        plus				                            : 'img/widgets/plus.gif',
        plusBottom	                         : 'img/widgets/plusbottom.gif',
        minus				                           : 'img/widgets/minus.gif',
        minusBottom	                        : 'img/widgets/minusbottom.gif',
        nlPlus			                           : 'img/widgets/nolines_plus.gif',
        nlMinus			                          : 'img/widgets/nolines_minus.gif'
    };

    this.m_strObjName   = strObjName;
    this.m_idxNodes     = new Object();

    this.m_oRoot        = new JTreeNode();
    this.m_idxNodes["m_root"] = this.m_oRoot;
    
    this.m_oOrphanNodes = [];

    this.m_arrIndent    = [];

    this.m_oSelNode     = null;
    
    this.getName        = function() { return this.m_strObjName; }
    
    this.m_nNodeCnt     = 0;
}

JTree.prototype.add = function(strParentId, strId, strName, strUrl, strTitle, strTarget, fIsOpen, fIsChecked) 
{
    return this.addNode(strParentId, new JTreeNode(strId, strName, strUrl, strTitle, strTarget, fIsOpen, fIsChecked));
}
JTree.prototype.push = function(strParentId, strId, strName, strUrl, strTitle, strTarget, fIsOpen, fIsChecked) 
{
    return this.addNode(strParentId, new JTreeNode(strId, strName, strUrl, strTitle, strTarget, fIsOpen, fIsChecked));
}
JTree.prototype.addNode = function(strParentId, oNode) 
{
    try
    {
        if(oNode.isRoot())
        {
            oNode.m_oChildNodes = this.m_oRoot.m_oChildNodes;
            this.m_oRoot = oNode;
            this.m_idxNodes["m_root"] = this.m_oRoot;
            return;
        }
    
        var oParentNode = this.m_idxNodes["m_" + ((strParentId == "")?"root":strParentId)];
        if(!oParentNode)
        {
            this.m_oOrphanNodes.push(oNode);
            this.m_idxNodes["m_" + ((oNode.getId() == "")?"root":oNode.getId())] = this.m_oOrphanNodes[this.m_oOrphanNodes.length-1];
            return;
        }
        oParentNode.addChild(oNode);
        this.m_idxNodes["m_" + ((oNode.getId() == "")?"root":oNode.getId())] = oNode;
    }
    catch(e)
    {
    }
    this.m_nNodeCnt++;
    return oNode;
}

JTree.prototype.getNode = function(strId) 
{
    return this.m_idxNodes["m_" + strId];
}

JTree.prototype.highlightNode = function(strNodeId) 
{
    if (!this.config.useSelection) 
	       return;

    var oNode = this.m_idxNodes["m_" + strNodeId];
    if(!oNode)
        return;

    if (oNode.haveChild() && !this.config.folderLinks) 
        return;

    if(this.m_oSelNode != null)
    {
        if (this.m_oSelNode.getId() != oNode.getId()) 
        {
            var eNode = $("s" + this.getName() + this.m_oSelNode.getId());
            if(eNode.name != "")
                eNode.className = "emptyNode";
            else                
                eNode.className = "node";
        }
    }
    var eNode = $("s" + this.getName() + oNode.getId());
    eNode.className = "nodeSel";
    
    this.m_oSelNode = oNode;
};


JTree.prototype.toggleNode = function(strNodeId) 
{
    var oNode = this.m_idxNodes["m_" + strNodeId];
    if(!oNode)
        return;
    
    oNode.open(!oNode.open());
    this.updateNodeStatus(oNode);

    if (this.config.closeSameLevel) 
        this.closeLevel(oNode.getId());
};

// Opens the tree to a specific node
JTree.prototype.openTo = function(strNodeId) 
{
    var oNode = this.m_idxNodes["m_" + strNodeId];
    if(!oNode)
        return;

    for(var oParent = oNode.getParent(); oParent != null && !oParent.isRoot(); oParent = oParent.getParent())
    {
        oParent.open(true);
        this.updateNodeStatus(oParent);
    }
};

// Closes all nodes on the same level as certain node
JTree.prototype.closeLevel = function(strNodeId) 
{
    var oNode = this.m_idxNodes["m_" + strNodeId];
    if(!oNode)
        return;

    for(var strKey in this.m_idxNodes)
    {
        if( _isFunction(this.m_idxNodes[strKey]) )
            continue;
            
        var oCurrNode = this.m_idxNodes[strKey];
        if(oCurrNode.getLevel() == oNode.getLevel() && oCurrNode.getId() != oNode.getId())
        {
            oCurrNode.open(false);
            this.updateNodeStatus(oCurrNode);
            this.closeChildren(oCurrNode.getId());
        }
    }
};

// Closes all children of a node
JTree.prototype.closeChildren = function(strNodeId) 
{
    var oNode = this.m_idxNodes["m_" + strNodeId];
    if(!oNode)
        return;

    for(var nIdx = 0, nCnt = oNode.getChildNbr(); nIdx < nCnt; nIdx++)
    {
        oNode.getChild(nIdx).open(false);
        this.updateNodeStatus(oNode.getChild(nIdx));
    }
}

JTree.prototype.updateNodeStatus = function(oNode) 
{
    var oDiv	= $('d' + this.getName() + oNode.getId());
    var oJoin	= $('j' + this.getName() + oNode.getId());

    if (this.config.useIcons && $('i' + this.getName() + oNode.getId())) 
        $('i' + this.getName() + oNode.getId()).src = (oNode.open()) ? oNode.m_oIcon.open : oNode.m_oIcon.base;

    if(oJoin)
    {
        oJoin.src = (this.config.useLines)?
        ((oNode.open())?((oNode.lastSibling())?this.defaultIcon.minusBottom:this.defaultIcon.minus):((oNode.lastSibling())?this.defaultIcon.plusBottom:this.defaultIcon.plus)):
        ((oNode.open())?this.defaultIcon.nlMinus:this.defaultIcon.nlPlus);
    }
    
    if(oDiv)
        oDiv.style.display = (oNode.open()) ? 'block': 'none';
};

JTree.prototype.toggleCheck = function(strNodeId, fIsAuto) 
{
    var oNode = this.m_idxNodes["m_" + strNodeId];
    if(!oNode)
        return;
    
    var fIsChildCheck = false;
    for(var nIdx = 0, nCnt = oNode.getChildNbr(); nIdx < nCnt && !fIsChildCheck; nIdx++)
        fIsChildCheck = (oNode.getChild(nIdx).check() != eNodeState.unChecked);

    if(fIsAuto || false)
    {
        if(!fIsChildCheck && oNode.check() != eNodeState.checked)
            oNode.check(eNodeState.unChecked);
        else if(fIsChildCheck && oNode.check() == eNodeState.unChecked)
            oNode.check(eNodeState.ghostChecked);
    }            
    else
    {
        if(!fIsChildCheck && oNode.check() == eNodeState.checked)
            oNode.check(eNodeState.unChecked);
        else if(fIsChildCheck && oNode.check() == eNodeState.checked)
            oNode.check(eNodeState.ghostChecked);
        else 
            oNode.check(eNodeState.checked);
    }

    if(((oNode.getBehavior() & eNodeBehavior.parentUpdate) == eNodeBehavior.parentUpdate) && oNode.getParent() != null)
        this.toggleCheck(oNode.getParent().getId(), true);

    this.updateCheckStatus(oNode);
}    

JTree.prototype.checkTo = function(strNodeId) 
{
    var oNode = this.m_idxNodes["m_" + strNodeId];
    if(!oNode)
        return;

    oNode.check(eNodeState.checked);
    if(((oNode.getBehavior() & eNodeBehavior.parentUpdate) == eNodeBehavior.parentUpdate) && oNode.getParent() != null)
        this.toggleCheck(oNode.getParent().getId(), true);

    this.updateCheckStatus(oNode);
};

JTree.prototype.updateCheckStatus = function(oNode) 
{
    if (!this.config.useCheckboxes && !this.config.useRadios)
        return;
    
    var oCheck	= $('c' + this.getName() + oNode.getId());
    if(oCheck)
        oCheck.src = ((oNode.check() == eNodeState.unChecked)? oNode.m_oIcon.unChecked : ((oNode.check() == eNodeState.ghostChecked)? oNode.m_oIcon.ghostChecked : oNode.m_oIcon.checked));
};


JTree.prototype.getIndent = function(oNode) 
{
    if(oNode.isRoot())
        return '';

    var arrRet = new Array();
    for (var nIdx=0, nCnt = oNode.getLevel()-1; nIdx < nCnt; nIdx++)
        arrRet.push('<img src="' + ((this.config.useLines && this.m_arrIndent[nIdx]) ? this.defaultIcon.line : this.defaultIcon.empty ) + '" alt="" />');
    
    if (oNode.haveChild()) 
    {
        arrRet.push('<a href="javascript: ' + this.getName() + '.toggleNode(' + oNode.getId() + '); ' + this.getName() + '.onOpen(' + this.getName() + '.getNode(\'' + oNode.getId() + '\'));"><img id="j' + this.getName() + oNode.getId() + '" src="');
        if (!this.config.useLines) 
            arrRet.push((oNode.open()) ? this.defaultIcon.nlMinus : this.defaultIcon.nlPlus);
        else 
            arrRet.push((oNode.open()) ? ((oNode.lastSibling()) ? this.defaultIcon.minusBottom : this.defaultIcon.minus) : ((oNode.lastSibling()) ? this.defaultIcon.plusBottom : this.defaultIcon.plus));

        arrRet.push('" alt="" border="0" /></a>');
    } 
    else 
        arrRet.push('<img src="' + ( (this.config.useLines) ? ((oNode.lastSibling()) ? this.defaultIcon.joinBottom : this.defaultIcon.join ) : this.defaultIcon.empty) + '" alt="" />');

    return arrRet.join('');
}

JTree.prototype.toString = function() 
{
    var arrRet = new Array();
    arrRet.push('<div class="dtree">\n');
    if (document.getElementById)
        arrRet.push(this.m_oRoot.toString(this));
    else 
        arrRet.push('Browser not supported.');

	   arrRet.push('</div>');
    
    return arrRet.join('');
}

// Events handlers
// Get a node from the node array
JTree.prototype.onCheck = function(oNode) 
{
    return ;            
};

// Get a node from the node array
JTree.prototype.onOpen = function(oNode) 
{
    return ;            
};

