// Title: COOLjsTree
// URL: http://javascript.cooldev.com/scripts/cooltree/
// Version: 2.7.5
// Last Modify: 15 Dec 2005
// Notes: Registration needed to use this script on your web site.
// Copyright (c) 2001-2005 by CoolDev.Com
// Copyright (c) 2001-2005 by Sergey Nosenko
// $Id: cooltree.js,v 1.1 2005/11/05 09:46:42 alx Exp $

// Options: PROFESSIONAL



function _isUndefined(_value)
{
        return typeof(_value) == 'undefined';
}

function _isNumber(_value)
{
        return typeof(_value) == 'number';
}

function _isObject(_value)
{
        return typeof(_value) == 'object';
}

function COOLjsTreePRO(_name, _nodes, _format, _static)

{
        this.name = this._name = _name;
        this.bw = new _BrowserDetector();

        var _fmt = {};

        _fmt._left = _format[0];
        _fmt._top = _format[1];
        _fmt._show = { nb:_format[2], nf:_format[5] };
        _fmt._buttons = _format[3];
        _fmt.iE = _format[3][2];
        _fmt._buttonWidth = _format[4][0];
        _fmt._buttonHeight = _format[4][1];
        _fmt.Ew = _format[4][2];
        _fmt._folders = _format[6];
        _fmt._iconWidth = _format[7][0];
        _fmt._iconHeight = _format[7][1];
        _fmt.ident = _format[8];
        _fmt._cssClass = _format[10];
        _fmt._cssClasses = _format[11];
        _fmt.so = _format[12];
        _fmt.pg = _format[13][0];
        _fmt.sp = _format[13][1];

        _fmt.exp = _format[14];
        _fmt.expimg = _format[15];
        _fmt.expimgsize = _format[16];
        _fmt.cook = _format[17];
        _fmt.rel = _format[18];
        _fmt.rels = _format[19];
        _fmt.resize = _format[20];
        _fmt.sel = _format[21];
        _fmt.selC = _format[22];
        _fmt._cssClassForSelectedNode = _format[22] ? _format[22][2] : '';
        _fmt._cssClassForOpenedNode = _format[22] ? _format[22][3] : '';
        _fmt._wrappingMargin = _format[23] || 0;
        _fmt._imageAlignment = _format[24] || 'middle';

        if (_fmt._show.nb)
                _preloadImages(_format[3]);

        if (_fmt._show.nf)
                _preloadImages(_format[6]);

        this._format = _fmt;
        this._selectedNodeIndex = null;

        if (!this.bw._ver3)
                this._back = new _COOLjsTreeBackPRO(_format[9], this);
        if (_isUndefined(window.CTrees))
                window.CTrees = [];
        window.CTrees[_name] = this;
        this.jsPath = "window.CTrees['" + _name + "']";
        this.Nodes = this._nodes = [];
        this._lastLocalIndex = -1;
        this._layerIndex = 0;

        this._layersToDetach = {};

        this._backbone = this._prepareNode(([ {id:null}, '', null, null, {format:{}} ]).concat(_nodes));

        this._px = this.bw._operaOld ? '' : 'px';
        this._dynamic = !_static && this.bw.dom && !this.bw._operaOld && !this.bw.ns4;
        this._rtl = document.body && document.body.dir == 'rtl';

        this._redrawAfter = -1;

}

$ = COOLjsTreePRO.prototype;

$.__handlers = {};

$.$handleEvent = function (_prefix, _suffix, _nodeIndex, _object)
{
        var _node = this._nodeByIndex(_nodeIndex), _handler = _prefix + '_' + _suffix;

        if (!_node._handlersAttached[_prefix])
        {
                this._attachHandlers(_prefix, _object, this, _nodeIndex);
                this._attachHandlers(_prefix, _object, _node._getFormat(), _nodeIndex);
                _node._handlersAttached[_prefix] = true;
        }

        this._executeHandler(_handler, _node._getFormat(), _node);
        return this._executeHandler(_handler, this, _node);
}

$._attachHandlers = function (_prefix, _object, _host, _nodeIndex)
{
        for (var _handler in _host)
                if (_handler.match(new RegExp('^' + _prefix + '_' + '(on.+)$')))
                        _object[RegExp.$1] = new Function(this._handler(_prefix, RegExp.$1, _nodeIndex));
}

$._executeHandler = function (_handler, _host, _argument)
{
        return _host[_handler] ? _host[_handler](_argument) : false;
}

$._handler = function (_prefix, _event, _nodeIndex)
{
        return 'return ' + this.jsPath + '.$handleEvent(\'' + _prefix + '\',\'' + _event + '\',' + _nodeIndex + ',this)';
}

$._handlers = function (_prefix, _node)
{
        return _attribute('onmouseover', this._handler(_prefix, 'onmouseover', _node._index));
}

$.getAdditionalColumns = function (_node)
{
        return '';
}

$.getRoot = $._getRoot = function ()
{
        if (!this._root) {
                this._backbone._object = this._root = new _COOLjsTreeNodePRO(this._backbone, this, null, false);
                this._root._setExpanded(true);
        }

        return this._root;
}

