/**
 * Project   : AMDA-NG
 * Name      : ParamsMgrUI.js
 * @class    amdaUI.ParamsMgrUI
 * @extends  Ext.Panel.Panel 
 * @brief     
 * @author Elena         
 */

Ext.define('amdaUI.ParamsMgrUI',{
	extend: 'Ext.panel.Panel',	
	alias: 'widget.paramsMgrPanel',
	
	baseId : null,
	srcTree : null,
	destTree : null,
    
	//TODO where keep this (==baseId) description ? Global variable?
	basesNames : ['CDAWEB', 'THEMIS'], // 'MAPSKP'
	bases : [],
   
	configSrc  : {title: 'source', enableDrag : true, enableDrop: false},
	configDest : {title: 'destination', enableDrag : false, enableDrop:true},
	       
	constructor: function(config){    
		this.init(config);
		this.callParent(arguments);
	}, 
	
	/*
	* Load new data bases trees	: source & destination
	*/   
	loadTrees : function(button, pressed){
		if (pressed) {    
			this.baseId =  button.text;	
			this.loadTree('source');
			this.loadTree('destination');
		}
	},
	
	/*
	* Real Load  data base tree	
	*/   
	loadTree : function(type){
		var title = this.baseId;
		if (type == 'source'){
			var store = this.srcTree.getStore();
			
		}
		else {
			var store = this.destTree.getStore();
			title = 'My '+ this.baseId;
		}
		// sort alphabetically
		store.sort([
			{ sorterFn: function(o1, o2){						
					return o1.get('text').toUpperCase()  < o2.get('text').toUpperCase() ? -1 : 1;
				} 
			}
		]);
		// or RELOAD?
		var root = store.getRootNode();		   
		store.load({
			node: root,
			params: {
				nodeType: type,
				baseId: this.baseId
			}
		});	
		root.set('text', title);		    		  
	},
	
	/*
	*   Store and tree creation
	*/
	initTree:  function(config){		  
		if (this.baseId){
			var title = config.title == 'source' ? this.baseId : 'My '+ this.baseId;
		}
		else 
			var title = config.title;
	   
		var selMode =  config.title == 'source' ? {mode: 'SIMPLE'} : {mode: 'SINGLE'};

		var store = Ext.create('Ext.data.TreeStore', {
			model: 'amdaModel.AmdaNode',		     
			root: {			  			  
					text: title,
					nodeType : 'remoteParam',
					expanded: true
			},
			listeners: {
				scope : this,
				beforeload: function(store, operation){
					store.proxy.extraParams = {
						nodeType: config.title,
						baseId: this.baseId
					}
				}}
		});
	
		var menu = new Ext.menu.Menu({
			items: [{
				text: 'Delete Data'
			}],
			listeners: {
				scope : this,
				click : this.deleteMulti
			}
		});
	
		var tree = Ext.create('Ext.tree.Panel', {
			store: store,
			id : config.title,
			flex: 1,
			height: 500,
			selModel: selMode, //{mode: 'SIMPLE'},
			viewConfig: {
				plugins:{
					ptype: 'treeviewdragdrop',
					allowContainerDrops : true,
					enableDrag: config.enableDrag,
					enableDrop: config.enableDrop,
					//TODO dataset drag/drop by parameters SELECTION
					dragText : "{0} selected parameter{1}",
					expandDelay : 100,   
					ddGroup : "RemoteTreeDD",
					
					isValidDropPoint : function(){	            
						return true;
					},
					
					onContainerOver : function() { 
						return this.dropAllowed;      
					},
					
					onNodeOver : function() { 
						return this.dropAllowed;      
					},
					
					onNodeDrop : function(nodeData, dd, e, data){ 
						if (!data.records)
							return false;
						Ext.Array.each(data.records, this.onDrop, this);
						// deselect source tree selection		      
						data.view.getSelectionModel().deselectAll();
						
						return true;      
					},
					
					onContainerDrop : function(dd, e, data){      
						if (!data.records)
							return false;		
						Ext.Array.each(data.records, this.onDrop, this); 
						// deselect source tree selection		      
						data.view.getSelectionModel().deselectAll();
						
						return true;
					},
					
					onDrop : function(record) {    
						var root = tree.getRootNode();		   
						var srcNode = record;		   
						var id = srcNode.get('id');						
						// Check if node exists already at destination
						var idToCheck = id.toLowerCase().replace(":", "_", "gi");
						// TODO check at sever side
						if (root.findChild('id',idToCheck, true)) {
							myDesktopApp.infoMsg('This parameter exists already in your treee');
							return;
						}
						var ddNode = srcNode;
						// Array of parent nodes description  
						var Arr = [];
						while (!ddNode.isRoot()) { 
							ddNode = ddNode.parentNode;
							Arr.push(ddNode);
						}
						// start with the highest node    
						Arr.reverse();   
						// create parent nodes if they do not exist
						var parentNode = root;
						Ext.Array.each(Arr,function(srcNode, index) {
							if (index > 0) {
								var nodeId = srcNode.get('id');
								var node = root.findChild('id',nodeId, true);
								if (!node) {
									node = srcNode.copy();
									parentNode.appendChild(node);
									parentNode.expand();
									node.setDirty();
								} 
								parentNode = node;
							}       
						});

						// Add new node to correct location    
						parentNode.expand(!this.isDataSet, function(res){ 
							var newNode = srcNode.copy();
							parentNode.appendChild(newNode); 	
							//to sync treeStore			  
							newNode.setDirty();
							//expand the whole subtree of added node
							tree.selectPath(newNode.getPath( 'id', '|'), 'id', '|');
						});
						return true; 
					},
					
					onViewRender : function(view){
						var me = this;

						if (me.enableDrag){
							me.dragZone = Ext.create('Ext.tree.ViewDragZone', {
								view: view,
								ddGroup: me.dragGroup || me.ddGroup,
								dragText: me.dragText
							});
						}
						
						if (me.enableDrop){
							me.dropZone = Ext.create('Ext.tree.ViewDropZone', {
								view: view,
								ddGroup: me.dropGroup || me.ddGroup,
								allowContainerDrops: me.allowContainerDrops,
								expandDelay: me.expandDelay,
								isValidDropPoint : me.isValidDropPoint,
								onContainerDrop : me.onContainerDrop,
								onNodeDrop      : me.onNodeDrop,
								onContainerOver : me.onContainerOver,
								onNodeOver : me.onNodeOver,
								onDrop : me.onDrop,
								onSimpleDrop : me.onSimpleDrop
							});
						}
					}
				}
			},
			
			listeners: {
				afterrender: function(comp) {		   
					var view = comp.getView();                  
					view.tip = Ext.create('Ext.tip.ToolTip', {
						// The overall target element.
						target: view.el,
						// Each grid row causes its own seperate show and hide.
						delegate: view.itemSelector,			  				   				 
						// Moving within the row should not hide the tip.
						trackMouse: true,			   
						autoRender: true,				   
						listeners: {
							// Change content dynamically depending on which element triggered the show.
							beforeshow: function updateTipBody(tip) {	
								var trigger =  view.getRecord(tip.triggerElement);
								if (trigger) {
									var info = trigger.get('info');
									if (!info || info == '') {    
										tip.addCls('hide');  
									}
									else { 
										tip.removeCls('hide'); 
										tip.update(info); 
									}  
								}
							}
						}
					});
				},
				
				itemmouseenter: function(view, record, item){ 
					if(record.get('allowDrag') && view.ownerCt.id == 'source'){		 
						var el = Ext.get(item),
						td = el.down('td > div');
						td.setStyle('cursor', 'crosshair');				
					}
				},
				
				beforeselect: function(selmodel, record, index) {		    
						if (!(record.get('isRemoteDataSet') || record.get('isParameter')) && tree.id == 'source') return false;			 	  			      
				},
				
				select: function(selmodel, record, index){			
					if (record.get('isRemoteDataSet') && tree.id == 'source' && record.isExpanded()) {
						var toSelect = selmodel.getCount() !== record.childNodes.length + 1;
						var alreadySelected = selmodel.isSelected(record.firstChild);
							
						selmodel.deselectAll();
							
						if (toSelect && !alreadySelected) 
							selmodel.select(record.childNodes);			 
					}
				},
				
				itemcontextmenu: function(view, rec, item, index, e)
				{		  
					e.preventDefault();//stopEvent();
					if (tree.id == 'destination' && rec.getDepth() > 0)  		        
								menu.showAt(e.getXY());        
				}
			}
		});
		
		return tree;
	},
	
	// for the moment SINGLE!    
	deleteMulti: function(){
		var selected = this.destTree.getSelectionModel().getSelection();
		Ext.Array.each(selected, function(rec){			
			rec.deleteData();
		}); 
		
		// reload destination tree and expand created nodes	     		     
		var store = this.destTree.getStore();
		var root = store.getRootNode();		
		store.load({ node : root, 
			params : { nodeType: 'destination',
							baseId : this.baseId }
		});
	},
       
	successCallBack : function(batch, options) {      
		loadMask.hide(); 
		// Check Errors
		var res = batch.operations[0].response.result;
		if (res.err) {
			myDesktopApp.errorMsg(res.err);
			this.loadTree('destination');	
		}
		else {
			var createdNodes = options.operations.create;
			// define Pathes to the created nodes	     
			Arr = [];	
			Ext.Array.each(createdNodes,function(item){ 			
				if (item.get('isParameter')){ // parameter level 
					Arr.push(item.getPath('id', '|')); 
				}
			});		
			// reload destination tree and expand created nodes	     
			var panel = this.destTree;	     
			var store = this.destTree.getStore();
			var root = store.getRootNode();		
			store.load({ node : root, 
				params : { nodeType: 'destination',
								baseId : this.baseId },	
				scope : this,
				callback : function(){
					for (var i = 0; i < Arr.length; i++){
						panel.selectPath(Arr[i], 'id', '|');
					}
				}
			});
			
			this.updateUserTree();
		}
	},
	
	failureCallBack : function(batch, options) {     
		myDesktopApp.errorMsg('Error while saving modifs');  
		loadMask.hide();	      
		this.loadTree('destination');	       	
	},   
	
	/*
	*  Update User Tree in Explorer after the the modifs
	*/
	updateUserTree : function() {
		// reload RemoteParam Tree in explorer
		var explorerTree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
		if (explorerTree) 
		{					  
			var explorerTreeStore = explorerTree.getStore();
			var explorerRoot = explorerTreeStore.getRootNode();
			var explorerPath = '/root/parameters-treeBase/myRemoteData-treeRootNode/';
			
			explorerTreeStore.load( { node : explorerRoot, 
					params : { nodeType: 'resources'},
					callback : function(){
						explorerTree.selectPath(explorerPath);						 
					}
			});	      	 
		}
		myDesktopApp.infoMsg('Parameter Tree has been updated');
	},
	
	/*
	*  Panel Trees generation
	*/
	init: function(config) {
		if (config.baseId && config.baseId != 'root') 
			this.baseId = config.baseId;
	
		this.srcTree = this.initTree(this.configSrc);
		this.destTree = this.initTree(this.configDest);
		  
		// synchron load of destination tree if the corresponding  node exists		  
		this.srcTree.on('itemexpand', function(node) { 		      
			var root = this.destTree.getRootNode();
			var destNode = root.findChild('id',node.get('id'),true);
			if (destNode) destNode.expand();
		}, this);
		
		// toolbar		  
		Ext.Array.each(this.basesNames, function(baseName,index){
			var isTheBase = false;
			if (this.baseId && baseName == this.baseId) var isTheBase = true;
			this.bases[index] = {text: baseName,  toggleGroup: 'remoteBases', pressed: isTheBase, scope : this, toggleHandler: this.loadTrees}
		}, this);
						    
		var myConf = {   
			id : 'rb_tab_panel', 
			title : 'Remote Data Base',
			items: [                 
				this.srcTree, 
				this.destTree                      
			],
			tbar: this.bases,	                       
			fbar: [
				{ text: 'Save Modifs', 
					scope : this,					  
					handler: function(){				  
						var store = this.destTree.getStore();	
						var new_nodes = store.getNewRecords();	
						var removed_nodes =  store.getRemovedRecords();
						// if only removed: no sync - already removed at Server by node.delete	
						if ( new_nodes.length === 0 && removed_nodes.length > 0) this.updateUserTree();
						if ( new_nodes.length > 0 ){  
							loadMask.show();
							store.sync({ success : this.successCallBack, failure: this.failureCallBack, scope : this});	
						}
					}
				} 
			]
		};
		Ext.apply(this, Ext.apply(arguments, myConf)); 
	}	   		 	      
});