/**
 * Project  : AMDA-NG4
 * Name     : InteractiveNode.js
 * @class   amdaModel.InteractiveNode
 * @extends amdaModel.AmdaNode
 * @brief   Generic Model of Interactive Node
 * @author  CDA
 * @version $Id: InteractiveNode.js 2683 2014-12-02 10:58:53Z elena $
 */

Ext.define('amdaModel.InteractiveNode', {
	extend: 'amdaModel.AmdaNode',

	fields: [
		{name: 'contextNode', type: 'amdaModel.AmdaNode', persist: false},
		{name: 'objectDataModel', type: 'string', persist: false},
		{name: 'object', type: 'object', persist: false},
		{name: 'moduleId', type: 'string', persist: false},
		{name: 'filtered', type: 'boolean', defaultValue: false, persist: false},
		{name: 'needsArgs', type:'boolean', defaultValue: false},
		{name: 'predefinedArgs', type:'boolean', defaultValue: false},
		{name: 'disable', type: 'boolean', defaultValue: false, persist: false},
		{name: 'last_update', type: 'int', defaultValue: 0}
	],

	statics: {
		preloadNodes : function(node,onready)
		{
			var me = this;
			var nodesToLoad = new Array();
			nodesToLoad.push(node);
			this.preloadTreeNode(node, nodesToLoad, function (node)
				{
					var isFinish = true;
					nodesToLoad.forEach(function (element, index, array)
					{
							if (!element.isLoaded())
								isFinish = false;
					});
					if (isFinish && onready)
						onready.call();
				});
		},

		preloadTreeNode : function(node, nodesToLoad, onloaded)
		{
			var me = this;

			if (node.isLoaded())
			{
				node.eachChild(function(n)
					{
						if (!n.isLoaded() && !n.isLeaf())
						{
							nodesToLoad.push(n);
							me.preloadTreeNode(n,nodesToLoad,onloaded);
						}
					});

					if (onloaded)
						onloaded.call(me,node);
					return;
			}

			node.store.load({
				node : node,
				callback : function(records, operation, successful)
					{
						records.forEach(function (record)
							{
								if (!record.isLoaded() && !record.isLeaf())
									{
										nodesToLoad.push(record);
										me.preloadTreeNode(record,nodesToLoad,onloaded);
									}
							});
						if (onloaded)
							onloaded.call(me,node);
					}
			});
		}
	},

	onReady : null,

	constructor : function(config)
	{
		this.callParent(arguments);
		this.set('nodeType',this.self.nodeType);
		this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
		if (this.get('id')) { // TODO why sometimes (delete in remote interoper tree) this.get('id') = undefined ?
			// if id of this node have root category suffix
			if (Ext.util.Format.substr(this.get('id'), -(amdaUI.ExplorerUI.CAT_SUFFIX.length), this.get('id').length) === amdaUI.ExplorerUI.CAT_SUFFIX)
			{
			// set the expanded property to true
				this.set('expanded',true);
			}
		}
	},

/**
* this method is overriden into ExecutableNode to return true
*/
	isExecutable: function()
	{
		return false;
	},

/**
* open Module with THIS NODE
*/
	editInModule : function (contextNode, onReady)
	{
		// set the contextNode of this node
		this.set('contextNode',contextNode);
		// parameter module
		var me = this;
		myDesktopApp.getLoadedModule(this.get('moduleId'),true, function (module) {
		// If the node to edit is not already linked to this module
			if (module.getLinkedNode() != me)
			{
				// set relative node into parameter Module
				module.setLinkedNode(me);
				if (contextNode==null)
				{
					// set the root node as contextNode
					contextNode = me.getRootNode();
				}
				module.setContextNode(contextNode);

			} else if (module.getLinkedNode() != null){
			//TODO the node to edit is already edited
				// myDesktopApp.warningMsg('This object is  being edited');
				//Sol1: msg alert: "warning this node is already edited! If you want to get the original, please press the 'reset' button"->'OK'
				//Sol2: msg with user choice: "warning this node is already edited! Would you confirm this action and lost your modification?"->'Confirm','Cancel'
			}
			// Opening parameter window
			module.createWindow(onReady);
		});
	},

/**
* Method to rename the workspace node
*/
	rename: function(value,callBackFn)
	{
		var dataToSend = {id : this.get('id'), old_name: this.modified.text, name: value,  parent : this.data.parentId, leaf: this.isLeaf(), nodeType: this.get('nodeType')};
		AmdaAction.renameObject(dataToSend, callBackFn);
	},

/**
* Method to rename the workspace node when D&D
*/
	renameDD: function(parentId, callBackFn)
	{
		var dataToSend = {id : this.get('id'), old_name: this.get('name'), name: this.get('name'), parent : parentId, leaf: this.isLeaf(), nodeType: this.get('nodeType')};
		AmdaAction.renameObject(dataToSend, callBackFn);
	},

/**
* validation method on name (used in module forms)
* @param name the name to validate
* @returns
*/
	isValidName : function(name, callBackFn)
	{
		var dataToSend = {name: name, nodeType: this.get('nodeType'), leaf: this.isLeaf()};
		AmdaAction.validNameObject(dataToSend, callBackFn);
	},

/**
* Method to persist modifications of an AmdaObject by Server side and update the workspace
* node linked to a Module
*/
	update : function(opt)
	{
		AmdaAction.modifyObject(this.get('object').getJsonValues(true), function(res,e){

			if(e.status) {
				if (res.id) {
					if (!this.get('contextNode')) {
						// set the root node of 'Derived Parameters' tree as contextNode
						this.set('contextNode',this.getRootNode());
					}
					this.get('contextNode').expand(false,false);
					this.myGetOwnerTree().getSelectionModel().select(this);

					if (opt)
					{

						var scope = opt.scope ? opt.scope : this;
						if (opt.callback)
							opt.callback.call(scope,'update',res);
              if(opt.notDisplayMsg || opt.callback ){
                   //do nothing
              }else{
                  Ext.Msg.alert('Complete', 'Object '+this.get('object').get('name')+' has been modified');
              }

					 }

					// fix the modifications for object
					this.get('object').commit();

					if (res.info) {
						this.set('info',res.info);
					}

					if (res.last_update) {
						this.set('last_update', res.last_update);
						this.get('object').set('last_update', res.last_update);
					}

					// myDataParam  and Parameter special update
					this.specialUpdate(res, false);

					// reload object into the view of corresponding Module
					var me = this;
					myDesktopApp.getLoadedModule(this.get('moduleId'), true, function (module) {
						if (!opt || !opt.plot) {
							module.getUiContent().setObject(me.get('object'));
						}
						else {
							module.getUiContent().reloadPlot(me);
						}
					});
				}
				else {
					//TODO proper error message handling
					// error code from server; but e.status==true
					// revert all modifications since last load or commit
					this.get('object').reject();
					myDesktopApp.errorMsg(res.error);
				}
			}
			else {
				// revert all modifications since last load or commit
				this.get('object').reject();
				myDesktopApp.errorMsg(e.message);
			}
		},this);
	},

/**
* Method to create a new AmdaObject by server side and create the workspace node linked to a Module
* under its contextNode or the root node corresponding to this nodeType category
*/
	create : function(opt)
	{
		if (!this.get('contextNode') || (this.get('contextNode').data.id == 'sharedtimeTable-treeRootNode') || (this.get('contextNode').data.id == 'sharedcatalog-treeRootNode')) {
			// set the root node of 'Derived Parameters' tree as contextNode
			this.set('contextNode',this.getRootNode());
		}
		// call the Ext.Direct method to create parameter
		AmdaAction.createObject(this.get('object').getJsonValues(false), this.get('contextNode').get('id'), function(res,e){
			//success
			if(e.status)
			{
				// if correct response received
				if (res.id) {   //if (res.id || res.error == 'NAME_EXISTS') {
					// 'save as' case ; delete old node if it exists
					if (this.toRename)
					{
						this.toRename	= false;
						var myRoot = this.getRootNode();
						// search the same named node to override
						var updateNode = myRoot.findChild('text',this.get('object').get('name'),true);
						// destroy the overrided node
						updateNode.parentNode.removeChild(updateNode);//TODO ??if destroy==true => too many recursions....
						updateNode.destroy();
					}
					// set text of this node
					this.set('text',this.get('object').get('name'));

					//set id of this node
					this.set('id',res.id);
					this.internalId = res.id;

					// set id of node's object
					this.get('object').set('id',res.id);
					if (res.created){
						// set the created date
						this.get('object').set('created',res.created);
					}

					if (res.info){
						// set the tooltip
						this.set('info',res.info);
					}

					var reloadObject = false;
					if (res.last_update) {
						this.set('last_update', res.last_update);
						this.get('object').set('last_update', res.last_update);
						reloadObject = true;
					}

					//set globalStart & global Stop to be used for time selection
					this.specialUpdate(res, true);

					// reload object into the view of corresponding Module
					var me = this;
					if (reloadObject) {
						myDesktopApp.getLoadedModule(this.get('moduleId'), true, function (module) {
							if (!opt || !opt.plot) {
								module.getUiContent().setObject(me.get('object'));
							}
							else {
								module.getUiContent().reloadPlot(me);
							}
 						});
					}

					//TODO do we need this commission ???
					// fix the modifications for object
					this.get('object').commit();

					// if ownerTree panel is not active
					if (this.myGetOwnerTree().ownerCt.getActiveTab()!==this.myGetOwnerTree()) {
						// set ownerTree panel as the active tab - to enable selection of this node his ownerTree must have a view
						this.myGetOwnerTree().ownerCt.setActiveTab(this.myGetOwnerTree());
					}
                                                                                                    if(opt && opt.notDisplayMsg){
                                                                                                        //do nothing
                                                                                                        }else{
                                                                                                                       Ext.Msg.alert('Complete', 'New object '+this.get('object').get('name')+' has been created');
                                                                                                            }

					// expand the contextNode
					this.get('contextNode').expand(false, function() {
						if (!this.get('contextNode').findChild('text',this.get('text'))) {
							// create node in tree as child of contextNode
							this.get('contextNode').appendChild(this);
						}
						// select the new node
						this.myGetOwnerTree().getSelectionModel().select(this);
						if (opt) {
							var scope = opt.scope ? opt.scope : this;
							if (opt.callback)
									opt.callback.call(scope,'create',res);
						}
					}, this);
				}
				// error code from server; but e.status==true
				else {
					myDesktopApp.errorMsg(res.error);
					// revert all modifications since last load or commit
					this.get('object').reject();
				}
			}
			// failure: e.status == false
			else {
				// revert all modifications since last load or commit
				this.get('object').reject();
				//TODO: this.destroy();
				myDesktopApp.errorMsg(e.message);
			}
		},this);
	},

	specialUpdate : function() {},
/**
* Generic part of Context Menu
*
*/
	allMenuItems : function() {
		var src = this.self.objectName;
		var menuItems =
		[ {
			fnId : 'root-createLeaf',
			text : 'Create '+ src
		}, {
			fnId : 'root-createDir',
			text : 'Create Folder'
		}, {
			fnId : 'dire-createLeaf',
			text : 'Create ' + src
		}, {
			fnId : 'dire-createDir',
			text : 'Create Folder'
		}, {
			fnId : 'dire-renameNode',
			text : 'Rename Folder'
		}, {
			fnId : 'dire-deleteNode',
			text : 'Delete Folder'
		}, {
			fnId : 'leaf-editLeaf',
			text : 'Edit ' + src
		}, {
			fnId : 'leaf-renameNode',
			text : 'Rename ' + src
		}, {
			fnId : 'leaf-deleteNode',
			text : 'Delete '+ src
		} ];
		return menuItems;
	},

	allMenuMultiItems : function() {
		var menuMulti = [
		{
			fnId : 'mult-deleteMulti',
			text : 'Delete selected ' + this.self.objectName + 's'
		}
		];
		return menuMulti;
	},

	getAllContextMenuItems: function(){
		return  this.allMenuItems();
	},

	getMultiContextMenuItems: function(){
		return this.allMenuMultiItems();
	},

/**
* default implementation
* no menu display if there's no override of this function
*/
	getMultiContextMenuItems: function(){
		return null;
	},

/**
*  Context Menu Actions
*
*/
	onMenuItemClick : function(menu,item,event) {
		// fnId parsing :
		var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length);

		switch (fnId) {
			case 'deleteNode':
				this.deleteNode();
				break;
			case 'createDir':
				this.createDir();
				break;
			case 'createLeaf':
				this.createLeaf(this);
				break;
			case 'renameNode':
				this.renameNode(false);
				break;
			case 'editLeaf':
				this.editLeaf();
				break;
			case 'deleteMulti':
				this.deleteMulti();
				break;
			case 'plotParam':
				this.createPlot(this);
				break;
			case 'downParam':
				this.createDownload(this);
				break;
			case 'generateCatalog':
				this.generateCatalog(this);
				break;
			case 'generateTT':
				this.generateTT(this);
				break;
			case 'plotTT':
				this.createPlot(this);
				break;
			case 'copyID':
				this.ttCopyID(this);
				break;
			default:
				break;
		} // switch end
	},


     ttCopyID : function(node) {
        var ID = document.createElement("textarea");
		ID.value = node.data.id;
		document.body.appendChild(ID);
		ID.select();
		document.execCommand("copy");
		document.body.removeChild(ID);
     },

	getTimeFromNode: function(node)  {
		var startString = new String(node.get('globalStart'));
		var stopString = new String(node.get('globalStop'));

		var startDate =  new Date(startString.replace(/\-/g,'\/').replace(/[T|Z]/g,' '));
		var stopDate =  new Date(stopString.replace(/\-/g,'\/').replace(/[T|Z]/g,' '));
                                                
		if (stopDate -  startDate  > 86400000 ) {
			var startTime = Ext.Date.add(stopDate, Ext.Date.DAY, -1);
			// var timeObj = {start: Ext.Date.format(startTime, 'Y/m/d H:i:s'), stop: Ext.Date.format(stopDate, 'Y/m/d H:i:s')};
			var timeObj = {start: Ext.Date.format(startTime, 'Y/m/d H:i:s.u'), stop: Ext.Date.format(stopDate, 'Y/m/d H:i:s.u')};
		}
		else {
			var timeObj = {start: Ext.Date.format(startDate, 'Y/m/d H:i:s.u'), stop: Ext.Date.format(stopDate, 'Y/m/d H:i:s.u')};
		}
		return timeObj;
	},

	createPlot: function(node)
	{
		if (node.get('disable')) return;
		myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id, true, function (module) {
                    module.addParameter(node);
		});
	},

	createDownload: function(node)
	{
		myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id, true, function (module) {
		    module.addParameter(node);
		});
	},

	deleteNode: function() {
			// if the target is a directory
			if (!this.isLeaf()) {
				// determine if this directory is empty before launching the delete confirmation method
				this.isNotEmptyDir(this.confirmDirectoryDeletion);
			// else (the target is a leaf)
			} else {
				// no confirmation prompt for leaves
				this.confirmDirectoryDeletion(false);
			}
	},