$._findNode = function (_index)
{
        var _path = this._nodePathBy('n', _index, this._backbone._children);

        if (!_path)
                return null;

        var _parent = this._backbone, i = 0;

        for (var i = 0; i < _path.length - 1; i++)
                _parent = _parent._children[_path[i]];

        return [ _parent, _path[i] ];
}

$._stripObjects = function (_node)
{

        if (_node._object)
        {
                _node._object._detachLayers();
                _node._parentNode = null;
                _node._object = null;
        }

        for (var i in _node._children)
                if (_node._children[i]._object)
                        this._stripObjects(_node._children[i]);
}

$._insertNodes = function (_parentIndex, _minorIndex, _definition)
{
        var _parent;

        if (_parentIndex == this._backbone._index)
                _parent = this._backbone;
        else {
                var _pair = this._findNode(_parentIndex);
                if (_pair)
                        _parent = _pair[0]._children[_pair[1]];
        }

        if (_parent) {
                this._stripObjects(_parent);

                for (var i in _definition)
                        _definition[i] = this._prepareNode(_definition[i]);

                _minorIndex = Math.max(0, Math.min(_minorIndex, _parent._children.length));

                if (_minorIndex == _parent._children.length) {
                        _parent._children = _parent._children.concat(_definition);
                } else {
                        var _children = _parent._children;
                        _parent._children = [];

                        for (var i in _children) {
                                if (i == _minorIndex)
                                        _parent._children = _parent._children.concat(_definition);
                                _parent._children[_parent._children.length] = _children[i];
                        }
                }

                this._redraw();

                return _minorIndex;
        } else
                return null;
}

$._replaceDefinition = function (_index, _definition, _reuseId, _reuseFormat, _reuseChildren)
{
        var _pair = this._findNode(_index);

        if (_pair) {
                var _parent = _pair[0], _children = _parent._children, _index = _pair[1];
                this._stripObjects(_parent);
                var _definition = this._prepareNode(_definition);
                if (_reuseId)
                        _definition[0] = _parent._children[_index][0];
                if (_reuseFormat)
                        _definition[4] = _parent._children[_index][4];
                if (_reuseChildren)
                        _definition._children = _parent._children[_index]._children;
                _definition.i = _definition[0].id;
                _definition.f = _definition[4].format;
                _parent._children[_index] = _definition;
        }
}

$._deleteNode = function (_parent, _index)
{
        if (!_isUndefined(_parent._children[_index])) {
                var _children = _parent._children;
                this._stripObjects(_parent);
                _parent._children = [];
                for (var i in _children)
                        if (i != _index)
                                _parent._children[_parent._children.length] = _children[i];
        }
}

$.getSelectedNode = function ()
{
        return this.nodeByIndex(this._selectedNodeIndex);
}

$._isNodeSelected = function (_node)
{
        return this._selectedNodeIndex === _node._index;
}

$._needAdvancedWrapping = function ()
{
        return this._dynamic && this._format._wrappingMargin && this._format.exp;
}

$._walk_ns4_layers = function (_collection)
{
        for (var i in _collection) {
                this._ns4_layers[_collection[i].id] = _collection[i];
                if (_collection[i].layers)
                        this._walk_ns4_layers(_collection[i].layers);
        }
}

$._getElement = function (_id)
{
        if (this.bw.ns4) {
                if (!this._ns4_layers) {
                        this._ns4_layers = {};
                        this._walk_ns4_layers(document.layers);
                }
                return this._ns4_layers[_id];
        } else
                return (document.all && document.all[_id]) || document.getElementById(_id);
}

$.moveTo = function (x, y)
{
        this._back._top = y;
        this._back._left = x;
        this._back._moveTo(x, y);
        this._format._top = y;
        this._format._left = x;
        this.draw();
}

$.ensureVisible = function (_index, _noredraw)
{
        var _node = this.nodeByIndex(_index);
        var _redraw = false;
        while (_node) {
                _node = _node._parentNode;

                if (_node._isRoot())
                        break;

                if (!_node._isExpanded()) {
                        this.expandNode(_node._index, 1);
                        _redraw = true;
                }
        }

        if (_redraw && !_noredraw)
                this.draw();
}

$._nodePathBy = function (_field, _value, _nodes)
{
        for (var i in _nodes)
        {
                switch (typeof(_value))
                {
                case 'string':
                case 'number':
                        if (_nodes[i][_field] == _value)
                                return [i];
                        break;
                default:
                        if (('' + _nodes[i][_field]).match(_value))
                                return [i];
                }

                var _subPath = this._nodePathBy(_field, _value, _nodes[i]._children);
                if (_subPath)
                        return [i].concat(_subPath);
        }

        return null;
}

$._nodeBy = function (_field, _value)
{
        return this._getRoot()._getNodeByPath(this._nodePathBy(_field, _value, this._backbone._children));
}

$.nbn = $.nodeByName = function (_value) { return this._nodeBy('c', _value); }
$.nodeByID = function (_value) { return this._nodeBy('i', _value); }
$.nodeByURL = function (_value) { return this._nodeBy('u', _value); }

