
var PagesTree = new Class({
	Extends: pAjaxApplication,
	initialize: function(params) {
		this.itemClass=params.itemClass;
		this.nodes = new Hash();
		if (typeof params.onNewItem != 'function') {
			this.onNewItem = function(item) {};
		}
		else {
			this.onNewItem = params.onNewItem;
		}
		if (typeof params.onSelectItem != 'function') {
			this.onSelectItem = function(item,event) {};
		}
		else {
			this.onSelectItem = params.onSelectItem;
		}
		this.parent(params);
		this.backend = '';
		this.backendAction = '';
		this.selectedId=0;
	},
	createControls: function() {
		this.addNode({
			id: 0,
			child: this.data.get('child')
		},null);
		this.container.setStyle('display','block');
	},
	addNode: function(data,parentNode) {
		if (!parentNode) {
			parentNode=null;
		}
		var item = null;
		// если указан id, отличный от 0 (корень), то добавляем элемент
		if (data.id) {
			item = new this.itemClass({
				context: this,
				parentNode: parentNode,
				data: data
			});
			this.nodes.set(data.id,item);
		}
		// создаем элементы для всех дочерних элементов
		if (data.child) {
			data.child.each(function(itemData) {
				this.addNode(itemData,item);
			}.bind(this));
		}
		
		if (item) {
			this.onNewItem(item);
		}

		return item;
	}
});

var PagesTreeItem = new Class({
	initialize: function(params) {
		this.context=params.context;
		this.parentNode=params.parentNode;
		this.depth=0;
		this.closed=true;
		this.childNodes = new Array();
		this.data=params.data;
		if (this.parentNode) {
			this.depth = this.parentNode.depth+1
			this.parentNode.childNodes.push(this);
		}
		this.container=null;
		this.nodeContainer=null;
		this.childContainer=null;
		this.nodeText=null;
		this.nodeLink=null;
		this.nodeIcon=null;
		this.createControls();
	},
	createControls: function() {
		// основной контейнер, вставляется в контейнер контекста
		this.container = new Element('div',{
			'styles': {
				'margin-left': this.depth > 0 ? 9 : 0
			}
		});
		
		// контейнер самого пункта меню, вставляется либо в дочерний контейнер родителя, либо в контейнер контекста (если родитель отсутствует)
		this.nodeContainer = new Element('div',{
			'class': 'treeNode'
		});

		// контейнер дочерних пунктов меню, вставляется либо в дочерний контейнер родителя, либо в контейнер контекста (если родитель отсутствует)
		this.childContainer = new Element('div',{
			'styles': {
				'display': 'none'
			}
		});

		// контейнер для иконки
		this.nodeIcon = new Element('div',{
			'class': 'treeIcon'
		}).inject(this.nodeContainer);
		
		// контейнер для подписи
		this.nodeText = new Element('div',{
			'class': 'nodeText'
		}).inject(this.nodeContainer);

		// текст подписи
		this.nodeLink = new Element('a',{
			'class': 'nodeLink',
			'href': this.data.url,
			'text': this.data.title_short,
			'title': this.data.title
		}).inject(this.nodeText);
		
		this.nodeLink.addEvent('click',function(e) {
			this.select(true,e);
		}.bind(this));

		// обновления статуса пункта меню (открыт, закрыт, папка, файл и т.п.)
		this.updateNode();

		// сборка
		this.nodeContainer.inject(this.container);
		this.childContainer.inject(this.container);
		this.container.inject(this.parentNode ? this.parentNode.childContainer : this.context.container);
	},
	updateNode: function() {
		this.nodeIcon.removeClass('treeFile');
		this.nodeIcon.removeClass('treeFolder');
		this.nodeIcon.removeClass('treeFolderOpen');
		this.nodeIcon.removeEvents();

		if (this.data.total > 0) {
			if (this.closed) {
				this.childContainer.fade(0);
				this.nodeIcon.addClass('treeFolder');
				this.childContainer.setStyle('display','none');
			}
			else {
				this.childContainer.setStyle('display','block');
				this.nodeIcon.addClass('treeFolderOpen');
				this.childContainer.fade(1);
			}
			this.nodeIcon.addEvent('click',function(e) {
				this.closed ? this.open() : this.close();
			}.bind(this));
		}
		else {
			this.nodeIcon.addClass('treeFile');
		}
		return this;
	},
	open: function() {
		if (this.closed) {
			// сначала проверим, виден ли элемент, который требуется открыть
			if (this.parentNode) {
				if (this.parentNode.closed) {
					this.parentNode.open();
				}
			}
			this.closed=false;
			this.updateNode();
		}
		return this;
	},
	close: function() {
		if (!this.closed) {
			this.closed=true;
			this.updateNode();
		}
		return this;
	},
	select: function(set,e) {
		if (set) {
			// снимем выделение с предыдущего элемента
			if (this.context.nodes.get(this.context.selectedId)) {
				this.context.nodes.get(this.context.selectedId).select(false);
			}
			this.context.selectedId=this.data.id;
			this.nodeLink.addClass('selected');
			this.context.onSelectItem(this,e);
		}
		else {
			this.nodeLink.removeClass('selected');
		}
		return this;
	},
	addChild: function(data) {
		var newNode = this.context.addNode(data,this);
		if (!this.data.total) {
			this.data.total=0;
		}
		this.data.total++;
		this.updateNode().open();
		newNode.select(true);
	},
	destroy: function() {
		this.container.destroy();
		// удаляем указатель из списка элементов дерева
		this.context.nodes.erase(this.data.id);
		if (this.parentNode) {
			with (this.parentNode) {
				// удаляем указатель из списка дочерних элементов родителя
				childNodes.each(function(node,index) {
					if (node.data.id == this.data.id) {
						childNodes.splice(index,1);
						data.total--;
					}
				}.bind(this));
				updateNode().open().select(true);
			}
		}
	}
});