/**
* this method return if node has Childs even if it was not already loaded
*/
	isNotEmptyDir : function(callbackFn) {
		var hasChilds;
		// if node not already loaded
		if (!this.isLoaded()){
			// call directFunction to load this node
			AmdaAction.getTree({node:this.get('id'),nodeType:this.get('nodeType')},function(res,e){
				callbackFn.call(this,res.length>0?true:false);
			},this);
		}
		else {
			callbackFn.call(this,this.hasChildNodes());
		}
	},

/**
* this method is used to display a confirmation message
*/
	confirmDirectoryDeletion : function(isNotEmptyDir)
	{
		// if this is a non-empty directory
		if (isNotEmptyDir) {
			// Prompt to the user if he also wants to delete its content
			Ext.Msg.confirm('non-empty directory', 'The target is a non-empty directory!<br>Do you want to continue and also delete its content?', function(btn, text){
				if (btn == 'yes'){
					// do delete
					this.realDelete();
				}
			},this);
		}
		else {
			this.realDelete();
		}
	},

/*
*    Call the extDirect method to delete parameter
*    Callback method needed to execute node deletion in tree if id in result or to show error msg
*/
	realDelete : function()
	{
		AmdaAction.deleteObject({id: this.get('id'), leaf: this.isLeaf(), nodeType: this.get('nodeType')}, function(res,e){
			//TODO proper errors handling
			// node deletion in tree
			if (res) {  // if success
				if (res.id) {
					//Ext.Msg.show({title:'Warning', msg: 'Requests with parameter '+node.data.text+' are deleted', icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK});
					if (this.parentNode) {
						if (this.isLeaf()){
							var moduleId = this.get('moduleId');
							// if really interactive node
							if (moduleId) {
								var win = myDesktopApp.getDesktop().getWindow(moduleId);
								// if window is really open
								if (win) {
									var me = this;
									myDesktopApp.getLoadedModule(moduleId, true, function (module) {
										var editedNode = module.getLinkedNode();

										// file node is not linked directly to the module
										var isThisFile = false;
										if (editedNode && editedNode.$className == 'amdaModel.MyDataParamNode')
											if (editedNode.get('fileObject').get('fileName') == me.get('text'))
												isThisFile = true;

										// node was created BEFORE tree loading; node.id are different ; but it is the same node
										if ( editedNode && editedNode.get('id') == me.get('id') && editedNode !== me ) {
											module.setLinkedNode(me);
											isThisFile = true;
										}

										if (me.$className == 'amdaModel.DerivedParamNode') {
											var obj = {
												paramId : 'ws_'+me.get('text')
											};
											AmdaAction.compilParamDelete(obj);
										}

										if (editedNode === me || isThisFile ){
											var newNode = Ext.ModelManager.create({leaf : true}, me.$className);
											// several tabs could be connected to one node
											if (moduleId === myDesktopApp.dynamicModules.plot.id) {
												var linkedNodes = module.linkedNodes;

												if (linkedNodes) {
													linkedNodes.each(function(key, value){
														if (value === me) {
															linkedNodes.replace(key,newNode);
															var tabPanel = module.getUiContent().tabPanel.items.getByKey(key);
															tabPanel.setObject(Ext.create(amdaModel.Plot.$className, {}));
														}
													}, me);
												}
											}
											newNode.editInModule();
										}
									});
								}
							}
							else {
								if((this.get('nodeType') == "bkgWorks") &&
                                   (this.get('status') == amdaModel.BkgJobNode.STATUS_LIST.IN_PROGRESS)){
									switch (this.get('jobType')) 
									{
										case 'condition' : var type = 'Data Mining '; break;
										case 'request' : var type = 'Plot '; break;   
										case 'download' : var type = 'Download '; break;
										case 'statistic' : var type = 'Statistics '; break;
										default: var type = 'unknown';    
									}
				
									var message = Ext.Date.format(new Date(res.time*1000), 'Y-m-d H:i:s: ') + type + ' '+this.get('text') + ' killed';
									myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id, true, function (module) {
										module.addLogMessage(message); 
									});
								}
							}
						}
						//update mask info in myData
						if (res.maskDesc && !res.maskDeleted) {
							this.parentNode.set('info', res.maskDesc);
							this.updateMyDataParam(res.mask, res.maskDesc);
						}
						this.remove();
					}
					//TODO Several special node-dependent actions - to move to node functions..
					// nodes of another nodeType to be deleted as they depend on deleted node
					if (res.params) {
						this.deleteDependence(res.params);
						//TODO reset
					}
					// mask was deleted or updated - to update mydata tree
					if (res.maskDeleted) {
						this.updateMyData();
					}
				}
				else {
					myDesktopApp.warningMsg(res.error);
				}
			}
			else {
				myDesktopApp.errorMsg(e.message);
			}
		}, this);
	},