$.nodeByIndex = $._nodeByIndex = function (_value)
{
        if (!this._nodes[_value])
                this._nodes[_value] = this._nodeBy('n', _value);
        return this._nodes[_value];
}

$.nodeByXY = function (_X, _Y)
{
        for (var i in this._nodes)
                if (this._nodes[i])
                        with (this._nodes[i])
                                if (visible && _x <= _X && _y <= _Y && _x + w > _X && _y + h > _Y)
                                        return this._nodes[i];
        return null;
}

$._redraw = function (_y)
{
        if (!this._redrawTO)
                this._redrawTO = window.setTimeout(this.jsPath + '.draw()', 1);
        if (typeof(_y) == 'number')
                this._redrawAfter = Math.min(_y, this._redrawAfter);
        else
                this._redrawAfter = -1;
}

$._detachLayers = function (_node)
{
        _node._detachLayers();
}

$._actuallyDetachLayers = function ()
{
        if (this._dynamic)
                for (var _index in this._layersToDetach) {
                        var _node = this.nodeByIndex(_index);
                        if (_node)
                                _node._actuallyDetachLayers();
                }

        this._layersToDetach = {};
}

$.draw = function ()
{
        if (this.bw._ver3 || !this._redrawComplete)
                return;

        this._actuallyDetachLayers();
        this._canDetachImmediately = true;

        this._maxHeight = 0;
        this._maxWidth = 0;

        with (this._getRoot()) {
                draw(true);
                if (this._rtl)
                        draw(true);
        }

        if (!this._format.rel || this._format.resize)

                this._back._resize(this._maxWidth, this._maxHeight);

        this._redrawTO = null;
        this._redrawAfter = 10000000;

        if (this.ondraw)
                this.ondraw(this);

        this._canDetachImmediately = false;

        this._saveState();
}

$._saveState = function ()
{
        with (this)
                _setCookie('Selected', _selectedNodeIndex),
                _setCookie('State', _getState());
}

$.expandNode = function (_index, _noRedraw, _selectNode)
{
        if (!this.bw._ver3) {
                var _node = this.nodeByIndex(_index);
                if (_selectNode)
                        this.selectNode(_index);
                if (_node && _node._hasChildren()) {
                        var _newState = !_node._isExpanded();
                        if (this._format.so) {
                                this.collapseAll(this._parentNode);
                                this.ensureVisible(_node.index, true);
                        }
                        _node._setExpanded(_newState);
                        this._redraw(_node._y);
                }
        }
}

$._selectNode = $.selectNode = function (_index)
{
        this._selectedNodeIndex = parseInt(_index);
        this._redraw();
}

$.__setStateGlobally = function (_state, _node)
{
        for (var i in _node._children) {
                this.__setStateGlobally(_state, _node._children[i]);
                if (_node._children[i]._children.length)
                        if (_node._children[i]._object)
                                _node._children[i]._object._setExpanded(_state);
                        else
                                _node._children[i][4].format.expanded = _state;
        }
}

$._setStateGlobally = function (_state, _node)
{
        this.__setStateGlobally(_state, _node || this._backbone);
        this._redraw();
}

$.collapseAll = function (_node)
{
        this._setStateGlobally(false, _node && _node._definition);
}

$.expandAll = function (_node)
{
        this._setStateGlobally(true, _node && _node._definition);
}

$._prepareNode = function (_node)
{
        if (_isUndefined(_node[_node.length - 1]))
                _node = _node.slice(0, _node.length - 1);

        if (_isUndefined(_node[0].id))
                _node = ([{id:null}]).concat(_node);

        if (_isUndefined(_node[4]) || _isUndefined(_node[4].format))
                _node = _node.slice(0, 4).concat([{format:{}}]).concat(_node.slice(4));

        var _index = this._lastLocalIndex++;
        var _children = _node.slice(5);
        _node = _node.slice(0, 5);
        _node._children = [];

        for (var i in _children)
                _node._children[i] = this._prepareNode(_children[i]);

        _node[4] = _copyObject(_node[4]);

        _node.i = _node[0].id;
        _node.c = _node[1];
        _node.u = _node[2];
        _node.t = _node[3];
        _node.f = _node[4].format;
        _node.n = _node._index = _index;

        _node._object = null;

        return _node;
}

$.init = function ()
{
        var s = this._getRoot()._getHtml(!this._dynamic);

        if (this._format.cook) {
                this._selectNode(this._getCookie('Selected'));
                this._setState(this._getCookie('State'));
        }

        if (!this.bw._ver3)
                s = this._back._init(s);

        if (this.bw.ns4)
                s = '<div id="' + this._name + 'dummytreediv" style="position:absolute;"></div>' + s;

        document.write(s);

        if (this.bw.ns4)
        {
                this._redrawComplete = true;
                this.draw();
        }

}

$._getCookie = function(_name)
{
        return document.cookie.match(new RegExp('(\\W|^)' + this._name + _name + '=([^;]+)')) ? RegExp.$2 : null;
}

$._setCookie = function (_name, _value)
{
        document.cookie = this._name + _name + '=' + _value + '; path=/';
}

