/**
 * Узел дерева
 *
 * @extends Container_Element_Abstract 
 *
 * @param Object
 */
function Tree_Node_Abstract(params)
{
    Tree_Node_Abstract.superclass.constructor.call(this);
    
    /**
     * Параметры узла
     * 
     * @var Object
     *      typeId: ID типа загружаемого нода
     *      nodeId: ID самого загржаемого нода
     *      mode: Режим отображения
     */
    this._loadParams = {
        typeId: params.typeId ? params.typeId : undefined,
        nodeId: params.nodeId ? params.nodeId : undefined,
        mode: params.mode ? params.mode : "",
        url: params.url ? params.url : undefined,
        data: params.data ? params.data : undefined,
        method: params.method ? params.method : undefined
    };
    
    /**
     * Адрес сервиса получения данных
     *
     * @var String
     */
    this._serviceUrl = "/showobject.asmx/macView";
    
    /**
     * Метод доступа к сервису
     *
     * @var String
     */
    this._serviceMethod = "GET";
    
    /**
     * @var bool
     */
    this._isLoaded = false;
    
    /**
     * @var bool
     */
    this._isOpened = false;
    
    /**
     * Элемент, показывающий загрузку содержимого с сервера
     * 
     * @var DOM Element
     */
    this._loadingElement = Rup.create('div');
    this._loadingElement.innerHTML = 'Загрузка...';
    
    this._errorElement = Rup.create('div');
    
    /**
     * Элемент, показывающийся для открытого узла дерева
     * 
     * @var DOM Element
     */
    this._openElement = undefined;
    
    /**
     * Элемент, показывающийся для закрытого узла дерева
     * 
     * @var DOM Element
     */
    this._closeElement = undefined;
    
    this._hideLoading();
}

Rup.extend(Tree_Node_Abstract, Container_Element_Abstract);

Tree_Node_Abstract.prototype._getLoadParams = function()
{
	return "id=" + this._loadParams.nodeId + "&iTypeId=" + this._loadParams.typeId + "&sMode=" + this._loadParams.mode;
}

/**
 * Загружает данные в узел дерева (точнее сказать, инициализирует загрузку данных). 
 * 
 * @see Tree_Node_Abstract._loadingHandler
 */
Tree_Node_Abstract.prototype._load = function()
{
    this._showLoading();
    var instance = this;
    ProcessAjax({
        method: this._loadParams.method ? this._loadParams.method : this._serviceMethod,
        data: this._loadParams.data ? this._loadParams.data : this._getLoadParams(),
        url: this._loadParams.url ? this._loadParams.url : this._serviceUrl,
        callback: function(xml){ instance._loadingHandler.call(instance, xml) },
        beforesend: function(){ instance._showLoading.call(instance) },
        errback: function(){ instance._showError('Ошибка связи с сервером', '', 0) }
    });
}

/**
 * Очищает содержимое узла (после очистки при попытке открыть узел - он заново загружает содержимое с сервера)
 */
Tree_Node_Abstract.prototype.clear = function()
{
    this.close();
    this._isLoaded = false;
    this._removeChilds();
}

/**
 * Открывает узел (если он еще не загружен - то и загружает)
 */
Tree_Node_Abstract.prototype.open = function()
{
    if( !this._isLoaded )
    {
        this._load();
    }
    else
    {
        this._showContainer();
    }
    this._isOpened = true;
    
    if( this._openElement )
    {
        this._openElement.style.display = '';
    }
    if( this._closeElement )
    {
        this._closeElement.style.display = 'none';
    }
}

/**
 * Закрывает узел дерева, не удаляя при этом содержимое узла (при следующем 
 * открытии содержимое не будет подгружаться с сервера)
 */
Tree_Node_Abstract.prototype.close = function()
{
    this._hideContainer();
    this._isOpened = false;

    if( this._openElement )
    {
        this._openElement.style.display = 'none';
    }
    if( this._closeElement )
    {
        this._closeElement.style.display = '';
    }
}

/**
 * Функция-перехватчик загруженных с сервера данных узла. Добавляет загруженные дочерние ноды
 */
Tree_Node_Abstract.prototype._loadingHandler = function(xml)
{
    this._hideLoading();
    this._showContainer();
    
    var aError = xml.getElementsByTagName('error');
    if( aError.length )
    {
    	this._showError(aError[0].getAttribute('title'), aError[0].getAttribute('content'), aError[0].getAttribute('level'))
        return;
    }
    this._isLoaded = true;
    var aNodes = xml.getElementsByTagName('node');
    
    var instance = this;
    
    for( var i = 0; i < aNodes.length; i++ )
    {
        var elem = Node_Factory.get(aNodes[i], function( params ){ return instance.getLink( params ); });
        this.appendChild( elem );
        replaceroot(elem.dom());
    }
}

/**
 * Две функции показывают/скрывают элемент контейнер для дочерних нодов
 */
Tree_Node_Abstract.prototype._showContainer = function()
{
    this._containerElement.style.display = 'block';
}
Tree_Node_Abstract.prototype._hideContainer = function()
{
    this._containerElement.style.display = 'none';
}

/**
 * Две функции показывают/скрывают элемент, показывающий загрузку содержимого с сервера
 */
Tree_Node_Abstract.prototype._showLoading = function()
{
    if( this._loadingElement )
    {
        this._loadingElement.style.display = 'block';
    }
}
Tree_Node_Abstract.prototype._hideLoading = function()
{
    if( this._loadingElement )
    {
        this._loadingElement.style.display = 'none';
    }
}

/**
 * Две функции показывают/скрывают элемент, показывающий ошибку
 */
Tree_Node_Abstract.prototype._showError = function(title, content, level)
{
	this._hideLoading();
	this._isLoaded = true;
    if( this._errorElement )
    {
        
        var oErrorHeader = Rup.create('h3');
        oErrorHeader.innerHTML = title;
        oErrorContent = Rup.create('div');
        oErrorContent.innerHTML = content;
        this._errorElement.innerHTML = '';
        this._errorElement.appendChild(oErrorHeader);
        this._errorElement.appendChild(oErrorContent);
        
        if( level == 0 )
        {
        	var instance = this;
        	var oButton = Rup.GetButton('Обновить', function(){
        	   instance.open();
        	});
        	this._errorElement.appendChild(oButton);
        	this._isLoaded = false;
        }
        
        this._errorElement.style.display = 'block';
        this._containerElement.appendChild(this._errorElement);
    }
}

/**
 * Устанавливает элемент, показывающий загрузку содержимого с сервера
 *
 * @param DOM Element 
 */
Tree_Node_Abstract.prototype._setLoadingElement = function( element )
{
    this._loadingElement = element;
}

/**
 * Устанавливает элемент, показывающий ошибку
 *
 * @param DOM Element 
 */
Tree_Node_Abstract.prototype._setErrorElement = function( element )
{
    this._errorElement = element;
}

/**
 * Устанавливает элемент, показывающий для открытого узла дерева
 *
 * @param DOM Element 
 */
Tree_Node_Abstract.prototype._setOpenElement = function( element )
{
    this._openElement = element;
}

/**
 * Устанавливает элемент, показывающий для закрытого узла дерева
 *
 * @param DOM Element 
 */
Tree_Node_Abstract.prototype._setCloseElement = function( element )
{
    this._closeElement = element;
}

/**
 * Возвращает, загружено или нет содержимое узла
 * 
 * @return bool 
 */
Tree_Node_Abstract.prototype.loaded = function()
{
    return this._isLoaded;
}