/*
*  Delete musti selection
*/
	deleteMulti: function()
	{
		var selection = this.myGetOwnerTree().getSelectionModel().selected.items;
		alert(selection.length +' to delete!');
		Ext.Array.each(selection,function(item,index,allItems){
			item.deleteNode();
		})
	},

/*
*  Create Folder
*/
	createDir: function() {
		var me = this;
		amdaModel.InteractiveNode.preloadNodes(this.getRootNode(),
			function()
			{
				var newNode = Ext.create(me.$className,
				{
					leaf : false, nodeType : me.get('nodeType'),
					text : amdaModel.AmdaNode.NEW_DIR_NAME,
					children : [],
          parentId: me.get('id')
				});

				// insert the new node as a child of node
        me.insertChild(0, newNode);
				// start text edition on this new directory node
				me.expand(false);
				newNode.expand(false);

				// select the new node
				me.myGetOwnerTree().getSelectionModel().select(newNode);
				// call the renameNode method for this new node
				newNode.renameNode(true);
			});
	},

/*
*
*/
	createLeaf: function(contextNode) {
		// create new node with the same type than the contextNode
		var newNode = Ext.create(contextNode.$className, {leaf : true});

		// load the rootNode and recursively all its child nodes
		amdaModel.InteractiveNode.preloadNodes(contextNode.getRootNode(),
			function()
			{
				// edit newNode into Parameter Module with node as contextNode
				newNode.editInModule(contextNode);
			});
	},

	renameNode: function(deleteOnFailure)
	{
		if (this.myGetOwnerTree())
		{
			// load the rootNode and recursively all its child nodes if not already loaded
			var me = this;
			amdaModel.InteractiveNode.preloadNodes(this.getRootNode(),
				function()
				{
					// fire the edition event on tree
					var item = me.myGetOwnerTree().getSelectionModel().selected.items[0];
					item.deleteOnFailure = deleteOnFailure;
					me.myGetOwnerTree().fireEvent('edition', me.myGetOwnerTree().view, item);
				});
		}
		else
		{
			myDesktopApp.errorMsg('tree is undefined');
		}
	},