$.__getState = function (_node)
{
        var _result = '';

        for (var i in _node._children)
                if (_node._children[i]._children.length)
                        _result += (_node._children[i][4].format.expanded ? 1 : 0) + this.__getState(_node._children[i]);

        return _result;
}

$._getState = function ()
{
        return this.__getState(this._backbone);
}

$.__setState = function (_node, _state, _index)
{
        for (var i in _node._children) {
                if (_node._children[i]._children.length) {
                        if (_node._children[i]._object)
                                _node._children[i]._object._setExpanded(_state.charAt(_index) == '1');
                        else
                                _node._children[i][4].format.expanded = _state.charAt(_index) == '1';
                        _index = this.__setState(_node._children[i], _state, _index + 1);
                }
        }

        return _index;
}

$._setState = function (_state)
{
        this.__setState(this._backbone, _state || '', 0);
}

$.layer_onmousedown = function (_node)
{
        _node._active = true;
        _node._updateImages();
        _node._updateVisibility();
        return true;
}

$.layer_onmouseup = $.layer_onclick = function (_node)
{
        _node._active = false;
        _node._updateImages();
        _node._updateVisibility();
        return true;
}

$.layer_onmouseover = function (_node)
{
        _node._hover = true;
        _node._updateImages();
        _node._updateVisibility();
        return true;
}

$.layer_onmouseout = function (_node)
{
        _node._hover = false;
        _node._updateImages();
        _node._updateVisibility();
        return true;
}

$.image_onclick = $.caption_onclick = function (_node)
{
        //this.expandNode(_node.index, 1, 1);
        return true;
}

$.button_onclick = function (_node)
{
        this.expandNode(_node.index);
        return true;
}

$.image_onmouseover = $.button_onmouseover = $.caption_onmouseover = function (_node)
{
        window.status = _node.text;
        return true;
}

$.image_onmouseout = $.button_onmouseout = $.caption_onmouseout = function (node)
{
        window.status = window.defaultStatus;
        return true;
}

function _COOLjsTreeNodePRO(_definition, _tree, _parent, _hasNext)
{
        var _index = _definition._index;
        this._definition = _definition;
        this._index = this.index = _index;
        this.jsPath = _tree.jsPath + '.nodeByIndex(' + _index + ')';
        this.treeView = this._tree = _tree;
        this._parentNode = this.parentNode = _parent;
        this._hasNext = _hasNext;
        this.text = _definition[1];
        this.url = _definition[2];
        this.target = _definition[3];
        this._layerOwner = null;
        this._handlersAttached = {};

        this.nodeID = _definition[0].id;
        this._format = _definition[4].format;

        this._previousExpanded = null;
        this._setExpanded(this._definition[4].format.expanded);
        this.children = this._children = [];
        this._level = this.level = _parent ? _parent._level + 1 : -1;
        this.visible = false;
        this._layers = {};
        this._exceeds = false;
        this._imagesToUpdate = {};

        if (_parent)
                this._initImages();
}

$ = _COOLjsTreeNodePRO.prototype;

$._isRoot = function ()
{
        return this._tree._backbone._index == this._index;
}

$._isExpanded = function ()
{
        return this._definition[4].format.expanded;
}

$.id = function ()
{
        return this._id;
}

$._setProperties = function (_caption, _url, _target)
{
        this._tree._replaceDefinition(this._index, [ _isUndefined(_caption) ? this._getCaption() : _caption, _isUndefined(_url) ? this._getUrl() : _url, _isUndefined(_target) ? this._getTarget() : _target ], true, true, true);
        this._tree._redraw();
}

$.getTree = function () { return this._tree; }

$.getParent = function () { return this._parentNode; }

                $.getId = function () { return this._definition[0].id; }
$._getCaption = $.getCaption = function () { return this._definition[1]; }
$._getUrl = $.getUrl = function () { return this._definition[2]; }
$._getTarget = $.getTarget = function () { return this._definition[3]; }
$._getFormat = $.getFormat = function () { return this._definition[4].format; }

$.setCaption = function (_value) { this._setProperties(_value, this._undefined, this._undefined); }
$.setUrl = function (_value) { this._setProperties(this._undefined, _value, this._undefined); }
$.setTarget = function (_value) { this._setProperties(this._undefined, this._undefined, _value); }

$.hasChildren = $._hasChildren = function ()
{
        return !!this._definition._children.length;
}

$._isItFolder = function ()
{
        return this._hasChildren() || this._definition[4].format.isFolder;
}

$._getNodeByPath = function (_path)
{
        if (_path)
                return _path.length ? this._getChild(_path[0])._getNodeByPath(_path.slice(1)) : this;

        return null;
}

$._setExpanded = function (_value)
{
        this.expanded = this._definition[4].format.expanded = !!_value;
        this._updateImages();
}

$._getButtonImage = function ()
{
        if (this._tree._format._show.nb && !this._format.nobuttons && this._hasChildren())
        {

                if (this._tree._format.exp)
                        return this._selectImage(this._tree._format.expimg, this._format.eimages, this._isExpanded() ? (this._hasNext ? 3 : 4) : (this._hasNext ? 5 : 6));
                else

                        return this._selectImage(this._tree._format._buttons, this._format.buttons, this._isExpanded() ? 1 : 0);
        }

        return null;
}

