Ext.ns('Nexts.tree');

/**
 * @class Nexts.tree.StaticTreePanel
 * @extends Ext.tree.TreePanel
 */
Nexts.tree.StaticTreePanel = Ext.extend(Ext.tree.TreePanel, {
	/**
	 * @cfg {Object} defaultRootConfig Default configuration of root node 
	 * @private
	 */
	defaultRootConfig: {
		loaded: true,
		expanded: true,
		leaf: false,
		id: Ext.id()
	},

	/**
	 * @cfg {Object} expandedNodes keeps currently expanded nodes paths for state keeping
	 * @private
	 */
	expandedNodes: {},

	/**
	 * @cfg {Object} rootConfig Configuration for the root node
	 */ 

	/**
	 * @cfg {Object} stateEvents allows us to keep expanded state
	 * @private
	 */
	stateEvents: [ 'expandnode', 'collapsenode' ],

	/**
	 * initialize component
	 * @private
	 */
	initComponent:function() {
		// create root config
		var cfg = Ext.apply(this.defaultRootConfig, this.rootConfig, {children:this.children});

		// configure ourselves
		Ext.apply(this, {
			root: new Ext.tree.AsyncTreeNode(cfg),
			loader: new Ext.tree.TreeLoader(),
			sorter: this.sort ? new Ext.tree.TreeSorter(this) : undefined
		});
		
		// call parent
		Nexts.tree.StaticTreePanel.superclass.initComponent.apply(this, arguments);

		// handle expanded/collapsed state for state keeping
		if (false !== this.stateful) {
			this.on({
				scope: this,
				beforeexpandnode: this.beforeExpandNode,
				beforecollapsenode: this.beforeCollapseNode
			});
		}
	},
	
	/**
	 * restores tree state (expands nodes)
	 * @private
	 */
	afterRender: function() {
		// call parent
		Nexts.tree.StaticTreePanel.superclass.afterRender.apply(this, arguments);

		// restore tree state
		this.restoreTreeState();
	},

	restoreTreeState: function() {
		for (var id in this.expandedNodes) {
			if (this.expandedNodes.hasOwnProperty(id)) {
				this.expandPath(this.expandedNodes[id]);
			}
		}
	},
	
	/**
	 * saves path of the node
	 * @private
	 */
	beforeExpandNode:function(n) {
		if (n.id) {
			this.expandedNodes[n.id] = n.getPath();
		}
	},
	
	/**
	 * deletes expanded state
	 */
	beforeCollapseNode: function(n) {
		if (n.id) {
			delete(this.expandedNodes[n.id]);
			n.cascade(function(child) {
				if (child.id) {
					delete(this.expandedNodes[child.id]);
				}
			}, this);
		}
	},
	
	/**
	 * returns the expandedNodes hash
	 * @private
	 */
	getState: function() {
		return {
			expandedNodes: this.expandedNodes
		};
	},
	
	clearChildren: function() {
		while (this.root.firstChild != null) {
			this.root.firstChild.remove();
		}
	},
	
	appendChild: function(c) {
		var n = this.getLoader().createNode(c);
		this.root.appendChild(n);
	}
});
 
// register xtype
Ext.reg('n.statictreepanel', Nexts.tree.StaticTreePanel); 
 