/*
*       load the rootNode and recursively all its child nodes
*       to know all names of DerivedParameters
*/
	editLeaf: function(onReady)
	{
		var me = this;
		amdaModel.InteractiveNode.preloadNodes(this.getRootNode(),
		function()
		{
			if (me.get('object'))
			{
				// launch edition of parameter into parameter module
				me.editInModule(null, onReady);
			}
			else
			{
				// call the ext method to get the details of parameter
				// the edition of real parameter is done into callback method getObjectCallback
				if (onReady)
					me.onReady = onReady;

				AmdaAction.getObject(me.get('id'), me.get('nodeType'), me.getObjectCallback, me);
			}
		});
	},

/*
*
*/
	getObjectCallback : function(result,remoteEvent)
	{
		var t = remoteEvent.getTransaction();

		if (result) {
			var paramObj = Ext.create(this.get('objectDataModel'), result);
			// set parameter into node
			this.set('object',paramObj);
			// Edition of parameter into parameter Module
			this.editInModule(null, this.onReady);
			this.onReady = null;
		}
		else {
		// EXCEPTION : parameter not found !?
			myDesktopApp.errorMsg(t.action + "." + t.method + " : No parameter '"
			+ this.get('name') + "' found!");
		}
 	},

        generateCatalog: function(node){
            id = node.get('id');
            name = node.get('text');
            Ext.Msg.prompt('Create catalog', 'Enter the number of columns:', function (btn, text) {
            if (btn == 'ok') {
                var catObj = Ext.create('amdaModel.Catalog');
                var catNode = Ext.create('amdaModel.CatalogNode', {leaf: true});
                catObj.set('relatedTimeTableId', id);
                //creatDate = new Date(this.object.get('created'));
                //date = Ext.Date.format(creatDate, 'Y-m-d\\TH:i:s');
                descr = 'Generated by CDPP/Amda Time Table Module \n' + 'From Time Table: ' + name;
                catObj.set('description', descr );
                var nbParam = parseInt(text);
                if ((nbParam <= 0) || (nbParam > 100)) {
                    nbParam = 1;
                }
                catObj.set('nbParameters', nbParam);
                catNode.set('object', catObj);
                var explorerTree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
                var catRootNode = explorerTree.getRootNode().findChild('id', 'catalog-treeRootNode', true);
                amdaModel.InteractiveNode.preloadNodes(catRootNode.getRootNode(),
                        function ()
                        {
                            catNode.editInModule();
                        });
              }
          }, this);
        }, 
      generateTT: function(node){
                       var catObj = Ext.create('amdaModel.TimeTable');
                              var timeTabNode = Ext.create('amdaModel.TimeTableNode',{leaf : true});
                              catObj.set('relatedCatalogId', node.get('id'));
                              desc =   'Generated by CDPP/Amda Catalog Module \n';
                              if (node.get('description'))
                                  desc = desc + node.get('description');
                              catObj.set('description', desc);
                              timeTabNode.set('object',catObj);
                              var explorerTree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
                                        var ttRootNode = explorerTree.getRootNode().findChild('id', 'timeTable-treeRootNode', true);
                                        amdaModel.InteractiveNode.preloadNodes(ttRootNode.getRootNode(),
                        function()
                        {
                                timeTabNode.editInModule();
                        });
        },

});