$._getIconImage = function ()
{
        if (this._tree._format._show.nf && !this._format.nofolders)
        {
                var _index = this._isItFolder() ? (this._isExpanded() ? 1 : 0) : 2;

                if (this._tree._format.exp)
                        return this._selectImage(this._tree._format.expimg, this._format.eimages, _index);
                else

                        return this._selectImage(this._tree._format._folders, this._format.folders, _index);
        }

        return null;
}

$._selectImage = function (_array1,_array2, _index)
{
        var _src = (_array2 && _array2[_index] ? _array2 : _array1)[_index];

        if (typeof(_src)!='string' && _src[0])
        {
                if (this._active && this._hover && _src[2])
                        _src = _src[2];
                else if (this._hover && _src[1])
                        _src = _src[1];
                else
                        _src = _src[0];
        }

        return _src;
}

$._updateImages = function ()
{
        if (this._layersAttached)
        {
                this._updateImage('nb', this._getButtonImage());
                this._updateImage('nf', this._getIconImage());
        }
}

$._updateImage = function (_suffix, _src)
{
        if (_src) {
                var _img = (this._getLayer().document || document).images[this._id + _suffix];

                if ((this._tree._format._show[_suffix] || this._tree._format.exp) && _img && _img.src != _src)

                        this._imagesToUpdate[_suffix] = { _image:_img, _path:_src };
        }
}

$._initImages = function ()
{

        if (this._tree._format.exp) {
                var esz = this._tree._format.expimgsize;
                this.wimg = this._iconWidth = this._buttonWidth = esz[0];
                this.himg = this._iconHeight = this._buttonHeight = esz[1];
        } else {

                this._buttonWidth = _isUndefined(this._format.bsize) ? this._tree._format._buttonWidth : this._format.bsize[0];
                this._buttonHeight = _isUndefined(this._format.bsize) ? this._tree._format._buttonHeight : this._format.bsize[1];
                this._iconWidth = _isUndefined(this._format.fsize) ? this._tree._format._iconWidth : this._format.fsize[0];
                this._iconHeight = _isUndefined(this._format.fsize) ? this._tree._format._iconHeight : this._format.fsize[1];

        }

}

$._getHtml = function (_recursive)
{
        var _result = '';

        this._id = 'nt' + this._tree._name + '_' + this._tree._layerIndex++;

        if (!this._isRoot())
                _result += this._tree.bw._ver3 ? this._getContent() : '<div' + this._tree._handlers('layer', this) + ' id="' + this._id + 'd"  style="' + (this._tree.bw.mac || this._tree.bw._operaOld ? '' : 'height:1px;width:1px;') + 'left:-10000px;top:-10000px;position:absolute;' + (this._tree._dynamic ? '' : 'visibility:hidden;') + '">' + this._getContent() + '</div>';

        if (_recursive)
                _result += this._getHtmlForChildren(_recursive);

        return _result;
}

$._getHtmlForChildren = function (_recursive)
{
        var _result = '';

        for (var i = 0; i < this._getNumberOfChildren(); i++)
                _result += this._getChild(i)._getHtml(_recursive);

        return _result;
}

$._anchor = function (_url, _prefix, _content, _cssClass, _needId)
{
        return '<a' + this._tree._handlers(_prefix, this) + ' href="' + (_url || 'javascript:void(0)') + '"' + _attribute('target', _url && this.target) + _attribute('id', _needId && (this._id + 'an')) + _attribute('class', _cssClass) + '>' + _content + '</a>';
}

$._square = function (_prefix, _suffix, _imgSrc, _needAnchor, _needUrl, w, h, _background)
{
        if (!w || !_imgSrc)
                return '';

        if (!this._tree._needAdvancedWrapping() && _background && _imgSrc == this._tree._format.iE)
                _imgSrc = _background;

        var i = '<img' + (_suffix ? ' name="' + this._id + _suffix + '" id="' + this._id + _suffix + '"' : '') + ' src="' + _imgSrc + '" width="' + w + '" height="' + h + '" border="0"' + (this._tree.bw.ns4 ? '' : ' style="display: block"') + ' />';

        return '<td' + (this._tree._needAdvancedWrapping() ? _attribute('background', _background) : '') + ' style="font-size:1px;" valign="' + (this._tree._format.exp ? 'top' : this._tree._format._imageAlignment) + '" width="' + w + '">' + (_needAnchor ? this._anchor(_needUrl && this.url, _prefix, i) : i) + '</td>';

}

$._lineSquares = function () {
        return this._level >= 0 ? this._parentNode._lineSquares() + this._square('', '', this._tree._format.iE, false, false, this._tree._format.expimgsize[0], this._tree._format.expimgsize[1], this._hasNext && this._tree._format.expimg[7]) : '';
}

$._getIndent = function ()
{
        with (this._tree._format)
                return _isUndefined(ident[this._level]) ? ident[0] * this._level : ident[this._level];
}

$._getContent = function ()
{

        var w = this._tree._format._wrappingMargin;

        var s = '<table' + _attribute('width', w) + ' cellpadding="' + this._tree._format.pg + '" cellspacing="' + this._tree._format.sp + '" border="0" class="cls' + this._tree._name + '_back' + this._level + '"><tbody><tr>';

        if (this._tree._format.exp) {
                s += this._parentNode._lineSquares();
                if (!this._hasChildren())
                        s += this._square('', '', (this._hasNext ? this._tree._format.expimg[8] : this._tree._format.expimg[9]), false, false, this._tree._format.expimgsize[0], this._tree._format.expimgsize[1], this._hasNext && this._tree._format.exp && this._tree._format.expimg[7]);
        } else

                s += this._square('', '', this._tree._format.iE, false, false, this._getIndent() + (this._hasChildren() ? 0 : this._tree._format.Ew), 1);

        s += this._square(
                'button',
                'nb',
                this._getButtonImage(),
                true,
                false,
                this._buttonWidth,
                this._buttonHeight,

                this._hasNext
                && this._tree._format.exp
                && this._tree._format.expimg[7]

        );

        s += this._square(
                'image',
                'nf',
                this._getIconImage(),
                true,
                true,
                this._iconWidth,
                this._iconHeight,

                this._isExpanded()
                && this._hasChildren()
                && this._tree._format.exp
                && this._tree._format.expimg[7]

        );

        s += '<td' + (w ? '' : ' nowrap="nowrap"') + '><div id="' + this._id + 'a" style="position:relative;">' + this._anchor(this.url, 'caption', this.text, this._getCssClass(), true) + '</div></td>';

        return s + this._tree.getAdditionalColumns(this).replace(/\{node\}/g, this.jsPath) + '</tr></tbody></table>';
}

$._getCssClass = function ()
{
        var _result;

        if (this._tree._format.sel)
                if (this._isSelected())
                        _result = this._tree._format._cssClassForSelectedNode;
                else if (this._hasChildren() && this._isExpanded())
                        _result = this._tree._format._cssClassForOpenedNode;

        if (!_result)

                with (this._tree._format)
                        _result = _cssClasses[this._level] || _cssClass;

        if (typeof(_result) != 'string')
                _result = _result[this._level];

        return _result || '';
}

$._getBackgroundColor = function ()
{
        return this._tree._format.sel ? this._tree._format.selC[this._isSelected() ? 1 : 0] : '';
}

$._moveTo = function (_x, _y)
{
        if (this._x != _x || this._y != _y) {
                this._x = _x;
                this._y = _y;

                with (this._getLayer())
                        if (this._tree.bw.ns4)
                                moveTo(_x, _y);
                        else {
                                style.left = _x + this._tree._px;
                                style.top = _y + this._tree._px;
                        }
        }
}

$._getLayerForChildren = function ()
{
        if (!this._layerForChildren)
                if (this._tree._dynamic)
                {
                        var _el = this._layerForChildren = document.createElement('div');
                        _el.style.position = 'absolute';
                        _el.style.top = _el.style.left = '0px';
                        _el.innerHTML = this._getHtmlForChildren();
                        this._tree._back._getLayer().appendChild(_el);
                }
                else
                        this._layerForChildren = this._getLayer('ch');

        return this._layerForChildren;
}

function _destroy(_layer)
{
        _layer.parentNode.removeChild(_layer);
}

$._destroyLayerForChildren = function ()
{
        if (this._layerForChildren)
        {
                var _tmp = this._layerForChildren;
                this._layerForChildren = null;

                for (var i in this._definition._children)
                        with (this._definition._children[i])
                                if (_object)
                                        _object._actuallyDetachLayers();

                _destroy(_tmp);
        }
}

$._attachLayers = function ()
{
        if (!this._layersAttached) {
                if (this._tree._dynamic && !this._isRoot())
                        this._parentNode._getLayerForChildren();

                this._layersAttached = true;
                this._layers = {};
        }
}

$._detachLayers = function ()
{
        if (this._tree._canDetachImmediately)
                this._actuallyDetachLayers();
        else {
                this._tree._layersToDetach[this._index] = true;
                this._tree._redraw();
        }
}

$._actuallyDetachLayers = function ()
{
        if (this._layersAttached)
        {
                for (var i in this._layers)
                {
                        _destroy(this._layers[i]);
                        this._layers[i] = null;
                }

                this._layers = {};

                this.w = this.h = this._x = this._y = 0;

                this._layersAttached = false;
        }

        this._destroyLayerForChildren();

        if (!this._isRoot())
                this._parentNode._destroyLayerForChildren();
}

$._setVisibility = function (_layer, _value)
{
        if (this._tree.bw.ns4)
                _layer.visibility = _value ? 'show' : 'hide';
        else
                _layer.style.visibility = _value ? 'visible' : 'hidden';
}

$._updateVisibility = function ()
{
        if (!this._tree._dynamic)
                this._setVisibility(this._getLayer(), this.visible);

        if (this.visible) {
                for (var i in this._imagesToUpdate)
                        with (this._imagesToUpdate[i])
                                _image.src = _path;

                this._imagesToUpdate = {};
        }
}

$._updatePosition = function ()
{
        if (!this.visible)
                this._moveTo(-10000, -10000);
        else
                this._moveTo(this._tree._rtl ? (this._tree.bw.gecko ? this._tree._maxWidth : 0) - this.w : 0, this._tree._currTop);
}

$._updateStyle = function () {
        if (this._tree._format.sel) {
                if (this._isSelected() == !this._lastSelected)
                {
                        var _backgroundColor = this._getBackgroundColor();

                        with (this._getLayer('a'))
                                if (this._tree.bw.ns4)
                                        bgColor = _backgroundColor;
                                else
                                        style.backgroundColor = _backgroundColor;

                        this._lastSelected = this._isSelected();
                }

                if (this._tree.bw.dom) {
                        if (_isUndefined(this._originalClassName))
                                this._lastCssClass = this._originalClassName = this._tree._getElement(this._id + 'an').className;

                        var _cssClass = this._getCssClass();

                        if (_cssClass != this._lastCssClass) {
                                this._getLayer('an').className = this._lastCssClass = _cssClass;
                                this.h = 0;
                        }
                }
        }
}

$._updateDimensions = function (_force)
{
        if (!this.h || _force) {
                if (this._tree.bw.gecko)
                        with (this._getLayer().childNodes[0]) {
                                this.w = offsetWidth;
                                this.h = offsetHeight;
                        }
                else if (this._tree.bw.ns4)
                        with (this._getLayer()) {
                                this.w = clip.width;
                                this.h = clip.height;
                        }
                else if (this._tree.bw.operaNew)
                        with (this._getLayer().childNodes[0]) {
                                this.w = offsetWidth;
                                this.h = offsetHeight;
                        }
                else
                        with (this._getLayer()) {
                                this.w = offsetWidth || scrollWidth || style.pixelWidth;
                                this.h = offsetHeight || scrollHeight || style.pixelHeight;
                        }

                if (this._tree._needAdvancedWrapping())
                        this._exceeds = this._tree._format.exp && this.h > this._tree._format.expimgsize[1];

        }
}

$.draw = function (_visible)
{
        var _visibilityChanged = this.visible != _visible;
        var _wasAttached = this._layersAttached;
        var _wasExceeding = this._exceeds;

        if (this._isRoot()) {
                this._tree._currTop = 0;
                this.visible = _visible;
        } else if (this._y < this._tree._redrawAfter) {
                this._tree._currTop = this._y + this.h;
                this._tree._maxWidth = this._maxWidth;
                this._tree._maxHeight = this._maxHeight;
        } else if (this.visible || _visible) {
                this._tree._redrawAfter = -1;
                this.visible = _visible;
                this._updateVisibility();

                if (this.visible)
                {

                        if (_wasAttached || this._isSelected())
                                this._updateStyle();

                        this._updateDimensions();
                        this._updatePosition();

                        if ( this._exceeds && this._previousExpanded != this._isExpanded() && _wasAttached) {
                                this._actuallyDetachLayers();
                                this.visible = _visible;
                                this._updateDimensions();
                                this._updatePosition();
                                this._updateVisibility();
                        }

                        this._tree._maxWidth = Math.max(this.w, this._tree._maxWidth);
                        this._tree._currTop += this.h;
                        this._tree._maxHeight = Math.max(this._tree._currTop, this._tree._maxHeight);

                        this._maxWidth = this._tree._maxWidth;
                        this._maxHeight = this._tree._maxHeight;
                }
        }

        if (
                (this.visible && (this._previousExpanded || this._isExpanded()))
                || (!this.visible && _visibilityChanged && this._previousExpanded)
        )
                this._drawChildren(this._isExpanded() && this.visible);

        if (this._tree._dynamic)
        {
                if (this._hasChildren())
                        this._setVisibility(this._getLayerForChildren(), this._isExpanded() && this.visible);
        }

        this._previousExpanded = this._isExpanded();
}

$._drawChildren = function (_visible)
{
        for (var i = 0; i < this._getNumberOfChildren(); i++)
                this._getChild(i).draw(_visible);
}

$._isSelected = function ()
{
        return this._tree._isNodeSelected(this);
}

$.getNumberOfChildren = $._getNumberOfChildren = function ()
{
        return this._definition._children.length;
}

$.getChild = $._getChild = function (_minorIndex)
{
        with (this._definition._children[_minorIndex]) {
                if (!_object)
                {
                        var _raw = this._definition._children[_minorIndex];
                        _object = this._tree._nodes[_raw._index] = new _COOLjsTreeNodePRO(_raw, this._tree, this, _minorIndex < this._getNumberOfChildren() - 1);
                }

                return _object;
        }
}

$.getMinorIndex =

$._getMinorIndex = function ()
{
        var _result = 0;

        while (_result < this._parentNode._definition._children.length)
                if (this._parentNode._definition._children[_result]._index == this._index)
                        return _result;
                else
                        _result++;

        return null;
}

$.addNode = function (_minorIndex, _raw)
{
        return this._getChild(this._tree._insertNodes(this._index, _minorIndex, [ _raw ]));
}

$.recreate = function (_raw, _reuseChildren)
{
        this._tree._replaceDefinition(this._index, _raw, false, false, _reuseChildren);
        this._tree._redraw();
}

$.deleteNode = function (_index)
{
        this._tree._deleteNode(this._definition, _index);
}

$.getLayer = $._getLayer = function (_suffix)
{
        if (!_suffix)
                _suffix = 'd';

        if (!this._layers[_suffix])
        {
                this._attachLayers();
                this._layers[_suffix] = this._tree._getElement(this._id + _suffix);
        }

        return this._layers[_suffix];
}

function _COOLjsTreeBackPRO(_color, _tree) {
        this._tree = _tree;
        this._left = _tree._format._left;
        this._top = _tree._format._top;
        this._name = 'cls' + _tree._name + '_back';
        this.color = _color;
}

$ = _COOLjsTreeBackPRO.prototype;

$._getLayer = function (_suffix) {
        return this._tree._getElement(this._name + (_suffix || ''));
}

$._resize = function (_width, _height) {
        if (this._tree.bw._operaOld && !this._first) {
                this._first = true;
        } else {

                with (this._getLayer()) {
                        if (this._tree.bw.ns4)
                                resizeTo(_width, _height);
                        else {
                                style.width = _width + this._tree._px;
                                style.height = _height + this._tree._px;
                        }
                }
        }
}

$._moveTo = function (_left, _top)
{
        with (this._getLayer())
                if (this._tree.bw.ns4)
                        moveTo(_left, _top);
                else
                {
                        style.left = _left + this._tree._px;
                        style.top = _top + this._tree._px;
                }
}

$._init = function (_html) {
        var p = 'relative', w = 1, h = 1;

        if (this._tree._format.rel)
        {
                w = this._tree._format.rels[0];
                h = this._tree._format.rels[1];
        }
        else

                p = 'absolute';

        var _result =
                '<div style="overflow:'
                + (this._tree._operaOld ? 'scroll' : 'hidden') + ';'
                + (this.color == "" ? "" : (this._tree.bw.ns4 ? 'layer-' : '')
                + 'background-color:' + this.color + ";")
                + 'position:' + p + ';top:' + this._top + 'px;left:' + this._left
                + 'px;width:' + w + 'px;height:' + h + 'px;z-index:0;" id="'
                + this._name + '">'
                + (
                        this._tree.bw.ns4
                        ? '<img src="' + this._tree._format.iE
                        + '" width="' + w + '" height="' + h + '" />'
                        : ''
                )

                ;

        return _result + _html + '</div>';
}

_attribute = function (_name, _value)
{
        return _value ? ' ' + _name + '="' + _value + '"' : '';
}

function _RedrawAllTrees()
{
        for (var i in window.CTrees) {
                window.CTrees[i]._redrawComplete = true;
                window.CTrees[i].draw();
        }
}

function RedrawAllTrees()
{
        if (!new _BrowserDetector().ns4)
                _RedrawAllTrees();
}

function _BrowserDetector()
{
        var _is_major = parseInt(navigator.appVersion);

        this.ver = navigator.appVersion;
        this.agent = navigator.userAgent;
        this.dom = document.getElementById ? 1 : 0;
        this.opera = window.opera ? 1 : 0;
        this.ie5 = this.ver.match(/MSIE 5/) && this.dom && !this.opera;
        this.ie6 = this.ver.match(/MSIE 6/) && this.dom && !this.opera;
        this.ie4 = document.all && !this.dom && !this.opera;
        this.ie = this.ie4 || this.ie5 || this.ie6;
        this.mac = this.agent.match(/Mac/);

        this.ie3 = this.ver.match(/MSIE/) && _is_major < 4;
        this.hotjava = this.agent.match(/hotjava/i);
        this.ns4 = document.layers && !this.dom && !this.hotjava;

        this._ver3 = this.hotjava || this.ie3;
        this.operaNew = this.agent.match(/opera.[789]/i);
        this.gecko = this.agent.match(/gecko/i);
        this.oldGecko = this.agent.match(/gecko\/2002/i);
        this._operaOld = this.opera && !this.operaNew;
}

function _preloadImages(_list)
{
        for (var i in _list)
                (new Image()).src = _list[i];
}

window._oldCTOnLoad = window.onload;

window._oldCTOnUnLoad = window.onunload;

window.onload = function () {
        var bw = new _BrowserDetector();
        if (typeof(window._oldCTOnLoad) == 'function')
                window._oldCTOnLoad();
}

window.onunload = function () {
        for (var i in window.CTrees)
                with (window.CTrees[i])
                        if (_format.cook)
                                _saveState();
        if (typeof(window._oldCTOnUnLoad) == 'function')
                window._oldCTOnUnLoad();
}

function _copyObject (o)
{
        var r = {};

        for (var i in o)
                r[i] = typeof(o[i]) == 'object' && o[i] !== null ? _copyObject(o[i]) : o[i];

        return r;
}


